From f907f91debdac174659dee0d281d0022fa77d515 Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Mon, 21 Mar 2016 15:06:22 -0700 Subject: [PATCH] qcacld-3.0: Reduce packet loss while roaming As soon as the firmware is done with the roaming scan and about to start hand-off, it will notify the host that the roaming is about to start using WMI_ROAM_NOTIF_ROAM_START. The host driver will then notify the upper layers to stop sending the packets and the host later informs them as part of roam synch propagation after roaming is done to start sending the packets. Once the firmware sends the notification and if it fails to roam for some reason, then it will send another notification WMI_ROAM_NOTIF_ROAM_ABORT to let the host know the upper layers to resume sending the packets again. Introduce an operation code for the CSR roaming callback to determine what it needs to do when called by the lower layers. CRs-Fixed: 996949 Change-Id: I674262b95f1781747b34fb675ad179952a8ae4d1 --- core/hdd/src/wlan_hdd_assoc.c | 12 ++++++++++++ core/mac/inc/sir_api.h | 15 +++++++++++++-- core/sme/inc/csr_api.h | 2 ++ core/sme/inc/csr_neighbor_roam.h | 4 ++-- core/sme/src/csr/csr_api_roam.c | 21 +++++++++++++++++++-- core/wma/inc/wma.h | 3 ++- core/wma/inc/wma_types.h | 6 ++++-- core/wma/src/wma_mgmt.c | 3 ++- core/wma/src/wma_scan_roam.c | 29 +++++++++++++++++++++++------ 9 files changed, 79 insertions(+), 16 deletions(-) diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 3475a18c9622..cad7ae03bc89 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -4038,6 +4038,18 @@ hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId, FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"), pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId); break; + case eCSR_ROAM_DISABLE_QUEUES: + hdd_info("Disabling queues"); + wlan_hdd_netif_queue_control(pAdapter, + WLAN_NETIF_TX_DISABLE, + WLAN_CONTROL_PATH); + break; + case eCSR_ROAM_ENABLE_QUEUES: + hdd_info("Enabling queues"); + wlan_hdd_netif_queue_control(pAdapter, + WLAN_WAKE_ALL_NETIF_QUEUE, + WLAN_CONTROL_PATH); + break; case eCSR_ROAM_SHOULD_ROAM: /* notify apps that we can't pass traffic anymore */ diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index e54d51277bb0..0a9b8a92a714 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -170,10 +170,21 @@ typedef enum { #define SIR_UAPSD_FLAG_ACBE (1 << SIR_UAPSD_BITOFFSET_ACBE) #define SIR_UAPSD_GET(ac, mask) (((mask) & (SIR_UAPSD_FLAG_ ## ac)) >> SIR_UAPSD_BITOFFSET_ ## ac) -#define ROAM_SYNCH_PROPAGATION 1 -#define ROAMING_TX_QUEUE_DISABLE 2 #endif +/** + * enum sir_roam_op_code - Operation to be done by the callback. + * @SIR_ROAM_SYNCH_PROPAGATION: Propagate the new BSS info after roaming. + * @SIR_ROAMING_DEREGISTER_STA: Deregister the old STA after roaming. + * @SIR_ROAMING_TX_QUEUE_DISABLE: Disable the network queues while roaming. + * @SIR_ROAMING_TX_QUEUE_ENABLE: Enable back the n/w queues in case roam fails. + */ +enum sir_roam_op_code { + SIR_ROAM_SYNCH_PROPAGATION = 1, + SIR_ROAMING_DEREGISTER_STA, + SIR_ROAMING_TX_QUEUE_DISABLE, + SIR_ROAMING_TX_QUEUE_ENABLE, +}; /** * Module ID definitions. */ diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 0d06b3ac3346..ae0c98749e4f 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -493,6 +493,8 @@ typedef enum { eCSR_ROAM_DFS_CHAN_SW_NOTIFY, eCSR_ROAM_EXT_CHG_CHNL_IND, eCSR_ROAM_STATUS_UPDATE_HW_MODE, + eCSR_ROAM_DISABLE_QUEUES, + eCSR_ROAM_ENABLE_QUEUES, } eRoamCmdStatus; /* comment inside indicates what roaming callback gets */ diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h index f56c2e32d73a..b8b8e875a18f 100644 --- a/core/sme/inc/csr_neighbor_roam.h +++ b/core/sme/inc/csr_neighbor_roam.h @@ -364,11 +364,11 @@ QDF_STATUS csr_neighbor_roam_offload_update_preauth_list(tpAniSirGlobal pMac, roam_offload_synch_ind *roam_synch_ind_ptr, uint8_t sessionId); void csr_roam_synch_callback(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr, uint8_t reason); + tpSirBssDescription bss_desc_ptr, enum sir_roam_op_code reason); #else static inline void csr_roam_synch_callback(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr, uint8_t reason) + tpSirBssDescription bss_desc_ptr, enum sir_roam_op_code reason) {} #endif void csr_neighbor_roam_state_transition(tpAniSirGlobal mac_ctx, diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 832b82806d7d..b86916195094 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -18693,7 +18693,7 @@ void csr_roam_fill_tdls_info(tCsrRoamInfo *roam_info, tpSirSmeJoinRsp join_rsp) */ void csr_roam_synch_callback(tpAniSirGlobal mac_ctx, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc, uint8_t reason) + tpSirBssDescription bss_desc, enum sir_roam_op_code reason) { uint8_t session_id = roam_synch_data->roamedVdevId; tCsrRoamSession *session = CSR_GET_SESSION(mac_ctx, session_id); @@ -18721,11 +18721,28 @@ void csr_roam_synch_callback(tpAniSirGlobal mac_ctx, return; } session->roam_synch_in_progress = true; - if (reason == ROAMING_TX_QUEUE_DISABLE) { + switch (reason) { + case SIR_ROAMING_DEREGISTER_STA: 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_TX_QUEUE_DISABLE: + csr_roam_call_callback(mac_ctx, session_id, NULL, 0, + eCSR_ROAM_DISABLE_QUEUES, eSIR_SME_SUCCESS); + sme_release_global_lock(&mac_ctx->sme); + return; + case SIR_ROAMING_TX_QUEUE_ENABLE: + csr_roam_call_callback(mac_ctx, session_id, NULL, 0, + eCSR_ROAM_ENABLE_QUEUES, eSIR_SME_SUCCESS); + sme_release_global_lock(&mac_ctx->sme); + return; + case SIR_ROAM_SYNCH_PROPAGATION: + break; + default: + sms_log(mac_ctx, LOGE, FL("LFR3: callback reason %d"), reason); + sme_release_global_lock(&mac_ctx->sme); + return; } session->roam_synch_data = roam_synch_data; if (!QDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies(mac_ctx, diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 886179f74337..06f19bf20090 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1339,7 +1339,8 @@ typedef struct { #ifdef WLAN_FEATURE_ROAM_OFFLOAD void (*csr_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr, uint8_t reason); + tpSirBssDescription bss_desc_ptr, + enum sir_roam_op_code reason); QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, tpSirBssDescription bss_desc_ptr); diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index dfd8f8ac0b5f..c82cfa033a33 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -704,7 +704,8 @@ QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx, #ifdef WLAN_FEATURE_ROAM_OFFLOAD void (*csr_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr, uint8_t reason), + tpSirBssDescription bss_desc_ptr, + enum sir_roam_op_code reason), QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, tpSirBssDescription bss_desc_ptr)); @@ -712,7 +713,8 @@ QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx, static inline QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx, void (*csr_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr, uint8_t reason), + tpSirBssDescription bss_desc_ptr, + enum sir_roam_op_code reason), QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, tpSirBssDescription bss_desc_ptr)) diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 6a2ddde6bd8a..e9fe6441471c 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -3173,7 +3173,8 @@ QDF_STATUS wma_de_register_mgmt_frm_client(void *cds_ctx) QDF_STATUS wma_register_roaming_callbacks(void *cds_ctx, void (*csr_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, - tpSirBssDescription bss_desc_ptr, uint8_t reason), + tpSirBssDescription bss_desc_ptr, + enum sir_roam_op_code reason), QDF_STATUS (*pe_roam_synch_cb)(tpAniSirGlobal mac, roam_offload_synch_ind *roam_synch_data, tpSirBssDescription bss_desc_ptr)) diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 91212cd44cd6..78d57ac32921 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -1883,7 +1883,7 @@ void wma_fill_roam_synch_buffer(tp_wma_handle wma, WMI_MAC_ADDR_TO_CHAR_ARRAY(&synch_event->bssid, roam_synch_ind_ptr->bssid.bytes); wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context, - roam_synch_ind_ptr, NULL, ROAMING_TX_QUEUE_DISABLE); + roam_synch_ind_ptr, NULL, SIR_ROAMING_DEREGISTER_STA); /* Beacon/Probe Rsp data */ roam_synch_ind_ptr->beaconProbeRespOffset = sizeof(roam_offload_synch_ind); @@ -2088,7 +2088,7 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, roam_synch_ind_ptr, bss_desc_ptr); wma_roam_update_vdev(wma, roam_synch_ind_ptr); wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context, - roam_synch_ind_ptr, bss_desc_ptr, ROAM_SYNCH_PROPAGATION); + roam_synch_ind_ptr, bss_desc_ptr, SIR_ROAM_SYNCH_PROPAGATION); wma_process_roam_synch_complete(wma, synch_event->vdev_id); cleanup_label: if (roam_synch_ind_ptr->join_rsp) @@ -2380,7 +2380,6 @@ void wma_process_unit_test_cmd(WMA_HANDLE handle, } #ifdef WLAN_FEATURE_ROAM_OFFLOAD - /** * wma_roam_ho_fail_handler() - LFR3.0 roam hand off failed handler * @wma: wma handle @@ -5367,6 +5366,8 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, tp_wma_handle wma_handle = (tp_wma_handle) handle; WMI_ROAM_EVENTID_param_tlvs *param_buf; wmi_roam_event_fixed_param *wmi_event; + struct sSirSmeRoamOffloadSynchInd *roam_synch_data; + enum sir_roam_op_code op_code = {0}; param_buf = (WMI_ROAM_EVENTID_param_tlvs *) event_buf; if (!param_buf) { @@ -5375,9 +5376,9 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, } wmi_event = param_buf->fixed_param; - WMA_LOGD("%s: Reason %x for vdevid %x, rssi %d", - __func__, wmi_event->reason, wmi_event->vdev_id, - wmi_event->rssi); + WMA_LOGD("%s: Reason %x, Notif %x for vdevid %x, rssi %d", + __func__, wmi_event->reason, wmi_event->notif, + wmi_event->vdev_id, wmi_event->rssi); switch (wmi_event->reason) { case WMI_ROAM_REASON_BMISS: @@ -5403,6 +5404,22 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf, wma_roam_ho_fail_handler(wma_handle, wmi_event->vdev_id); break; #endif + case WMI_ROAM_REASON_INVALID: + roam_synch_data = qdf_mem_malloc(sizeof(*roam_synch_data)); + if (NULL == roam_synch_data) { + WMA_LOGE("Memory unavailable for roam synch data"); + return -ENOMEM; + } + if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_START) + op_code = SIR_ROAMING_TX_QUEUE_DISABLE; + if (wmi_event->notif == WMI_ROAM_NOTIF_ROAM_ABORT) + op_code = SIR_ROAMING_TX_QUEUE_ENABLE; + roam_synch_data->roamedVdevId = wmi_event->vdev_id; + wma_handle->csr_roam_synch_cb( + (tpAniSirGlobal)wma_handle->mac_context, + roam_synch_data, NULL, op_code); + qdf_mem_free(roam_synch_data); + break; default: WMA_LOGD("%s:Unhandled Roam Event %x for vdevid %x", __func__, wmi_event->reason, wmi_event->vdev_id);