Explorar el Código

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 hace 4 años
padre
commit
82eb94c989
Se han modificado 5 ficheros con 90 adiciones y 90 borrados
  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;
 	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))
 		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)) {
 		DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.fail, 1, len);
+		dp_peer_unref_delete(vdev_peer);
 		return nbuf;
 	}
 
 	DP_STATS_INC_PKT(vdev_peer, rx.intra_bss.pkts, 1, len);
+	dp_peer_unref_delete(vdev_peer);
 	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_neighbour_peer *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);
 
 	if (!vdev)
@@ -5204,14 +5205,11 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc,
 
 	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)) {
 		dp_info("vdev bss_peer!!");
 		peer->bss_peer = 1;
-		vdev->vap_bss_peer = peer;
 	}
 
 	if (wlan_op_mode_sta == vdev->opmode &&
 	    qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw,
 			QDF_MAC_ADDR_SIZE) == 0) {
-		vdev->vap_self_peer = peer;
+		peer->sta_self_peer = 1;
 	}
 
 	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;
 }
 
-/*
- * 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
  * @soc: dataptah soc handle
@@ -6345,8 +6313,8 @@ void dp_peer_unref_delete(struct dp_peer *peer)
 
 		/* cleanup the peer data */
 		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 */
 		vdev_opmode = vdev->opmode;
 		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 */
 
-#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
 /* rx hw stats event wait timeout in ms */
 #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;
 	}
 
-	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) {
 		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];
 	txrx_ast_free_cb cb = NULL;
 	void *cookie = NULL;
+	struct dp_peer *vap_bss_peer = NULL;
 	bool is_peer_found = false;
 
 	vdev = peer->vdev;
@@ -916,7 +917,13 @@ add_ast_entry:
 		ast_entry->type = CDP_TXRX_AST_TYPE_MEC;
 		break;
 	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->type = CDP_TXRX_AST_TYPE_DA;
 		break;
@@ -953,11 +960,16 @@ add_ast_entry:
 				next_node_mac,
 				flags,
 				ast_entry->type)) {
+			if (vap_bss_peer)
+				dp_peer_unref_delete(vap_bss_peer);
 			qdf_spin_unlock_bh(&soc->ast_lock);
 			return QDF_STATUS_SUCCESS;
 		}
 	}
 
+	if (vap_bss_peer)
+		dp_peer_unref_delete(vap_bss_peer);
+
 	qdf_spin_unlock_bh(&soc->ast_lock);
 	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) {
 				dp_info("STA vdev bss_peer!!!!");
 				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) {
@@ -4033,3 +4041,60 @@ bool dp_peer_find_by_id_valid(struct dp_soc *soc, uint16_t peer_id)
 
 	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
 
+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_ */

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

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