diff mbox series

[v2,1/2] wifi: nl80211: add link id of transmitted profile for MLO MBSSID

Message ID 20241025013857.2793346-2-quic_msinada@quicinc.com
State New
Headers show
Series MLO MBSSID Support | expand

Commit Message

Muna Sinada Oct. 25, 2024, 1:38 a.m. UTC
From: Rameshkumar Sundaram <quic_ramess@quicinc.com>

Currently non-transmitted profile provides the interface index of the
transmitted profile. The index matches one of the interface indices
advertised by the kernel.

For MLO MBSSID, if the transmitted profile is part of an MLD, then the
transmitted profile is a specific link of that MLD. Utilizing only the
interface index of transmitted profile is no longer sufficient to
identify transmitted profile for MLO.

Add a new attribute to specify link id of the transmitted profile of
MBSSID group if the profile is part of an MLD. It is required to map
the nontransmitted link to corresponding transmitted link.

Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Co-developed-by: Aloka Dixit <quic_alokad@quicinc.com>
Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
---
v2: addressed review comments
 - cleaned up commit message
 - added link id value for non-MLO to documentation
 - rewrote documentation for link id NL attibute
 - cleaned up error path
 - removed usage of tx_netdev

---
 include/net/cfg80211.h       |  3 +++
 include/uapi/linux/nl80211.h |  7 ++++++
 net/wireless/nl80211.c       | 43 +++++++++++++++++++++++++++---------
 3 files changed, 42 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 192d72c8b465..cd313f59dc68 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1286,11 +1286,14 @@  struct cfg80211_crypto_settings {
  * struct cfg80211_mbssid_config - AP settings for multi bssid
  *
  * @tx_wdev: pointer to the transmitted interface in the MBSSID set
+ * @tx_link_id: link ID of the transmitted interface if it is part of an MLD.
+ *	If transmitted interface is not part of an MLD, link ID is set to -1.
  * @index: index of this AP in the multi bssid group.
  * @ema: set to true if the beacons should be sent out in EMA mode.
  */
 struct cfg80211_mbssid_config {
 	struct wireless_dev *tx_wdev;
+	int tx_link_id;
 	u8 index;
 	bool ema;
 };
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f97f5adc8d51..ebf48c11dc0b 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -7987,6 +7987,12 @@  enum nl80211_sar_specs_attrs {
  *	Setting this flag is permitted only if the driver advertises EMA support
  *	by setting wiphy->ema_max_profile_periodicity to non-zero.
  *
+ * @NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID: Parameter for a non-transmitted
+ *	profile which provides the link ID (u8) of the transmitted profile when
+ *	the latter is part of an MLD. This is a mandatory parameter for a
+ *	non-transmitted profile. If transmitted profile is not part of an MLD,
+ *	link_id will be set to -1.
+ *
  * @__NL80211_MBSSID_CONFIG_ATTR_LAST: Internal
  * @NL80211_MBSSID_CONFIG_ATTR_MAX: highest attribute
  */
@@ -7998,6 +8004,7 @@  enum nl80211_mbssid_config_attributes {
 	NL80211_MBSSID_CONFIG_ATTR_INDEX,
 	NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX,
 	NL80211_MBSSID_CONFIG_ATTR_EMA,
+	NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID,
 
 	/* keep last */
 	__NL80211_MBSSID_CONFIG_ATTR_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7397a372c78e..32adca100f23 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -454,6 +454,8 @@  nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = {
 	[NL80211_MBSSID_CONFIG_ATTR_INDEX] = { .type = NLA_U8 },
 	[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 },
 	[NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG },
+	[NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID] =
+		NLA_POLICY_MAX(NLA_U8, IEEE80211_MLD_MAX_NUM_LINKS),
 };
 
 static const struct nla_policy
@@ -5477,6 +5479,7 @@  static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
 				       u8 num_elems)
 {
 	struct nlattr *tb[NL80211_MBSSID_CONFIG_ATTR_MAX + 1];
+	int err;
 
 	if (!wiphy->mbssid_max_interfaces)
 		return -EOPNOTSUPP;
@@ -5509,18 +5512,14 @@  static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
 			return -EINVAL;
 
 		if (tx_ifindex != dev->ifindex) {
-			struct net_device *tx_netdev =
-				dev_get_by_index(wiphy_net(wiphy), tx_ifindex);
-
-			if (!tx_netdev || !tx_netdev->ieee80211_ptr ||
-			    tx_netdev->ieee80211_ptr->wiphy != wiphy ||
-			    tx_netdev->ieee80211_ptr->iftype !=
-							NL80211_IFTYPE_AP) {
-				dev_put(tx_netdev);
-				return -EINVAL;
+			config->tx_wdev =
+			 dev_get_by_index(wiphy_net(wiphy), tx_ifindex)->ieee80211_ptr;
+			if (!config->tx_wdev ||
+			    config->tx_wdev->wiphy != wiphy ||
+			    config->tx_wdev->iftype != NL80211_IFTYPE_AP) {
+				err = -EINVAL;
+				goto out;
 			}
-
-			config->tx_wdev = tx_netdev->ieee80211_ptr;
 		} else {
 			config->tx_wdev = dev->ieee80211_ptr;
 		}
@@ -5530,7 +5529,29 @@  static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
 		return -EINVAL;
 	}
 
+	config->tx_link_id = 0;
+	if (config->tx_wdev->valid_links) {
+		if (!tb[NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID])
+			goto out;
+
+		config->tx_link_id =
+			  nla_get_u8(tb[NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID]);
+		if (!(config->tx_wdev->valid_links & BIT(config->tx_link_id))) {
+			err = -ENOLINK;
+			goto out;
+		}
+	} else if (tb[NL80211_MBSSID_CONFIG_ATTR_TX_LINK_ID]) {
+		goto out;
+	}
+
 	return 0;
+
+out:
+	if (config->tx_wdev && config->tx_wdev->netdev &&
+	    config->tx_wdev->netdev != dev)
+		dev_put(config->tx_wdev->netdev);
+
+	return err;
 }
 
 static struct cfg80211_mbssid_elems *