From f86f052f74f767fcd54388cf7c76b567b8922cb4 Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Mon, 13 Mar 2017 17:10:03 -0700 Subject: [PATCH] qcacld-3.0: Issue disconnect if roaming fails If the offloaded roaming feature has started, but has not completed for some reason, then issue a disconnect and cleanup Change-Id: Ibcd4f83ea126a1d05531f9bf30d6827008fdbfea CRs-Fixed: 2019435 --- core/sme/inc/csr_internal.h | 1 + core/sme/src/csr/csr_api_roam.c | 105 ++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index bb766cf53757..8954b2a818b5 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -991,6 +991,7 @@ typedef struct tagCsrRoamSession { uint8_t disconnect_reason; uint8_t uapsd_mask; struct scan_cmd_info scan_info; + qdf_mc_timer_t roaming_offload_timer; } tCsrRoamSession; typedef struct tagCsrRoamStruct { diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index f017f7bb5be6..0fa4fd65220e 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -94,6 +94,15 @@ /* variable. */ #define SNR_HACK_BMPS (127) +/* + * ROAMING_OFFLOAD_TIMER_START - Indicates the action to start the timer + * ROAMING_OFFLOAD_TIMER_STOP - Indicates the action to stop the timer + * CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD - Timeout value for roaming offload timer + */ +#define ROAMING_OFFLOAD_TIMER_START 1 +#define ROAMING_OFFLOAD_TIMER_STOP 2 +#define CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD (5 * QDF_MC_TIMER_TO_SEC_UNIT) + static bool b_roam_scan_offload_started; /*-------------------------------------------------------------------------- @@ -205,6 +214,9 @@ static QDF_STATUS csr_roam_start_roaming_timer(tpAniSirGlobal pMac, static QDF_STATUS csr_roam_stop_roaming_timer(tpAniSirGlobal pMac, uint32_t sessionId); static void csr_roam_roaming_timer_handler(void *pv); +static void csr_roam_roaming_offload_timer_action(tpAniSirGlobal mac_ctx, + uint32_t interval, uint8_t session_id, uint8_t action); +static void csr_roam_roaming_offload_timeout_handler(void *timer_data); QDF_STATUS csr_roam_start_wait_for_key_timer(tpAniSirGlobal pMac, uint32_t interval); static void csr_roam_wait_for_key_time_out_handler(void *pv); static QDF_STATUS csr_init11d_info(tpAniSirGlobal pMac, tCsr11dinfo *ps11dinfo); @@ -11580,6 +11592,33 @@ void csr_roam_roaming_timer_handler(void *pv) } } +/** + * csr_roam_roaming_offload_timeout_handler() - Handler for roaming failure + * @timer_data: Carries the mac_ctx and session info + * + * This function would be invoked when the roaming_offload_timer expires. + * The timer is waiting in anticipation of a related roaming event from + * the firmware after receiving the ROAM_START event. + * + * Return: None + */ +void csr_roam_roaming_offload_timeout_handler(void *timer_data) +{ + tCsrTimerInfo *timer_info = (tCsrTimerInfo *) timer_data; + + if (timer_info) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL("LFR3:roaming offload timer expired, session: %d"), + timer_info->sessionId); + } else { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("Invalid Session")); + return; + } + csr_roam_disconnect(timer_info->pMac, timer_info->sessionId, + eCSR_DISCONNECT_REASON_UNSPECIFIED); +} + QDF_STATUS csr_roam_start_roaming_timer(tpAniSirGlobal pMac, uint32_t sessionId, uint32_t interval) { @@ -11662,6 +11701,48 @@ void csr_roam_wait_for_key_time_out_handler(void *pv) } +/** + * csr_roam_roaming_offload_timer_action() - API to start/stop the timer + * @mac_ctx: MAC Context + * @interval: Value to be set for the timer + * @session_id: Session on which the timer should be operated + * @action: Start/Stop action for the timer + * + * API to start/stop the roaming offload timer + * + * Return: None + */ +void csr_roam_roaming_offload_timer_action(tpAniSirGlobal mac_ctx, + uint32_t interval, uint8_t session_id, + uint8_t action) +{ + tCsrRoamSession *csr_session = CSR_GET_SESSION(mac_ctx, session_id); + + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, + FL("LFR3: timer action %d, session %d, intvl %d"), + action, session_id, interval); + if (mac_ctx) { + csr_session = CSR_GET_SESSION(mac_ctx, session_id); + } else { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("LFR3: Invalid MAC Context")); + return; + } + if (!csr_session) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("LFR3: session %d not found"), session_id); + return; + } + csr_session->roamingTimerInfo.sessionId = (uint8_t) session_id; + if (action == ROAMING_OFFLOAD_TIMER_START) + qdf_mc_timer_start(&csr_session->roaming_offload_timer, + interval / QDF_MC_TIMER_TO_MS_UNIT); + if (action == ROAMING_OFFLOAD_TIMER_STOP) + qdf_mc_timer_stop(&csr_session->roaming_offload_timer); + + return; +} + QDF_STATUS csr_roam_start_wait_for_key_timer(tpAniSirGlobal pMac, uint32_t interval) { QDF_STATUS status; @@ -15402,6 +15483,16 @@ QDF_STATUS csr_roam_open_session(tpAniSirGlobal mac_ctx, FL("cannot allocate memory for Roaming timer")); break; } + status = qdf_mc_timer_init( + &session->roaming_offload_timer, + QDF_TIMER_TYPE_SW, + csr_roam_roaming_offload_timeout_handler, + &session->roamingTimerInfo); + if (!QDF_IS_STATUS_SUCCESS(status)) { + sms_log(mac_ctx, LOGE, + FL("mem fail for roaming timer")); + break; + } /* get the HT capability info */ if (wlan_cfg_get_int(mac_ctx, WNI_CFG_HT_CAP_INFO, &value) != eSIR_SUCCESS) { @@ -15631,6 +15722,7 @@ void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId) csr_roam_free_connect_profile(&pSession->connectedProfile); csr_roam_free_connected_info(pMac, &pSession->connectedInfo); qdf_mc_timer_destroy(&pSession->hTimerRoaming); + qdf_mc_timer_destroy(&pSession->roaming_offload_timer); #ifdef FEATURE_WLAN_BTAMP_UT_RF qdf_mc_timer_destroy(&pSession->hTimerJoinRetry); #endif @@ -19242,6 +19334,8 @@ void csr_process_ho_fail_ind(tpAniSirGlobal pMac, void *pMsgBuf) return; } cds_set_connection_in_progress(false); + csr_roam_roaming_offload_timer_action(pMac, 0, sessionId, + ROAMING_OFFLOAD_TIMER_STOP); csr_roam_call_callback(pMac, sessionId, NULL, 0, eCSR_ROAM_NAPI_OFF, eSIR_SME_SUCCESS); csr_roam_synch_clean_up(pMac, sessionId); @@ -19985,16 +20079,27 @@ void csr_roam_synch_callback(tpAniSirGlobal mac_ctx, sms_log(mac_ctx, LOG1, FL("LFR3: reason: %d"), reason); switch (reason) { case SIR_ROAMING_DEREGISTER_STA: + /* + * The following is the first thing done in CSR + * after receiving RSI. Hence stopping the timer here. + */ + csr_roam_roaming_offload_timer_action(mac_ctx, + 0, session_id, ROAMING_OFFLOAD_TIMER_STOP); csr_roam_call_callback(mac_ctx, session_id, NULL, 0, eCSR_ROAM_FT_START, eSIR_SME_SUCCESS); sme_release_global_lock(&mac_ctx->sme); return; case SIR_ROAMING_START: + csr_roam_roaming_offload_timer_action(mac_ctx, + CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD, session_id, + ROAMING_OFFLOAD_TIMER_START); csr_roam_call_callback(mac_ctx, session_id, NULL, 0, eCSR_ROAM_START, eSIR_SME_SUCCESS); sme_release_global_lock(&mac_ctx->sme); return; case SIR_ROAMING_ABORT: + csr_roam_roaming_offload_timer_action(mac_ctx, + 0, session_id, ROAMING_OFFLOAD_TIMER_STOP); csr_roam_call_callback(mac_ctx, session_id, NULL, 0, eCSR_ROAM_ABORT, eSIR_SME_SUCCESS); sme_release_global_lock(&mac_ctx->sme);