Search Linux Wireless

[PATCH v1 1/3] support for antenna configuration profiles

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

 



This adds support for antenna switch configuration profiles to nl80211.

Signed-off-by: Daniel Golle <dgolle@xxxxxxxxx>
---
 include/linux/nl80211.h |   47 +++++++++++++++++++++++++++++++
 include/net/cfg80211.h  |   26 +++++++++++++++++
 net/wireless/nl80211.c  |   71 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 97bfebf..0653896 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1185,6 +1185,12 @@ enum nl80211_commands {
  *    abides to when initiating radiation on DFS channels. A country maps
  *    to one DFS region.
  *
+ * @NL80211_ATTR_WIPHY_EXTANT: External antenna switch profiles. This nested
+ *	structure contains a list of available profiles as well as the current
+ *	profile selection status.
+ *
+ * @NL80211_ATTR_WIPHY_EXTANT_SELECT: Select extant profile.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1428,6 +1434,9 @@ enum nl80211_attrs {
 	NL80211_ATTR_DISABLE_HT,
 	NL80211_ATTR_HT_CAPABILITY_MASK,
 
+	NL80211_ATTR_WIPHY_EXTANT,
+	NL80211_ATTR_WIPHY_EXTANT_SELECT,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
@@ -1720,6 +1729,44 @@ enum nl80211_mpath_info {
 	NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
 };
 
+
+
+/**
+ * enum nl80211_extant_attr - external antenna switch
+ * @__NL80211_EXTANT_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_EXTANT_ATTR_STATE: currently selected profile
+ * @NL80211_EXTANT_ATTR_PROFILES: highest profile attribute currently defined
+ * @NL80211_EXTANT_ATTR_MAX: highest profile attribute currently defined
+ * @__NL80211_EXTANT_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_extant_attr {
+	__NL80211_EXTANT_ATTR_INVALID,
+	NL80211_EXTANT_ATTR_STATE,
+	NL80211_EXTANT_ATTR_PROFILES,
+	/* keep last */
+	__NL80211_EXTANT_ATTR_AFTER_LAST,
+	NL80211_EXTANT_ATTR_MAX = __NL80211_EXTANT_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_easp_attr - external antenna switch configuration profile
+ * @__NL80211_EASP_ATTR_INVALID: attribute number 0 is reserved
+ * @NL80211_EASP_ATTR_ID: unique identifier
+ * @NL80211_EASP_ATTR_NAME: human-readable name of the configuration profile
+ * @NL80211_EASP_ATTR_DESC: human-readable description of the configuration profile
+ * @NL80211_EASP_ATTR_MAX: highest profile attribute currently defined
+ * @__NL80211_EASP_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_easp_attr {
+	__NL80211_EASP_ATTR_INVALID,
+	NL80211_EASP_ATTR_ID,
+	NL80211_EASP_ATTR_NAME,
+	NL80211_EASP_ATTR_DESC,
+	/* keep last */
+	__NL80211_EASP_ATTR_AFTER_LAST,
+	NL80211_EASP_ATTR_MAX = __NL80211_EASP_ATTR_AFTER_LAST - 1
+};
+
 /**
  * enum nl80211_band_attr - band attributes
  * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d5e1891..4896e7a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1456,6 +1456,9 @@ struct cfg80211_gtk_rekey_data {
  *
  * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).
  *
+ * @set_extant: Select the external antenna switch configuration profile.
+ * @get_extant: Get currently selected antenna switch profile.
+ *
  * @set_ringparam: Set tx and rx ring sizes.
  *
  * @get_ringparam: Get tx and rx ring current and maximum sizes.
@@ -1637,6 +1640,9 @@ struct cfg80211_ops {
 	int	(*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
 	int	(*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant);
 
+	int	(*set_extant)(struct wiphy *wiphy, u32 extant);
+	int	(*get_extant)(struct wiphy *wiphy, u32 *extant);
+
 	int	(*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx);
 	void	(*get_ringparam)(struct wiphy *wiphy,
 				 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
@@ -1748,6 +1754,7 @@ enum wiphy_flags {
 	WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD	= BIT(19),
 	WIPHY_FLAG_OFFCHAN_TX			= BIT(20),
 	WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL	= BIT(21),
+	WIPHY_FLAG_HAS_EXTANT_SWITCH		= BIT(22),
 };
 
 /**
@@ -1875,6 +1882,21 @@ struct wiphy_wowlan_support {
 };
 
 /**
+ * struct wiphy_extant_profile - User-parsable external antenna switch info
+ *
+ * This structure is used to provide the available switch configurations.
+ * @id: unique identifier of the profile
+ * @name: profile name (a short string)
+ * @description: user-parsable description of the profile
+ */
+struct wiphy_extant_profile {
+	int id;
+	char *name;
+	char *desc;
+};
+
+
+/**
  * struct wiphy - wireless hardware description
  * @reg_notifier: the driver's regulatory notification callback,
  *	note that if your driver uses wiphy_apply_custom_regulatory()
@@ -1955,6 +1977,8 @@ struct wiphy_wowlan_support {
  *	configured as RX antennas. Antenna configuration commands will be
  *	rejected unless this or @available_antennas_tx is set.
  *
+ * @extant: struct holding the available antenna switch configuration profiles.
+ *
  * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation
  *	may request, if implemented.
  *
@@ -2025,6 +2049,8 @@ struct wiphy {
 	 */
 	u32 probe_resp_offload;
 
+	struct wiphy_extant_profile *extant;
+
 	/* If multiple wiphys are registered and you're handed e.g.
 	 * a regular netdev with assigned ieee80211_ptr, you won't
 	 * know whether it points to a wiphy your driver has registered
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a1cabde..9c861ae 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -204,6 +204,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 	[NL80211_ATTR_HT_CAPABILITY_MASK] = {
 		.len = NL80211_HT_CAPABILITY_LEN
 	},
+	[NL80211_ATTR_WIPHY_EXTANT] = { .type = NLA_NESTED },
+	[NL80211_ATTR_WIPHY_EXTANT_SELECT] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -252,6 +254,17 @@ nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
 						 .len = IEEE80211_MAX_SSID_LEN },
 };
 
+/* policy for external antenna switch configuration profiles */
+static const struct nla_policy
+nl80211_easp_policy[NL80211_EASP_ATTR_MAX + 1] = {
+	[NL80211_EASP_ATTR_ID] = { .type = NLA_U32 },
+	[NL80211_EASP_ATTR_NAME] = { .type = NLA_STRING,
+					.len = IEEE80211_MAX_DATA_LEN },
+	[NL80211_EASP_ATTR_DESC] = { .type = NLA_STRING,
+					.len = IEEE80211_MAX_DATA_LEN },
+};
+
+
 /* ifidx get helper */
 static int nl80211_get_ifidx(struct netlink_callback *cb)
 {
@@ -699,6 +712,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	struct nlattr *nl_bands, *nl_band;
 	struct nlattr *nl_freqs, *nl_freq;
 	struct nlattr *nl_rates, *nl_rate;
+	struct nlattr *nl_easps, *nl_easp;
+	struct nlattr *nl_extant;
 	struct nlattr *nl_cmds;
 	enum ieee80211_band band;
 	struct ieee80211_channel *chan;
@@ -781,6 +796,48 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 		}
 	}
 
+	/*
+	 * antenna switch configuration profile support
+	 */
+	if (dev->wiphy.flags & WIPHY_FLAG_HAS_EXTANT_SWITCH) {
+		struct wiphy_extant_profile *weprof;
+		nl_extant = nla_nest_start(msg, NL80211_ATTR_WIPHY_EXTANT);
+		if (!nl_extant)
+			goto nla_put_failure;
+
+		/* currently selected configuration profile */
+		if (dev->ops->get_extant) {
+			u32 extant;
+			int res;
+			res = dev->ops->get_extant(&dev->wiphy, &extant);
+			if (!res)
+				NLA_PUT_U32(msg,
+					NL80211_EXTANT_ATTR_STATE,
+					extant);
+		}
+
+		/* available profiles */
+		i=0;
+		nl_easps = nla_nest_start(msg, NL80211_EXTANT_ATTR_PROFILES);
+		for (weprof = dev->wiphy.extant; weprof->id >= 0; weprof++) {
+			nl_easp = nla_nest_start(msg, i);
+			if (!nl_easp)
+				goto nla_put_failure;
+			NLA_PUT_U32(msg, NL80211_EASP_ATTR_ID,
+				weprof->id);
+			NLA_PUT(msg, NL80211_EASP_ATTR_NAME,
+				strlen(weprof->name),
+				weprof->name);
+			NLA_PUT(msg, NL80211_EASP_ATTR_DESC,
+				strlen(weprof->desc),
+				weprof->desc);
+			nla_nest_end(msg, nl_easp);
+			i++;
+		}
+		nla_nest_end(msg, nl_easps);
+		nla_nest_end(msg, nl_extant);
+	}
+
 	if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
 				dev->wiphy.interface_modes))
 		goto nla_put_failure;
@@ -1374,6 +1431,20 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 			goto bad_res;
 	}
 
+	if (info->attrs[NL80211_ATTR_WIPHY_EXTANT_SELECT]) {
+		u32 extant;
+		if (!rdev->ops->set_extant) {
+			result = -EOPNOTSUPP;
+			goto bad_res;
+		}
+
+		extant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_EXTANT_SELECT]);
+
+		result = rdev->ops->set_extant(&rdev->wiphy, extant);
+		if (result)
+			goto bad_res;
+	}
+
 	changed = 0;
 
 	if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
-- 
1.7.4.1

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux