Ver Fonte

qcacmn: add state to data path peer

Add states to data path peer and appropriate
checks for transistion of states

Change-Id: Ieaadbf4b406351d48aece7fd3552abe42d61db1e
Chaithanya Garrepalli há 4 anos atrás
pai
commit
1322dc7949
5 ficheiros alterados com 107 adições e 20 exclusões
  1. 11 8
      dp/wifi3.0/dp_main.c
  2. 23 6
      dp/wifi3.0/dp_peer.c
  3. 57 1
      dp/wifi3.0/dp_peer.h
  4. 0 4
      dp/wifi3.0/dp_stats.c
  5. 16 1
      dp/wifi3.0/dp_types.h

+ 11 - 8
dp/wifi3.0/dp_main.c

@@ -1313,7 +1313,6 @@ static void dp_print_peer_table(struct dp_vdev *vdev)
 			       " wds_enabled = %d"
 			       " tx_cap_enabled = %d"
 			       " rx_cap_enabled = %d"
-			       " delete in progress = %d"
 			       " peer id = %d",
 			       peer->mac_addr.raw,
 			       peer->nawds_enabled,
@@ -1321,7 +1320,6 @@ static void dp_print_peer_table(struct dp_vdev *vdev)
 			       peer->wds_enabled,
 			       peer->tx_cap_enabled,
 			       peer->rx_cap_enabled,
-			       peer->delete_in_progress,
 			       peer->peer_id);
 	}
 	qdf_spin_unlock_bh(&vdev->peer_list_lock);
@@ -5423,7 +5421,6 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 
 		qdf_spin_lock_bh(&soc->ast_lock);
 		dp_peer_delete_ast_entries(soc, peer);
-		peer->delete_in_progress = false;
 		qdf_spin_unlock_bh(&soc->ast_lock);
 
 		if ((vdev->opmode == wlan_op_mode_sta) &&
@@ -5453,6 +5450,8 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 
 		for (i = 0; i < DP_MAX_TIDS; i++)
 			qdf_spinlock_create(&peer->rx_tid[i].tid_lock);
+
+		dp_peer_update_state(soc, peer, DP_PEER_STATE_INIT);
 		return QDF_STATUS_SUCCESS;
 	} else {
 		/*
@@ -5587,6 +5586,9 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 	dp_peer_tx_capture_filter_check(pdev, peer);
 
 	dp_set_peer_isolation(peer, false);
+
+	dp_peer_update_state(soc, peer, DP_PEER_STATE_INIT);
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -6245,10 +6247,8 @@ void dp_peer_unref_delete(struct dp_peer *peer, enum dp_peer_mod_id mod_id)
 				     inactive_list_elem);
 		/* delete this peer from the list */
 		qdf_spin_unlock_bh(&soc->inactive_peer_list_lock);
-		/*
-		 * Peer AST list hast to be empty here
-		 */
 		DP_AST_ASSERT(TAILQ_EMPTY(&peer->ast_entry_list));
+		dp_peer_update_state(soc, peer, DP_PEER_STATE_FREED);
 
 		qdf_mem_free(peer);
 
@@ -6288,7 +6288,6 @@ static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc_hdl,
 						      0, vdev_id,
 						      DP_MOD_ID_CDP);
 	struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
-
 	if (!vdev)
 		return QDF_STATUS_E_FAILURE;
 
@@ -9418,9 +9417,13 @@ dp_peer_teardown_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	if (peer->peer_state == DP_PEER_STATE_INIT)
+		dp_peer_cleanup(peer->vdev, peer);
+
 	qdf_spin_lock_bh(&soc->ast_lock);
-	peer->delete_in_progress = true;
 	dp_peer_delete_ast_entries(soc, peer);
+
+	dp_peer_update_state(soc, peer, DP_PEER_STATE_LOGICAL_DELETE);
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
 	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);

+ 23 - 6
dp/wifi3.0/dp_peer.c

