Kaynağa Gözat

qcacmn: Fix AST index for STA Vdev overwritten issue

For KIWI, STA AST index lookup search is enabled and remote
AP peer's AST index will be stored in STA Vdev if receive
AP peer htt peer map msg. but if STA TDLS connection happened,
host will receive another peer map msg for remote TDLS STA peer,
this remote TDLS STA peer's AST index will overwrite original AP's
AST index. if TDLS disconnected, STA vdev will still use remote
TDLS STA's AST index for TX, then TX to AP might fail.

Add is_tdls_peer flag in dp peer and configure this value by
cdp_peer_set_peer_as_tdls() from control path right after TDLS peer
created. if is_tdls_peer is true, do not store this TDLS peer's
AST index to STA Vdev, skip bss_peer flag setting as well.

Change-Id: I7b5df1caca6a0b5305a6e867cd92099b5f6a4890
CRs-Fixed: 3151035
Jinwei Chen 3 yıl önce
ebeveyn
işleme
691ffe9f3f
4 değiştirilmiş dosya ile 60 ekleme ve 13 silme
  1. 18 0
      dp/wifi3.0/dp_internal.h
  2. 2 0
      dp/wifi3.0/dp_main.c
  3. 38 12
      dp/wifi3.0/dp_peer.c
  4. 2 1
      dp/wifi3.0/dp_types.h

+ 18 - 0
dp/wifi3.0/dp_internal.h

@@ -1929,6 +1929,17 @@ int dp_get_peer_state(struct cdp_soc_t *soc, uint8_t vdev_id,
 void dp_local_peer_id_pool_init(struct dp_pdev *pdev);
 void dp_local_peer_id_alloc(struct dp_pdev *pdev, struct dp_peer *peer);
 void dp_local_peer_id_free(struct dp_pdev *pdev, struct dp_peer *peer);
+/**
+ * dp_set_peer_as_tdls_peer() - set tdls peer flag to peer
+ * @soc_hdl: datapath soc handle
+ * @vdev_id: vdev_id
+ * @peer_mac: peer mac addr
+ * @val: tdls peer flag
+ *
+ * Return: none
+ */
+void dp_set_peer_as_tdls_peer(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
+			      uint8_t *peer_mac, bool val);
 #else
 /**
  * dp_get_vdevid() - Get virtual interface id which peer registered
@@ -1960,7 +1971,14 @@ static inline
 void dp_local_peer_id_free(struct dp_pdev *pdev, struct dp_peer *peer)
 {
 }
+
+static inline
+void dp_set_peer_as_tdls_peer(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
+			      uint8_t *peer_mac, bool val)
+{
+}
 #endif
+
 int dp_addba_resp_tx_completion_wifi3(struct cdp_soc_t *cdp_soc,
 				      uint8_t *peer_mac, uint16_t vdev_id,
 				      uint8_t tid,

+ 2 - 0
dp/wifi3.0/dp_main.c

@@ -7188,6 +7188,7 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 		dp_peer_add_ast(soc, peer, peer_mac_addr, ast_type, 0);
 
 		peer->valid = 1;
+		peer->is_tdls_peer = false;
 		dp_local_peer_id_alloc(pdev, peer);
 
 		qdf_spinlock_create(&peer->peer_info_lock);
@@ -13528,6 +13529,7 @@ static struct cdp_peer_ops dp_ops_peer = {
 	.peer_get_peer_mac_addr = dp_peer_get_peer_mac_addr,
 	.get_peer_state = dp_get_peer_state,
 	.peer_flush_frags = dp_peer_flush_frags,
+	.set_peer_as_tdls_peer = dp_set_peer_as_tdls_peer,
 };
 #endif
 

+ 38 - 12
dp/wifi3.0/dp_peer.c

@@ -2828,6 +2828,7 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
 		       uint8_t is_wds)
 {
 	struct dp_peer *peer = NULL;
+	struct dp_vdev *vdev = NULL;
 	enum cdp_txrx_ast_entry_type type = CDP_TXRX_AST_TYPE_STATIC;
 	QDF_STATUS err = QDF_STATUS_SUCCESS;
 
@@ -2867,19 +2868,23 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
 					   hw_peer_id, vdev_id);
 
 		if (peer) {
-			if (wlan_op_mode_sta == peer->vdev->opmode &&
-			    qdf_mem_cmp(peer->mac_addr.raw,
-					peer->vdev->mac_addr.raw,
-					QDF_MAC_ADDR_SIZE) != 0) {
-				dp_peer_info("%pK: STA vdev bss_peer!!!!", soc);
-				peer->bss_peer = 1;
-				if (peer->txrx_peer)
-					peer->txrx_peer->bss_peer = 1;
-			}
+			vdev = peer->vdev;
+			/* Only check for STA Vdev and peer is not for TDLS */
+			if (wlan_op_mode_sta == vdev->opmode &&
+			    !peer->is_tdls_peer) {
+				if (qdf_mem_cmp(peer->mac_addr.raw,
+						vdev->mac_addr.raw,
+						QDF_MAC_ADDR_SIZE) != 0) {
+					dp_info("%pK: STA vdev bss_peer", soc);
+					peer->bss_peer = 1;
+					if (peer->txrx_peer)
+						peer->txrx_peer->bss_peer = 1;
+				}
 
-			if (peer->vdev->opmode == wlan_op_mode_sta) {
-				peer->vdev->bss_ast_hash = ast_hash;
-				peer->vdev->bss_ast_idx = hw_peer_id;
+				dp_info("bss ast_hash 0x%x, ast_index 0x%x",
+					ast_hash, hw_peer_id);
+				vdev->bss_ast_hash = ast_hash;
+				vdev->bss_ast_idx = hw_peer_id;
 			}
 
 			/* Add ast entry incase self ast entry is
@@ -5398,6 +5403,27 @@ bool dp_find_peer_exist(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 
 	return false;
 }
+
+void dp_set_peer_as_tdls_peer(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
+			      uint8_t *peer_mac, bool val)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	struct dp_peer *peer = NULL;
+
+	peer = dp_peer_find_hash_find(soc, peer_mac, 0, vdev_id,
+				      DP_MOD_ID_CDP);
+	if (!peer) {
+		dp_err("Failed to find peer for:" QDF_MAC_ADDR_FMT,
+		       QDF_MAC_ADDR_REF(peer_mac));
+		return;
+	}
+
+	dp_info("Set tdls flag %d for peer:" QDF_MAC_ADDR_FMT,
+		val, QDF_MAC_ADDR_REF(peer_mac));
+	peer->is_tdls_peer = val;
+
+	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
+}
 #endif
 
 /**

+ 2 - 1
dp/wifi3.0/dp_types.h

@@ -3888,7 +3888,8 @@ struct dp_peer {
 		authorize:1, /* Set when authorized */
 		valid:1, /* valid bit */
 		delete_in_progress:1, /* Indicate kickout sent */
-		sta_self_peer:1; /* Indicate STA self peer */
+		sta_self_peer:1, /* Indicate STA self peer */
+		is_tdls_peer:1; /* Indicate TDLS peer */
 
 #ifdef WLAN_FEATURE_11BE_MLO
 	uint8_t first_link:1, /* first link peer for MLO */