From: Daniel Golle <dgolle@allnet.de>
To: ath9k-devel@lists.ath9k.org
Subject: [ath9k-devel] [PATCH v0 1/6] support for antenna configuration profiles
Date: Mon, 14 Nov 2011 14:02:02 +0100 [thread overview]
Message-ID: <20111114130202.GA3106@localhost> (raw)
This introduces support for configuring an external antenna switch from
userspace using the nl80211 API.
Inspired by the previous discussion this is done by letting the user choose
from a set of pre-defined values (=profiles).
Supplying both, a profile name and a verbose description via platform-data
might be overkill. Maybe just a profile name is enough and have verbose
descriptions either in iw of libiwinfo?
Signed-off-by: Daniel Golle <dgolle@allnet.de>
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1109,6 +1109,12 @@ enum nl80211_commands {
* %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
* used for asking the driver to perform a TDLS operation.
*
+ * @NL80211_ATTR_WIPHY_EXTANT_SUPPORT: Flag indicating support for an external
+ * antenna switch.
+ * @NL80211_ATTR_WIPHY_EXTANT_STATE: Currently selected antenna switch profile.
+ * @NL80211_ATTR_WIPHY_EXTANT_SUPP_PROFILES: Nested attribute containing names
+ * and descriptions of the supported antenna switch configuration profiles.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1337,6 +1343,10 @@ enum nl80211_attrs {
NL80211_ATTR_TDLS_SUPPORT,
NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+ NL80211_ATTR_WIPHY_EXTANT_SUPPORT,
+ NL80211_ATTR_WIPHY_EXTANT_STATE,
+ NL80211_ATTR_WIPHY_EXTANT_SUPP_PROFILES,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1632,6 +1644,26 @@ enum nl80211_mpath_info {
NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
};
+
+/**
+ * enum nl80211_easp_attr - external antenna switch configuration profiles
+ * @__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
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -197,6 +197,9 @@ static const struct nla_policy nl80211_p
[NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
[NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
[NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
+ [NL80211_ATTR_WIPHY_EXTANT_SUPPORT] = { .type = NLA_FLAG },
+ [NL80211_ATTR_WIPHY_EXTANT_STATE] = { .type = NLA_U32 },
+ [NL80211_ATTR_WIPHY_EXTANT_SUPP_PROFILES] = { .type = NLA_NESTED },
};
/* policy for the key attributes */
@@ -245,6 +248,17 @@ nl80211_match_policy[NL80211_SCHED_SCAN_
.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)
{
@@ -692,6 +706,7 @@ static int nl80211_send_wiphy(struct sk_
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_cmds;
enum ieee80211_band band;
struct ieee80211_channel *chan;
@@ -743,6 +758,8 @@ static int nl80211_send_wiphy(struct sk_
NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT);
if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)
NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP);
+ if (dev->wiphy.flags & WIPHY_FLAG_HAS_EXTANT_SWITCH)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_WIPHY_EXTANT_SUPPORT);
NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -770,6 +787,36 @@ static int nl80211_send_wiphy(struct sk_
}
}
+/* currently selected external antenna switch configuration profile */
+ if ((dev->wiphy.flags & WIPHY_FLAG_HAS_EXTANT_SWITCH) && dev->ops->get_extant) {
+ u32 extant;
+ int res;
+ res = dev->ops->get_extant(&dev->wiphy, &extant);
+ if (!res) {
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_EXTANT_STATE, extant);
+ }
+ }
+
+/* available external antenna switch configuration profiles */
+ if (dev->wiphy.flags & WIPHY_FLAG_HAS_EXTANT_SWITCH) {
+ nl_easps = nla_nest_start(msg, NL80211_ATTR_WIPHY_EXTANT_SUPP_PROFILES);
+ for (i = 0; dev->wiphy.extant[i].id >= 0; i++) {
+ nl_easp = nla_nest_start(msg, i);
+ if (!nl_easp)
+ goto nla_put_failure;
+ NLA_PUT_U32(msg, NL80211_EASP_ATTR_ID,
+ dev->wiphy.extant[i].id);
+ NLA_PUT(msg, NL80211_EASP_ATTR_NAME,
+ strlen(dev->wiphy.extant[i].name),
+ dev->wiphy.extant[i].name);
+ NLA_PUT(msg, NL80211_EASP_ATTR_DESC,
+ strlen(dev->wiphy.extant[i].desc),
+ dev->wiphy.extant[i].desc);
+ nla_nest_end(msg, nl_easp);
+ }
+ nla_nest_end(msg, nl_easps);
+ }
+
if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
dev->wiphy.interface_modes))
goto nla_put_failure;
@@ -1335,6 +1382,17 @@ static int nl80211_set_wiphy(struct sk_b
goto bad_res;
}
+ if (info->attrs[NL80211_ATTR_WIPHY_EXTANT_STATE]) {
+ u32 extant;
+ if ((!rdev->ops->set_extant) ||
+ (!rdev->wiphy.extant)) {
+ result = -EOPNOTSUPP;
+ goto bad_res;
+ }
+ extant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_EXTANT_STATE]);
+ result = rdev->ops->set_extant(&rdev->wiphy, extant);
+ }
+
changed = 0;
if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1435,6 +1435,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.
@@ -1613,6 +1616,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);
@@ -1688,6 +1694,8 @@ struct cfg80211_ops {
* teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT
* command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be
* used for asking the driver/firmware to perform a TDLS operation.
+ * @WIPHY_FLAG_HAS_EXTANT_SWITCH: The device got a configurable external antenna
+ * switch.
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1706,6 +1714,7 @@ enum wiphy_flags {
WIPHY_FLAG_AP_UAPSD = BIT(14),
WIPHY_FLAG_SUPPORTS_TDLS = BIT(15),
WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16),
+ WIPHY_FLAG_HAS_EXTANT_SWITCH = BIT(17),
};
/**
@@ -1833,6 +1842,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()
@@ -1912,6 +1936,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 external antenna switch configurations.
+ *
* @max_remain_on_channel_duration: Maximum time a remain-on-channel operation
* may request, if implemented.
*
@@ -1972,6 +1998,8 @@ struct wiphy {
u32 available_antennas_tx;
u32 available_antennas_rx;
+ 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
reply other threads:[~2011-11-14 13:02 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111114130202.GA3106@localhost \
--to=dgolle@allnet.de \
--cc=ath9k-devel@lists.ath9k.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.