linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bruno Randolf <br1@einfach.org>
To: linville@tuxdriver.com
Cc: ath5k-devel@lists.ath5k.org, linux-wireless@vger.kernel.org
Subject: [PATCH v2 13/20] cfg80211: Add nl80211 antenna configuration
Date: Wed, 19 May 2010 10:31:48 +0900	[thread overview]
Message-ID: <20100519013147.22206.71360.stgit@tt-desk> (raw)
In-Reply-To: <20100519012528.22206.77550.stgit@tt-desk>

Allow setting TX and RX antenna configuration via nl80211/cfg80211.

The antenna configuration is defined as a bitmap of allowed antennas. This
bitmap is 8 bit at the moment, each bit representing one antenna. If multiple
antennas are selected, the driver may use diversity for receive and transmit.
This allows for a simple, yet flexible configuration interface for antennas,
while drivers may reject configurations they cannot support.

Signed-off-by: Bruno Randolf <br1@einfach.org>
---
 include/linux/nl80211.h |   12 +++++
 include/net/cfg80211.h  |    3 +
 net/wireless/nl80211.c  |  116 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index b7c77f9..46a2c76 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -341,6 +341,9 @@
  *	of any other interfaces, and other interfaces will again take
  *	precedence when they are used.
  *
+ * @NL80211_CMD_SET_ANTENNA: Set a bitmap of antennas to use.
+ * @NL80211_CMD_GET_ANTENNA: Get antenna configuration from driver.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -441,6 +444,9 @@ enum nl80211_commands {
 
 	NL80211_CMD_SET_CHANNEL,
 
+	NL80211_CMD_SET_ANTENNA,
+	NL80211_CMD_GET_ANTENNA,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -725,6 +731,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations
  *	connected to this BSS.
  *
+ * @NL80211_ATTR_ANTENNA_TX: Bitmap of antennas to use for transmitting.
+ * @NL80211_ATTR_ANTENNA_RX: Bitmap of antennas to use for receiving.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -882,6 +891,9 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_AP_ISOLATE,
 
+	NL80211_ATTR_ANTENNA_TX,
+	NL80211_ATTR_ANTENNA_RX,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b44a2e5..8861f40 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1176,6 +1176,9 @@ struct cfg80211_ops {
 	int	(*set_cqm_rssi_config)(struct wiphy *wiphy,
 				       struct net_device *dev,
 				       s32 rssi_thold, u32 rssi_hyst);
+
+	int	(*set_antenna)(struct wiphy *wiphy, u8 tx_ant, u8 rx_ant);
+	int	(*get_antenna)(struct wiphy *wiphy, u8 *tx_ant, u8 *rx_ant);
 };
 
 /*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index aaa1aad..29998e0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -153,6 +153,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 	[NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
 	[NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
 	[NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
+	[NL80211_ATTR_ANTENNA_TX] = { .type = NLA_U8 },
+	[NL80211_ATTR_ANTENNA_RX] = { .type = NLA_U8 },
 };
 
 /* policy for the attributes */
@@ -590,6 +592,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 		NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
 	}
 	CMD(set_channel, SET_CHANNEL);
+	CMD(set_antenna, SET_ANTENNA);
+	CMD(get_antenna, GET_ANTENNA);
 
 #undef CMD
 
@@ -4963,6 +4967,106 @@ out:
 	return err;
 }
 
