qcacmn: Enhancements for link switch connect
Introduce following for link switch disconnect: 1) Connect request source. 2) Connect request reason. If the set MAC address response for new link is successful, post connection on new link and transition the link switch state to connecting. If the status of connection is successful, update the state to link switch complete or else directly go for deserializing link switch command and posting response to FW. Based on the final state of link switch at the time of sending FW response, send the appropirate status of link switch and reset the state of link switch to idle post FW notify. Don't unlink BSS incase of failure in connection. Don't indicate connect results to userspace. As we are already in serialization due to link switch, don't serialize/deserialize connection command if it is due to link switch. Incase of race condition between link switch connect and userspace connect/disconnect always abort link switch connect. Change-Id: Ie350b52021c36802b82d6cb5f6f441fe1bd10458 CRs-Fixed: 3556529
Šī revīzija ir iekļauta:

revīziju iesūtīja
Rahul Choudhary

vecāks
a147f231ea
revīzija
35ea97c560
@@ -38,6 +38,7 @@
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
#include <wlan_mlo_mgr_peer.h>
|
||||
#endif
|
||||
#include <wlan_mlo_mgr_link_switch.h>
|
||||
#include <wlan_mlo_mgr_sta.h>
|
||||
#include "wlan_mlo_mgr_op.h"
|
||||
#include <wlan_objmgr_vdev_obj.h>
|
||||
@@ -1660,6 +1661,14 @@ cm_handle_connect_req_in_non_init_state(struct cnx_mgr *cm_ctx,
|
||||
cm_state_substate);
|
||||
}
|
||||
|
||||
/* Reject any link switch connect request while in non-init state */
|
||||
if (cm_req->req.source == CM_MLO_LINK_SWITCH_CONNECT) {
|
||||
mlme_info(CM_PREFIX_FMT "Ignore disconnect req from source %d state %d",
|
||||
CM_PREFIX_REF(vdev_id, cm_req->cm_id),
|
||||
cm_req->req.source, cm_state_substate);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
switch (cm_state_substate) {
|
||||
case WLAN_CM_S_ROAMING:
|
||||
/* for FW roam/LFR3 remove the req from the list */
|
||||
@@ -1796,7 +1805,18 @@ QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = cm_ser_connect_req(pdev, cm_ctx, cm_req);
|
||||
if (cm_req->req.source == CM_MLO_LINK_SWITCH_CONNECT) {
|
||||
/* The error handling has to be different here.not corresponds
|
||||
* to connect req serialization now.
|
||||
*/
|
||||
status = cm_sm_deliver_event_sync(cm_ctx,
|
||||
WLAN_CM_SM_EV_CONNECT_ACTIVE,
|
||||
sizeof(wlan_cm_id),
|
||||
&cm_req->cm_id);
|
||||
} else {
|
||||
status = cm_ser_connect_req(pdev, cm_ctx, cm_req);
|
||||
}
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
reason = CM_SER_FAILURE;
|
||||
goto connect_err;
|
||||
@@ -2757,7 +2777,7 @@ QDF_STATUS cm_notify_connect_complete(struct cnx_mgr *cm_ctx,
|
||||
resp->connect_status);
|
||||
cm_inform_dlm_connect_complete(cm_ctx->vdev, resp);
|
||||
if (QDF_IS_STATUS_ERROR(resp->connect_status) &&
|
||||
sm_state == WLAN_CM_S_INIT)
|
||||
sm_state == WLAN_CM_S_INIT && !(resp->cm_id & CM_ID_LSWITCH_BIT))
|
||||
cm_clear_vdev_mlo_cap(cm_ctx->vdev);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
@@ -2819,6 +2839,12 @@ QDF_STATUS cm_connect_complete(struct cnx_mgr *cm_ctx,
|
||||
resp->cm_id));
|
||||
cm_remove_cmd(cm_ctx, &resp->cm_id);
|
||||
|
||||
if (resp->cm_id & CM_ID_LSWITCH_BIT) {
|
||||
cm_reset_active_cm_id(cm_ctx->vdev, resp->cm_id);
|
||||
mlo_mgr_link_switch_connect_done(cm_ctx->vdev,
|
||||
resp->connect_status);
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@@ -36,6 +36,7 @@ static uint32_t cm_get_prefix_for_cm_id(enum wlan_cm_source source) {
|
||||
case CM_OSIF_CONNECT:
|
||||
case CM_OSIF_CFG_CONNECT:
|
||||
case CM_MLO_LINK_VDEV_CONNECT:
|
||||
case CM_MLO_LINK_SWITCH_CONNECT:
|
||||
return CONNECT_REQ_PREFIX;
|
||||
case CM_ROAMING_HOST:
|
||||
case CM_ROAMING_FW:
|
||||
@@ -59,7 +60,8 @@ wlan_cm_id cm_get_cm_id(struct cnx_mgr *cm_ctx, enum wlan_cm_source source)
|
||||
cm_id = (cm_id & CM_ID_MASK);
|
||||
cm_id = CM_ID_SET_VDEV_ID(cm_id, vdev_id);
|
||||
cm_id = (cm_id | prefix);
|
||||
if (source == CM_MLO_LINK_SWITCH_DISCONNECT)
|
||||
if (source == CM_MLO_LINK_SWITCH_DISCONNECT ||
|
||||
source == CM_MLO_LINK_SWITCH_CONNECT)
|
||||
cm_id |= CM_ID_LSWITCH_BIT;
|
||||
|
||||
return cm_id;
|
||||
@@ -597,6 +599,14 @@ cm_handle_connect_flush(struct cnx_mgr *cm_ctx, struct cm_req *cm_req)
|
||||
cm_fill_connect_resp_from_req(cm_ctx->vdev, resp, cm_req);
|
||||
|
||||
cm_notify_connect_complete(cm_ctx, resp, 0);
|
||||
|
||||
/* For link switch connect request, notify MLO mgr */
|
||||
if (resp->cm_id & CM_ID_LSWITCH_BIT) {
|
||||
cm_reset_active_cm_id(cm_ctx->vdev, resp->cm_id);
|
||||
mlo_mgr_link_switch_connect_done(cm_ctx->vdev,
|
||||
resp->connect_status);
|
||||
}
|
||||
|
||||
qdf_mem_free(resp);
|
||||
}
|
||||
|
||||
|
@@ -156,6 +156,7 @@ struct wlan_fils_con_info {
|
||||
* @CM_MLO_LINK_VDEV_DISCONNECT: Disconnect req for ML link
|
||||
* @CM_MLO_LINK_VDEV_CONNECT: Connect req for ML link
|
||||
* @CM_MLO_ROAM_INTERNAL_DISCONNECT: Disconnect req triggered for mlo roaming
|
||||
* @CM_MLO_LINK_SWITCH_CONNECT: Connect req triggered for mlo link switch
|
||||
* @CM_MLO_LINK_SWITCH_DISCONNECT: Disconnect req triggered for mlo link switch
|
||||
* @CM_SOURCE_MAX: max value of connection manager source
|
||||
* @CM_SOURCE_INVALID: Invalid connection manager req source
|
||||
@@ -177,6 +178,7 @@ enum wlan_cm_source {
|
||||
CM_MLO_LINK_VDEV_DISCONNECT,
|
||||
CM_MLO_LINK_VDEV_CONNECT,
|
||||
CM_MLO_ROAM_INTERNAL_DISCONNECT,
|
||||
CM_MLO_LINK_SWITCH_CONNECT,
|
||||
CM_MLO_LINK_SWITCH_DISCONNECT,
|
||||
CM_SOURCE_MAX,
|
||||
CM_SOURCE_INVALID = CM_SOURCE_MAX,
|
||||
|
Atsaukties uz šo jaunā problēmā
Block a user