Search Linux Wireless

[PATCH] nl80211: Add support to configure allowed frequency list for AP operation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add support to configure the list of allowed 20 MHz channels for AP
operation using an array of channel center frequencies in MHz, this
configuration is valid until the AP is stopped. Driver shall filter out
channels on top of this list of channels based on regulatory or other
constraints during channel switch etc. Driver shall stop the AP
operation if all the channels are filtered out during such operation.

This configuration can be used to specify user's choice of frequencies,
allowed list of channels with static puncturing feature etc.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam@xxxxxxxxxxx>
---
 include/net/cfg80211.h       | 14 +++++++++++
 include/uapi/linux/nl80211.h | 28 ++++++++++++++++++++++
 net/wireless/nl80211.c       | 45 ++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9e04f69712b1..062d75709f4f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1359,6 +1359,18 @@ struct cfg80211_unsol_bcast_probe_resp {
  * @punct_bitmap: Preamble puncturing bitmap. Each bit represents
  *	a 20 MHz channel, lowest bit corresponding to the lowest channel.
  *	Bit set to 1 indicates that the channel is punctured.
+ * @allowed_freqs: List of allowed 20 MHz channel center frequencies in MHz for
+ *	the AP operation. The configuration is valid until the AP is stopped.
+ *	Whenever performing a channel selection, the driver shall generate a new
+ *	list based on this provided list by filtering out the channels that
+ *	cannot be used at that time due to regulatory or other constraints. The
+ *	resulting list is used as the list of all allowed channels, i.e.,
+ *	operation on any channel that is not included is not allowed, whenever
+ *	performing operations like ACS and DFS. If all the channels are filtered
+ *	out during such operation driver shall stop the AP operation. Driver
+ *	shall advertise %NL80211_EXT_FEATURE_AP_ALLOWED_FREQ_LIST when it
+ *	supports this configuration.
+ * @num_allowed_freqs: Number of frequencies specified in %allowed_freqs
  */
 struct cfg80211_ap_settings {
 	struct cfg80211_chan_def chandef;
@@ -1394,6 +1406,8 @@ struct cfg80211_ap_settings {
 	struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp;
 	struct cfg80211_mbssid_config mbssid_config;
 	u16 punct_bitmap;
+	u32 *allowed_freqs;
+	int num_allowed_freqs;
 };
 
 /**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index cf4fb981e131..9c9152a6f935 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2805,6 +2805,18 @@ enum nl80211_commands {
  *	index. If the userspace includes more RNR elements than number of
  *	MBSSID elements then these will be added in every EMA beacon.
  *
+ * @NL80211_ATTR_AP_ALLOWED_FREQ_LIST: Nested attribute with frequencies in u32
+ *	attributes. A list of allowed 20 MHz channel center frequencies in MHz
+ *	for AP operation. Used with %NL80211_CMD_START_AP. The configuration is
+ *	valid until the AP is stopped. The drivers shall filter out channels on
+ *	top of this list of channels based on regulatory or other constraints
+ *	during channel switch etc. If all the channels are filtered out during
+ *	such operation, the driver shall stop the AP operation.
+ *	This can be used to specify userspace choice of frequencies, allowed
+ *	list of channels with static puncturing feature etc. This configuration
+ *	allowed only when driver indicates
+ *	%NL80211_EXT_FEATURE_AP_ALLOWED_FREQ_LIST.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3341,6 +3353,8 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_EMA_RNR_ELEMS,
 
+	NL80211_ATTR_AP_ALLOWED_FREQ_LIST,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -6365,6 +6379,19 @@ enum nl80211_feature_flags {
  *	in authentication and deauthentication frames sent to unassociated peer
  *	using @NL80211_CMD_FRAME.
  *
+ * @NL80211_EXT_FEATURE_AP_ALLOWED_FREQ_LIST: Driver supports configuring
+ *	allowed frequency list for AP operation in %NL80211_CMD_START_AP with
+ *	%NL80211_ATTR_AP_ALLOWED_FREQ_LIST from userspace. When driver indicates
+ *	this and userspace sends %NL80211_ATTR_AP_ALLOWED_FREQ_LIST in
+ *	%NL80211_CMD_START_AP, driver shall generate a new list based on the
+ *	provided list in %NL80211_ATTR_AP_ALLOWED_FREQ_LIST by filtering out the
+ *	channels that can't be used at that time due to regulatory or other
+ *	constraints. The resulting list is used as the list of all allowed
+ *	channels, i.e., operation on any channel that is not included is not
+ *	allowed, whenever performing operations like ACS and DFS. If all the
+ *	channels are filtered out during such operation driver shall stop the AP
+ *	operation.
+ *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
  */
@@ -6436,6 +6463,7 @@ enum nl80211_ext_feature_index {
 	NL80211_EXT_FEATURE_PUNCT,
 	NL80211_EXT_FEATURE_SECURE_NAN,
 	NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA,
+	NL80211_EXT_FEATURE_AP_ALLOWED_FREQ_LIST,
 
 	/* add new features before the definition below */
 	NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f1cd3d9130dd..65576d8ccb82 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -810,6 +810,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 },
 	[NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
 	[NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
+	[NL80211_ATTR_AP_ALLOWED_FREQ_LIST] = { .type = NLA_NESTED },
 };
 
 /* policy for the key attributes */
@@ -5886,6 +5887,35 @@ static void nl80211_send_ap_started(struct wireless_dev *wdev,
 	nlmsg_free(msg);
 }
 
+static int parse_ap_allowed_freq_list(struct nlattr *freq_list,
+				      struct cfg80211_ap_settings *params)
+{
+	struct nlattr *attr;
+	int tmp;
+	int n_freqs = 0;
+
+	nla_for_each_nested(attr, freq_list, tmp) {
+		if (nla_len(attr) != sizeof(u32))
+			return -EINVAL;
+
+		n_freqs++;
+	}
+
+	if (!n_freqs)
+		return -EINVAL;
+
+	params->allowed_freqs = kcalloc(n_freqs, sizeof(*params->allowed_freqs),
+					GFP_KERNEL);
+	if (!params->allowed_freqs)
+		return -ENOMEM;
+
+	nla_for_each_nested(attr, freq_list, tmp)
+		params->allowed_freqs[params->num_allowed_freqs++] =
+				nla_get_u32(attr);
+
+	return 0;
+}
+
 static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6049,6 +6079,20 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
+	if (info->attrs[NL80211_ATTR_AP_ALLOWED_FREQ_LIST]) {
+		if (!wiphy_ext_feature_isset(&rdev->wiphy,
+				NL80211_EXT_FEATURE_AP_ALLOWED_FREQ_LIST)) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
+
+		err = parse_ap_allowed_freq_list(
+				info->attrs[NL80211_ATTR_AP_ALLOWED_FREQ_LIST],
+				params);
+		if (err)
+			goto out;
+	}
+
 	wdev_lock(wdev);
 
 	if (info->attrs[NL80211_ATTR_TX_RATES]) {
@@ -6187,6 +6231,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
 	wdev_unlock(wdev);
 out:
 	kfree(params->acl);
+	kfree(params->allowed_freqs);
 	kfree(params->beacon.mbssid_ies);
 	if (params->mbssid_config.tx_wdev &&
 	    params->mbssid_config.tx_wdev->netdev &&
-- 
2.25.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux