Эх сурвалжийг харах

qcacmn: Enable DBDC WAR in Root AP mode

In current code, DBDC WAR for AST applies only for repeater mode.
Add support to enable this even in AP modex, for use in SON usecases

Change-Id: I82791fbae0cc86ac6d951c4d85b709c755334273
Pamidipati, Vijay 6 жил өмнө
parent
commit
13f5ec2749

+ 2 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -676,10 +676,12 @@ struct cdp_soc_t {
  *			to set values in pdev
  * @CDP_CONFIG_DEBUG_SNIFFER: Enable debug sniffer feature
  * @CDP_CONFIG_BPR_ENABLE: Enable bcast probe feature
+ * @CDP_CONFIG_PRIMARY_RADIO: Configure radio as primary
  */
 enum cdp_pdev_param_type {
 	CDP_CONFIG_DEBUG_SNIFFER,
 	CDP_CONFIG_BPR_ENABLE,
+	CDP_CONFIG_PRIMARY_RADIO,
 };
 
 /*

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

@@ -6673,6 +6673,7 @@ dp_get_htt_stats(struct cdp_pdev *pdev_handle, void *data, uint32_t data_len)
 static void dp_set_pdev_param(struct cdp_pdev *pdev_handle,
 		enum cdp_pdev_param_type param, uint8_t val)
 {
+	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
 	switch (param) {
 	case CDP_CONFIG_DEBUG_SNIFFER:
 		dp_config_debug_sniffer(pdev_handle, val);
@@ -6680,6 +6681,9 @@ static void dp_set_pdev_param(struct cdp_pdev *pdev_handle,
 	case CDP_CONFIG_BPR_ENABLE:
 		dp_set_bpr_enable(pdev_handle, val);
 		break;
+	case CDP_CONFIG_PRIMARY_RADIO:
+		pdev->is_primary = val;
+		break;
 	default:
 		break;
 	}

+ 21 - 1
dp/wifi3.0/dp_peer.c

@@ -433,8 +433,28 @@ int dp_peer_add_ast(struct dp_soc *soc,
 	ast_entry = dp_peer_ast_hash_find(soc, mac_addr);
 
 	if (ast_entry) {
-		if (ast_entry->type == CDP_TXRX_AST_TYPE_MEC)
+		if (ast_entry->type == CDP_TXRX_AST_TYPE_MEC) {
 			ast_entry->is_active = TRUE;
+			qdf_spin_unlock_bh(&soc->ast_lock);
+			return 0;
+		}
+
+		/*
+		 * WAR for HK 1.x AST issue
+		 * If an AST entry with same mac address already exists and is
+		 * mapped to a different radio, and if the current radio is
+		 * primary radio , delete the existing AST entry and return.
+		 *
+		 * New AST entry will be created again on next SA_invalid
+		 * frame
+		 */
+		if ((ast_entry->pdev_id != vdev->pdev->pdev_id) &&
+		    vdev->pdev->is_primary) {
+			qdf_print("Deleting ast_pdev=%d pdev=%d addr=%pM\n",
+				  ast_entry->pdev_id,
+				  vdev->pdev->pdev_id, mac_addr);
+			dp_peer_del_ast(soc, ast_entry);
+		}
 
 		qdf_spin_unlock_bh(&soc->ast_lock);
 		return 0;

+ 16 - 10
dp/wifi3.0/dp_rx.h

@@ -427,7 +427,6 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
 					CDP_TXRX_AST_TYPE_WDS,
 					flags);
 		return;
-
 	}
 
 	/*
@@ -443,6 +442,8 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
 		return;
 	}
 
+	qdf_spin_unlock_bh(&soc->ast_lock);
+
 	/*
 	 * Ensure we are updating the right AST entry by
 	 * validating ast_idx.
@@ -455,6 +456,20 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
 	if (sa_sw_peer_id != ta_peer->peer_ids[0]) {
 		sa_peer = ast->peer;
 
+		if ((ast->type != CDP_TXRX_AST_TYPE_STATIC) &&
+		    (ast->type != CDP_TXRX_AST_TYPE_SELF)) {
+			if (ast->pdev_id != ta_peer->vdev->pdev->pdev_id) {
+				ret = dp_peer_add_ast(soc,
+						      ta_peer, wds_src_mac,
+						      CDP_TXRX_AST_TYPE_WDS,
+						      flags);
+			} else {
+				qdf_spin_lock_bh(&soc->ast_lock);
+				dp_peer_update_ast(soc, ta_peer, ast, flags);
+				qdf_spin_unlock_bh(&soc->ast_lock);
+				return;
+			}
+		}
 		/*
 		 * Do not kickout STA if it belongs to a different radio.
 		 * For DBDC repeater, it is possible to arrive here
@@ -462,14 +477,6 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
 		 * clients and looped back (intrabss) by Root AP
 		 */
 		if (ast->pdev_id != ta_peer->vdev->pdev->pdev_id) {
-			qdf_spin_unlock_bh(&soc->ast_lock);
-			return;
-		}
-
-		if ((ast->type != CDP_TXRX_AST_TYPE_STATIC) &&
-		    (ast->type != CDP_TXRX_AST_TYPE_SELF)) {
-			dp_peer_update_ast(soc, ta_peer, ast, flags);
-			qdf_spin_unlock_bh(&soc->ast_lock);
 			return;
 		}
 
@@ -487,7 +494,6 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc,
 		}
 	}
 
-	qdf_spin_unlock_bh(&soc->ast_lock);
 	return;
 }
 #else

+ 13 - 0
dp/wifi3.0/dp_types.h

@@ -1201,8 +1201,21 @@ struct dp_pdev {
 		uint32_t mgmt_buf_len; /* Len of mgmt. payload in ppdu stats */
 		uint32_t ppdu_id;
 	} mgmtctrl_frm_info;
+
 	/* Current noise-floor reading for the pdev channel */
 	int16_t chan_noise_floor;
+
+	/*
+	 * For multiradio device, this flag indicates if
+	 * this radio is primary or secondary.
+	 *
+	 * For HK 1.0, this is used for WAR for the AST issue.
+	 * HK 1.x mandates creation of only 1 AST entry with same MAC address
+	 * across 2 radios. is_primary indicates the radio on which DP should
+	 * install HW AST entry if there is a request to add 2 AST entries
+	 * with same MAC address across 2 radios
+	 */
+	uint8_t is_primary;
 };
 
 struct dp_peer;