Browse Source

qcacmn: Do cleanup related to peer_map_unmap_v2

AST entry delete logic has some conditional checks making code with respect
to HTT V1 and V2 messages making it tough to follow.

Change-Id: I229324446134b32021a956fb689e4726256fcc28
Radha Krishna Simha Jiguru 5 years ago
parent
commit
64b4848aa0
3 changed files with 100 additions and 50 deletions
  1. 4 2
      dp/wifi3.0/dp_main.c
  2. 90 48
      dp/wifi3.0/dp_peer.c
  3. 6 0
      dp/wifi3.0/dp_peer.h

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

@@ -6240,7 +6240,7 @@ void dp_peer_unref_delete(struct dp_peer *peer)
 	struct cdp_peer_cookie peer_cookie;
 	enum wlan_op_mode vdev_opmode;
 	uint8_t vdev_mac_addr[QDF_MAC_ADDR_SIZE];
-
+	struct dp_ast_entry *peer_ast_entry = NULL;
 
 	/*
 	 * Hold the lock all the way from checking if the peer ref count
@@ -6272,7 +6272,9 @@ void dp_peer_unref_delete(struct dp_peer *peer)
 
 		qdf_spin_lock_bh(&soc->ast_lock);
 		if (peer->self_ast_entry) {
-			dp_peer_del_ast(soc, peer->self_ast_entry);
+			peer_ast_entry = peer->self_ast_entry;
+			dp_peer_unlink_ast_entry(soc, peer_ast_entry);
+			dp_peer_free_ast_entry(soc, peer_ast_entry);
 			peer->self_ast_entry = NULL;
 		}
 		qdf_spin_unlock_bh(&soc->ast_lock);

+ 90 - 48
dp/wifi3.0/dp_peer.c

@@ -677,8 +677,7 @@ int dp_peer_add_ast(struct dp_soc *soc,
 			 * can take care of adding HMWDS ast enty on delete
 			 * confirmation from target
 			 */
