Browse Source

qcacmn: remove bss and self peer back pointers from dp_vdev

Remove self and BSS peer back pointers and added APIs to
get self and BSS peer from VDEV

These new APIs will iterate through peer list and return
the appropriate peer by taking a reference

Caller has to take care of releasing the reference

Change-Id: I550ff83d665f3ad0a185bea1a1e6270c5474ff07
Chaithanya Garrepalli 4 years ago
parent
commit
82eb94c989
5 changed files with 90 additions and 90 deletions
  1. 3 1
      dp/wifi3.0/dp_ipa.c
  2. 10 76
      dp/wifi3.0/dp_main.c
  3. 70 5
      dp/wifi3.0/dp_peer.c
  4. 4 0
      dp/wifi3.0/dp_peer.h
  5. 3 8
      dp/wifi3.0/dp_types.h

+ 3 - 1
dp/wifi3.0/dp_ipa.c

@@ -1717,7 +1717,7 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev,
 	struct dp_peer *vdev_peer;
 	struct dp_peer *vdev_peer;
 	uint16_t len;
 	uint16_t len;
 
 
-	vdev_peer = vdev->vap_bss_peer;
+	vdev_peer = dp_vdev_bss_peer_ref_n_get(pdev->soc, vdev);
 	if (qdf_unlikely(!vdev_peer))
 	if (qdf_unlikely(!vdev_peer))
 		return nbuf;
 		return nbuf;
 
 
@@ -1726,10 +1726,12 @@ static qdf_nbuf_t dp_ipa_intrabss_send(struct dp_pdev *pdev,
 
 
 	if (dp_tx_send((struct cdp_soc_t *)pdev->soc, vdev->vdev_id, nbuf)) {
 	if (dp_tx_send((struct cdp_soc_t *)pdev->soc, vdev->vdev_id, nbuf)) {
 		DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.fail, 1, len);
 		DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.fail, 1, len);
+		dp_peer_unref_delete(vdev_peer);
 		return nbuf;
 		return nbuf;
 	}
 	}
 
 
 	DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.pkts, 1, len);
 	DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.pkts, 1, len);
+	dp_peer_unref_delete(vdev_peer);
 	return NULL;
 	return NULL;
 }
 }
 
 

+ 10 - 76
dp/wifi3.0/dp_main.c

@@ -5197,6 +5197,7 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc,
 	struct dp_pdev *pdev;
 	struct dp_pdev *pdev;
 	struct dp_neighbour_peer *peer = NULL;
 	struct dp_neighbour_peer *peer = NULL;
 	struct dp_neighbour_peer *temp_peer = NULL;
 	struct dp_neighbour_peer *temp_peer = NULL;
+	struct dp_peer *vap_self_peer = NULL;
 	struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
 	struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
 
 
 	if (!vdev)
 	if (!vdev)
@@ -5204,14 +5205,11 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc,
 
 
 	pdev = vdev->pdev;
 	pdev = vdev->pdev;
 
 
