qcacld-3.0: Cleanup CSR/LIM for Roam sync indication failure in CSR

Currently, failure in csr_roam_synch_cb is not handled, therefore
failure during roam sync indication processing in CSR, leads to
out-of-sync between LIM and CSR sessions.

Handle the failure in csr_roam_synch_cb, by aborting the
roam complete notification to FW, and then process HO failure from
FW to cleanup LIM and CSR which will hold different BSSID profile.

Use vdev id instead of BSSID to retrieve/delete the LIM session.

Change-Id: I5ff2280e7ba1a8cb8e44c0c6b70647bf12b6ef31
CRs-Fixed: 3046370
This commit is contained in:
Surya Prakash Sivaraj 2021-09-29 00:17:01 +05:30 committed by Madan Koyyalamudi
parent 9c2abc72fc
commit fa0078c9a9
5 changed files with 145 additions and 50 deletions

View File

@ -1129,6 +1129,10 @@ cm_roam_switch_to_rso_enable(struct wlan_objmgr_pdev *pdev,
return QDF_STATUS_SUCCESS;
case WLAN_ROAM_SYNCH_IN_PROG:
if (reason == REASON_ROAM_ABORT) {
mlme_debug("Roam synch in progress, drop Roam abort");
return QDF_STATUS_SUCCESS;
}
/*
* After roam sych propagation is complete, send
* RSO start command to firmware to update AP profile,

View File

@ -2133,11 +2133,14 @@ lim_roam_fill_bss_descr(struct mac_context *mac,
qdf_mem_free(parsed_frm_ptr);
return QDF_STATUS_E_FAILURE;
}
pe_debug("LFR3:Beacon/Prb Rsp: %d bssid "QDF_MAC_ADDR_FMT" beacon "QDF_MAC_ADDR_FMT,
pe_debug("LFR3:Beacon/Prb Rsp: %d len %d bssid "QDF_MAC_ADDR_FMT" beacon "QDF_MAC_ADDR_FMT,
roam_synch_ind_ptr->isBeacon,
roam_synch_ind_ptr->beaconProbeRespLength,
QDF_MAC_ADDR_REF(roam_synch_ind_ptr->bssid.bytes),
QDF_MAC_ADDR_REF(mac_hdr->bssId));
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
bcn_proberesp_ptr,
roam_synch_ind_ptr->beaconProbeRespLength);
status = lim_roam_gen_beacon_descr(mac,
roam_synch_ind_ptr,
parsed_frm_ptr,
@ -2215,15 +2218,21 @@ lim_roam_fill_bss_descr(struct mac_context *mac,
(uint8_t *)parsed_frm_ptr->mdie,
SIR_MDIE_SIZE);
}
pe_debug("chan: %d rssi: %d ie_len %d",
pe_debug("chan: %d rssi: %d desc len %d",
bss_desc_ptr->chan_freq,
bss_desc_ptr->rssi, ie_len);
bss_desc_ptr->rssi,
bss_desc_ptr->length);
qdf_mem_free(parsed_frm_ptr);
if (ie_len) {
qdf_mem_copy(&bss_desc_ptr->ieFields,
ie, ie_len);
qdf_mem_free(ie);
} else {
pe_err("Beacon/Probe rsp doesn't have any IEs");
return QDF_STATUS_E_FAILURE;
}
qdf_mem_free(parsed_frm_ptr);
return QDF_STATUS_SUCCESS;
}

View File

@ -2491,13 +2491,14 @@ static void __lim_process_sme_disassoc_req(struct mac_context *mac,
disassocTrigger = eLIM_HOST_DISASSOC;
goto sendDisassoc;
}
pe_debug("vdev %d (session %d) Systemrole %d Reason: %u SmeState: %d limMlmState %d ho fail %d send OTA %d from: "
QDF_MAC_ADDR_FMT, pe_session->vdev_id, pe_session->peSessionId,
pe_debug("vdev %d (session %d) Systemrole %d Reason: %u SmeState: %d limMlmState %d ho fail %d send OTA %d from: " QDF_MAC_ADDR_FMT " bssid :" QDF_MAC_ADDR_FMT,
pe_session->vdev_id, pe_session->peSessionId,
GET_LIM_SYSTEM_ROLE(pe_session), smeDisassocReq.reasonCode,
pe_session->limSmeState, pe_session->limMlmState,
smeDisassocReq.process_ho_fail,
smeDisassocReq.doNotSendOverTheAir,
QDF_MAC_ADDR_REF(smeDisassocReq.peer_macaddr.bytes));
QDF_MAC_ADDR_REF(smeDisassocReq.peer_macaddr.bytes),
QDF_MAC_ADDR_REF(smeDisassocReq.bssid.bytes));
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
lim_diag_event_report(mac, WLAN_PE_DIAG_DISASSOC_REQ_EVENT, pe_session,
@ -2833,11 +2834,12 @@ static void __lim_process_sme_deauth_req(struct mac_context *mac_ctx,
deauth_trigger = eLIM_HOST_DEAUTH;
goto send_deauth;
}
pe_debug("vdev %d (session %d) Systemrole %d reasoncode %u limSmestate %d limMlmState %d from "
QDF_MAC_ADDR_FMT, vdev_id, session_entry->peSessionId,
pe_debug("vdev %d (session %d) Systemrole %d reasoncode %u limSmestate %d limMlmState %d from " QDF_MAC_ADDR_FMT " bssid : " QDF_MAC_ADDR_FMT,
vdev_id, session_entry->peSessionId,
GET_LIM_SYSTEM_ROLE(session_entry), sme_deauth_req.reasonCode,
session_entry->limSmeState, session_entry->limMlmState,
QDF_MAC_ADDR_REF(sme_deauth_req.peer_macaddr.bytes));
QDF_MAC_ADDR_REF(sme_deauth_req.peer_macaddr.bytes),
QDF_MAC_ADDR_REF(sme_deauth_req.bssid.bytes));
#ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM /* FEATURE_WLAN_DIAG_SUPPORT */
lim_diag_event_report(mac_ctx, WLAN_PE_DIAG_DEAUTH_REQ_EVENT,
session_entry, 0, sme_deauth_req.reasonCode);
@ -4822,23 +4824,53 @@ static void lim_process_disconnect_sta(struct pe_session *session,
sizeof(*msg), msg);
}
static
struct pe_session *lim_get_disconnect_session(struct mac_context *mac_ctx,
uint8_t *bssid,
uint8_t vdev_id)
{
struct pe_session *session;
uint8_t session_id;
/* Try to find pe session with bssid */
session = pe_find_session_by_bssid(mac_ctx, bssid,
&session_id);
/*
* If bssid search fail try to find by vdev id, this can happen if
* Roaming change the BSSID during disconnect was getting processed.
*/
if (!session) {
session = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
if (session)
pe_info("Session found for vdev_id : %d session id : %d Requested bssid : " QDF_MAC_ADDR_FMT " Actual bssid : " QDF_MAC_ADDR_FMT " sme state %d mlm state %d",
vdev_id, session->peSessionId,
QDF_MAC_ADDR_REF(bssid),
QDF_MAC_ADDR_REF(session->bssId),
session->limSmeState,
session->limMlmState);
}
return session;
}
static void lim_process_sme_disassoc_cnf(struct mac_context *mac_ctx,
struct scheduler_msg *msg)
{
struct disassoc_cnf sme_disassoc_cnf;
struct pe_session *session;
uint8_t session_id;
uint32_t *err_msg = NULL;
QDF_STATUS status;
qdf_mem_copy(&sme_disassoc_cnf, msg->bodyptr, sizeof(sme_disassoc_cnf));
session = pe_find_session_by_bssid(mac_ctx,
sme_disassoc_cnf.bssid.bytes,
&session_id);
session = lim_get_disconnect_session(mac_ctx,
sme_disassoc_cnf.bssid.bytes,
sme_disassoc_cnf.vdev_id);
if (!session) {
pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(sme_disassoc_cnf.bssid.bytes));
pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT "vdev id: %d",
QDF_MAC_ADDR_REF(sme_disassoc_cnf.bssid.bytes),
sme_disassoc_cnf.vdev_id);
status = lim_prepare_disconnect_done_ind
(mac_ctx, &err_msg,
sme_disassoc_cnf.vdev_id,
@ -4852,11 +4884,24 @@ static void lim_process_sme_disassoc_cnf(struct mac_context *mac_ctx,
return;
}
if (LIM_IS_STA_ROLE(session))
/* In LFR3, if Roam synch indication processing might fail
* in CSR, then CSR and LIM peer will be out-of-sync.
* To recover from this, during HO failure delete the LIM
* session corresponding to the vdev id, irrespective of the
* BSSID. Copy the BSSID present in LIM session into the
* disassoc cnf msg sent to LIM and SME.
*/
if (LIM_IS_STA_ROLE(session)) {
struct disassoc_cnf *sta_disassoc_cnf = msg->bodyptr;
qdf_mem_copy(sta_disassoc_cnf->bssid.bytes,
session->bssId, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(sta_disassoc_cnf->peer_macaddr.bytes,
session->bssId, QDF_MAC_ADDR_SIZE);
lim_process_disconnect_sta(session, msg);
else
} else {
__lim_process_sme_disassoc_cnf(mac_ctx,
(uint32_t *)msg->bodyptr);
}
}
static void lim_process_sme_disassoc_req(struct mac_context *mac_ctx,
@ -4864,16 +4909,16 @@ static void lim_process_sme_disassoc_req(struct mac_context *mac_ctx,
{
struct disassoc_req disassoc_req;
struct pe_session *session;
uint8_t session_id;
qdf_mem_copy(&disassoc_req, msg->bodyptr, sizeof(struct disassoc_req));
session = pe_find_session_by_bssid(mac_ctx,
disassoc_req.bssid.bytes,
&session_id);
session = lim_get_disconnect_session(mac_ctx,
disassoc_req.bssid.bytes,
disassoc_req.sessionId);
if (!session) {
pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(disassoc_req.bssid.bytes));
pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT "vdev id: %d",
QDF_MAC_ADDR_REF(disassoc_req.bssid.bytes),
disassoc_req.sessionId);
lim_send_sme_disassoc_ntf(mac_ctx,
disassoc_req.peer_macaddr.bytes,
eSIR_SME_INVALID_PARAMETERS,
@ -4900,11 +4945,24 @@ static void lim_process_sme_disassoc_req(struct mac_context *mac_ctx,
return;
}
if (LIM_IS_STA_ROLE(session))
/* In LFR3, if Roam synch indication processing might fail
* in CSR, then CSR and LIM peer will be out-of-sync.
* To recover from this, during HO failure delete the LIM
* session corresponding to the vdev id, irrespective of the
* BSSID. Copy the BSSID present in LIM session into the
* disassoc cnf msg sent to LIM and SME.
*/
if (LIM_IS_STA_ROLE(session)) {
struct disassoc_req *sta_disassoc_req = msg->bodyptr;
qdf_mem_copy(sta_disassoc_req->bssid.bytes,
session->bssId, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(sta_disassoc_req->peer_macaddr.bytes,
session->bssId, QDF_MAC_ADDR_SIZE);
lim_process_disconnect_sta(session, msg);
else
} else {
__lim_process_sme_disassoc_req(mac_ctx,
(uint32_t *)msg->bodyptr);
}
}
static void lim_process_sme_deauth_req(struct mac_context *mac_ctx,
@ -4912,16 +4970,17 @@ static void lim_process_sme_deauth_req(struct mac_context *mac_ctx,
{
struct deauth_req sme_deauth_req;
struct pe_session *session;
uint8_t session_id;
qdf_mem_copy(&sme_deauth_req, msg->bodyptr, sizeof(sme_deauth_req));
session = pe_find_session_by_bssid(mac_ctx,
sme_deauth_req.bssid.bytes,
&session_id);
session = lim_get_disconnect_session(mac_ctx,
sme_deauth_req.bssid.bytes,
sme_deauth_req.vdev_id);
if (!session) {
pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(sme_deauth_req.bssid.bytes));
pe_err("session not found for bssid:"QDF_MAC_ADDR_FMT "vdev id: %d",
QDF_MAC_ADDR_REF(sme_deauth_req.bssid.bytes),
sme_deauth_req.vdev_id);
lim_send_sme_deauth_ntf(mac_ctx,
sme_deauth_req.peer_macaddr.bytes,
eSIR_SME_INVALID_PARAMETERS,
@ -4942,11 +5001,24 @@ static void lim_process_sme_deauth_req(struct mac_context *mac_ctx,
return;
}
if (LIM_IS_STA_ROLE(session))
/* In LFR3, if Roam synch indication processing might fail
* in CSR, then CSR and LIM peer will be out-of-sync.
* To recover from this, during HO failure delete the LIM
* session corresponding to the vdev id, irrespective of the
* BSSID. Copy the BSSID present in LIM session into the
* disassoc cnf msg sent to LIM and SME.
*/
if (LIM_IS_STA_ROLE(session)) {
struct deauth_req *sta_deauth_req = msg->bodyptr;
qdf_mem_copy(sta_deauth_req->bssid.bytes,
session->bssId, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(sta_deauth_req->peer_macaddr.bytes,
session->bssId, QDF_MAC_ADDR_SIZE);
lim_process_disconnect_sta(session, msg);
else
} else {
__lim_process_sme_deauth_req(mac_ctx,
(uint32_t *)msg->bodyptr);
}
}
/**

View File

@ -11490,7 +11490,6 @@ csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
{
struct csr_roam_session *session;
uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
QDF_STATUS status;
struct disassoc_ind *pDisassocInd;
tSmeCmd *cmd;
@ -11504,11 +11503,11 @@ csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
* the WmStatusChange requests is pushed and processed
*/
pDisassocInd = (struct disassoc_ind *)msg_ptr;
status = csr_roam_get_session_id_from_bssid(mac_ctx,
&pDisassocInd->bssid, &sessionId);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sme_err("Session Id not found for BSSID "QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes));
sessionId = pDisassocInd->vdev_id;
if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
sme_err("Invalid session. Session Id: %d BSSID: " QDF_MAC_ADDR_FMT,
sessionId, QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes));
qdf_mem_free(cmd);
return;
}
@ -11589,7 +11588,6 @@ csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
{
struct csr_roam_session *session;
uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
QDF_STATUS status;
struct deauth_ind *pDeauthInd;
pDeauthInd = (struct deauth_ind *)msg_ptr;
@ -11597,10 +11595,8 @@ csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
pDeauthInd->vdev_id,
QDF_MAC_ADDR_REF(pDeauthInd->bssid.bytes));
status = csr_roam_get_session_id_from_bssid(mac_ctx,
&pDeauthInd->bssid,
&sessionId);
if (!QDF_IS_STATUS_SUCCESS(status))
sessionId = pDeauthInd->vdev_id;
if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId))
return;
if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
@ -21211,7 +21207,14 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
status = csr_get_parsed_bss_description_ies(
mac_ctx, bss_desc, &ies_local);
if (!QDF_IS_STATUS_SUCCESS(status)) {
sme_err("LFR3: fail to parse IEs");
sme_err("LFR3: fail to parse IEs. Len Bcn : %d, Reassoc req : %d Reassoc rsp : %d",
roam_synch_data->beaconProbeRespLength,
roam_synch_data->reassoc_req_length,
roam_synch_data->reassocRespLength);
qdf_trace_hex_dump(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
(uint8_t *)roam_synch_data +
roam_synch_data->beaconProbeRespOffset,
roam_synch_data->beaconProbeRespLength);
goto end;
}

View File

@ -1358,14 +1358,21 @@ int wma_mlme_roam_synch_event_handler_cb(void *handle, uint8_t *event,
if (QDF_IS_STATUS_ERROR(wma->pe_roam_synch_cb(wma->mac_context,
roam_synch_ind_ptr, bss_desc_ptr,
SIR_ROAM_SYNCH_PROPAGATION))) {
wma_err("LFR3: PE roam synch cb failed");
wma_err("LFR3: PE roam synch propagation failed");
status = -EBUSY;
goto cleanup_label;
}
wma_roam_update_vdev(wma, roam_synch_ind_ptr);
wma->csr_roam_synch_cb(wma->mac_context, roam_synch_ind_ptr,
bss_desc_ptr, SIR_ROAM_SYNCH_PROPAGATION);
if (QDF_IS_STATUS_ERROR(wma->csr_roam_synch_cb(wma->mac_context,
roam_synch_ind_ptr,
bss_desc_ptr, SIR_ROAM_SYNCH_PROPAGATION))) {
wma_err("CSR roam synch propagation failed, abort roam");
status = -EINVAL;
goto cleanup_label;
}
wma_process_roam_synch_complete(wma, synch_event->vdev_id);
/* update freq and channel width */