Browse Source

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
Chaithanya Garrepalli 6 years ago
parent
commit
af34aae9cd
3 changed files with 35 additions and 0 deletions
  1. 2 0
      dp/wifi3.0/dp_main.c
  2. 31 0
      dp/wifi3.0/dp_rx.c
  3. 2 0
      dp/wifi3.0/dp_types.h

+ 2 - 0
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",

+ 31 - 0
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,

+ 2 - 0
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 */