diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 2355398190..14cc99f758 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -9137,20 +9137,21 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, { tListElem *pEntry = NULL; tSmeCmd *pCommand = NULL; + mac_handle_t mac_handle = MAC_HANDLE(mac); struct csr_roam_session *session_ptr; struct csr_roam_connectedinfo *prev_connect_info; - uint32_t len = 0; + tPmkidCacheInfo pmksa_entry; + uint32_t len = 0, roamId = 0, reason_code = 0; + bool is_dis_pending; - if (pSmeJoinRsp) { - session_ptr = CSR_GET_SESSION(mac, pSmeJoinRsp->sessionId); - } else { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - FL("Sme Join Response is NULL")); + if (!pSmeJoinRsp) { + sme_err("Sme Join Response is NULL"); return; } + + session_ptr = CSR_GET_SESSION(mac, pSmeJoinRsp->sessionId); if (!session_ptr) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - ("session %d not found"), pSmeJoinRsp->sessionId); + sme_err("session %d not found", pSmeJoinRsp->sessionId); return; } @@ -9166,8 +9167,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, session_ptr->fils_seq_num = pSmeJoinRsp->fils_seq_num; if (eSIR_SME_SUCCESS == pSmeJoinRsp->status_code) { - if (pCommand - && eCsrSmeIssuedAssocToSimilarAP == + if (pCommand && + eCsrSmeIssuedAssocToSimilarAP == pCommand->u.roamCmd.roamReason) { #ifndef WLAN_MDM_CODE_REDUCTION_OPT sme_qos_csr_event_ind(mac, pSmeJoinRsp->sessionId, @@ -9180,10 +9181,9 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, session_ptr->vdev_nss = pSmeJoinRsp->nss; } - session_ptr->supported_nss_1x1 = - pSmeJoinRsp->supported_nss_1x1; + session_ptr->supported_nss_1x1 = pSmeJoinRsp->supported_nss_1x1; sme_debug("SME session supported nss: %d", - session_ptr->supported_nss_1x1); + session_ptr->supported_nss_1x1); /* * The join bssid count can be reset as soon as @@ -9192,104 +9192,110 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, */ session_ptr->join_bssid_count = 0; csr_roam_complete(mac, eCsrJoinSuccess, (void *)pSmeJoinRsp, - pSmeJoinRsp->sessionId); - } else { - uint32_t roamId = 0; - bool is_dis_pending; + pSmeJoinRsp->sessionId); - /* The head of the active list is the request we sent - * Try to get back the same profile and roam again + return; + } + + + /* The head of the active list is the request we sent + * Try to get back the same profile and roam again + */ + if (pCommand) + roamId = pCommand->u.roamCmd.roamId; + + reason_code = pSmeJoinRsp->protStatusCode; + session_ptr->joinFailStatusCode.reasonCode = reason_code; + session_ptr->joinFailStatusCode.status_code = pSmeJoinRsp->status_code; + + sme_warn("SmeJoinReq failed with status_code= 0x%08X [%d] reason:%d", + pSmeJoinRsp->status_code, pSmeJoinRsp->status_code, + reason_code); + + /* + * Delete the PMKID of the BSSID for which the assoc reject is + * received from the AP due to invalid PMKID reason. + * This will avoid the driver trying to connect to same AP with + * the same stale PMKID if multiple connection attempts to different + * bss fail and supplicant issues connect request back to the same + * AP. + */ + if (reason_code == eSIR_MAC_INVALID_PMKID) { + sme_warn("Assoc reject from BSSID:%pM due to invalid PMKID", + session_ptr->joinFailStatusCode.bssId); + qdf_mem_copy(&pmksa_entry.BSSID.bytes, + &session_ptr->joinFailStatusCode.bssId, + sizeof(tSirMacAddr)); + sme_roam_del_pmkid_from_cache(mac_handle, session_ptr->vdev_id, + &pmksa_entry, false); + } + + /* If Join fails while Handoff is in progress, indicate + * disassociated event to supplicant to reconnect + */ + if (csr_roam_is_handoff_in_progress(mac, pSmeJoinRsp->sessionId)) { + csr_roam_call_callback(mac, pSmeJoinRsp->sessionId, NULL, + roamId, eCSR_ROAM_DISASSOCIATED, + eCSR_ROAM_RESULT_FORCED); + /* Should indicate neighbor roam algorithm about the + * connect failure here */ - if (pCommand) - roamId = pCommand->u.roamCmd.roamId; - session_ptr->joinFailStatusCode.status_code = - pSmeJoinRsp->status_code; - session_ptr->joinFailStatusCode.reasonCode = - pSmeJoinRsp->protStatusCode; - sme_warn("SmeJoinReq failed with status_code= 0x%08X [%d]", - pSmeJoinRsp->status_code, pSmeJoinRsp->status_code); - /* If Join fails while Handoff is in progress, indicate - * disassociated event to supplicant to reconnect - */ - if (csr_roam_is_handoff_in_progress(mac, - pSmeJoinRsp->sessionId)) { - csr_roam_call_callback(mac, pSmeJoinRsp->sessionId, - NULL, roamId, - eCSR_ROAM_DISASSOCIATED, - eCSR_ROAM_RESULT_FORCED); - /* Should indicate neighbor roam algorithm about the - * connect failure here - */ - csr_neighbor_roam_indicate_connect(mac, - pSmeJoinRsp->sessionId, - QDF_STATUS_E_FAILURE); - } + csr_neighbor_roam_indicate_connect(mac, pSmeJoinRsp->sessionId, + QDF_STATUS_E_FAILURE); + } - len = pSmeJoinRsp->assocReqLength + - pSmeJoinRsp->assocRspLength + pSmeJoinRsp->beaconLength; - if (prev_connect_info->pbFrames) - csr_roam_free_connected_info(mac, prev_connect_info); - - prev_connect_info->pbFrames = qdf_mem_malloc(len); - if (!prev_connect_info->pbFrames) - sme_err("memory allocation failed for previous assoc profile"); - else { - qdf_mem_copy(prev_connect_info->pbFrames, - pSmeJoinRsp->frames, len); - prev_connect_info->nAssocReqLength = - pSmeJoinRsp->assocReqLength; - prev_connect_info->nAssocRspLength = - pSmeJoinRsp->assocRspLength; - prev_connect_info->nBeaconLength = - pSmeJoinRsp->beaconLength; - } - /* - * if userspace has issued disconnection, - * driver should not continue connecting - */ - is_dis_pending = is_disconnect_pending(mac, - session_ptr->sessionId); - if (pCommand && (session_ptr->join_bssid_count < - CSR_MAX_BSSID_COUNT) && !is_dis_pending) { - csr_roam(mac, pCommand); - } else { - /* - * When the upper layers issue a connect command, there - * is a roam command with reason eCsrHddIssued that - * gets enqueued and an associated timer for the SME - * command timeout is started which is currently 120 - * seconds. This command would be dequeued only upon - * successful connections. In case of join failures, if - * there are too many BSS in the cache, and if we fail - * Join requests with all of them, there is a chance of - * timing out the above timer. - */ - if (session_ptr->join_bssid_count >= - CSR_MAX_BSSID_COUNT) - QDF_TRACE(QDF_MODULE_ID_SME, - QDF_TRACE_LEVEL_ERROR, - "Excessive Join Req Failures"); - - if (is_dis_pending) - QDF_TRACE(QDF_MODULE_ID_SME, - QDF_TRACE_LEVEL_ERROR, - "disconnect is pending, complete roam"); - - if (session_ptr->bRefAssocStartCnt) - session_ptr->bRefAssocStartCnt--; - - session_ptr->join_bssid_count = 0; - - csr_roam_call_callback(mac, session_ptr->sessionId, - NULL, roamId, - eCSR_ROAM_ASSOCIATION_COMPLETION, - eCSR_ROAM_RESULT_NOT_ASSOCIATED); - - csr_roam_complete(mac, eCsrNothingToJoin, NULL, - pSmeJoinRsp->sessionId); - } + len = pSmeJoinRsp->assocReqLength + + pSmeJoinRsp->assocRspLength + pSmeJoinRsp->beaconLength; + if (prev_connect_info->pbFrames) csr_roam_free_connected_info(mac, prev_connect_info); - } /*else: ( eSIR_SME_SUCCESS == pSmeJoinRsp->status_code ) */ + + prev_connect_info->pbFrames = qdf_mem_malloc(len); + if (prev_connect_info->pbFrames) { + qdf_mem_copy(prev_connect_info->pbFrames, pSmeJoinRsp->frames, + len); + prev_connect_info->nAssocReqLength = + pSmeJoinRsp->assocReqLength; + prev_connect_info->nAssocRspLength = + pSmeJoinRsp->assocRspLength; + prev_connect_info->nBeaconLength = pSmeJoinRsp->beaconLength; + } + + /* + * if userspace has issued disconnection, driver should not continue + * connecting + */ + is_dis_pending = is_disconnect_pending(mac, session_ptr->sessionId); + if (pCommand && !is_dis_pending && + session_ptr->join_bssid_count < CSR_MAX_BSSID_COUNT) { + csr_roam(mac, pCommand); + csr_roam_free_connected_info(mac, prev_connect_info); + return; + } + + /* + * When the upper layers issue a connect command, there is a roam + * command with reason eCsrHddIssued that gets enqueued and an + * associated timer for the SME command timeout is started which is + * currently 120 seconds. This command would be dequeued only upon + * successful connections. In case of join failures, if there are too + * many BSS in the cache, and if we fail Join requests with all of them, + * there is a chance of timing out the above timer. + */ + if (session_ptr->join_bssid_count >= CSR_MAX_BSSID_COUNT) + sme_err("Excessive Join Req Failures"); + + if (is_dis_pending) + sme_err("disconnect is pending, complete roam"); + + if (session_ptr->bRefAssocStartCnt) + session_ptr->bRefAssocStartCnt--; + + session_ptr->join_bssid_count = 0; + csr_roam_call_callback(mac, session_ptr->sessionId, NULL, roamId, + eCSR_ROAM_ASSOCIATION_COMPLETION, + eCSR_ROAM_RESULT_NOT_ASSOCIATED); + csr_roam_complete(mac, eCsrNothingToJoin, NULL, pSmeJoinRsp->sessionId); + csr_roam_free_connected_info(mac, prev_connect_info); } static QDF_STATUS csr_roam_issue_join(struct mac_context *mac, uint32_t sessionId,