Răsfoiți Sursa

qcacmn: Support multi AST delete WMI command

Add change to support multi ast entries deletion.

Change-Id: I74b9000c6949d7455da5eb54678e976ab1b9bb20
CRs-Fixed: 3124258
Santosh Anbu 3 ani în urmă
părinte
comite
83d13e1ffd
4 a modificat fișierele cu 175 adăugiri și 3 ștergeri
  1. 14 0
      dp/wifi3.0/dp_peer.c
  2. 6 0
      dp/wifi3.0/dp_peer.h
  3. 150 3
      dp/wifi3.0/dp_txrx_wds.c
  4. 5 0
      wmi/inc/wmi_unified_priv.h

+ 14 - 0
dp/wifi3.0/dp_peer.c

@@ -2102,6 +2102,20 @@ void dp_peer_ast_send_wds_del(struct dp_soc *soc,
 
 }
 
+#ifdef WLAN_FEATURE_MULTI_AST_DEL
+void dp_peer_ast_send_multi_wds_del(
+		struct dp_soc *soc, uint8_t vdev_id,
+		struct peer_del_multi_wds_entries *wds_list)
+{
+	struct cdp_soc_t *cdp_soc = &soc->cdp_soc;
+
+	if (cdp_soc && cdp_soc->ol_ops &&
+	    cdp_soc->ol_ops->peer_del_multi_wds_entry)
+		cdp_soc->ol_ops->peer_del_multi_wds_entry(soc->ctrl_psoc,
+							  vdev_id, wds_list);
+}
+#endif
+
 #ifdef FEATURE_WDS
 /**
  * dp_peer_ast_free_wds_entries() - Free wds ast entries associated with peer

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

@@ -687,6 +687,12 @@ void dp_peer_ast_send_wds_del(struct dp_soc *soc,
 			      struct dp_ast_entry *ast_entry,
 			      struct dp_peer *peer);
 
+#ifdef WLAN_FEATURE_MULTI_AST_DEL
+void dp_peer_ast_send_multi_wds_del(
+		struct dp_soc *soc, uint8_t vdev_id,
+		struct peer_del_multi_wds_entries *wds_list);
+#endif
+
 void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
 			   struct cdp_soc *dp_soc,
 			   void *cookie,

+ 150 - 3
dp/wifi3.0/dp_txrx_wds.c

@@ -44,6 +44,116 @@
 #define DP_PEER_AST3_FLOW_MASK 0x2
 #define DP_MAX_AST_INDEX_PER_PEER 4
 
+#ifdef WLAN_FEATURE_MULTI_AST_DEL
+
+void dp_peer_free_peer_ase_list(struct dp_soc *soc,
+				struct peer_del_multi_wds_entries *wds_list)
+{
+	struct peer_wds_entry_list *wds_entry, *tmp_entry;
+
+	TAILQ_FOREACH_SAFE(wds_entry, &wds_list->ase_list,
+			   ase_list_elem, tmp_entry) {
+		dp_peer_debug("type: %d mac_addr: " QDF_MAC_ADDR_FMT,
+			      wds_entry->type,
+			      QDF_MAC_ADDR_REF(wds_entry->dest_addr));
+		TAILQ_REMOVE(&wds_list->ase_list, wds_entry, ase_list_elem);
+		wds_list->num_entries--;
+		qdf_mem_free(wds_entry);
+	}
+}
+
+static void
+dp_pdev_build_peer_ase_list(struct dp_soc *soc, struct dp_peer *peer,
+			    void *arg)
+{
+	struct dp_ast_entry *ase, *temp_ase;
+	struct peer_del_multi_wds_entries *list = arg;
+	struct peer_wds_entry_list *wds_entry;
+
+	if (!soc || !peer || !arg) {
+		dp_peer_err("Invalid input");
+		return;
+	}
+
+	list->vdev_id = peer->vdev->vdev_id;
+	DP_PEER_ITERATE_ASE_LIST(peer, ase, temp_ase) {
+		if (ase->type != CDP_TXRX_AST_TYPE_WDS &&
+		    ase->type != CDP_TXRX_AST_TYPE_DA)
+			continue;
+
+		if (ase->is_active) {
+			ase->is_active = false;
+			continue;
+		}
+
+		if (ase->delete_in_progress) {
+			dp_info_rl("Del set addr:" QDF_MAC_ADDR_FMT " type:%d",
+				   QDF_MAC_ADDR_REF(ase->mac_addr.raw),
+				   ase->type);
+			continue;
+		}
+
+		if (ase->is_mapped)
+			soc->ast_table[ase->ast_idx] = NULL;
+
+		if (!ase->next_hop) {
+			dp_peer_unlink_ast_entry(soc, ase, peer);
+			continue;
+		}
+
+		wds_entry = (struct peer_wds_entry_list *)
+			    qdf_mem_malloc(sizeof(*wds_entry));
+		if (!wds_entry) {
+			dp_peer_err("%pK: fail to allocate wds_entry", soc);
+			dp_peer_free_peer_ase_list(soc, list);
+			return;
+		}
+
+		DP_STATS_INC(soc, ast.aged_out, 1);
+		ase->delete_in_progress = true;
+		wds_entry->dest_addr = ase->mac_addr.raw;
+		wds_entry->type = ase->type;
+
+		if (dp_peer_state_cmp(peer, DP_PEER_STATE_LOGICAL_DELETE))
+			wds_entry->delete_in_fw = false;
+		else
+			wds_entry->delete_in_fw = true;
+
+		dp_peer_debug("ase->type: %d pdev: %u vdev: %u mac_addr: " QDF_MAC_ADDR_FMT " next_hop: %u peer: %u",
+			      ase->type, ase->pdev_id, ase->vdev_id,
+			      QDF_MAC_ADDR_REF(ase->mac_addr.raw),
+			      ase->next_hop, ase->peer_id);
+		TAILQ_INSERT_TAIL(&list->ase_list, wds_entry, ase_list_elem);
+		list->num_entries++;
+	}
+	dp_peer_info("Total num of entries :%d", list->num_entries);
+}
+
+static void
+dp_peer_age_multi_ast_entries(struct dp_soc *soc, void *arg,
+			      enum dp_mod_id mod_id)
+{
+	uint8_t i;
+	struct dp_pdev *pdev = NULL;
+	struct peer_del_multi_wds_entries wds_list = {0};
+
+	TAILQ_INIT(&wds_list.ase_list);
+	for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) {
+		pdev = soc->pdev_list[i];
+		dp_pdev_iterate_peer(pdev, dp_pdev_build_peer_ase_list,
+				     &wds_list, mod_id);
+		if (wds_list.num_entries > 0) {
+			dp_peer_ast_send_multi_wds_del(soc, wds_list.vdev_id,
+						       &wds_list);
+			dp_peer_free_peer_ase_list(soc, &wds_list);
+		} else {
+			dp_peer_debug("No AST entries for pdev:%u",
+				      pdev->pdev_id);
+		}
+	}
+}
+#endif /* WLAN_FEATURE_MULTI_AST_DEL */
+
 static void
 dp_peer_age_ast_entries(struct dp_soc *soc, struct dp_peer *peer, void *arg)
 {
@@ -113,12 +223,12 @@ dp_peer_age_mec_entries(struct dp_soc *soc)
 	dp_peer_mec_free_list(soc, &free_list);
 }
 