-	if (wlan_op_mode_sta == vdev->opmode) {
-		if (vdev->vap_self_peer)
-			dp_peer_delete_wifi3((struct cdp_soc_t *)soc,
-					     vdev->vdev_id,
-					     vdev->vap_self_peer->mac_addr.raw,
-					     0);
-		else
-			dp_err("vdev self peer is NULL");
+	vap_self_peer = dp_sta_vdev_self_peer_ref_n_get(soc, vdev);
+	if (vap_self_peer) {
+		dp_peer_delete_wifi3((struct cdp_soc_t *)soc, vdev->vdev_id,
+				     vap_self_peer->mac_addr.raw, 0);
+		dp_peer_unref_delete(vap_self_peer);
 	}
 	}
 
 
 	/*
 	/*
@@ -5563,13 +5561,12 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 			(wlan_op_mode_sta != vdev->opmode)) {
 			(wlan_op_mode_sta != vdev->opmode)) {
 		dp_info("vdev bss_peer!!");
 		dp_info("vdev bss_peer!!");
 		peer->bss_peer = 1;
 		peer->bss_peer = 1;
-		vdev->vap_bss_peer = peer;
 	}
 	}
 
 
 	if (wlan_op_mode_sta == vdev->opmode &&
 	if (wlan_op_mode_sta == vdev->opmode &&
 	    qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw,
 	    qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw,
 			QDF_MAC_ADDR_SIZE) == 0) {
 			QDF_MAC_ADDR_SIZE) == 0) {
-		vdev->vap_self_peer = peer;
+		peer->sta_self_peer = 1;
 	}
 	}
 
 
 	for (i = 0; i < DP_MAX_TIDS; i++)
 	for (i = 0; i < DP_MAX_TIDS; i++)
@@ -6146,35 +6143,6 @@ dp_peer_authorize(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	return status;
 	return status;
 }
 }
 
 
-/*
- * dp_vdev_reset_peer() - Update peer related member in vdev
-			  as peer is going to free
- * @vdev: datapath vdev handle
- * @peer: dataptah peer handle
- *
- * Return: None
- */
-static void dp_vdev_reset_peer(struct dp_vdev *vdev,
-			       struct dp_peer *peer)
-{
-	struct dp_peer *bss_peer = NULL;
-
-	if (!vdev) {
-		dp_err("vdev is NULL");
-	} else {
-		if (vdev->vap_bss_peer == peer) {
-			vdev->vap_bss_peer = NULL;
-			qdf_mem_zero(vdev->vap_bss_peer_mac_addr,
-				     QDF_MAC_ADDR_SIZE);
-		}
-
-		if (vdev && vdev->vap_bss_peer) {
-		    bss_peer = vdev->vap_bss_peer;
-		    DP_UPDATE_STATS(vdev, peer);
-		}
-	}
-}
-
 /*
 /*
  * dp_peer_release_mem() - free dp peer handle memory
  * dp_peer_release_mem() - free dp peer handle memory
  * @soc: dataptah soc handle
  * @soc: dataptah soc handle
@@ -6345,8 +6313,8 @@ void dp_peer_unref_delete(struct dp_peer *peer)
 
 
 		/* cleanup the peer data */
 		/* cleanup the peer data */
 		dp_peer_cleanup(vdev, peer, false);
 		dp_peer_cleanup(vdev, peer, false);
-		/* reset this peer related info in vdev */
-		dp_vdev_reset_peer(vdev, peer);
+		if (!peer->bss_peer)
+			DP_UPDATE_STATS(vdev, peer);
 		/* save vdev related member in case vdev freed */
 		/* save vdev related member in case vdev freed */
 		vdev_opmode = vdev->opmode;
 		vdev_opmode = vdev->opmode;
 		qdf_mem_copy(vdev_mac_addr, vdev->mac_addr.raw,
 		qdf_mem_copy(vdev_mac_addr, vdev->mac_addr.raw,
@@ -10460,39 +10428,6 @@ dp_txrx_post_data_stall_event(struct cdp_soc_t *soc_hdl,
 }
 }
 #endif /* WLAN_SUPPORT_DATA_STALL */
 #endif /* WLAN_SUPPORT_DATA_STALL */
 
 
-#ifdef DP_PEER_EXTENDED_API
-/**
- * dp_peer_get_ref_find_by_addr - get peer with addr by ref count inc
- * @dev: physical device instance
- * @peer_mac_addr: peer mac address
- * @debug_id: to track enum peer access
- *
- * Return: peer instance pointer
- */
-static void *
-dp_peer_get_ref_find_by_addr(struct cdp_pdev *dev, uint8_t *peer_mac_addr,
-			     enum peer_debug_id_type debug_id)
-{
-	struct dp_pdev *pdev = (struct dp_pdev *)dev;
-	struct dp_peer *peer;
-
-	peer = dp_peer_find_hash_find(pdev->soc, peer_mac_addr, 0, DP_VDEV_ALL);
-
-	if (!peer)
-		return NULL;
-
-	if (peer->delete_in_progress) {
-		dp_err("Peer deletion in progress");
-		dp_peer_unref_delete(peer);
-		return NULL;
-	}
-
-	dp_info_rl("peer %pK mac: %pM", peer, peer->mac_addr.raw);
-
-	return peer;
-}
-#endif /* DP_PEER_EXTENDED_API */
-
 #ifdef WLAN_FEATURE_STATS_EXT
 #ifdef WLAN_FEATURE_STATS_EXT
 /* rx hw stats event wait timeout in ms */
 /* rx hw stats event wait timeout in ms */
 #define DP_REO_STATUS_STATS_TIMEOUT 1500
 #define DP_REO_STATUS_STATS_TIMEOUT 1500
@@ -10594,8 +10529,7 @@ dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
 		return QDF_STATUS_E_INVAL;
 		return QDF_STATUS_E_INVAL;
 	}
 	}
 
 
