|
@@ -34,6 +34,184 @@ dp_rx_mon_status_process(struct dp_soc *soc,
|
|
|
uint32_t mac_id,
|
|
|
uint32_t quota);
|
|
|
|
|
|
+/*
|
|
|
+ * dp_rx_mon_status_buf_validate () - Validate first monitor status buffer addr
|
|
|
+ * against status buf addr given in monitor destination ring
|
|
|
+ *
|
|
|
+ * @pdev: DP pdev handle
|
|
|
+ * @mac_id: lmac id
|
|
|
+ *
|
|
|
+ * Return: QDF_STATUS
|
|
|
+ */
|
|
|
+static inline QDF_STATUS
|
|
|
+dp_rx_mon_status_buf_validate(struct dp_pdev *pdev, uint32_t mac_id)
|
|
|
+{
|
|
|
+ struct dp_soc *soc = pdev->soc;
|
|
|
+ hal_soc_handle_t hal_soc;
|
|
|
+ void *mon_status_srng;
|
|
|
+ void *ring_entry;
|
|
|
+ uint32_t rx_buf_cookie;
|
|
|
+ qdf_nbuf_t status_nbuf;
|
|
|
+ struct dp_rx_desc *rx_desc;
|
|
|
+ uint64_t buf_paddr;
|
|
|
+ struct rx_desc_pool *rx_desc_pool;
|
|
|
+ uint32_t tlv_tag;
|
|
|
+ void *rx_tlv;
|
|
|
+ struct hal_rx_ppdu_info *ppdu_info;
|
|
|
+ QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
|
|
+ QDF_STATUS buf_status;
|
|
|
+
|
|
|
+ mon_status_srng = soc->rxdma_mon_status_ring[mac_id].hal_srng;
|
|
|
+
|
|
|
+ qdf_assert(mon_status_srng);
|
|
|
+ if (!mon_status_srng || !hal_srng_initialized(mon_status_srng)) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ "%s %d : HAL Monitor Status Ring Init Failed -- %pK",
|
|
|
+ __func__, __LINE__, mon_status_srng);
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ hal_soc = soc->hal_soc;
|
|
|
+
|
|
|
+ qdf_assert(hal_soc);
|
|
|
+
|
|
|
+ if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_status_srng))) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ "%s %d : HAL SRNG access Failed -- %pK",
|
|
|
+ __func__, __LINE__, mon_status_srng);
|
|
|
+ return status;
|
|
|
+ }
|
|
|
+
|
|
|
+ ring_entry = hal_srng_src_peek_n_get_next(hal_soc, mon_status_srng);
|
|
|
+ if (!ring_entry) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ "%s %d : HAL SRNG entry is NULL srng:-- %pK",
|
|
|
+ __func__, __LINE__, mon_status_srng);
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ ppdu_info = &pdev->ppdu_info;
|
|
|
+
|
|
|
+ rx_desc_pool = &soc->rx_desc_status[mac_id];
|
|
|
+
|
|
|
+ buf_paddr = (HAL_RX_BUFFER_ADDR_31_0_GET(ring_entry) |
|
|
|
+ ((uint64_t)(HAL_RX_BUFFER_ADDR_39_32_GET(ring_entry)) << 32));
|
|
|
+
|
|
|
+ if (!buf_paddr) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ "%s %d : buf addr is NULL -- %pK",
|
|
|
+ __func__, __LINE__, mon_status_srng);
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ rx_buf_cookie = HAL_RX_BUF_COOKIE_GET(ring_entry);
|
|
|
+ rx_desc = dp_rx_cookie_2_va_mon_status(soc, rx_buf_cookie);
|
|
|
+
|
|
|
+ qdf_assert(rx_desc);
|
|
|
+
|
|
|
+ status_nbuf = rx_desc->nbuf;
|
|
|
+
|
|
|
+ qdf_nbuf_sync_for_cpu(soc->osdev, status_nbuf,
|
|
|
+ QDF_DMA_FROM_DEVICE);
|
|
|
+
|
|
|
+ rx_tlv = qdf_nbuf_data(status_nbuf);
|
|
|
+
|
|
|
+ buf_status = hal_get_rx_status_done(rx_tlv);
|
|
|
+
|
|
|
+ /* If status buffer DMA is not done,
|
|
|
+ * hold on to mon destination ring.
|
|
|
+ */
|
|
|
+ if (buf_status != QDF_STATUS_SUCCESS) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("Monitor status ring: DMA is not done "
|
|
|
+ "for nbuf: %pK buf_addr: %llx"),
|
|
|
+ status_nbuf, buf_paddr);
|
|
|
+ pdev->rx_mon_stats.tlv_tag_status_err++;
|
|
|
+ pdev->hold_mon_dest_ring = true;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_nbuf_unmap_nbytes_single(soc->osdev, status_nbuf,
|
|
|
+ QDF_DMA_FROM_DEVICE,
|
|
|
+ rx_desc_pool->buf_size);
|
|
|
+
|
|
|
+ rx_tlv = hal_rx_status_get_next_tlv(rx_tlv);
|
|
|
+
|
|
|
+ tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
|
|
|
+
|
|
|
+ if (tlv_tag == WIFIRX_PPDU_START_E) {
|
|
|
+ rx_tlv = (uint8_t *)rx_tlv + HAL_RX_TLV32_HDR_SIZE;
|
|
|
+ ppdu_info->com_info.ppdu_id = HAL_RX_GET(rx_tlv,
|
|
|
+ RX_PPDU_START_0,
|
|
|
+ PHY_PPDU_ID);
|
|
|
+ pdev->status_buf_addr = buf_paddr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* If Monitor destination ring is on hold and ppdu id matches,
|
|
|
+ * deliver PPDU data which was on hold.
|
|
|
+ */
|
|
|
+ if (pdev->hold_mon_dest_ring &&
|
|
|
+ (pdev->mon_desc->ppdu_id == pdev->ppdu_info.com_info.ppdu_id)) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("Monitor destination was on Hold "
|
|
|
+ "PPDU id matched"));
|
|
|
+
|
|
|
+ pdev->hold_mon_dest_ring = false;
|
|
|
+ goto done;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((pdev->mon_desc->status_buf.paddr != buf_paddr) ||
|
|
|
+ (pdev->mon_desc->ppdu_id != pdev->ppdu_info.com_info.ppdu_id)) {
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("Monitor: PPDU id or status buf_addr mismatch "
|
|
|
+ "status_ppdu_id: %d dest_ppdu_id: %d "
|
|
|
+ "status_addr: %llx status_buf_cookie: %d "
|
|
|
+ "dest_addr: %llx tlv_tag: %d"
|
|
|
+ " status_nbuf: %pK"),
|
|
|
+ pdev->ppdu_info.com_info.ppdu_id,
|
|
|
+ pdev->mon_desc->ppdu_id, pdev->status_buf_addr,
|
|
|
+ rx_buf_cookie,
|
|
|
+ pdev->mon_desc->status_buf.paddr, tlv_tag,
|
|
|
+ status_nbuf);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Monitor Status ring is reaped in two cases:
|
|
|
+ * a. If first status buffer's buf_addr_info matches
|
|
|
+ * with latched status buffer addr info in monitor
|
|
|
+ * destination ring.
|
|
|
+ * b. If monitor status ring is lagging behind
|
|
|
+ * monitor destination ring. Hold on to monitor
|
|
|
+ * destination ring in this case until status ring
|
|
|
+ * and destination ring ppdu id matches.
|
|
|
+ */
|
|
|
+ if ((pdev->mon_desc->status_buf.paddr == buf_paddr) ||
|
|
|
+ (pdev->mon_desc->ppdu_id > pdev->ppdu_info.com_info.ppdu_id)) {
|
|
|
+ if (pdev->mon_desc->ppdu_id >
|
|
|
+ pdev->ppdu_info.com_info.ppdu_id) {
|
|
|
+
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("Monitor status ring is lagging behind "
|
|
|
+ "monitor destination ring "
|
|
|
+ "status_ppdu_id: %d dest_ppdu_id: %d "
|
|
|
+ "status_nbuf: %pK tlv_tag: %d "
|
|
|
+ "status_addr: %llx dest_addr: %llx "),
|
|
|
+ ppdu_info->com_info.ppdu_id,
|
|
|
+ pdev->mon_desc->ppdu_id,
|
|
|
+ status_nbuf, tlv_tag,
|
|
|
+ pdev->status_buf_addr,
|
|
|
+ pdev->mon_desc->status_buf.paddr);
|
|
|
+
|
|
|
+ pdev->rx_mon_stats.ppdu_id_mismatch++;
|
|
|
+ pdev->rx_mon_stats.status_ppdu_drop++;
|
|
|
+ pdev->hold_mon_dest_ring = true;
|
|
|
+ }
|
|
|
+ status = QDF_STATUS_SUCCESS;
|
|
|
+ }
|
|
|
+done:
|
|
|
+ hal_srng_access_end(hal_soc, mon_status_srng);
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* dp_rx_mon_prepare_mon_mpdu () - API to prepare dp_mon_mpdu object
|
|
|
*
|
|
@@ -52,7 +230,7 @@ dp_rx_mon_prepare_mon_mpdu(struct dp_pdev *pdev,
|
|
|
mon_mpdu = qdf_mem_malloc(sizeof(struct dp_mon_mpdu));
|
|
|
|
|
|
if (!mon_mpdu) {
|
|
|
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
|
|
FL("Monitor MPDU object allocation failed -- %pK"),
|
|
|
pdev);
|
|
|
qdf_assert_always(0);
|
|
@@ -69,6 +247,40 @@ dp_rx_mon_prepare_mon_mpdu(struct dp_pdev *pdev,
|
|
|
return mon_mpdu;
|
|
|
}
|
|
|
|
|
|
+static inline void
|
|
|
+dp_rx_mon_drop_ppdu(struct dp_pdev *pdev, uint32_t mac_id)
|
|
|
+{
|
|
|
+ struct dp_mon_mpdu *mpdu = NULL;
|
|
|
+ struct dp_mon_mpdu *temp_mpdu = NULL;
|
|
|
+ qdf_nbuf_t mon_skb, skb_next;
|
|
|
+
|
|
|
+ if (!TAILQ_EMPTY(&pdev->mon_mpdu_q)) {
|
|
|
+ TAILQ_FOREACH_SAFE(mpdu,
|
|
|
+ &pdev->mon_mpdu_q,
|
|
|
+ mpdu_list_elem,
|
|
|
+ temp_mpdu) {
|
|
|
+ TAILQ_REMOVE(&pdev->mon_mpdu_q,
|
|
|
+ mpdu, mpdu_list_elem);
|
|
|
+
|
|
|
+ mon_skb = mpdu->head;
|
|
|
+ while (mon_skb) {
|
|
|
+ skb_next = qdf_nbuf_next(mon_skb);
|
|
|
+
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP,
|
|
|
+ QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ "[%s][%d] mon_skb=%pK len %u"
|
|
|
+ " __func__, __LINE__",
|
|
|
+ mon_skb, mon_skb->len);
|
|
|
+
|
|
|
+ qdf_nbuf_free(mon_skb);
|
|
|
+ mon_skb = skb_next;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_mem_free(mpdu);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* dp_rx_monitor_deliver_ppdu () - API to deliver all MPDU for a MPDU
|
|
|
* to upper layer stack
|
|
@@ -128,21 +340,39 @@ dp_rx_mon_reap_status_ring(struct dp_soc *soc,
|
|
|
uint32_t work_done = 0;
|
|
|
|
|
|
status_buf_count = desc_info->status_buf_count;
|
|
|
+ desc_info->drop_ppdu = false;
|
|
|
|
|
|
-status_reap:
|
|
|
- work_done += dp_rx_mon_status_process(soc, mac_id, status_buf_count);
|
|
|
+ if (dp_rx_mon_status_buf_validate(pdev, mac_id) == QDF_STATUS_SUCCESS)
|
|
|
+ work_done = dp_rx_mon_status_process(soc,
|
|
|
+ mac_id,
|
|
|
+ status_buf_count);
|
|
|
|
|
|
if (desc_info->ppdu_id != pdev->ppdu_info.com_info.ppdu_id) {
|
|
|
- pdev->rx_mon_stats.ppdu_id_mismatch++;
|
|
|
-
|
|
|
- qdf_err("count: %d quota: %d work_done: %d status_ppdu_id: %d"
|
|
|
- "dest_ppdu_id: %d ", status_buf_count, quota,
|
|
|
- work_done,
|
|
|
- pdev->ppdu_info.com_info.ppdu_id,
|
|
|
- desc_info->ppdu_id);
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("Monitor: PPDU id mismatch "
|
|
|
+ "status_ppdu_id: %d dest_ppdu_id: %d "
|
|
|
+ "status_addr: %llx dest_addr: %llx "
|
|
|
+ "count: %d quota: %d work_done: %d "),
|
|
|
+ pdev->ppdu_info.com_info.ppdu_id,
|
|
|
+ pdev->mon_desc->ppdu_id, pdev->status_buf_addr,
|
|
|
+ pdev->mon_desc->status_buf.paddr,
|
|
|
+ status_buf_count, quota, work_done);
|
|
|
+ }
|
|
|
|
|
|
- if (desc_info->ppdu_id > pdev->ppdu_info.com_info.ppdu_id)
|
|
|
- goto status_reap;
|
|
|
+ if (desc_info->ppdu_id < pdev->ppdu_info.com_info.ppdu_id) {
|
|
|
+ pdev->rx_mon_stats.ppdu_id_mismatch++;
|
|
|
+ desc_info->drop_ppdu = true;
|
|
|
+ pdev->rx_mon_stats.dest_ppdu_drop++;
|
|
|
+
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("Monitor destination ring is lagging behind "
|
|
|
+ "monitor status ring "
|
|
|
+ "status_ppdu_id: %d dest_ppdu_id: %d "
|
|
|
+ "status_addr: %llx dest_addr: %llx "),
|
|
|
+ pdev->ppdu_info.com_info.ppdu_id,
|
|
|
+ pdev->mon_desc->ppdu_id,
|
|
|
+ pdev->status_buf_addr,
|
|
|
+ pdev->mon_desc->status_buf.paddr);
|
|
|
}
|
|
|
|
|
|
return work_done;
|
|
@@ -347,6 +577,63 @@ next_msdu:
|
|
|
return rx_buf_reaped;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * dp_rx_mon_deliver_prev_ppdu () - Deliver previous PPDU
|
|
|
+ *
|
|
|
+ * @pdev: DP pdev handle
|
|
|
+ * @mac_id: lmac id
|
|
|
+ * @quota: quota
|
|
|
+ *
|
|
|
+ * Return: remaining qouta
|
|
|
+ */
|
|
|
+static inline uint32_t
|
|
|
+dp_rx_mon_deliver_prev_ppdu(struct dp_pdev *pdev,
|
|
|
+ uint32_t mac_id,
|
|
|
+ uint32_t quota)
|
|
|
+{
|
|
|
+
|
|
|
+ struct dp_soc *soc = pdev->soc;
|
|
|
+ struct hal_rx_mon_desc_info *desc_info = pdev->mon_desc;
|
|
|
+ uint32_t work_done = 0;
|
|
|
+ bool hold_mon_dest_ring = false;
|
|
|
+
|
|
|
+ while (pdev->hold_mon_dest_ring) {
|
|
|
+ if (dp_rx_mon_status_buf_validate(pdev, mac_id) == QDF_STATUS_SUCCESS) {
|
|
|
+ work_done = dp_rx_mon_status_process(soc, mac_id, 1);
|
|
|
+ }
|
|
|
+ quota -= work_done;
|
|
|
+
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
|
|
+ FL("Hold on Monitor destination ring "
|
|
|
+ "work_done: %d quota: %d status_ppdu_id: %d "
|
|
|
+ "dest_ppdu_id: %d s_addr: %llx d_addr: %llx "),
|
|
|
+ work_done, quota,
|
|
|
+ pdev->ppdu_info.com_info.ppdu_id,
|
|
|
+ desc_info->ppdu_id, pdev->status_buf_addr,
|
|
|
+ desc_info->status_buf.paddr);
|
|
|
+
|
|
|
+ hold_mon_dest_ring = true;
|
|
|
+
|
|
|
+ if (!quota)
|
|
|
+ return quota;
|
|
|
+ }
|
|
|
+ if (hold_mon_dest_ring) {
|
|
|
+ if (quota >= desc_info->status_buf_count) {
|
|
|
+ qdf_err("DEBUG:");
|
|
|
+ work_done = dp_rx_mon_status_process(soc, mac_id,
|
|
|
+ desc_info->status_buf_count);
|
|
|
+ dp_rx_monitor_deliver_ppdu(soc, mac_id);
|
|
|
+ hold_mon_dest_ring = false;
|
|
|
+ } else {
|
|
|
+ pdev->hold_mon_dest_ring = true;
|
|
|
+ return quota;
|
|
|
+ }
|
|
|
+ quota -= work_done;
|
|
|
+ }
|
|
|
+
|
|
|
+ return quota;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* dp_rx_mon_process () - Core brain processing for monitor mode
|
|
|
*
|
|
@@ -375,30 +662,42 @@ uint32_t dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
|
|
|
struct hal_rx_mon_desc_info *desc_info;
|
|
|
int mac_for_pdev = mac_id;
|
|
|
QDF_STATUS status;
|
|
|
+ uint32_t work_done = 0;
|
|
|
+
|
|
|
+ qdf_spin_lock_bh(&pdev->mon_lock);
|
|
|
+ if (qdf_unlikely(!dp_soc_is_full_mon_enable(pdev))) {
|
|
|
+ quota -= dp_rx_mon_status_process(soc, mac_id, quota);
|
|
|
+ qdf_spin_unlock_bh(&pdev->mon_lock);
|
|
|
+ return quota;
|
|
|
+ }
|
|
|
+
|
|
|
+ desc_info = pdev->mon_desc;
|
|
|
+
|
|
|
+ quota = dp_rx_mon_deliver_prev_ppdu(pdev, mac_id, quota);
|
|
|
|
|
|
- if (qdf_unlikely(!dp_soc_is_full_mon_enable(pdev)))
|
|
|
- return dp_rx_mon_status_process(soc, mac_id, quota);
|
|
|
+ /* Do not proceed if quota expires */
|
|
|
+ if (!quota || pdev->hold_mon_dest_ring) {
|
|
|
+ qdf_spin_unlock_bh(&pdev->mon_lock);
|
|
|
+ return quota;
|
|
|
+ }
|
|
|
|
|
|
mon_dest_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_for_pdev);
|
|
|
|
|
|
if (qdf_unlikely(!mon_dest_srng ||
|
|
|
!hal_srng_initialized(mon_dest_srng))) {
|
|
|
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
|
|
FL("HAL Monitor Destination Ring Init Failed -- %pK"),
|
|
|
mon_dest_srng);
|
|
|
- goto done;
|
|
|
+ goto done1;
|
|
|
}
|
|
|
|
|
|
hal_soc = soc->hal_soc;
|
|
|
|
|
|
qdf_assert_always(hal_soc && pdev);
|
|
|
|
|
|
- qdf_spin_lock_bh(&pdev->mon_lock);
|
|
|
-
|
|
|
- desc_info = pdev->mon_desc;
|
|
|
|
|
|
if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_dest_srng))) {
|
|
|
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
|
|
FL("HAL Monitor Destination Ring access Failed -- %pK"),
|
|
|
mon_dest_srng);
|
|
|
goto done1;
|
|
@@ -473,7 +772,7 @@ uint32_t dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
|
|
|
head_msdu,
|
|
|
tail_msdu);
|
|
|
|
|
|
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
|
|
+ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
|
|
FL("Dest_srng: %pK MPDU_OBJ: %pK "
|
|
|
"head_msdu: %pK tail_msdu: %pK -- "),
|
|
|
mon_dest_srng,
|
|
@@ -501,70 +800,16 @@ uint32_t dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
|
|
|
*/
|
|
|
rx_mon_stats->dest_ppdu_done++;
|
|
|
|
|
|
-#if 0
|
|
|
- if (pdev->ppdu_info.com_info.ppdu_id !=
|
|
|
- pdev->mon_desc->ppdu_id) {
|
|
|
- pdev->rx_mon_stats.ppdu_id_mismatch++;
|
|
|
-
|
|
|
- qdf_err("PPDU id mismatch, status_ppdu_id: %d"
|
|
|
- "dest_ppdu_id: %d status_ppdu_done: %d "
|
|
|
- "dest_ppdu_done: %d ppdu_id_mismatch_cnt: %u"
|
|
|
- "dest_mpdu_drop: %u",
|
|
|
- pdev->ppdu_info.com_info.ppdu_id,
|
|
|
- pdev->mon_desc->ppdu_id,
|
|
|
- pdev->rx_mon_stats.status_ppdu_done,
|
|
|
- pdev->rx_mon_stats.dest_ppdu_done,
|
|
|
- pdev->rx_mon_stats.ppdu_id_mismatch,
|
|
|
- pdev->rx_mon_stats.dest_mpdu_drop);
|
|
|
-
|
|
|
- /* WAR: It is observed that in some cases, status ring ppdu_id
|
|
|
- * and destination ring ppdu_id doesn't match.
|
|
|
- * Following WAR is added to fix it.
|
|
|
- * a. If status ppdu_id is less than destination ppdu_id,
|
|
|
- * hold onto destination ring until ppdu_id matches
|
|
|
- * b. If status ppdu_id is greater than destination ring
|
|
|
- * ppdu_Id, move tp in destination ring.
|
|
|
- */
|
|
|
- if (pdev->ppdu_info.com_info.ppdu_id <
|
|
|
- pdev->mon_desc->ppdu_id) {
|
|
|
- break;
|
|
|
- } else {
|
|
|
- ring_desc = hal_srng_dst_get_next(hal_soc,
|
|
|
- mon_dest_srng);
|
|
|
- continue;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * At this point, end_of_ppdu is one here,
|
|
|
- * When 'end_of_ppdu' is one, status buffer_count and
|
|
|
- * status_buf_addr must be valid.
|
|
|
- *
|
|
|
- * Assert if
|
|
|
- * a. status_buf_count is zero
|
|
|
- * b. status_buf.paddr is NULL
|
|
|
- */
|
|
|
- if (!pdev->mon_desc->status_buf_count ||
|
|
|
- !pdev->mon_desc->status_buf.paddr) {
|
|
|
- qdf_assert_always(0);
|
|
|
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
|
|
- FL("Status buffer info is NULL"
|
|
|
- "status_buf_count: %d"
|
|
|
- "status_buf_addr: %pK"
|
|
|
- "ring_desc: %pK-- "),
|
|
|
- pdev->mon_desc->status_buf_count,
|
|
|
- pdev->mon_desc->status_buf.paddr,
|
|
|
- ring_desc);
|
|
|
- goto done2;
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
- quota -= dp_rx_mon_reap_status_ring(soc, mac_id,
|
|
|
+ work_done = dp_rx_mon_reap_status_ring(soc, mac_id,
|
|
|
quota, desc_info);
|
|
|
/* Deliver all MPDUs for a PPDU */
|
|
|
- dp_rx_monitor_deliver_ppdu(soc, mac_id);
|
|
|
+ if (desc_info->drop_ppdu)
|
|
|
+ dp_rx_mon_drop_ppdu(pdev, mac_id);
|
|
|
+ else if (!pdev->hold_mon_dest_ring)
|
|
|
+ dp_rx_monitor_deliver_ppdu(soc, mac_id);
|
|
|
|
|
|
hal_srng_dst_get_next(hal_soc, mon_dest_srng);
|
|
|
+ quota -= work_done;
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -573,7 +818,6 @@ uint32_t dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
|
|
|
done1:
|
|
|
qdf_spin_unlock_bh(&pdev->mon_lock);
|
|
|
|
|
|
-done:
|
|
|
return quota;
|
|
|
}
|
|
|
|