qcacmn: WAR for duplicate buffers in monitor mode

WAR to discard duplicate indications (buffers and link descriptors)
from monitor DMA seen sometimes on RXDMA2SW ring.

Change-Id: I687b782f54fbbf85ae932ee833ac9263b5879ca6
This commit is contained in:
Karunakar Dasineni
2018-11-06 12:40:07 -08:00
committed by nshrivas
parent 45cff82c5f
commit 700ad73754
5 changed files with 42 additions and 5 deletions

View File

@@ -212,6 +212,8 @@ enum {
* @status_ppdu_done: status ring PPDU done TLV count * @status_ppdu_done: status ring PPDU done TLV count
* @dest_ppdu_done: destination ring PPDU count * @dest_ppdu_done: destination ring PPDU count
* @dest_mpdu_done: destination ring MPDU count * @dest_mpdu_done: destination ring MPDU count
* @dup_mon_linkdesc_cnt: duplicate link descriptor indications from HW
* @dup_mon_buf_cnt: duplicate buffer indications from HW
*/ */
struct cdp_pdev_mon_stats { struct cdp_pdev_mon_stats {
#ifndef REMOVE_MON_DBG_STATS #ifndef REMOVE_MON_DBG_STATS
@@ -226,5 +228,7 @@ struct cdp_pdev_mon_stats {
uint32_t dest_ppdu_done; uint32_t dest_ppdu_done;
uint32_t dest_mpdu_done; uint32_t dest_mpdu_done;
uint32_t dest_mpdu_drop; uint32_t dest_mpdu_drop;
uint32_t dup_mon_linkdesc_cnt;
uint32_t dup_mon_buf_cnt;
}; };
#endif #endif

View File

@@ -5899,6 +5899,10 @@ dp_print_pdev_rx_mon_stats(struct dp_pdev *pdev)
rx_mon_stats->dest_mpdu_done); rx_mon_stats->dest_mpdu_done);
DP_PRINT_STATS("dest_mpdu_drop_cnt = %d", DP_PRINT_STATS("dest_mpdu_drop_cnt = %d",
rx_mon_stats->dest_mpdu_drop); rx_mon_stats->dest_mpdu_drop);
DP_PRINT_STATS("dup_mon_linkdesc_cnt = %d",
rx_mon_stats->dup_mon_linkdesc_cnt);
DP_PRINT_STATS("dup_mon_buf_cnt = %d",
rx_mon_stats->dup_mon_buf_cnt);
} }
/** /**

View File

@@ -88,6 +88,9 @@ struct dp_rx_desc {
#define RX_DESC_COOKIE_POOL_ID_SHIFT 18 #define RX_DESC_COOKIE_POOL_ID_SHIFT 18
#define RX_DESC_COOKIE_POOL_ID_MASK 0x1c0000 #define RX_DESC_COOKIE_POOL_ID_MASK 0x1c0000
#define DP_RX_DESC_COOKIE_MAX \
(RX_DESC_COOKIE_INDEX_MASK | RX_DESC_COOKIE_POOL_ID_MASK)
#define DP_RX_DESC_COOKIE_POOL_ID_GET(_cookie) \ #define DP_RX_DESC_COOKIE_POOL_ID_GET(_cookie) \
(((_cookie) & RX_DESC_COOKIE_POOL_ID_MASK) >> \ (((_cookie) & RX_DESC_COOKIE_POOL_ID_MASK) >> \
RX_DESC_COOKIE_POOL_ID_SHIFT) RX_DESC_COOKIE_POOL_ID_SHIFT)

View File

@@ -242,6 +242,7 @@ struct dp_rx_desc *dp_rx_get_mon_desc(struct dp_soc *soc,
* @ppdu_id: ppdu id of processing ppdu * @ppdu_id: ppdu id of processing ppdu
* @head: head of descs list to be freed * @head: head of descs list to be freed
* @tail: tail of decs list to be freed * @tail: tail of decs list to be freed
*
* Return: number of msdu in MPDU to be popped * Return: number of msdu in MPDU to be popped
*/ */
static inline uint32_t static inline uint32_t
@@ -295,6 +296,13 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
is_first_msdu = true; is_first_msdu = true;
do { do {
/* WAR for duplicate link descriptors received from HW */
if (qdf_unlikely(dp_pdev->mon_last_linkdesc_paddr ==
buf_info.paddr)) {
dp_pdev->rx_mon_stats.dup_mon_linkdesc_cnt++;
return rx_bufs_used;
}
rx_msdu_link_desc = rx_msdu_link_desc =
dp_rx_cookie_2_mon_link_desc(dp_pdev, dp_rx_cookie_2_mon_link_desc(dp_pdev,
buf_info, mac_id); buf_info, mac_id);
@@ -306,12 +314,22 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
for (i = 0; i < num_msdus; i++) { for (i = 0; i < num_msdus; i++) {
uint32_t l2_hdr_offset; uint32_t l2_hdr_offset;
struct dp_rx_desc *rx_desc = struct dp_rx_desc *rx_desc = NULL;
dp_rx_get_mon_desc(soc,
msdu_list.sw_cookie[i]); /* WAR for duplicate buffers received from HW */
if (qdf_unlikely(dp_pdev->mon_last_buf_cookie ==
msdu_list.sw_cookie[i])) {
/* Skip duplicate buffer and drop subsequent
* buffers in this MPDU
*/
drop_mpdu = true;
dp_pdev->rx_mon_stats.dup_mon_buf_cnt++;
continue;
}
rx_desc = dp_rx_get_mon_desc(soc,
msdu_list.sw_cookie[i]);
qdf_assert_always(rx_desc); qdf_assert_always(rx_desc);
msdu = rx_desc->nbuf; msdu = rx_desc->nbuf;
if (rx_desc->unmapped == 0) { if (rx_desc->unmapped == 0) {
@@ -373,7 +391,8 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
*ppdu_id = msdu_ppdu_id; *ppdu_id = msdu_ppdu_id;
return rx_bufs_used; return rx_bufs_used;
} }
dp_pdev->mon_last_linkdesc_paddr =
buf_info.paddr;
} }
if (hal_rx_desc_is_first_msdu(rx_desc_tlv)) if (hal_rx_desc_is_first_msdu(rx_desc_tlv))
@@ -459,6 +478,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
last = msdu; last = msdu;
next_msdu: next_msdu:
dp_pdev->mon_last_buf_cookie = msdu_list.sw_cookie[i];
rx_bufs_used++; rx_bufs_used++;
dp_rx_add_to_free_desc_list(head, dp_rx_add_to_free_desc_list(head,
tail, rx_desc); tail, rx_desc);
@@ -1410,6 +1430,8 @@ dp_rx_pdev_mon_attach(struct dp_pdev *pdev) {
return status; return status;
} }
} }
pdev->mon_last_linkdesc_paddr = 0;
pdev->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
qdf_spinlock_create(&pdev->mon_lock); qdf_spinlock_create(&pdev->mon_lock);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }

View File

@@ -1193,6 +1193,10 @@ struct dp_pdev {
struct cdp_mon_status rx_mon_recv_status; struct cdp_mon_status rx_mon_recv_status;
/* monitor mode status/destination ring PPDU and MPDU count */ /* monitor mode status/destination ring PPDU and MPDU count */
struct cdp_pdev_mon_stats rx_mon_stats; struct cdp_pdev_mon_stats rx_mon_stats;
/* to track duplicate link descriptor indications by HW for a WAR */
uint64_t mon_last_linkdesc_paddr;
/* to track duplicate buffer indications by HW for a WAR */
uint32_t mon_last_buf_cookie;
/* pool addr for mcast enhance buff */ /* pool addr for mcast enhance buff */
struct { struct {