qcacmn: Return missing link and mon desc and free associated buffers

It is observed that in some corner cases msdu count received
in montior destination ring descriptor is unreliable as a
result some of the link descriptor and associated monitor buf
descs are not returned. This change return such missing link/buf
descriptors and free associated buffers.

Change-Id: Iaad476b8e7a0372122981fd29c1f6e4685137817
CRs-Fixed: 3483157
This commit is contained in:
Jeevan Kukkalli
2023-04-28 21:20:22 +05:30
committed by Madan Koyyalamudi
parent 2c3de7f375
commit 794367b541
4 changed files with 19 additions and 8 deletions

View File

@@ -3168,6 +3168,7 @@ struct cdp_pdev_deter_stats {
* @peer_unauth_rx_pkt_drop: stats counter for drops due to unauthorized peer * @peer_unauth_rx_pkt_drop: stats counter for drops due to unauthorized peer
* @telemetry_stats: pdev telemetry stats * @telemetry_stats: pdev telemetry stats
* @deter_stats: * @deter_stats:
* @invalid_msdu_cnt: Invalid MSDU count received counter
*/ */
struct cdp_pdev_stats { struct cdp_pdev_stats {
struct { struct {
@@ -3265,6 +3266,7 @@ struct cdp_pdev_stats {
struct cdp_pdev_telemetry_stats telemetry_stats; struct cdp_pdev_telemetry_stats telemetry_stats;
struct cdp_pdev_deter_stats deter_stats; struct cdp_pdev_deter_stats deter_stats;
#endif #endif
uint32_t invalid_msdu_cnt;
}; };
/** /**

View File

@@ -7818,6 +7818,7 @@ dp_print_pdev_rx_stats(struct dp_pdev *pdev)
dp_pdev_iterate_peer_lock_safe(pdev, dp_peer_ctrl_frames_stats_get, dp_pdev_iterate_peer_lock_safe(pdev, dp_peer_ctrl_frames_stats_get,
NULL, DP_MOD_ID_GENERIC_STATS); NULL, DP_MOD_ID_GENERIC_STATS);
/* Get bar_recv_cnt */ /* Get bar_recv_cnt */
DP_PRINT_STATS("BAR Received Count: = %u", DP_PRINT_STATS("BAR Received Count: = %u",
pdev->stats.rx.bar_recv_cnt); pdev->stats.rx.bar_recv_cnt);
@@ -7830,6 +7831,9 @@ dp_print_pdev_rx_stats(struct dp_pdev *pdev)
DP_PRINT_STATS("\tAllocations from the pool during replenish = %llu", DP_PRINT_STATS("\tAllocations from the pool during replenish = %llu",
pdev->stats.rx_buffer_pool.num_pool_bufs_replenish); pdev->stats.rx_buffer_pool.num_pool_bufs_replenish);
DP_PRINT_STATS("Invalid MSDU count = %u",
pdev->stats.invalid_msdu_cnt);
dp_rx_basic_fst_stats(pdev); dp_rx_basic_fst_stats(pdev);
} }

View File

@@ -894,21 +894,21 @@ uint8_t *dp_rx_mon_get_buffer_data(struct dp_rx_desc *rx_desc)
/** /**
* dp_rx_cookie_2_mon_link_desc() - Retrieve Link descriptor based on target * dp_rx_cookie_2_mon_link_desc() - Retrieve Link descriptor based on target
* @pdev: core physical device context * @pdev: core physical device context
* @buf_info: structure holding the buffer info * @buf_info: ptr to structure holding the buffer info
* @mac_id: mac number * @mac_id: mac number
* *
* Return: link descriptor address * Return: link descriptor address
*/ */
static inline static inline
void *dp_rx_cookie_2_mon_link_desc(struct dp_pdev *pdev, void *dp_rx_cookie_2_mon_link_desc(struct dp_pdev *pdev,
struct hal_buf_info buf_info, struct hal_buf_info *buf_info,
uint8_t mac_id) uint8_t mac_id)
{ {
if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) if (pdev->soc->wlan_cfg_ctx->rxdma1_enable)
return dp_rx_cookie_2_mon_link_desc_va(pdev, &buf_info, return dp_rx_cookie_2_mon_link_desc_va(pdev, buf_info,
mac_id); mac_id);
return dp_rx_cookie_2_link_desc_va(pdev->soc, &buf_info); return dp_rx_cookie_2_link_desc_va(pdev->soc, buf_info);
} }
/** /**

View File

@@ -230,6 +230,11 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
is_first_msdu = true; is_first_msdu = true;
do { do {
if (!msdu_cnt) {
drop_mpdu = true;
DP_STATS_INC(dp_pdev, invalid_msdu_cnt, 1);
}
/* WAR for duplicate link descriptors received from HW */ /* WAR for duplicate link descriptors received from HW */
if (qdf_unlikely(mon_pdev->mon_last_linkdesc_paddr == if (qdf_unlikely(mon_pdev->mon_last_linkdesc_paddr ==
buf_info.paddr)) { buf_info.paddr)) {
@@ -239,7 +244,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
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);
qdf_assert_always(rx_msdu_link_desc); qdf_assert_always(rx_msdu_link_desc);
@@ -384,7 +389,7 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
rx_desc_tlv, rx_desc_tlv,
&first_rx_desc_tlv, &first_rx_desc_tlv,
&is_frag_non_raw, data); &is_frag_non_raw, data);
if (!is_frag) if (!is_frag && msdu_cnt)
msdu_cnt--; msdu_cnt--;
dp_rx_mon_dest_debug("total_len %u frag_len %u flags %u", dp_rx_mon_dest_debug("total_len %u frag_len %u flags %u",
@@ -457,7 +462,7 @@ next_msdu:
bm_action) bm_action)
!= QDF_STATUS_SUCCESS) != QDF_STATUS_SUCCESS)
dp_err_rl("monitor link desc return failed"); dp_err_rl("monitor link desc return failed");
} while (buf_info.paddr && msdu_cnt); } while (buf_info.paddr);
dp_rx_mon_init_tail_msdu(head_msdu, msdu, last, tail_msdu); dp_rx_mon_init_tail_msdu(head_msdu, msdu, last, tail_msdu);
dp_rx_mon_remove_raw_frame_fcs_len(soc, head_msdu, tail_msdu); dp_rx_mon_remove_raw_frame_fcs_len(soc, head_msdu, tail_msdu);
@@ -506,7 +511,7 @@ static int dp_rx_mon_drop_one_mpdu(struct dp_pdev *pdev,
do { do {
rx_msdu_link_desc = dp_rx_cookie_2_mon_link_desc(pdev, rx_msdu_link_desc = dp_rx_cookie_2_mon_link_desc(pdev,
buf_info, &buf_info,
mac_id); mac_id);
if (qdf_unlikely(!rx_msdu_link_desc)) { if (qdf_unlikely(!rx_msdu_link_desc)) {
mon_pdev->rx_mon_stats.mon_link_desc_invalid++; mon_pdev->rx_mon_stats.mon_link_desc_invalid++;