From f82fb2b8f7ce91faf9a5f1e883e686c038787cc3 Mon Sep 17 00:00:00 2001 From: "Pamidipati, Vijay" Date: Wed, 28 Jun 2017 05:31:50 +0530 Subject: [PATCH] qcacmn: Add support to process v2 fw2wbm completion structure FW has moved to using v2 HTT_FW2WBM message format for Tx completions Add corresponding change on Host. Add missing code to free Tx descriptors for few HTT completion types Also change the descriptor pool lock to spinlock_bh since transmit path and completions typically run in tasklet/softirq context Change-Id: I024d44243f95907f19086225f0f02a5cd64f4508 CRs-Fixed: 2068155 --- dp/wifi3.0/dp_tx.c | 21 ++++++--------------- dp/wifi3.0/dp_tx_desc.h | 17 +++++++++-------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 21c4038a9524..886bfe0a79d7 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -845,8 +845,6 @@ static QDF_STATUS dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev, "%s TCL ring full ring_id:%d\n", __func__, ring_id); DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1); DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1); - hal_srng_access_end(soc->hal_soc, - soc->tcl_data_ring[ring_id].hal_srng); return QDF_STATUS_E_RESOURCES; } @@ -1044,11 +1042,10 @@ static qdf_nbuf_t dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, goto fail_return; } - hal_srng_access_end(soc->hal_soc, hal_srng); - - return NULL; + nbuf = NULL; fail_return: + hal_srng_access_end(soc->hal_soc, hal_srng); return nbuf; } @@ -1695,6 +1692,7 @@ static void dp_tx_inspect_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status) qdf_nbuf_len(tx_desc->nbuf)); DP_TX_FREE_SINGLE_BUF(soc, tx_desc->nbuf); + dp_tx_desc_release(tx_desc, tx_desc->pool_id); } /** @@ -1719,20 +1717,15 @@ void dp_tx_process_htt_completion(struct dp_tx_desc_s *tx_desc, uint8_t *status) pdev = tx_desc->pdev; soc = pdev->soc; - tx_status = HTT_TX_WBM_COMPLETION_TX_STATUS_GET(htt_status_word[0]); + tx_status = HTT_TX_WBM_COMPLETION_V2_TX_STATUS_GET(htt_status_word[0]); switch (tx_status) { case HTT_TX_FW2WBM_TX_STATUS_OK: - { - qdf_atomic_dec(&pdev->num_tx_exception); - DP_TX_FREE_SINGLE_BUF(soc, tx_desc->nbuf); - break; - } case HTT_TX_FW2WBM_TX_STATUS_DROP: case HTT_TX_FW2WBM_TX_STATUS_TTL: { - qdf_atomic_dec(&pdev->num_tx_exception); DP_TX_FREE_SINGLE_BUF(soc, tx_desc->nbuf); + dp_tx_desc_release(tx_desc, tx_desc->pool_id); break; } case HTT_TX_FW2WBM_TX_STATUS_REINJECT: @@ -2122,9 +2115,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id, "Txdesc invalid, flgs = %x,id = %d", tx_desc->flags, tx_desc_id); - /* TODO Handle Freeing of the buffer in this invalid - * descriptor */ - continue; + qdf_assert_always(0); } /* diff --git a/dp/wifi3.0/dp_tx_desc.h b/dp/wifi3.0/dp_tx_desc.h index cb8694f64d06..4a82cc7c81cc 100644 --- a/dp/wifi3.0/dp_tx_desc.h +++ b/dp/wifi3.0/dp_tx_desc.h @@ -39,8 +39,8 @@ #define TX_DESC_LOCK_CREATE(lock) qdf_spinlock_create(lock) #define TX_DESC_LOCK_DESTROY(lock) qdf_spinlock_destroy(lock) -#define TX_DESC_LOCK_LOCK(lock) qdf_spin_lock(lock) -#define TX_DESC_LOCK_UNLOCK(lock) qdf_spin_unlock(lock) +#define TX_DESC_LOCK_LOCK(lock) qdf_spin_lock_bh(lock) +#define TX_DESC_LOCK_UNLOCK(lock) qdf_spin_unlock_bh(lock) #define MAX_POOL_BUFF_COUNT 10000 QDF_STATUS dp_tx_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id, @@ -71,20 +71,21 @@ static inline struct dp_tx_desc_s *dp_tx_desc_alloc(struct dp_soc *soc, TX_DESC_LOCK_LOCK(&soc->tx_desc[desc_pool_id].lock); tx_desc = soc->tx_desc[desc_pool_id].freelist; + /* Pool is exhausted */ if (!tx_desc) { TX_DESC_LOCK_UNLOCK(&soc->tx_desc[desc_pool_id].lock); return NULL; } - if (soc->tx_desc[desc_pool_id].freelist) { - soc->tx_desc[desc_pool_id].freelist = - soc->tx_desc[desc_pool_id].freelist->next; - soc->tx_desc[desc_pool_id].num_allocated++; - soc->tx_desc[desc_pool_id].num_free--; - } + + soc->tx_desc[desc_pool_id].freelist = + soc->tx_desc[desc_pool_id].freelist->next; + soc->tx_desc[desc_pool_id].num_allocated++; + soc->tx_desc[desc_pool_id].num_free--; DP_STATS_INC(soc, tx.desc_in_use, 1); tx_desc->flags = DP_TX_DESC_FLAG_ALLOCATED; + TX_DESC_LOCK_UNLOCK(&soc->tx_desc[desc_pool_id].lock); return tx_desc;