qcacmn: Add bearer switch request in connect path
If LL_LT_SAP is already present and if STA tries to come up on same mac, then it may result in data loss on LL_LT_SAP as STA will need ROC on the connection channel for some time, to avoid these data loss during STA connection, add logic to switch the bearer for LL_LT_SAP data to non-wlan and once connection completes, switch back the bearer to wlan. Change-Id: Ic44cd77b9b5e569350d697c33260cf5cec3652e0 CRs-Fixed: 3627643
Cette révision appartient à :

révisé par
Rahul Choudhary

Parent
fb93c36d8d
révision
9a73106903
@@ -44,6 +44,9 @@
|
||||
#include <wlan_objmgr_vdev_obj.h>
|
||||
#include "wlan_psoc_mlme_api.h"
|
||||
#include "wlan_scan_public_structs.h"
|
||||
#ifdef WLAN_FEATURE_LL_LT_SAP
|
||||
#include "wlan_ll_sap_api.h"
|
||||
#endif
|
||||
|
||||
void
|
||||
cm_fill_failure_resp_from_cm_id(struct cnx_mgr *cm_ctx,
|
||||
@@ -313,9 +316,41 @@ cm_send_connect_start_fail(struct cnx_mgr *cm_ctx,
|
||||
}
|
||||
|
||||
#ifdef WLAN_POLICY_MGR_ENABLE
|
||||
static void
|
||||
cm_cont_connect_for_event(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
||||
wlan_cm_id cm_id, enum wlan_cm_sm_evt event)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
QDF_STATUS status;
|
||||
struct cnx_mgr *cm_ctx;
|
||||
|
||||
QDF_STATUS cm_handle_hw_mode_change(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
|
||||
enum wlan_cm_sm_evt event)
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
||||
WLAN_MLME_CM_ID);
|
||||
if (!vdev)
|
||||
return;
|
||||
|
||||
cm_ctx = cm_get_cm_ctx(vdev);
|
||||
if (!cm_ctx) {
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
status = cm_sm_deliver_event(vdev, event, sizeof(wlan_cm_id), &cm_id);
|
||||
|
||||
/*
|
||||
* Handle failure if posting fails, i.e. the SM state has
|
||||
* changed or head cm_id doesn't match the active cm_id. If
|
||||
* new command has been received connect should be
|
||||
* aborted from here with req cleanup.
|
||||
*/
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
cm_connect_handle_event_post_fail(cm_ctx, cm_id);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
cm_ser_connect_after_mode_change_resp(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
|
||||
enum wlan_cm_sm_evt event)
|
||||
{
|
||||
struct cm_req *cm_req;
|
||||
enum wlan_cm_connect_fail_reason reason = CM_GENERIC_FAILURE;
|
||||
@@ -337,18 +372,22 @@ QDF_STATUS cm_handle_hw_mode_change(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
|
||||
goto send_failure;
|
||||
}
|
||||
|
||||
if (event == WLAN_CM_SM_EV_HW_MODE_SUCCESS) {
|
||||
switch (event) {
|
||||
case WLAN_CM_SM_EV_HW_MODE_SUCCESS:
|
||||
case WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE:
|
||||
status = cm_ser_connect_req(pdev, cm_ctx, &cm_req->connect_req);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
reason = CM_SER_FAILURE;
|
||||
goto send_failure;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
case WLAN_CM_SM_EV_HW_MODE_FAILURE:
|
||||
reason = CM_HW_MODE_FAILURE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set reason HW mode fail for event WLAN_CM_SM_EV_HW_MODE_FAILURE */
|
||||
reason = CM_HW_MODE_FAILURE;
|
||||
|
||||
send_failure:
|
||||
return cm_send_connect_start_fail(cm_ctx, &cm_req->connect_req, reason);
|
||||
}
|
||||
@@ -356,40 +395,16 @@ send_failure:
|
||||
void cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
|
||||
wlan_cm_id cm_id, QDF_STATUS status)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
QDF_STATUS qdf_status;
|
||||
enum wlan_cm_sm_evt event = WLAN_CM_SM_EV_HW_MODE_SUCCESS;
|
||||
struct cnx_mgr *cm_ctx;
|
||||
|
||||
mlme_debug(CM_PREFIX_FMT "Continue connect after HW mode change, status %d",
|
||||
CM_PREFIX_REF(vdev_id, cm_id), status);
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
|
||||
WLAN_MLME_CM_ID);
|
||||
if (!vdev)
|
||||
return;
|
||||
|
||||
cm_ctx = cm_get_cm_ctx(vdev);
|
||||
if (!cm_ctx) {
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
event = WLAN_CM_SM_EV_HW_MODE_FAILURE;
|
||||
qdf_status = cm_sm_deliver_event(vdev, event, sizeof(wlan_cm_id),
|
||||
&cm_id);
|
||||
|
||||
/*
|
||||
* Handle failure if posting fails, i.e. the SM state has
|
||||
* changed or head cm_id doesn't match the active cm_id.
|
||||
* hw mode change resp should be handled only in JOIN_PENDING. If
|
||||
* new command has been received connect should be
|
||||
* aborted from here with connect req cleanup.
|
||||
*/
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
cm_connect_handle_event_post_fail(cm_ctx, cm_id);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
cm_cont_connect_for_event(wlan_pdev_get_psoc(pdev), vdev_id, cm_id,
|
||||
event);
|
||||
}
|
||||
|
||||
static QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
|
||||
@@ -400,10 +415,7 @@ static QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
|
||||
return policy_mgr_change_hw_mode_sta_connect(psoc, scan_list, vdev_id,
|
||||
connect_id);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
static inline
|
||||
QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
|
||||
qdf_list_t *scan_list, uint8_t vdev_id,
|
||||
@@ -411,9 +423,35 @@ QDF_STATUS cm_check_for_hw_mode_change(struct wlan_objmgr_psoc *psoc,
|
||||
{
|
||||
return QDF_STATUS_E_ALREADY;
|
||||
}
|
||||
|
||||
#endif /* WLAN_POLICY_MGR_ENABLE */
|
||||
|
||||
#ifdef WLAN_FEATURE_LL_LT_SAP
|
||||
void cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
||||
wlan_cm_id cm_id, QDF_STATUS status)
|
||||
{
|
||||
mlme_debug(CM_PREFIX_FMT "Continue connect after bearer switch %d",
|
||||
CM_PREFIX_REF(vdev_id, cm_id), status);
|
||||
|
||||
cm_cont_connect_for_event(psoc, vdev_id, cm_id,
|
||||
WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
cm_check_for_bearer_switch(struct wlan_objmgr_psoc *psoc, qdf_list_t *scan_list,
|
||||
uint8_t vdev_id, wlan_cm_id cm_id)
|
||||
{
|
||||
return wlan_ll_sap_switch_bearer_on_sta_connect_start(psoc, scan_list,
|
||||
vdev_id, cm_id);
|
||||
}
|
||||
#else
|
||||
static inline QDF_STATUS
|
||||
cm_check_for_bearer_switch(struct wlan_objmgr_psoc *psoc, qdf_list_t *scan_list,
|
||||
uint8_t vdev_id, wlan_cm_id cm_id)
|
||||
{
|
||||
return QDF_STATUS_E_ALREADY;
|
||||
}
|
||||
#endif /* WLAN_FEATURE_LL_LT_SAP */
|
||||
|
||||
static inline void cm_delete_pmksa_for_bssid(struct cnx_mgr *cm_ctx,
|
||||
struct qdf_mac_addr *bssid)
|
||||
{
|
||||
@@ -1889,6 +1927,14 @@ QDF_STATUS cm_connect_start(struct cnx_mgr *cm_ctx,
|
||||
goto connect_err;
|
||||
}
|
||||
|
||||
status = cm_check_for_bearer_switch(psoc, cm_req->candidate_list,
|
||||
vdev_id, cm_req->cm_id);
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
mlme_debug(CM_PREFIX_FMT "Connect will continue after bearer switch",
|
||||
CM_PREFIX_REF(vdev_id, cm_req->cm_id));
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
status = cm_check_for_hw_mode_change(psoc, cm_req->candidate_list,
|
||||
vdev_id, cm_req->cm_id);
|
||||
if (QDF_IS_STATUS_ERROR(status) && status != QDF_STATUS_E_ALREADY) {
|
||||
|
@@ -752,7 +752,7 @@ void cm_reassoc_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev,
|
||||
* new command has been received reassoc should be
|
||||
* aborted from here with reassoc req cleanup.
|
||||
*/
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
if (QDF_IS_STATUS_ERROR(qdf_status))
|
||||
cm_reassoc_handle_event_post_fail(cm_ctx, cm_id);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
||||
}
|
||||
|
@@ -332,19 +332,22 @@ void cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
|
||||
wlan_cm_id cm_id, QDF_STATUS status);
|
||||
|
||||
/**
|
||||
* cm_handle_hw_mode_change() - SM handling of hw mode change resp
|
||||
* cm_ser_connect_after_mode_change_resp() - SM handling of
|
||||
* hw mode change/bearer switch resp
|
||||
* @cm_ctx: connection manager context
|
||||
* @cm_id: Connection mgr ID assigned to this connect request.
|
||||
* @event: HW mode success or failure event
|
||||
* @event: success or failure event
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cm_handle_hw_mode_change(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
|
||||
enum wlan_cm_sm_evt event);
|
||||
QDF_STATUS cm_ser_connect_after_mode_change_resp(struct cnx_mgr *cm_ctx,
|
||||
wlan_cm_id *cm_id,
|
||||
enum wlan_cm_sm_evt event);
|
||||
#else
|
||||
static inline
|
||||
QDF_STATUS cm_handle_hw_mode_change(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id,
|
||||
enum wlan_cm_sm_evt event)
|
||||
QDF_STATUS cm_ser_connect_after_mode_change_resp(struct cnx_mgr *cm_ctx,
|
||||
wlan_cm_id *cm_id,
|
||||
enum wlan_cm_sm_evt event)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1591,4 +1594,19 @@ cm_bss_mlo_type(struct wlan_objmgr_psoc *psoc,
|
||||
return SLO;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_LL_LT_SAP
|
||||
/**
|
||||
* cm_bearer_switch_resp() - Bearer switch response
|
||||
* @psoc: Psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @cm_id: connection ID which gave the hw mode change request
|
||||
* @status: status of the bearer switch
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
||||
wlan_cm_id cm_id, QDF_STATUS status);
|
||||
#endif
|
||||
|
||||
#endif /* __WLAN_CM_MAIN_API_H__ */
|
||||
|
@@ -618,12 +618,13 @@ static bool cm_subst_join_pending_event(void *ctx, uint16_t event,
|
||||
break;
|
||||
case WLAN_CM_SM_EV_HW_MODE_SUCCESS:
|
||||
case WLAN_CM_SM_EV_HW_MODE_FAILURE:
|
||||
case WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE:
|
||||
/* check if cm id is valid for the current req */
|
||||
if (!cm_check_cmid_match_list_head(cm_ctx, data)) {
|
||||
event_handled = false;
|
||||
break;
|
||||
}
|
||||
cm_handle_hw_mode_change(cm_ctx, data, event);
|
||||
cm_ser_connect_after_mode_change_resp(cm_ctx, data, event);
|
||||
break;
|
||||
case WLAN_CM_SM_EV_SCAN:
|
||||
cm_sm_transition_to(cm_ctx, WLAN_CM_SS_SCAN);
|
||||
@@ -1279,6 +1280,7 @@ static const char *cm_sm_event_names[] = {
|
||||
"EV_REASSOC_TIMER",
|
||||
"EV_HO_ROAM_DISCONNECT_DONE",
|
||||
"EV_RSO_STOP_RSP",
|
||||
"EV_BEARER_SWITCH_COMPLETE",
|
||||
};
|
||||
|
||||
enum wlan_cm_sm_state cm_get_state(struct cnx_mgr *cm_ctx)
|
||||
|
@@ -70,6 +70,8 @@
|
||||
* @WLAN_CM_SM_EV_HO_ROAM_DISCONNECT_DONE: Disconnect done for hands off/roaming
|
||||
* @WLAN_CM_SM_EV_RSO_STOP_RSP: Event to continue disconnect after
|
||||
* RSO stop response is received
|
||||
* @WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE: Event to continue connect after bearer
|
||||
* switch complete
|
||||
* @WLAN_CM_SM_EV_MAX: Max event
|
||||
*/
|
||||
enum wlan_cm_sm_evt {
|
||||
@@ -111,6 +113,7 @@ enum wlan_cm_sm_evt {
|
||||
WLAN_CM_SM_EV_REASSOC_TIMER = 35,
|
||||
WLAN_CM_SM_EV_HO_ROAM_DISCONNECT_DONE = 36,
|
||||
WLAN_CM_SM_EV_RSO_STOP_RSP = 37,
|
||||
WLAN_CM_SM_EV_BEARER_SWITCH_COMPLETE = 38,
|
||||
WLAN_CM_SM_EV_MAX,
|
||||
};
|
||||
|
||||
|
@@ -662,4 +662,18 @@ enum MLO_TYPE
|
||||
wlan_cm_bss_mlo_type(struct wlan_objmgr_psoc *psoc,
|
||||
struct scan_cache_entry *entry,
|
||||
qdf_list_t *scan_list);
|
||||
|
||||
#ifdef WLAN_FEATURE_LL_LT_SAP
|
||||
/**
|
||||
* wlan_cm_bearer_switch_resp() - Bearer switch response
|
||||
* @psoc: psoc pointer
|
||||
* @vdev_id: vdev id
|
||||
* @cm_id: connection ID which gave the hw mode change request
|
||||
* @status: status of the Bearer switch
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void wlan_cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
||||
wlan_cm_id cm_id, QDF_STATUS status);
|
||||
#endif /* WLAN_FEATURE_LL_LT_SAP */
|
||||
#endif /* __WLAN_CM_UCFG_API_H */
|
||||
|
@@ -361,6 +361,14 @@ void wlan_cm_hw_mode_change_resp(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
|
||||
}
|
||||
#endif /* ifdef POLICY_MGR_ENABLE */
|
||||
|
||||
#ifdef WLAN_FEATURE_LL_LT_SAP
|
||||
void wlan_cm_bearer_switch_resp(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
||||
wlan_cm_id cm_id, QDF_STATUS status)
|
||||
{
|
||||
cm_bearer_switch_resp(psoc, vdev_id, cm_id, status);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SM_ENG_HIST_ENABLE
|
||||
void wlan_cm_sm_history_print(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur