summaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorBruno Randolf <br1@einfach.org>2010-12-08 05:59:24 +0100
committerJohn W. Linville <linville@tuxdriver.com>2010-12-13 21:23:27 +0100
commita7ffac9591a2a0ee74c431396ae475a8d0caa51e (patch)
tree174134b89e490592003307263e6b3964d9a1eacf /net/wireless/nl80211.c
parentath9k: fix assumptions for idle calls on suspend/resume (diff)
downloadlinux-a7ffac9591a2a0ee74c431396ae475a8d0caa51e.tar.xz
linux-a7ffac9591a2a0ee74c431396ae475a8d0caa51e.zip
cfg80211: Add antenna availability information
Add a field to wiphy for the hardware to report the availble antennas for configuration. Only if this is set to something bigger than zero, will the anntenna configuration ops be executed. Allthough this could be a simple number of antennas, I defined it as a bitmap of antennas which are available for configuration, since it's more consistent with the rest of the antenna API and there could be cases where the hardware allows only configuration of certain antennas. As it does not make much of a difference in size or normal usage, I think it's better to be able to support this, in case the need arises. The antenna configuration is now also checked against the availabe antennas and rejected if it does not match. Signed-off-by: Bruno Randolf <br1@einfach.org> -- v3: always apply available antenna mask (for "all" antennas case). v2: reject antenna configurations which don't match the available antennas Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c3f80e565365..73a7f6d354c9 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -548,7 +548,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
- if (dev->ops->get_antenna) {
+ if (dev->wiphy.available_antennas && dev->ops->get_antenna) {
u32 tx_ant = 0, rx_ant = 0;
int res;
res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
@@ -1046,7 +1046,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
u32 tx_ant, rx_ant;
- if (!rdev->ops->set_antenna) {
+ if (!rdev->wiphy.available_antennas || !rdev->ops->set_antenna) {
result = -EOPNOTSUPP;
goto bad_res;
}
@@ -1054,6 +1054,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
+ /* reject antenna configurations which don't match the
+ * available antenna mask, except for the "all" mask */
+ if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas)) ||
+ (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas))) {
+ result = -EINVAL;
+ goto bad_res;
+ }
+
+ tx_ant = tx_ant & rdev->wiphy.available_antennas;
+ rx_ant = rx_ant & rdev->wiphy.available_antennas;
+
result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
if (result)
goto bad_res;