diff mbox series

[iwlwifi-next,15/15] wifi: iwlwifi: mld: allow 2 ROCs on the same vif

Message ID 20250511195137.1f8c55198578.I17cb191596ed4e97a4854108f8ca5ca197662a62@changeid
State New
Headers show
Series [iwlwifi-next,01/15] wifi: iwlwifi: cfg: mark Ty devices as discrete | expand

Commit Message

Miri Korenblit May 11, 2025, 4:53 p.m. UTC
In the current code, if an ROC is started on a vif that already has an
active ROC we reject it and warn.

But really there is no such limitation. The actual limitation is to not
have 2 ROCs of the same type simultaneously.

Add a helper function to find a vif that has an active ROC of a given
type, and only if one exist - reject the ROC.

This allows also to remove bss_roc_vif.

Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/mld.h |  2 -
 drivers/net/wireless/intel/iwlwifi/mld/roc.c | 59 +++++++++++++++-----
 2 files changed, 44 insertions(+), 17 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mld.h b/drivers/net/wireless/intel/iwlwifi/mld/mld.h
index 74fcaad85a32..1a2c44f44eff 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mld.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mld.h
@@ -127,7 +127,6 @@ 
  *	cleanup using iwl_mld_free_internal_sta
  * @netdetect: indicates the FW is in suspend mode with netdetect configured
  * @p2p_device_vif: points to the p2p device vif if exists
- * @bss_roc_vif: points to the BSS vif that has an active ROC.
  * @dev: pointer to device struct. For printing purposes
  * @trans: pointer to the transport layer
  * @cfg: pointer to the device configuration
@@ -213,7 +212,6 @@  struct iwl_mld {
 		bool netdetect;
 #endif /* CONFIG_PM_SLEEP */
 		struct ieee80211_vif *p2p_device_vif;
-		struct ieee80211_vif *bss_roc_vif;
 		struct iwl_bt_coex_profile_notif last_bt_notif;
 	);
 	struct ieee80211_link_sta __rcu *fw_id_to_link_sta[IWL_STATION_COUNT_MAX];
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/roc.c b/drivers/net/wireless/intel/iwlwifi/mld/roc.c
index 944d70901de5..e85f45bce79a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/roc.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/roc.c
@@ -31,6 +31,47 @@  iwl_mld_vif_iter_emlsr_block_roc(void *data, u8 *mac, struct ieee80211_vif *vif)
 		*result = ret;
 }
 
+struct iwl_mld_roc_iter_data {
+	enum iwl_roc_activity activity;
+	struct ieee80211_vif *vif;
+	bool found;
+};
+
+static void iwl_mld_find_roc_vif_iter(void *data, u8 *mac,
+				      struct ieee80211_vif *vif)
+{
+	struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
+	struct iwl_mld_roc_iter_data *roc_data = data;
+
+	if (mld_vif->roc_activity != roc_data->activity)
+		return;
+
+	/* The FW supports one ROC of each type simultaneously */
+	if (WARN_ON(roc_data->found)) {
+		roc_data->vif = NULL;
+		return;
+	}
+
+	roc_data->found = true;
+	roc_data->vif = vif;
+}
+
+static struct ieee80211_vif *
+iwl_mld_find_roc_vif(struct iwl_mld *mld, enum iwl_roc_activity activity)
+{
+	struct iwl_mld_roc_iter_data roc_data = {
+		.activity = activity,
+		.found = false,
+	};
+
+	ieee80211_iterate_active_interfaces_mtx(mld->hw,
+						IEEE80211_IFACE_ITER_NORMAL,
+						iwl_mld_find_roc_vif_iter,
+						&roc_data);
+
+	return roc_data.vif;
+}
+
 int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		      struct ieee80211_channel *channel, int duration,
 		      enum ieee80211_roc_type type)
@@ -73,10 +114,8 @@  int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		activity = ROC_ACTIVITY_HOTSPOT;
 	}
 
-	if (WARN_ON(mld_vif->roc_activity != ROC_NUM_ACTIVITIES))
-		return -EBUSY;
-
-	if (vif->type == NL80211_IFTYPE_STATION && mld->bss_roc_vif)
+	/* The FW supports one ROC of each type simultaneously */
+	if (WARN_ON(iwl_mld_find_roc_vif(mld, activity)))
 		return -EBUSY;
 
 	ieee80211_iterate_active_interfaces_mtx(mld->hw,
@@ -109,9 +148,6 @@  int iwl_mld_start_roc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 	mld_vif->roc_activity = activity;
 
-	if (vif->type == NL80211_IFTYPE_STATION)
-		mld->bss_roc_vif = vif;
-
 	return 0;
 }
 
@@ -130,9 +166,6 @@  static void iwl_mld_destroy_roc(struct iwl_mld *mld,
 {
 	mld_vif->roc_activity = ROC_NUM_ACTIVITIES;
 
-	if (vif->type == NL80211_IFTYPE_STATION)
-		mld->bss_roc_vif = NULL;
-
 	ieee80211_iterate_active_interfaces_mtx(mld->hw,
 						IEEE80211_IFACE_ITER_NORMAL,
 						iwl_mld_vif_iter_emlsr_unblock_roc,
@@ -203,11 +236,7 @@  void iwl_mld_handle_roc_notif(struct iwl_mld *mld,
 	struct iwl_mld_vif *mld_vif;
 	struct ieee80211_vif *vif;
 
-	if (activity == ROC_ACTIVITY_HOTSPOT)
-		vif = mld->bss_roc_vif;
-	else
-		vif = mld->p2p_device_vif;
-
+	vif = iwl_mld_find_roc_vif(mld, activity);
 	if (WARN_ON(!vif))
 		return;