-			if ((type == CDP_TXRX_AST_TYPE_WDS_HM) &&
-			    soc->is_peer_map_unmap_v2) {
+			if (type == CDP_TXRX_AST_TYPE_WDS_HM) {
 				struct dp_ast_free_cb_params *param = NULL;
 
 				if (ast_entry->type ==
@@ -835,6 +834,67 @@ add_ast_entry:
 	return ret;
 }
 
+/*
+ * dp_peer_free_ast_entry() - Free up the ast entry memory
+ * @soc: SoC handle
+ * @ast_entry: Address search entry
+ *
+ * This API is used to free up the memory associated with
+ * AST entry.
+ *
+ * Return: None
+ */
+void dp_peer_free_ast_entry(struct dp_soc *soc,
+			    struct dp_ast_entry *ast_entry)
+{
+	/*
+	 * NOTE: Ensure that call to this API is done
+	 * after soc->ast_lock is taken
+	 */
+	ast_entry->callback = NULL;
+	ast_entry->cookie = NULL;
+
+	DP_STATS_INC(soc, ast.deleted, 1);
+	dp_peer_ast_hash_remove(soc, ast_entry);
+	dp_peer_ast_cleanup(soc, ast_entry);
+	qdf_mem_free(ast_entry);
+	soc->num_ast_entries--;
+}
+
+/*
+ * dp_peer_unlink_ast_entry() - Free up the ast entry memory
+ * @soc: SoC handle
+ * @ast_entry: Address search entry
+ *
+ * This API is used to remove/unlink AST entry from the peer list
+ * and hash list.
+ *
+ * Return: None
+ */
+void dp_peer_unlink_ast_entry(struct dp_soc *soc,
+			      struct dp_ast_entry *ast_entry)
+{
+	/*
+	 * NOTE: Ensure that call to this API is done
+	 * after soc->ast_lock is taken
+	 */
+	struct dp_peer *peer = ast_entry->peer;
+
+	TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
+
+	if (ast_entry == peer->self_ast_entry)
+		peer->self_ast_entry = NULL;
+
+	/*
+	 * release the reference only if it is mapped
+	 * to ast_table
+	 */
+	if (ast_entry->is_mapped)
+		soc->ast_table[ast_entry->ast_idx] = NULL;
+
+	ast_entry->peer = NULL;
+}
+
 /*
  * dp_peer_del_ast() - Delete and free AST entry
  * @soc: SoC handle
@@ -853,45 +913,45 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry)
 	if (!ast_entry)
 		return;
 
-	peer =  ast_entry->peer;
+	if (ast_entry->delete_in_progress)
+		return;
+
+	ast_entry->delete_in_progress = true;
 
+	peer = ast_entry->peer;
 	dp_peer_ast_send_wds_del(soc, ast_entry);
 
-	/*
-	 * release the reference only if it is mapped
-	 * to ast_table
-	 */
+	/* Remove SELF and STATIC entries in teardown itself */
+	if (!ast_entry->next_hop)
+		dp_peer_unlink_ast_entry(soc, ast_entry);
+
 	if (ast_entry->is_mapped)
 		soc->ast_table[ast_entry->ast_idx] = NULL;
 
-	/*
-	 * if peer map v2 is enabled we are not freeing ast entry
+	/* if peer map v2 is enabled we are not freeing ast entry
 	 * here and it is supposed to be freed in unmap event (after
 	 * we receive delete confirmation from target)
 	 *
 	 * if peer_id is invalid we did not get the peer map event
 	 * for the peer free ast entry from here only in this case
 	 */
-	if (soc->is_peer_map_unmap_v2) {
 
-		/*
-		 * For HM_SEC and SELF type we do not receive unmap event
-		 * free ast_entry from here it self
-		 */
-		if ((ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC) &&
-		    (ast_entry->type != CDP_TXRX_AST_TYPE_SELF))
-			return;
-	}
+	/* For HM_SEC and SELF type we do not receive unmap event
+	 * free ast_entry from here it self
+	 */
+	if ((ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC) &&
+	    (ast_entry->type != CDP_TXRX_AST_TYPE_SELF))
+		return;
 
-	/* SELF and STATIC entries are removed in teardown itself */
-	if (ast_entry->next_hop)
-		TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
+	/* for WDS secondary entry ast_entry->next_hop would be set so
+	 * unlinking has to be done explicitly here.
+	 * As this entry is not a mapped entry unmap notification from
+	 * FW wil not come. Hence unlinkling is done right here.
+	 */
+	if (ast_entry->type == CDP_TXRX_AST_TYPE_WDS_HM_SEC)
+		dp_peer_unlink_ast_entry(soc, ast_entry);
 
-	DP_STATS_INC(soc, ast.deleted, 1);
-	dp_peer_ast_hash_remove(soc, ast_entry);
-	dp_peer_ast_cleanup(soc, ast_entry);
-	qdf_mem_free(ast_entry);
-	soc->num_ast_entries--;
+	dp_peer_free_ast_entry(soc, ast_entry);
 }
 
 /*
@@ -1088,9 +1148,6 @@ void dp_peer_ast_send_wds_del(struct dp_soc *soc,
 	struct dp_peer *peer = ast_entry->peer;
 	struct cdp_soc_t *cdp_soc = &soc->cdp_soc;
 
-	if (ast_entry->delete_in_progress)
-		return;
-
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_TRACE,
 		  "%s: ast_entry->type: %d pdevid: %u vdev: %u mac_addr: %pM next_hop: %u peer_mac: %pM\n",
 		  __func__, ast_entry->type, peer->vdev->pdev->pdev_id,
@@ -1104,14 +1161,6 @@ void dp_peer_ast_send_wds_del(struct dp_soc *soc,
 						    ast_entry->type);
 	}
 
-	/* Remove SELF and STATIC entries in teardown itself */
-	if (!ast_entry->next_hop) {
-		TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
-		peer->self_ast_entry = NULL;
-		ast_entry->peer = NULL;
-	}
-
-	ast_entry->delete_in_progress = true;
 }
 
 /**
@@ -1148,19 +1197,13 @@ static int dp_peer_ast_free_entry_by_mac(struct dp_soc *soc,
 		soc->ast_table[ast_entry->ast_idx] = NULL;
 	}
 
-	TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
-	DP_STATS_INC(soc, ast.deleted, 1);
-	dp_peer_ast_hash_remove(soc, ast_entry);
-
 	cb = ast_entry->callback;
 	cookie = ast_entry->cookie;
-	ast_entry->callback = NULL;
-	ast_entry->cookie = NULL;
 
-	if (ast_entry == peer->self_ast_entry)
-		peer->self_ast_entry = NULL;
 
-	soc->num_ast_entries--;
+	dp_peer_unlink_ast_entry(soc, ast_entry);
+	dp_peer_free_ast_entry(soc, ast_entry);
+
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
 	if (cb) {
@@ -1169,7 +1212,6 @@ static int dp_peer_ast_free_entry_by_mac(struct dp_soc *soc,
 		   cookie,
 		   CDP_TXRX_AST_DELETED);
 	}
-	qdf_mem_free(ast_entry);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -1602,7 +1644,7 @@ dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id,
 
 	/* If V2 Peer map messages are enabled AST entry has to be freed here
 	 */
-	if (soc->is_peer_map_unmap_v2 && is_wds) {
+	if (is_wds) {
 		if (!dp_peer_ast_free_entry_by_mac(soc, peer, mac_addr))
 			return;
 

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

@@ -148,6 +148,12 @@ void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
 void dp_peer_ast_hash_remove(struct dp_soc *soc,
 			     struct dp_ast_entry *ase);
 
+void dp_peer_free_ast_entry(struct dp_soc *soc,
+			    struct dp_ast_entry *ast_entry);
+
+void dp_peer_unlink_ast_entry(struct dp_soc *soc,
+			      struct dp_ast_entry *ast_entry);
+
 /*
  * dp_peer_find_by_id_exist - check if peer exists for given id
  * @soc: core DP soc context