summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/dp/htt/htt_rx.c50
-rw-r--r--core/dp/htt/htt_types.h6
-rw-r--r--core/dp/ol/inc/ol_htt_rx_api.h19
-rw-r--r--core/dp/txrx/ol_rx.c12
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 */