+#ifdef WLAN_FEATURE_MULTI_AST_DEL
 static void dp_ast_aging_timer_fn(void *soc_hdl)
 {
 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
 	struct ast_del_ctxt del_ctxt = {0};
 
-
 	if (soc->wds_ast_aging_timer_cnt++ >= DP_WDS_AST_AGING_TIMER_CNT) {
 		del_ctxt.age = true;
 		soc->wds_ast_aging_timer_cnt = 0;
@@ -130,8 +240,44 @@ static void dp_ast_aging_timer_fn(void *soc_hdl)
 		/* AST list access lock */
 		qdf_spin_lock_bh(&soc->ast_lock);
 
-		dp_soc_iterate_peer(soc, dp_peer_age_ast_entries, &del_ctxt,
-				    DP_MOD_ID_AST);
+		if (soc->multi_peer_grp_cmd_supported)
+			dp_peer_age_multi_ast_entries(soc, NULL, DP_MOD_ID_AST);
+		else
+			dp_soc_iterate_peer(soc, dp_peer_age_ast_entries,
+					    &del_ctxt, DP_MOD_ID_AST);
+		qdf_spin_unlock_bh(&soc->ast_lock);
+	}
+
+	/*
+	 * If NSS offload is enabled, the MEC timeout
+	 * will be managed by NSS.
+	 */
+	if (qdf_atomic_read(&soc->mec_cnt) &&
+	    !wlan_cfg_get_dp_soc_nss_cfg(soc->wlan_cfg_ctx))
+		dp_peer_age_mec_entries(soc);
+
+	if (qdf_atomic_read(&soc->cmn_init_done))
+		qdf_timer_mod(&soc->ast_aging_timer,
+			      DP_AST_AGING_TIMER_DEFAULT_MS);
+}
+#else
+static void dp_ast_aging_timer_fn(void *soc_hdl)
+{
+	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
+	struct ast_del_ctxt del_ctxt = {0};
+
+	if (soc->wds_ast_aging_timer_cnt++ >= DP_WDS_AST_AGING_TIMER_CNT) {
+		del_ctxt.age = true;
+		soc->wds_ast_aging_timer_cnt = 0;
+	}
+
+	if (soc->pending_ageout || del_ctxt.age) {
+		soc->pending_ageout = false;
+
+		/* AST list access lock */
+		qdf_spin_lock_bh(&soc->ast_lock);
+		dp_soc_iterate_peer(soc, dp_peer_age_ast_entries,
+				    &del_ctxt, DP_MOD_ID_AST);
 		qdf_spin_unlock_bh(&soc->ast_lock);
 	}
 
@@ -147,6 +293,7 @@ static void dp_ast_aging_timer_fn(void *soc_hdl)
 		qdf_timer_mod(&soc->ast_aging_timer,
 			      DP_AST_AGING_TIMER_DEFAULT_MS);
 }
+#endif /* WLAN_FEATURE_MULTI_AST_DEL */
 
 /*
  * dp_soc_wds_attach() - Setup WDS timer and AST table

+ 5 - 0
wmi/inc/wmi_unified_priv.h

@@ -1326,6 +1326,11 @@ QDF_STATUS (*send_peer_add_wds_entry_cmd)(wmi_unified_t wmi_handle,
 QDF_STATUS (*send_peer_del_wds_entry_cmd)(wmi_unified_t wmi_handle,
 		struct peer_del_wds_entry_params *param);
 
+#ifdef WLAN_FEATURE_MULTI_AST_DEL
+QDF_STATUS (*send_peer_del_multi_wds_entries_cmd)(wmi_unified_t wmi_handle,
+		struct peer_del_multi_wds_entry_params *param);
+#endif
+
 QDF_STATUS (*send_peer_update_wds_entry_cmd)(wmi_unified_t wmi_handle,
 		struct peer_update_wds_entry_params *param);
 #endif