diff options
| author | Naveen Rawat <nrawat@qca.qualcomm.com> | 2014-06-15 23:09:20 -0700 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-06-23 18:20:03 -0700 |
| commit | 3efd8457ff044d1e569b0b78f08a8c8a41f94ac1 (patch) | |
| tree | 8b06131ac63b20718fa304343328f91ad55abb5f | |
| parent | 97ab5e2a93a621c12aba73381727ca553c9f0b2d (diff) | |
qcacld: Fix for data loss during roaming
During roaming when VDEV_STOP is requested, there are still
some pending packets in hardware Tx queues. Checking pending
tx descriptors will indicate the packets still left in hardware
tx queues. To fix data loss while roaming Let them drain before
VDEV_STOP
Change-Id: Ib9ee3cf243f0d975eb3f48ce4b734e861acf46a6
CRs-Fixed: 679255
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 38 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.h | 11 |
2 files changed, 48 insertions, 1 deletions
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index b4f9b88a1dbd..fd59e4f49cc3 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -3317,6 +3317,14 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, goto err_event_init; } + /* Init tx queue empty check event */ + vos_status = vos_event_init(&wma_handle->tx_queue_empty_event); + if (!VOS_IS_STATUS_SUCCESS(vos_status)) { + WMA_LOGP("%s: failed to init tx_queue_empty_event", + __func__); + goto err_event_init; + } + vos_status = vos_event_init(&wma_handle->wma_resume_event); if (vos_status != VOS_STATUS_SUCCESS) { WMA_LOGP("%s: wma_resume_event initialization failed", __func__); @@ -9948,6 +9956,13 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss) ol_txrx_peer_state_update(pdev, add_bss->bssId, ol_txrx_peer_state_conn); #ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + peer = ol_txrx_find_peer_by_addr(pdev, add_bss->bssId, &peer_id); + if (!peer) { + WMA_LOGE("%s:%d Failed to find peer %pM", __func__, + __LINE__, add_bss->bssId); + goto send_fail_resp; + } + vdev = wma_find_vdev_by_id(wma, vdev_id); if (!vdev) { WMA_LOGE("%s Invalid txrx vdev", __func__); @@ -11490,7 +11505,8 @@ static void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) VOS_STATUS status = VOS_STATUS_SUCCESS; u_int8_t peer_id; ol_txrx_vdev_handle txrx_vdev; - + u_int8_t max_wait_iterations = WMA_TX_Q_RECHECK_TIMER_MAX_WAIT / + WMA_TX_Q_RECHECK_TIMER_WAIT; pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); if (NULL == pdev) { @@ -11543,6 +11559,23 @@ static void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) status = VOS_STATUS_E_NOMEM; goto detach_peer; } + + WMA_LOGW(FL("Outstanding msdu packets: %d"), + ol_txrx_get_tx_pending(pdev)); + + while ( ol_txrx_get_tx_pending(pdev) && max_wait_iterations ) + { + vos_wait_single_event(&wma->tx_queue_empty_event, + WMA_TX_Q_RECHECK_TIMER_MAX_WAIT); + max_wait_iterations--; + } + + if (ol_txrx_get_tx_pending(pdev)) + { + WMA_LOGW(FL("Outstanding msdu packets before VDEV_STOP : %d"), + ol_txrx_get_tx_pending(pdev)); + } + if (wmi_unified_vdev_stop_send(wma->wmi_handle, params->smesessionId)) { WMA_LOGP("%s: %d Failed to send vdev stop", __func__, __LINE__); @@ -18113,6 +18146,9 @@ static VOS_STATUS wma_tx_detach(tp_wma_handle wma_handle) /* Destroy Tx Frame Complete event */ vos_event_destroy(&wma_handle->tx_frm_download_comp_event); + /* Tx queue empty check event (dummy event) */ + vos_event_destroy(&wma_handle->tx_queue_empty_event); + /* Reset Tx Frm Callbacks */ wma_handle->tx_frm_download_comp_cb = NULL; diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 7f25e3606aeb..a818295874ad 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -573,6 +573,14 @@ typedef struct { /* Event to wait for tx download completion */ vos_event_t tx_frm_download_comp_event; + /* + * Dummy event to wait for draining MSDUs left in hardware tx + * queue and before requesting VDEV_STOP. Nobody will set this + * and wait will timeout, and code will poll the pending tx + * descriptors number to be zero. + */ + vos_event_t tx_queue_empty_event; + /* Ack Complete Callback registered by umac */ pWDAAckFnTxComp umac_ota_ack_cb[SIR_MAC_MGMT_RESERVED15]; pWDAAckFnTxComp umac_data_ota_ack_cb; @@ -1593,4 +1601,7 @@ enum uapsd_up { #define WMA_TGT_INVALID_SNR (-1) #define WMA_DYNAMIC_DTIM_SETTING_THRESHOLD 2 + +#define WMA_TX_Q_RECHECK_TIMER_WAIT 2 // 2 ms +#define WMA_TX_Q_RECHECK_TIMER_MAX_WAIT 20 // 20 ms #endif |
