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:

committed by
nshrivas

parent
45cff82c5f
commit
700ad73754
@@ -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
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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 {
|
||||||
|
Reference in New Issue
Block a user