diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 72fb311d60..dde69f6d04 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -354,6 +354,8 @@ static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_DFS_CHAN_AGEOUT_TIME); gen->sae_connect_retries = cfg_get(psoc, CFG_SAE_CONNECION_RETRIES); + gen->join_failure_retry_interval = + cfg_get(psoc, CFG_JOIN_FAILURE_RETRY_INTERVAL); } static void mlme_init_edca_ani_cfg(struct wlan_mlme_edca_params *edca_params) diff --git a/components/mlme/dispatcher/inc/cfg_mlme_generic.h b/components/mlme/dispatcher/inc/cfg_mlme_generic.h index 6bf57972b4..5729d1c61b 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_generic.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_generic.h @@ -781,6 +781,28 @@ 0, \ "WiFi Location Service(WLS) is 6Ghz capable or not") +/* + * + * join_failure_retry_interval - Set join failure retry interval (in ms) + * + * @Min: 0 + * @Max: 3000 + * @Default: 50 + * + * This ini to set the join failure retry interval in ms + * + * Related: None. + + * Supported Feature: General + * + * Usage: Internal + * + * + */ +#define CFG_JOIN_FAILURE_RETRY_INTERVAL CFG_INI_UINT("join_failure_retry_interval", \ + 0, 3000, 50, CFG_VALUE_OR_DEFAULT, \ + "Set join failure retry time in ms") + #define CFG_GENERIC_ALL \ CFG(CFG_ENABLE_DEBUG_PACKET_LOG) \ CFG(CFG_PMF_SA_QUERY_MAX_RETRIES) \ @@ -813,5 +835,6 @@ CFG(CFG_ENABLE_RING_BUFFER) \ CFG(CFG_DFS_CHAN_AGEOUT_TIME) \ CFG(CFG_SAE_CONNECION_RETRIES) \ + CFG(CFG_JOIN_FAILURE_RETRY_INTERVAL) \ CFG(CFG_WLS_6GHZ_CAPABLE) #endif /* __CFG_MLME_GENERIC_H */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 8b1134077b..1e63589411 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1153,6 +1153,7 @@ struct wlan_mlme_chainmask { * @dual_sta_roam_fw_support: Firmware support for dual sta roaming feature * @sae_connect_retries: sae connect retry bitmask * @wls_6ghz_capable: wifi location service(WLS) is 6ghz capable + * @join_failure_retry_interval: Join failure retry interval */ struct wlan_mlme_generic { uint32_t band_capability; @@ -1195,6 +1196,7 @@ struct wlan_mlme_generic { bool dual_sta_roam_fw_support; uint32_t sae_connect_retries; bool wls_6ghz_capable; + uint16_t join_failure_retry_interval; }; /* diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index da52dea16a..e1384dcaff 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -626,6 +626,7 @@ struct csr_roam_session { bool discon_in_progress; bool is_adaptive_11r_connection; struct csr_disconnect_stats disconnect_stats; + qdf_mc_timer_t join_retry_timer; }; struct csr_roamstruct { diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 9f66cad244..a065937a83 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -407,6 +407,7 @@ static QDF_STATUS csr_roam_start_roaming_timer(struct mac_context *mac, static QDF_STATUS csr_roam_stop_roaming_timer(struct mac_context *mac, uint32_t sessionId); static void csr_roam_roaming_timer_handler(void *pv); +static void csr_roam_join_failure_retry_connect_handler(void *pv); #ifdef WLAN_FEATURE_ROAM_OFFLOAD static void csr_roam_roaming_offload_timer_action(struct mac_context *mac_ctx, uint32_t interval, uint8_t session_id, uint8_t action); @@ -9156,6 +9157,8 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, bool retry_same_bss = false; bool attempt_next_bss = true; enum csr_akm_type auth_type = eCSR_AUTH_TYPE_NONE; + struct wlan_mlme_psoc_ext_obj *mlme_obj; + uint16_t retry_interval; if (!pSmeJoinRsp) { sme_err("Sme Join Response is NULL"); @@ -9168,6 +9171,11 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, return; } + mlme_obj = mlme_get_psoc_ext_obj(mac->psoc); + + if (!mlme_obj) + retry_interval = 0; + prev_connect_info = &session_ptr->prev_assoc_ap_info; /* The head of the active list is the request we sent */ pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); @@ -9297,6 +9305,18 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, &max_retry_count); } + if (pSmeJoinRsp->messageType == eWNI_SME_JOIN_RSP && + pSmeJoinRsp->status_code == eSIR_SME_JOIN_TIMEOUT_RESULT_CODE && + pCommand && pCommand->u.roamCmd.hBSSList) { + struct scan_result_list *bss_list = + (struct scan_result_list *)pCommand->u.roamCmd.hBSSList; + + if (csr_ll_count(&bss_list->List) == 1) { + retry_same_bss = true; + sme_err("retry_same_bss is set"); + } + } + if (attempt_next_bss && retry_same_bss && pCommand && pCommand->u.roamCmd.pRoamBssEntry) { struct tag_csrscan_result *scan_result; @@ -9338,9 +9358,19 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac, QDF_STATUS_E_FAILURE); } + retry_interval = mlme_obj->cfg.gen.join_failure_retry_interval; + if (pCommand && attempt_next_bss) { - csr_roam(mac, pCommand, use_same_bss); - return; + if (retry_interval && use_same_bss) { + qdf_mc_timer_stop(&session_ptr->join_retry_timer); + session_ptr->roamingTimerInfo.vdev_id = pSmeJoinRsp->vdev_id; + qdf_mc_timer_start(&session_ptr->join_retry_timer, retry_interval); + sme_err("Retry sending join req,after timer expiry : %d ms", retry_interval); + return; + } else { + csr_roam(mac, pCommand, use_same_bss); + return; + } } /* @@ -12510,6 +12540,31 @@ rel: wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); } +void csr_roam_join_failure_retry_connect_handler(void *pv) +{ + struct csr_timer_info *info = pv; + struct mac_context *mac = info->mac; + uint32_t vdev_id = info->vdev_id; + struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id); + tListElem *pEntry = NULL; + tSmeCmd *pCommand = NULL; + + if (!pSession) { + sme_err(" session %d not found ", vdev_id); + return; + } + + pEntry = csr_nonscan_active_ll_peek_head(mac, LL_ACCESS_LOCK); + + if (pEntry) + pCommand = GET_BASE_ADDR(pEntry, tSmeCmd, Link); + + if (pCommand) { + sme_err("Join failure timer expired,send join req"); + csr_roam(mac, pCommand, true); + } +} + QDF_STATUS csr_roam_start_roaming_timer(struct mac_context *mac, uint32_t vdev_id, uint32_t interval) @@ -16447,6 +16502,15 @@ QDF_STATUS csr_setup_vdev_session(struct vdev_mlme_obj *vdev_mlme) return status; } + status = qdf_mc_timer_init(&session->join_retry_timer, + QDF_TIMER_TYPE_SW, + csr_roam_join_failure_retry_connect_handler, + &session->roamingTimerInfo); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("timer init failed for join failure timer"); + return status; + } + ht_cap_info = &mac_ctx->mlme_cfg->ht_caps.ht_cap_info; session->ht_config.ht_rx_ldpc = ht_cap_info->adv_coding_cap; session->ht_config.ht_tx_stbc = ht_cap_info->tx_stbc; @@ -16519,6 +16583,7 @@ void csr_cleanup_vdev_session(struct mac_context *mac, uint8_t vdev_id) &pSession->prev_assoc_ap_info); qdf_mc_timer_destroy(&pSession->hTimerRoaming); qdf_mc_timer_destroy(&pSession->roaming_offload_timer); + qdf_mc_timer_destroy(&pSession->join_retry_timer); csr_init_session(mac, vdev_id); } }