diff options
| -rw-r--r-- | core/dp/htt/htt_rx.c | 50 | ||||
| -rw-r--r-- | core/dp/htt/htt_types.h | 6 | ||||
| -rw-r--r-- | core/dp/ol/inc/ol_htt_rx_api.h | 19 | ||||
| -rw-r--r-- | core/dp/txrx/ol_rx.c | 12 |
4 files changed, 79 insertions, 8 deletions
diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c index 617becb5e1db..991fa51d7e33 100644 --- a/core/dp/htt/htt_rx.c +++ b/core/dp/htt/htt_rx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -408,13 +408,17 @@ static void htt_rx_ring_refill_retry(void *arg) } #endif -static void htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num) +/* full_reorder_offload case: this function is called with lock held */ +static int htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num) { int idx; QDF_STATUS status; struct htt_host_rx_desc_base *rx_desc; + int filled = 0; idx = *(pdev->rx_ring.alloc_idx.vaddr); + +moretofill: while (num > 0) { qdf_dma_addr_t paddr; qdf_nbuf_t rx_netbuf; @@ -504,14 +508,21 @@ static void htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num) num--; idx++; + filled++; idx &= pdev->rx_ring.size_mask; } + if (qdf_atomic_read(&pdev->rx_ring.refill_debt) > 0) { + num = qdf_atomic_read(&pdev->rx_ring.refill_debt); + /* Ideally the following gives 0, but sub is safer */ + qdf_atomic_sub(num, &pdev->rx_ring.refill_debt); + goto moretofill; + } fail: *(pdev->rx_ring.alloc_idx.vaddr) = idx; htt_rx_dbg_rxbuf_indupd(pdev, idx); - return; + return filled; } static inline unsigned htt_rx_ring_elems(struct htt_pdev_t *pdev) @@ -583,6 +594,9 @@ void htt_rx_detach(struct htt_pdev_t *pdev) pdev->rx_ring.base_paddr, qdf_get_dma_mem_context((&pdev->rx_ring.buf), memctx)); + + /* destroy the rx-parallelization refill spinlock */ + qdf_spinlock_destroy(&(pdev->rx_ring.refill_lock)); } #endif @@ -2810,6 +2824,31 @@ void htt_rx_msdu_buff_replenish(htt_pdev_handle pdev) qdf_atomic_inc(&pdev->rx_ring.refill_ref_cnt); } +#define RX_RING_REFILL_DEBT_MAX 128 +int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num) +{ + int filled = 0; + + if (!qdf_spin_trylock_bh(&(pdev->rx_ring.refill_lock))) { + if (qdf_atomic_read(&pdev->rx_ring.refill_debt) + < RX_RING_REFILL_DEBT_MAX) { + qdf_atomic_add(num, &pdev->rx_ring.refill_debt); + return filled; /* 0 */ + } + /* + * else: + * If we have quite a debt, then it is better for the lock + * holder to finish its work and then acquire the lock and + * fill our own part. + */ + qdf_spin_lock_bh(&(pdev->rx_ring.refill_lock)); + } + filled = htt_rx_ring_fill_n(pdev, num); + qdf_spin_unlock_bh(&(pdev->rx_ring.refill_lock)); + + return filled; +} + #define AR600P_ASSEMBLE_HW_RATECODE(_rate, _nss, _pream) \ (((_pream) << 6) | ((_nss) << 4) | (_rate)) @@ -3201,6 +3240,11 @@ int htt_rx_attach(struct htt_pdev_t *pdev) qdf_atomic_init(&pdev->rx_ring.refill_ref_cnt); qdf_atomic_inc(&pdev->rx_ring.refill_ref_cnt); + /* Initialize the refill_lock and debt (for rx-parallelization) */ + qdf_spinlock_create(&(pdev->rx_ring.refill_lock)); + qdf_atomic_init(&pdev->rx_ring.refill_debt); + + /* Initialize the Rx refill retry timer */ qdf_timer_init(pdev->osdev, &pdev->rx_ring.refill_retry_timer, diff --git a/core/dp/htt/htt_types.h b/core/dp/htt/htt_types.h index cb4e885d5521..df126841b7c6 100644 --- a/core/dp/htt/htt_types.h +++ b/core/dp/htt/htt_types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -347,7 +347,9 @@ struct htt_pdev_t { * variable is used to guarantee that only one thread tries * to replenish Rx ring. */ - qdf_atomic_t refill_ref_cnt; + qdf_atomic_t refill_ref_cnt; + qdf_spinlock_t refill_lock; + qdf_atomic_t refill_debt; #ifdef DEBUG_DMA_DONE uint32_t dbg_initial_msdu_payld; uint32_t dbg_mpdu_range; diff --git a/core/dp/ol/inc/ol_htt_rx_api.h b/core/dp/ol/inc/ol_htt_rx_api.h index e2149be366df..5edebb7f7f8b 100644 --- a/core/dp/ol/inc/ol_htt_rx_api.h +++ b/core/dp/ol/inc/ol_htt_rx_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -788,6 +788,23 @@ void htt_rx_msdu_desc_free(htt_pdev_handle htt_pdev, qdf_nbuf_t msdu); void htt_rx_msdu_buff_replenish(htt_pdev_handle pdev); /** + * @brief Add new MSDU buffers for the target to fill. + * @details + * This is full_reorder_offload version of the replenish function. + * In full_reorder, FW sends HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND + * msg to host. It includes the number of MSDUs. Thgis will be fed + * into htt_rx_msdu_buff_in_order_replenish function. + * The reason for creating yet another function is to avoid checks + * in real-time. + * + * @param pdev - the HTT instance the rx data will be received on + * @num - number of buffers to replenish + * + * Return: number of buffers actually replenished + */ +int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num); + +/** * @brief Links list of MSDUs into an single MPDU. Updates RX stats * @details * When HW MSDU splitting is turned on each MSDU in an AMSDU MPDU occupies diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c index 20f96cb504bd..4a29fe4f501a 100644 --- a/core/dp/txrx/ol_rx.c +++ b/core/dp/txrx/ol_rx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1348,6 +1348,9 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, htt_pdev_handle htt_pdev = NULL; int status; qdf_nbuf_t head_msdu, tail_msdu = NULL; + uint8_t *rx_ind_data; + uint32_t *msg_word; + uint32_t msdu_count; #ifdef WDI_EVENT_ENABLE uint8_t pktlog_bit; #endif @@ -1374,6 +1377,11 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, pktlog_bit = (htt_rx_amsdu_rx_in_order_get_pktlog(rx_ind_msg) == 0x01); #endif + rx_ind_data = qdf_nbuf_data(rx_ind_msg); + msg_word = (uint32_t *)rx_ind_data; + /* Get the total number of MSDUs */ + msdu_count = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1)); + /* * Get a linked list of the MSDUs in the rx in order indication. * This also attaches each rx MSDU descriptor to the @@ -1389,7 +1397,7 @@ ol_rx_in_order_indication_handler(ol_txrx_pdev_handle pdev, /* Replenish the rx buffer ring first to provide buffers to the target rather than waiting for the indeterminate time taken by the OS to consume the rx frames */ - htt_rx_msdu_buff_replenish(htt_pdev); + htt_rx_msdu_buff_in_order_replenish(htt_pdev, msdu_count); /* Send the chain of MSDUs to the OS */ /* rx_opt_proc takes a NULL-terminated list of msdu netbufs */ |