+static int nl80211_set_antenna(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev;
+	int res;
+	u8 rx_ant = 0, tx_ant = 0;
+
+	if (!info->attrs[NL80211_ATTR_WIPHY] ||
+	    !info->attrs[NL80211_ATTR_ANTENNA_TX] ||
+	    !info->attrs[NL80211_ATTR_ANTENNA_RX]) {
+		return -EINVAL;
+	}
+
+	tx_ant = nla_get_u8(info->attrs[NL80211_ATTR_ANTENNA_TX]);
+	rx_ant = nla_get_u8(info->attrs[NL80211_ATTR_ANTENNA_RX]);
+
+	rtnl_lock();
+
+	rdev = cfg80211_get_dev_from_info(info);
+	if (IS_ERR(rdev)) {
+		res = -ENODEV;
+		goto unlock_rtnl;
+	}
+
+	if (!rdev->ops->set_antenna) {
+		res = -EOPNOTSUPP;
+		goto unlock_rdev;
+	}
+
+	res = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
+
+ unlock_rdev:
+	cfg80211_unlock_rdev(rdev);
+
+ unlock_rtnl:
+	rtnl_unlock();
+	return res;
+}
+
+static int nl80211_get_antenna(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev;
+	struct sk_buff *msg;
+	void *hdr;
+	int res;
+	u8 tx_ant, rx_ant;
+
+	if (!info->attrs[NL80211_ATTR_WIPHY])
+		return -EINVAL;
+
+	rtnl_lock();
+
+	rdev = cfg80211_get_dev_from_info(info);
+	if (IS_ERR(rdev)) {
+		res = -ENODEV;
+		goto unlock_rtnl;
+	}
+
+	if (!rdev->ops->get_antenna) {
+		res = -EOPNOTSUPP;
+		goto unlock_rdev;
+	}
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg) {
+		res = -ENOMEM;
+		goto unlock_rdev;
+	}
+
+	hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+			     NL80211_CMD_GET_ANTENNA);
+	if (!hdr) {
+		res = -ENOMEM;
+		goto free_msg;
+	}
+
+	res = rdev->ops->get_antenna(&rdev->wiphy, &tx_ant, &rx_ant);
+	if (res)
+		goto free_msg;
+
+	NLA_PUT_U8(msg, NL80211_ATTR_ANTENNA_TX, tx_ant);
+	NLA_PUT_U8(msg, NL80211_ATTR_ANTENNA_RX, rx_ant);
+
+	genlmsg_end(msg, hdr);
+	res = genlmsg_reply(msg, info);
+	goto unlock_rdev;
+
+ nla_put_failure:
+	res = -ENOBUFS;
+
+ free_msg:
+	nlmsg_free(msg);
+
+ unlock_rdev:
+	cfg80211_unlock_rdev(rdev);
+
+ unlock_rtnl:
+	rtnl_unlock();
+	return res;
+}
+
 static struct genl_ops nl80211_ops[] = {
 	{
 		.cmd = NL80211_CMD_GET_WIPHY,
@@ -5279,6 +5383,18 @@ static struct genl_ops nl80211_ops[] = {
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
 	},
+	{
+		.cmd = NL80211_CMD_SET_ANTENNA,
+		.doit = nl80211_set_antenna,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = NL80211_CMD_GET_ANTENNA,
+		.doit = nl80211_get_antenna,
+		.policy = nl80211_policy,
+		/* can be retrieved by unprivileged users */
+	},
 };
 
 static struct genl_multicast_group nl80211_mlme_mcgrp = {


  parent reply	other threads:[~2010-05-19  1:33 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-19  1:30 [PATCH v2 00/20] pending ath5k + antenna patches Bruno Randolf
2010-05-19  1:30 ` [PATCH v2 01/20] ath5k: add debugfs file for queue debugging Bruno Randolf
2010-05-19  1:30 ` [PATCH v2 02/20] ath5k: wake queues on reset Bruno Randolf
2010-05-20 12:51   ` [ath5k-devel] " Nick Kossifidis
2010-05-19  1:30 ` [PATCH v2 03/20] ath5k: initialize calibration timers Bruno Randolf
2010-05-20 12:48   ` Nick Kossifidis
2010-05-19  1:31 ` [PATCH v2 04/20] ath5k: move noise floor calibration into tasklet Bruno Randolf
2010-05-20 12:50   ` Nick Kossifidis
2010-05-19  1:31 ` [PATCH v2 05/20] ath5k: Stop queues only for NF calibration Bruno Randolf
2010-05-20 12:52   ` Nick Kossifidis
2010-05-19  1:31 ` [PATCH v2 06/20] ath5k: run NF calibration only every 60 seconds Bruno Randolf
2010-05-19  1:31 ` [PATCH v2 07/20] ath5k: remove ATH_TRACE macro Bruno Randolf
2010-05-20 12:56   ` Nick Kossifidis
2010-05-19  1:31 ` [PATCH v2 08/20] ath5k: clarify logic when to enable spur mitigation filter Bruno Randolf
2010-05-19  1:31 ` [PATCH v2 09/20] ath5k: use ath5k_softc as driver data Bruno Randolf
2010-05-19  1:31 ` [PATCH v2 10/20] ath5k: add sysfs files for ANI parameters Bruno Randolf
2010-05-20 12:58   ` Nick Kossifidis
2010-05-19  1:31 ` [PATCH v2 11/20] ath5k: always calculate ANI listen time Bruno Randolf
2010-05-20 12:59   ` Nick Kossifidis
2010-05-19  1:31 ` [PATCH v2 12/20] ath5k: print error message if ANI levels are out of range Bruno Randolf
2010-05-19  1:31 ` Bruno Randolf [this message]
2010-05-19 17:07   ` [PATCH v2 13/20] cfg80211: Add nl80211 antenna configuration Luis R. Rodriguez
2010-05-20  0:35     ` Bruno Randolf
2010-05-20  0:51       ` [ath5k-devel] " Luis R. Rodriguez
2010-05-20  1:12         ` Bruno Randolf
2010-05-20  1:26           ` Luis R. Rodriguez
2010-05-20  2:21             ` Bruno Randolf
2010-05-20  5:17               ` Luis R. Rodriguez
2010-05-20  5:36                 ` Bruno Randolf
2010-05-20  6:43                   ` Luis R. Rodriguez
2010-05-20 22:02                     ` David Quan
2010-05-20 22:05                     ` Luis R. Rodriguez
2010-05-20 22:14                       ` Sam Ng
2010-05-20 22:24                         ` Luis R. Rodriguez
2010-05-21  1:59                       ` Bruno Randolf
2010-05-21 17:11                         ` Luis R. Rodriguez
2010-05-21 19:10                           ` Felix Fietkau
2010-05-21 20:28                             ` Luis R. Rodriguez
2010-05-24  0:45                           ` Bruno Randolf
2010-05-24  9:15                             ` RHS Linux User
2010-06-04 19:30   ` John W. Linville
2010-06-04 21:21     ` [ath5k-devel] " Luis R. Rodriguez
2010-06-04 21:53       ` Luis R. Rodriguez
2010-06-07  3:45       ` Bruno Randolf
2010-05-19  1:31 ` [PATCH v2 14/20] mac80211: Add " Bruno Randolf
2010-05-19  1:31 ` [PATCH v2 15/20] ath5k: Add support for " Bruno Randolf
2010-05-19  1:32 ` [PATCH v2 16/20] ath5k: remove setting ANI and antenna thru debugfs files Bruno Randolf
2010-05-19  1:32 ` [PATCH v2 17/20] ath5k: fix NULL pointer in antenna configuration Bruno Randolf
2010-05-19  1:32 ` [PATCH v2 18/20] ath5k: update AR5K_PHY_RESTART_DIV_GC values to match masks Bruno Randolf
2010-05-20 12:54   ` Nick Kossifidis
2010-05-19  1:32 ` [PATCH v2 19/20] ath5k: new function for setting the antenna switch table Bruno Randolf
2010-05-19  1:32 ` [PATCH v2 20/20] ath5k: no need to save/restore the default antenna Bruno Randolf
2010-05-19  1:41 ` [PATCH v2 00/20] pending ath5k + antenna patches Luis R. Rodriguez
2010-05-19 12:59 ` John W. Linville

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=20100519013147.22206.71360.stgit@tt-desk \
    --to=br1@einfach.org \
    --cc=ath5k-devel@lists.ath5k.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).