From af34aae9cd34a0b557bbdc2be66a691f014d0ff1 Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Mon, 18 Feb 2019 20:44:27 +0530 Subject: [PATCH] qcacmn: add counters for sa_idx invalid issue Add counters in case where we identify HW issue where sa_valid and da_valid bit are set and sa_idx and da_idx are invalid Change-Id: I690b626dd3c2b7f20b35982514b0f27576221250 CRs-fixed: 2340521 --- dp/wifi3.0/dp_main.c | 2 ++ dp/wifi3.0/dp_rx.c | 31 +++++++++++++++++++++++++++++++ dp/wifi3.0/dp_types.h | 2 ++ 3 files changed, 35 insertions(+) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index c69a4ba8e6bf..1da077b9f8e4 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -6566,6 +6566,8 @@ dp_print_soc_rx_stats(struct dp_soc *soc) soc->stats.rx.err.invalid_rbm); DP_PRINT_STATS("Invalid Vdev = %d", soc->stats.rx.err.invalid_vdev); + DP_PRINT_STATS("Invalid sa_idx or da_idx = %d", + soc->stats.rx.err.invalid_sa_da_idx); DP_PRINT_STATS("Invalid Pdev = %d", soc->stats.rx.err.invalid_pdev); DP_PRINT_STATS("Invalid Peer = %d", diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index aed7117576d0..3f6a8cc00f33 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1257,6 +1257,21 @@ static void dp_rx_msdu_stats_update(struct dp_soc *soc, } } +static inline bool is_sa_da_idx_valid(struct dp_soc *soc, + void *rx_tlv_hdr) +{ + if ((hal_rx_msdu_end_sa_is_valid_get(rx_tlv_hdr) && + (hal_rx_msdu_end_sa_idx_get(rx_tlv_hdr) > + wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx))) || + (hal_rx_msdu_end_da_is_valid_get(rx_tlv_hdr) && + (hal_rx_msdu_end_da_idx_get(soc->hal_soc, + rx_tlv_hdr) > + wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)))) + return false; + + return true; +} + #ifdef WDS_VENDOR_EXTENSION int dp_wds_rx_policy_check( uint8_t *rx_tlv_hdr, @@ -1768,6 +1783,22 @@ done: /* WDS Destination Address Learning */ dp_rx_da_learn(soc, rx_tlv_hdr, peer, nbuf); + /* Due to HW issue, sometimes we see that the sa_idx + * and da_idx are invalid with sa_valid and da_valid + * bits set + * + * in this case we also see that value of + * sa_sw_peer_id is set as 0 + * + * Drop the packet if sa_idx and da_idx OOB or + * sa_sw_peerid is 0 + */ + if (!is_sa_da_idx_valid(soc, rx_tlv_hdr)) { + qdf_nbuf_free(nbuf); + nbuf = next; + DP_STATS_INC(soc, rx.err.invalid_sa_da_idx, 1); + continue; + } /* WDS Source Port Learning */ if (vdev->wds_enabled) dp_rx_wds_srcport_learn(soc, rx_tlv_hdr, diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 3cbe7bb0a336..62bd7816070e 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -608,6 +608,8 @@ struct dp_soc_stats { uint32_t invalid_vdev; /* Invalid PDEV error count */ uint32_t invalid_pdev; + /* Invalid sa_idx or da_idx*/ + uint32_t invalid_sa_da_idx; /* Invalid PEER Error count */ struct cdp_pkt_info rx_invalid_peer; /* Invalid PEER ID count */