瀏覽代碼

qcacmn: support MLO intra-bss forwarding

Support MLO intra-bss forwarding

Change-Id: I7ffd54bbead3e56c7811e88aef935867b0ee4fd6
CRs-Fixed: 3066899
Jinwei Chen 3 年之前
父節點
當前提交
7e267e17b1
共有 4 個文件被更改,包括 114 次插入36 次删除
  1. 95 27
      dp/wifi3.0/be/dp_be_rx.c
  2. 8 5
      dp/wifi3.0/dp_rx.c
  3. 2 0
      dp/wifi3.0/dp_rx.h
  4. 9 4
      dp/wifi3.0/li/dp_li_rx.c

+ 95 - 27
dp/wifi3.0/be/dp_be_rx.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -1100,60 +1101,125 @@ uint32_t dp_rx_nf_process(struct dp_intr *int_ctx,
 #endif
 
 #ifndef QCA_HOST_MODE_WIFI_DISABLED
-#ifdef INTRA_BSS_FW_OFFLOAD
+#ifdef WLAN_FEATURE_11BE_MLO
+/**
+ * dp_rx_intrabss_fwd_mlo_allow() - check if MLO forwarding is allowed
+ * @ta_peer: transmitter peer handle
+ * @da_peer: destination peer handle
+ *
+ * Return: true - MLO forwarding case, false: not
+ */
+static inline bool
+dp_rx_intrabss_fwd_mlo_allow(struct dp_peer *ta_peer,
+			     struct dp_peer *da_peer)
+{
+	/* one of TA/DA peer should belong to MLO connection peer,
+	 * only MLD peer type is as expected
+	 */
+	if (!IS_MLO_DP_MLD_PEER(ta_peer) &&
+	    !IS_MLO_DP_MLD_PEER(da_peer))
+		return false;
+
+	/* TA peer and DA peer's vdev should be partner MLO vdevs */
+	if (dp_peer_find_mac_addr_cmp(&ta_peer->vdev->mld_mac_addr,
+				      &da_peer->vdev->mld_mac_addr))
+		return false;
+
+	return true;
+}
+#else
+static inline bool
+dp_rx_intrabss_fwd_mlo_allow(struct dp_peer *ta_peer,
+			     struct dp_peer *da_peer)
+{
+	return false;
+}
+#endif
+
+#ifdef INTRA_BSS_FWD_OFFLOAD
+/**
+ * dp_rx_intrabss_ucast_check_be() - Check if intrabss is allowed
+				     for unicast frame
+ * @soc: SOC hanlde
+ * @nbuf: RX packet buffer
+ * @ta_peer: transmitter DP peer handle
+ * @msdu_metadata: MSDU meta data info
+ * @p_tx_vdev_id: get vdev id for Intra-BSS TX
+ *
+ * Return: true - intrabss allowed
+	   false - not allow
+ */
 static bool
 dp_rx_intrabss_ucast_check_be(struct dp_soc *soc, qdf_nbuf_t nbuf,
 			      struct dp_peer *ta_peer,
-			      struct hal_rx_msdu_metadata *msdu_metadata)
+			      struct hal_rx_msdu_metadata *msdu_metadata,
+			      uint8_t *p_tx_vdev_id)
 {
-	return qdf_nbuf_is_intra_bss(nbuf);
+	uint16_t da_peer_id;
+	struct dp_peer *da_peer;
+
+	if (!qdf_nbuf_is_intra_bss(nbuf))
+		return false;
+
+	da_peer_id = dp_rx_peer_metadata_peer_id_get_be(
+						soc,
+						msdu_metadata->da_idx);
+	da_peer = dp_peer_get_ref_by_id(soc, da_peer_id, DP_MOD_ID_RX);
+	if (!da_peer)
+		return false;
+	*p_tx_vdev_id = da_peer->vdev->vdev_id;
+	dp_peer_unref_delete(da_peer, DP_MOD_ID_RX);
+
+	return true;
 }
 #else
 static bool
 dp_rx_intrabss_ucast_check_be(struct dp_soc *soc, qdf_nbuf_t nbuf,
 			      struct dp_peer *ta_peer,
-			      struct hal_rx_msdu_metadata *msdu_metadata)
+			      struct hal_rx_msdu_metadata *msdu_metadata,
+			      uint8_t *p_tx_vdev_id)
 {
 	uint16_t da_peer_id;
 	struct dp_peer *da_peer;
+	bool ret = false;
 
 	if (!(qdf_nbuf_is_da_valid(nbuf) || qdf_nbuf_is_da_mcbc(nbuf)))
 		return false;
 
-	/* The field da_idx here holds DA peer id
-	 */
-	da_peer_id = msdu_metadata->da_idx;
-
-	/* TA peer cannot be same as peer(DA) on which AST is present
-	 * this indicates a change in topology and that AST entries
-	 * are yet to be updated.
-	 */
-	if ((da_peer_id == ta_peer->peer_id) ||
-	    (da_peer_id == HTT_INVALID_PEER))
-		return false;
-
+	da_peer_id = dp_rx_peer_metadata_peer_id_get_be(
+						soc,
+						msdu_metadata->da_idx);
 	da_peer = dp_peer_get_ref_by_id(soc, da_peer_id,
 					DP_MOD_ID_RX);
 	if (!da_peer)
 		return false;
 
+	*p_tx_vdev_id = da_peer->vdev->vdev_id;
 	/* If the source or destination peer in the isolation
 	 * list then dont forward instead push to bridge stack.
 	 */
 	if (dp_get_peer_isolation(ta_peer) ||
-	    dp_get_peer_isolation(da_peer) ||
-	    (da_peer->vdev->vdev_id != ta_peer->vdev->vdev_id)) {
-		dp_peer_unref_delete(da_peer, DP_MOD_ID_RX);
-		return false;
+	    dp_get_peer_isolation(da_peer))
+		goto rel_da_peer;
+
+	if (da_peer->bss_peer || da_peer == ta_peer)
+		goto rel_da_peer;
+
+	/* Same vdev, support Inra-BSS */
+	if (da_peer->vdev == ta_peer->vdev) {
+		ret = true;
+		goto rel_da_peer;
 	}
 
-	if (da_peer->bss_peer) {
-		dp_peer_unref_delete(da_peer, DP_MOD_ID_RX);
-		return false;
+	/* MLO specific Intra-BSS check */
+	if (dp_rx_intrabss_fwd_mlo_allow(ta_peer, da_peer)) {
+		ret = true;
+		goto rel_da_peer;
 	}
 
+rel_da_peer:
 	dp_peer_unref_delete(da_peer, DP_MOD_ID_RX);
-	return true;
+	return ret;
 }
 #endif
 /*
@@ -1171,6 +1237,7 @@ bool dp_rx_intrabss_fwd_be(struct dp_soc *soc, struct dp_peer *ta_peer,
 			   uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf,
 			   struct hal_rx_msdu_metadata msdu_metadata)
 {
+	uint8_t tx_vdev_id;
 	uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
 	uint8_t ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
 	struct cdp_tid_rx_stats *tid_stats = &ta_peer->vdev->pdev->stats.
@@ -1188,9 +1255,10 @@ bool dp_rx_intrabss_fwd_be(struct dp_soc *soc, struct dp_peer *ta_peer,
 		return dp_rx_intrabss_mcbc_fwd(soc, ta_peer, rx_tlv_hdr,
 					       nbuf, tid_stats);
 
-	if (dp_rx_intrabss_ucast_check_be(soc, nbuf, ta_peer, &msdu_metadata))
-		return dp_rx_intrabss_ucast_fwd(soc, ta_peer, rx_tlv_hdr,
-						nbuf, tid_stats);
+	if (dp_rx_intrabss_ucast_check_be(soc, nbuf, ta_peer,
+					  &msdu_metadata, &tx_vdev_id))
+		return dp_rx_intrabss_ucast_fwd(soc, ta_peer, tx_vdev_id,
+						rx_tlv_hdr, nbuf, tid_stats);
 
 	return false;
 }

+ 8 - 5
dp/wifi3.0/dp_rx.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -560,14 +561,16 @@ bool dp_rx_intrabss_mcbc_fwd(struct dp_soc *soc, struct dp_peer *ta_peer,
  * dp_rx_intrabss_ucast_fwd() - Does intrabss forward for unicast packets
  *
  * @soc: core txrx main context
- * @ta_peer	: source peer entry
- * @rx_tlv_hdr	: start address of rx tlvs
- * @nbuf	: nbuf that has to be intrabss forwarded
- * @tid_stats	: tid stats pointer
+ * @ta_peer: source peer entry
+ * @tx_vdev_id: VDEV ID for Intra-BSS TX
+ * @rx_tlv_hdr: start address of rx tlvs
+ * @nbuf: nbuf that has to be intrabss forwarded
+ * @tid_stats: tid stats pointer
  *
  * Return: bool: true if it is forwarded else false
  */
 bool dp_rx_intrabss_ucast_fwd(struct dp_soc *soc, struct dp_peer *ta_peer,
+			      uint8_t tx_vdev_id,
 			      uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf,
 			      struct cdp_tid_rx_stats *tid_stats)
 {
@@ -601,7 +604,7 @@ bool dp_rx_intrabss_ucast_fwd(struct dp_soc *soc, struct dp_peer *ta_peer,
 	}
 
 	if (!dp_tx_send((struct cdp_soc_t *)soc,
-			ta_peer->vdev->vdev_id, nbuf)) {
+			tx_vdev_id, nbuf)) {
 		DP_STATS_INC_PKT(ta_peer, rx.intra_bss.pkts, 1,
 				 len);
 	} else {

+ 2 - 0
dp/wifi3.0/dp_rx.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -1147,6 +1148,7 @@ bool dp_rx_intrabss_mcbc_fwd(struct dp_soc *soc, struct dp_peer *ta_peer,
 			     struct cdp_tid_rx_stats *tid_stats);
 
 bool dp_rx_intrabss_ucast_fwd(struct dp_soc *soc, struct dp_peer *ta_peer,
+			      uint8_t tx_vdev_id,
 			      uint8_t *rx_tlv_hdr, qdf_nbuf_t nbuf,
 			      struct cdp_tid_rx_stats *tid_stats);
 

+ 9 - 4
dp/wifi3.0/li/dp_li_rx.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -87,7 +88,8 @@ static inline bool dp_rx_mec_check_wrapper(struct dp_soc *soc,
 static bool
 dp_rx_intrabss_ucast_check_li(struct dp_soc *soc, qdf_nbuf_t nbuf,
 			      struct dp_peer *ta_peer,
-			      struct hal_rx_msdu_metadata *msdu_metadata)
+			      struct hal_rx_msdu_metadata *msdu_metadata,
+			      uint8_t *p_tx_vdev_id)
 {
 	uint16_t da_peer_id;
 	struct dp_peer *da_peer;
@@ -119,6 +121,7 @@ dp_rx_intrabss_ucast_check_li(struct dp_soc *soc, qdf_nbuf_t nbuf,
 	if (!da_peer)
 		return false;
 
+	*p_tx_vdev_id = da_peer->vdev->vdev_id;
 	/* If the source or destination peer in the isolation
 	 * list then dont forward instead push to bridge stack.
 	 */
@@ -155,6 +158,7 @@ dp_rx_intrabss_fwd_li(struct dp_soc *soc,
 		      qdf_nbuf_t nbuf,
 		      struct hal_rx_msdu_metadata msdu_metadata)
 {
+	uint8_t tx_vdev_id;
 	uint8_t tid = qdf_nbuf_get_tid_val(nbuf);
 	uint8_t ring_id = QDF_NBUF_CB_RX_CTX_ID(nbuf);
 	struct cdp_tid_rx_stats *tid_stats = &ta_peer->vdev->pdev->stats.
@@ -172,9 +176,10 @@ dp_rx_intrabss_fwd_li(struct dp_soc *soc,
 		return dp_rx_intrabss_mcbc_fwd(soc, ta_peer, rx_tlv_hdr,
 					       nbuf, tid_stats);
 
-	if (dp_rx_intrabss_ucast_check_li(soc, nbuf, ta_peer, &msdu_metadata))
-		return dp_rx_intrabss_ucast_fwd(soc, ta_peer, rx_tlv_hdr,
-						nbuf, tid_stats);
+	if (dp_rx_intrabss_ucast_check_li(soc, nbuf, ta_peer,
+					  &msdu_metadata, &tx_vdev_id))
+		return dp_rx_intrabss_ucast_fwd(soc, ta_peer, tx_vdev_id,
+						rx_tlv_hdr, nbuf, tid_stats);
 
 	return false;
 }