Explorar o código

qcacmn: Fix for Unicast packet flow from WDS node in Intrabss

When EasyMesh feature is enabled, ARP replies from WDS node are
getting dropped by the AP, as there is no proper way to find the
DA_PEER with given WDS mac address.
Fix is to get the peer mac address for wds node based on ast entry.

CRs-Fixed: 3265158
Change-Id: I5ea890ce37dfde89d067b471417ba7aeb8c5d6f5
Devender Kumar %!s(int64=2) %!d(string=hai) anos
pai
achega
13c6048f72
Modificáronse 1 ficheiros con 51 adicións e 12 borrados
  1. 51 12
      dp/wifi3.0/dp_ipa.c

+ 51 - 12
dp/wifi3.0/dp_ipa.c

@@ -3332,6 +3332,55 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev,
 	return NULL;
 }
 
+#ifdef IPA_WDS_EASYMESH_FEATURE
+/**
+ * dp_ipa_peer_check() - Check for peer for given mac
+ * @soc: dp soc object
+ * @peer_mac_addr: peer mac address
+ * @vdev_id: vdev id
+ *
+ * Return: true if peer is found, else false
+ */
+static inline bool dp_ipa_peer_check(struct dp_soc *soc,
+				     uint8_t *peer_mac_addr, uint8_t vdev_id)
+{
+	struct cdp_ast_entry_info ast_info = {0};
+	ol_txrx_soc_handle cdp_soc;
+	struct dp_peer *peer = NULL;
+
+	cdp_soc = dp_soc_to_cdp_soc_t(soc);
+	cdp_peer_get_ast_info_by_soc(cdp_soc, peer_mac_addr, &ast_info);
+
+	peer = dp_peer_get_ref_by_id(soc, ast_info.peer_id, DP_MOD_ID_IPA);
+
+	if (!peer) {
+		return false;
+	} else {
+		if ((peer->vdev->vdev_id == vdev_id)) {
+			dp_peer_unref_delete(peer, DP_MOD_ID_IPA);
+			return true;
+		}
+		dp_peer_unref_delete(peer, DP_MOD_ID_IPA);
+		return false;
+	}
+}
+#else
+static inline bool dp_ipa_peer_check(struct dp_soc *soc,
+				     uint8_t *peer_mac_addr, uint8_t vdev_id)
+{
+	struct dp_peer *peer = NULL;
+
+	peer = dp_peer_find_hash_find(soc, peer_mac_addr, 0, vdev_id,
+				      DP_MOD_ID_IPA);
+	if (!peer) {
+		return false;
+	} else {
+		dp_peer_unref_delete(peer, DP_MOD_ID_IPA);
+		return true;
+	}
+}
+#endif
+
 bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 			    qdf_nbuf_t nbuf, bool *fwd_success)
 {
@@ -3339,8 +3388,6 @@ bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
 						     DP_MOD_ID_IPA);
 	struct dp_pdev *pdev;
-	struct dp_peer *da_peer;
-	struct dp_peer *sa_peer;
 	qdf_nbuf_t nbuf_copy;
 	uint8_t da_is_bcmc;
 	struct ethhdr *eh;
@@ -3385,20 +3432,12 @@ bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	if (!qdf_mem_cmp(eh->h_dest, vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE))
 		goto out;
 
-	da_peer = dp_peer_find_hash_find(soc, eh->h_dest, 0, vdev->vdev_id,
-					 DP_MOD_ID_IPA);
-	if (!da_peer)
+	if (!dp_ipa_peer_check(soc, eh->h_dest, vdev->vdev_id))
 		goto out;
 
-	dp_peer_unref_delete(da_peer, DP_MOD_ID_IPA);
-
-	sa_peer = dp_peer_find_hash_find(soc, eh->h_source, 0, vdev->vdev_id,
-					 DP_MOD_ID_IPA);
-	if (!sa_peer)
+	if (!dp_ipa_peer_check(soc, eh->h_source, vdev->vdev_id))
 		goto out;
 
-	dp_peer_unref_delete(sa_peer, DP_MOD_ID_IPA);
-
 	/*
 	 * In intra-bss forwarding scenario, skb is allocated by IPA driver.
 	 * Need to add skb to internal tracking table to avoid nbuf memory