diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index a6c616496961..6d32923f851b 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -6012,16 +6012,14 @@ static enum csr_join_state csr_roam_join_next_bss(struct mac_context *mac_ctx, * When handling AP's capability change, continue to associate * to same BSS and make sure pRoamBssEntry is not Null. */ - if ((bss_list) && - ((false == use_same_bss) || - (!cmd->u.roamCmd.pRoamBssEntry))) { + if (bss_list) { if (!cmd->u.roamCmd.pRoamBssEntry) { /* Try the first BSS */ cmd->u.roamCmd.pLastRoamBss = NULL; cmd->u.roamCmd.pRoamBssEntry = csr_ll_peek_head(&bss_list->List, LL_ACCESS_LOCK); - } else { + } else if (!use_same_bss) { cmd->u.roamCmd.pRoamBssEntry = csr_ll_next(&bss_list->List, cmd->u.roamCmd.pRoamBssEntry, @@ -6041,14 +6039,26 @@ static enum csr_join_state csr_roam_join_next_bss(struct mac_context *mac_ctx, join_status = &session->joinFailStatusCode; roam_info->status_code = join_status->status_code; roam_info->reasonCode = join_status->reasonCode; + } else { + /* + * Try connect to same BSS again. Fill roam_info for the + * last attemp to indicate to HDD. + */ + roam_info->bss_desc = cmd->u.roamCmd.pLastRoamBss; + join_status = &session->joinFailStatusCode; + roam_info->status_code = join_status->status_code; + roam_info->reasonCode = join_status->reasonCode; } + done = csr_roam_select_bss(mac_ctx, - &cmd->u.roamCmd.pRoamBssEntry, &result, - &scan_result, session_id, cmd->u.roamCmd.roamId, - &roam_state, bss_list); + &cmd->u.roamCmd.pRoamBssEntry, + &result, &scan_result, session_id, + cmd->u.roamCmd.roamId, + &roam_state, bss_list); if (done) goto end; } + roam_info->u.pConnectedProfile = &session->connectedProfile; csr_roam_join_handle_profile(mac_ctx, session_id, cmd, roam_info, @@ -6076,7 +6086,8 @@ end: return roam_state; } -static QDF_STATUS csr_roam(struct mac_context *mac, tSmeCmd *pCommand) +static QDF_STATUS csr_roam(struct mac_context *mac, tSmeCmd *pCommand, + bool use_same_bss) { QDF_STATUS status = QDF_STATUS_SUCCESS; enum csr_join_state RoamState; @@ -6084,7 +6095,7 @@ static QDF_STATUS csr_roam(struct mac_context *mac, tSmeCmd *pCommand) uint32_t sessionId = pCommand->vdev_id; /* Attept to join a Bss... */ - RoamState = csr_roam_join_next_bss(mac, pCommand, false); + RoamState = csr_roam_join_next_bss(mac, pCommand, use_same_bss); /* if nothing to join.. */ if ((eCsrStopRoaming == RoamState) || @@ -6522,7 +6533,7 @@ QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand) * this point on. Attempt to roam with the new scan results * (if we need to..) */ - status = csr_roam(mac, pCommand); + status = csr_roam(mac, pCommand, false); if (!QDF_IS_STATUS_SUCCESS(status)) sme_warn("csr_roam() failed with status = 0x%08X", status); @@ -9471,6 +9482,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, struct wlan_crypto_pmksa *pmksa; uint32_t len = 0, roamId = 0, reason_code = 0; bool is_dis_pending; + bool use_same_bss = false; if (!pSmeJoinRsp) { sme_err("Sme Join Response is NULL"); @@ -9563,6 +9575,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, * AP. */ if (reason_code == eSIR_MAC_INVALID_PMKID) { + struct tag_csrscan_result *scan_result; pmksa = qdf_mem_malloc(sizeof(*pmksa)); if (!pmksa) return; @@ -9575,6 +9588,17 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, sme_roam_del_pmkid_from_cache(mac_handle, session_ptr->vdev_id, pmksa, false); qdf_mem_free(pmksa); + if (pCommand && pCommand->u.roamCmd.pRoamBssEntry) { + scan_result = + GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry, + struct tag_csrscan_result, Link); + /* Retry with same BSSID without PMKID */ + if (!scan_result->retry_count) { + sme_info("Retry once again with same BSSID without PMKID"); + scan_result->retry_count = 1; + use_same_bss = true; + } + } } /* If Join fails while Handoff is in progress, indicate @@ -9598,7 +9622,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, 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(mac, pCommand, use_same_bss); return; } @@ -9846,7 +9870,7 @@ csr_roaming_state_config_cnf_processor(struct mac_context *mac_ctx, cmd->u.roamCmd.roamId); if (!QDF_IS_STATUS_SUCCESS(status)) { /* try something else */ - csr_roam(mac_ctx, cmd); + csr_roam(mac_ctx, cmd, false); } } } else { @@ -9891,7 +9915,7 @@ csr_roaming_state_config_cnf_processor(struct mac_context *mac_ctx, } if (!QDF_IS_STATUS_SUCCESS(status)) { /* try something else */ - csr_roam(mac_ctx, cmd); + csr_roam(mac_ctx, cmd, false); } } if (is_ies_malloced) { diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 195a8b7726f3..e98ff3cf4607 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -76,6 +76,7 @@ struct tag_csrscan_result { /* Preferred auth type that matched with the profile. */ enum csr_akm_type authType; int bss_score; + uint8_t retry_count; tCsrScanResultInfo Result; /*