@@ -885,9 +885,13 @@ QDF_STATUS dp_peer_add_ast(struct dp_soc *soc,
 	is_peer_found = dp_peer_exist_on_pdev(soc, mac_addr, 0, pdev);
 
 	qdf_spin_lock_bh(&soc->ast_lock);
-	if (peer->delete_in_progress) {
-		qdf_spin_unlock_bh(&soc->ast_lock);
-		return QDF_STATUS_E_BUSY;
+
+	if (peer->peer_state != DP_PEER_STATE_ACTIVE) {
+		if ((type != CDP_TXRX_AST_TYPE_STATIC) &&
+		    (type != CDP_TXRX_AST_TYPE_SELF)) {
+			qdf_spin_unlock_bh(&soc->ast_lock);
+			return QDF_STATUS_E_BUSY;
+		}
 	}
 
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
@@ -1296,7 +1300,8 @@ int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer,
 	 *  2) Peer delete is already triggered
 	 *  3) We did not get the HTT map for create event
 	 */
-	if (ast_entry->delete_in_progress || peer->delete_in_progress ||
+	if (ast_entry->delete_in_progress ||
+	    (peer->peer_state != DP_PEER_STATE_ACTIVE) ||
 	    !ast_entry->is_mapped)
 		return ret;
 
@@ -1936,6 +1941,16 @@ static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc,
 			  "%s: ref_cnt: %d", __func__,
 			   qdf_atomic_read(&peer->ref_cnt));
 
+		/*
+		 * if peer is in logical delete CP triggered delete before map
+		 * is received ignore this event
+		 */
+		if (peer->peer_state == DP_PEER_STATE_LOGICAL_DELETE) {
+			dp_peer_unref_delete(peer, DP_MOD_ID_PEER_CONFIG);
+			dp_alert("Peer %pK[%pM] logical delete state vid %d",
+				 peer, peer_mac_addr, vdev_id);
+			return NULL;
+		}
 		dp_peer_find_id_to_obj_add(soc, peer, peer_id);
 		if (peer->peer_id == HTT_INVALID_PEER) {
 			peer->peer_id = peer_id;
@@ -1944,6 +1959,7 @@ static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc,
 			QDF_ASSERT(0);
 		}
 
+		dp_peer_update_state(soc, peer, DP_PEER_STATE_ACTIVE);
 		return peer;
 	}
 
@@ -2119,6 +2135,8 @@ dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id,
 	qdf_spin_lock_bh(&soc->inactive_peer_list_lock);
 	TAILQ_INSERT_TAIL(&soc->inactive_peer_list, peer, inactive_list_elem);
 	qdf_spin_unlock_bh(&soc->inactive_peer_list_lock);