-	peer = dp_peer_get_ref_find_by_addr((struct cdp_pdev *)vdev->pdev,
-					    vdev->vap_bss_peer_mac_addr, 0);
+	peer = dp_vdev_bss_peer_ref_n_get(soc, vdev);
 
 
 	if (!peer) {
 	if (!peer) {
 		dp_err("Peer is NULL");
 		dp_err("Peer is NULL");

+ 70 - 5
dp/wifi3.0/dp_peer.c

@@ -711,6 +711,7 @@ QDF_STATUS dp_peer_add_ast(struct dp_soc *soc,
 	uint8_t next_node_mac[6];
 	uint8_t next_node_mac[6];
 	txrx_ast_free_cb cb = NULL;
 	txrx_ast_free_cb cb = NULL;
 	void *cookie = NULL;
 	void *cookie = NULL;
+	struct dp_peer *vap_bss_peer = NULL;
 	bool is_peer_found = false;
 	bool is_peer_found = false;
 
 
 	vdev = peer->vdev;
 	vdev = peer->vdev;
@@ -916,7 +917,13 @@ add_ast_entry:
 		ast_entry->type = CDP_TXRX_AST_TYPE_MEC;
 		ast_entry->type = CDP_TXRX_AST_TYPE_MEC;
 		break;
 		break;
 	case CDP_TXRX_AST_TYPE_DA:
 	case CDP_TXRX_AST_TYPE_DA:
-		peer = peer->vdev->vap_bss_peer;
+		vap_bss_peer = dp_vdev_bss_peer_ref_n_get(soc, vdev);
+		if (!vap_bss_peer) {
+			qdf_spin_unlock_bh(&soc->ast_lock);
+			qdf_mem_free(ast_entry);
+			return QDF_STATUS_E_FAILURE;
+		}
+		peer = vap_bss_peer;
 		ast_entry->next_hop = 1;
 		ast_entry->next_hop = 1;
 		ast_entry->type = CDP_TXRX_AST_TYPE_DA;
 		ast_entry->type = CDP_TXRX_AST_TYPE_DA;
 		break;
 		break;
@@ -953,11 +960,16 @@ add_ast_entry:
 				next_node_mac,
 				next_node_mac,
 				flags,
 				flags,
 				ast_entry->type)) {
 				ast_entry->type)) {
+			if (vap_bss_peer)
+				dp_peer_unref_delete(vap_bss_peer);
 			qdf_spin_unlock_bh(&soc->ast_lock);
 			qdf_spin_unlock_bh(&soc->ast_lock);
 			return QDF_STATUS_SUCCESS;
 			return QDF_STATUS_SUCCESS;
 		}
 		}
 	}
 	}
 
 
+	if (vap_bss_peer)
+		dp_peer_unref_delete(vap_bss_peer);
+
 	qdf_spin_unlock_bh(&soc->ast_lock);
 	qdf_spin_unlock_bh(&soc->ast_lock);
 	return QDF_STATUS_E_FAILURE;
 	return QDF_STATUS_E_FAILURE;
 }
 }
@@ -1781,10 +1793,6 @@ dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
 					QDF_MAC_ADDR_SIZE) != 0) {
 					QDF_MAC_ADDR_SIZE) != 0) {
 				dp_info("STA vdev bss_peer!!!!");
 				dp_info("STA vdev bss_peer!!!!");
 				peer->bss_peer = 1;
 				peer->bss_peer = 1;
-				peer->vdev->vap_bss_peer = peer;
-				qdf_mem_copy(peer->vdev->vap_bss_peer_mac_addr,
-					     peer->mac_addr.raw,
-					     QDF_MAC_ADDR_SIZE);
 			}
 			}
 
 
 			if (peer->vdev->opmode == wlan_op_mode_sta) {
 			if (peer->vdev->opmode == wlan_op_mode_sta) {
@@ -4033,3 +4041,60 @@ bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id)
 
 
 	return false;
 	return false;
 }
 }