+
+	dp_peer_update_state(soc, peer, DP_PEER_STATE_INACTIVE);
 	/*
 	 * Remove a reference to the peer.
 	 * If there are no more references, delete the peer object.
@@ -2298,8 +2316,7 @@ QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
 	uint32_t alloc_tries = 0;
 	QDF_STATUS err = QDF_STATUS_SUCCESS;
 
-	if (peer->delete_in_progress ||
-	    !qdf_atomic_read(&peer->is_default_route_set))
+	if (!qdf_atomic_read(&peer->is_default_route_set))
 		return QDF_STATUS_E_FAILURE;
 
 	rx_tid->ba_win_size = ba_window_size;

+ 57 - 1
dp/wifi3.0/dp_peer.h

@@ -90,7 +90,7 @@ struct dp_peer *dp_peer_get_ref_by_id(struct dp_soc *soc,
 
 	qdf_spin_lock_bh(&soc->peer_map_lock);
 	peer = __dp_peer_find_by_id(soc, peer_id);
-	if (!peer || peer->delete_in_progress ||
+	if (!peer || peer->peer_state >= DP_PEER_STATE_LOGICAL_DELETE ||
 	    (dp_peer_get_ref(soc, peer, mod_id) != QDF_STATUS_SUCCESS)) {
 		qdf_spin_unlock_bh(&soc->peer_map_lock);
 		return NULL;
@@ -126,6 +126,62 @@ dp_clear_peer_internal(struct dp_soc *soc, struct dp_peer *peer)
 	dp_rx_flush_rx_cached(peer, true);
 }
 
+/**
+ * dp_peer_update_state() - update dp peer state
+ *
+ * @soc		: core DP soc context
+ * @peer	: DP peer
+ * @state	: new state
+ *
+ * Return: None
+ */
+static inline void
+dp_peer_update_state(struct dp_soc *soc,
+		     struct dp_peer *peer,
+		     enum dp_peer_state state)
+{
+	uint8_t peer_state = peer->peer_state;
+
+	switch (state) {
+	case DP_PEER_STATE_INIT:
+		QDF_ASSERT
+			((peer_state != DP_PEER_STATE_ACTIVE) ||
+			 (peer_state != DP_PEER_STATE_LOGICAL_DELETE));
+		break;
+
+	case DP_PEER_STATE_ACTIVE:
+		QDF_ASSERT(peer_state == DP_PEER_STATE_INIT);
+		break;
+
+	case DP_PEER_STATE_LOGICAL_DELETE:
+		QDF_ASSERT((peer_state == DP_PEER_STATE_ACTIVE) ||
+			   (peer_state == DP_PEER_STATE_INIT));
+		break;
+
+	case DP_PEER_STATE_INACTIVE:
+		QDF_ASSERT(peer_state == DP_PEER_STATE_LOGICAL_DELETE);
+		break;
+
+	case DP_PEER_STATE_FREED:
+		if (peer->sta_self_peer)
+			QDF_ASSERT(peer_state ==
+					DP_PEER_STATE_INIT);
+		else
+			QDF_ASSERT((peer_state ==
+					DP_PEER_STATE_INACTIVE) ||
+				   (peer_state ==
+					DP_PEER_STATE_LOGICAL_DELETE));
+		break;
+
+	default:
+		QDF_ASSERT(0);
+		break;
+	}
+	qdf_info("Updating peer state from %u to %u mac %pM\n",
+		 peer_state, state, peer->mac_addr.raw);
+	peer->peer_state = state;
+}
+
 void dp_print_ast_stats(struct dp_soc *soc);
 QDF_STATUS dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
 				  uint16_t hw_peer_id, uint8_t vdev_id,

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

@@ -6054,10 +6054,6 @@ dp_aggregate_pdev_ctrl_frames_stats(struct dp_pdev *pdev)
 	TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
 		TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
 
-			if (peer->delete_in_progress) {
-				dp_err("DP Peer deletion in progress");
-				continue;
-			}
 			if (dp_peer_get_ref(pdev->soc, peer,
 					    DP_MOD_ID_GENERIC_STATS) !=
 							QDF_STATUS_SUCCESS)

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

@@ -148,6 +148,19 @@ struct dp_rx_fst;
 struct dp_mon_filter;
 struct dp_mon_mpdu;
 
+/**
+ * enum for DP peer state
+ */
+enum dp_peer_state {
+	DP_PEER_STATE_NONE,
+	DP_PEER_STATE_INIT,
+	DP_PEER_STATE_ACTIVE,
+	DP_PEER_STATE_LOGICAL_DELETE,
+	DP_PEER_STATE_INACTIVE,
+	DP_PEER_STATE_FREED,
+	DP_PEER_STATE_INVALID,
+};
+
 /**
  * enum for modules ids of peer reference
  */
@@ -2413,7 +2426,7 @@ struct dp_peer {
 		rx_cap_enabled:1, /* Peer's rx-capture is enabled */
 		valid:1, /* valid bit */
 		in_twt:1, /* in TWT session */
-		delete_in_progress:1, /*delete_in_progress bit*/
+		delete_in_progress:1, /* Indicate kickout sent */
 		sta_self_peer:1; /* Indicate STA self peer */
 
 #ifdef QCA_SUPPORT_PEER_ISOLATION
@@ -2486,6 +2499,8 @@ struct dp_peer {
 	TAILQ_ENTRY(dp_peer) inactive_list_elem;
 
 	qdf_atomic_t mod_refs[DP_MOD_ID_MAX];
+
+	uint8_t peer_state;
 };
 
 /*