+
+/**
+ * dp_vdev_bss_peer_ref_n_get: Get bss peer of a vdev
+ * @soc: DP soc
+ * @vdev: vdev
+ *
+ * Return: VDEV BSS peer
+ */
+struct dp_peer *dp_vdev_bss_peer_ref_n_get(struct dp_soc *soc,
+					   struct dp_vdev *vdev)
+{
+	struct dp_peer *peer;
+
+	qdf_spin_lock_bh(&soc->peer_ref_mutex);
+	TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
+		if (peer->bss_peer)
+			break;
+	}
+
+	if (!peer || !qdf_atomic_inc_not_zero(&peer->ref_cnt)) {
+		qdf_spin_unlock_bh(&soc->peer_ref_mutex);
+		return NULL;
+	}
+
+	qdf_spin_unlock_bh(&soc->peer_ref_mutex);
+	return peer;
+}
+
+/**
+ * dp_sta_vdev_self_peer_ref_n_get: Get self peer of sta vdev
+ * @soc: DP soc
+ * @vdev: vdev
+ *
+ * Return: VDEV self peer
+ */
+struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc,
+						struct dp_vdev *vdev)
+{
+	struct dp_peer *peer;
+
+	if (vdev->opmode != wlan_op_mode_sta)
+		return NULL;
+
+	qdf_spin_lock_bh(&soc->peer_ref_mutex);
+	TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
+		if (peer->sta_self_peer)
+			break;
+	}
+
+	if (!peer || !qdf_atomic_inc_not_zero(&peer->ref_cnt)) {
+		qdf_spin_unlock_bh(&soc->peer_ref_mutex);
+		return NULL;
+	}
+
+	qdf_spin_unlock_bh(&soc->peer_ref_mutex);
+	return peer;
+}

+ 4 - 0
dp/wifi3.0/dp_peer.h

@@ -401,4 +401,8 @@ static inline void dp_peer_ext_stats_ctx_dealloc(struct dp_soc *soc,
 }
 }
 #endif
 #endif
 
 
+struct dp_peer *dp_vdev_bss_peer_ref_n_get(struct dp_soc *soc,
+					   struct dp_vdev *vdev);
+struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc,
+						struct dp_vdev *vdev);
 #endif /* _DP_PEER_H_ */
 #endif /* _DP_PEER_H_ */

+ 3 - 8
dp/wifi3.0/dp_types.h

@@ -2203,8 +2203,6 @@ struct dp_vdev {
 
 
 	/* TIDmap priority */
 	/* TIDmap priority */
 	uint8_t tidmap_prty;
 	uint8_t tidmap_prty;
-	/* Self Peer in STA mode */
-	struct dp_peer *vap_self_peer;
 
 
 #ifdef QCA_MULTIPASS_SUPPORT
 #ifdef QCA_MULTIPASS_SUPPORT
 	uint16_t *iv_vlan_map;
 	uint16_t *iv_vlan_map;
@@ -2230,10 +2228,6 @@ struct dp_vdev {
 	bool peer_protocol_count_track;
 	bool peer_protocol_count_track;
 	int peer_protocol_count_dropmask;
 	int peer_protocol_count_dropmask;
 #endif
 #endif
-
-	/* vap bss peer mac addr */
-	uint8_t vap_bss_peer_mac_addr[QDF_MAC_ADDR_SIZE];
-
 	/* callback to collect connectivity stats */
 	/* callback to collect connectivity stats */
 	ol_txrx_stats_rx_fp stats_cb;
 	ol_txrx_stats_rx_fp stats_cb;
 
 
@@ -2364,7 +2358,9 @@ struct dp_peer {
 		tx_cap_enabled:1, /* Peer's tx-capture is enabled */
 		tx_cap_enabled:1, /* Peer's tx-capture is enabled */
 		rx_cap_enabled:1, /* Peer's rx-capture is enabled */
 		rx_cap_enabled:1, /* Peer's rx-capture is enabled */
 		valid:1, /* valid bit */
 		valid:1, /* valid bit */
-		in_twt:1; /* in TWT session */
+		in_twt:1, /* in TWT session */
+		delete_in_progress:1, /*delete_in_progress bit*/
+		sta_self_peer:1; /* Indicate STA self peer */
 
 
 #ifdef QCA_SUPPORT_PEER_ISOLATION
 #ifdef QCA_SUPPORT_PEER_ISOLATION
 	bool isolation; /* enable peer isolation for this peer */
 	bool isolation; /* enable peer isolation for this peer */
@@ -2387,7 +2383,6 @@ struct dp_peer {
 #ifdef WDS_VENDOR_EXTENSION
 #ifdef WDS_VENDOR_EXTENSION
 	dp_ecm_policy wds_ecm;
 	dp_ecm_policy wds_ecm;
 #endif
 #endif
-	bool delete_in_progress;
 
 
 	/* Active Block ack sessions */
 	/* Active Block ack sessions */
 	uint16_t active_ba_session_cnt;
 	uint16_t active_ba_session_cnt;