aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/cfg80211.h5
-rw-r--r--net/wireless/nl80211.c15
2 files changed, 18 insertions, 2 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0d5979924be3..4d5acb013636 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1468,6 +1468,9 @@ struct ieee80211_txrx_stypes {
1468 * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or 1468 * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or
1469 * transmitted through nl80211, points to an array indexed by interface 1469 * transmitted through nl80211, points to an array indexed by interface
1470 * type 1470 * type
1471 *
1472 * @available_antennas: bitmap of antennas which are available to configure.
1473 * antenna configuration commands will be rejected unless this is set.
1471 */ 1474 */
1472struct wiphy { 1475struct wiphy {
1473 /* assign these fields before you register the wiphy */ 1476 /* assign these fields before you register the wiphy */
@@ -1507,6 +1510,8 @@ struct wiphy {
1507 1510
1508 u8 max_num_pmkids; 1511 u8 max_num_pmkids;
1509 1512
1513 u32 available_antennas;
1514
1510 /* If multiple wiphys are registered and you're handed e.g. 1515 /* If multiple wiphys are registered and you're handed e.g.
1511 * a regular netdev with assigned ieee80211_ptr, you won't 1516 * a regular netdev with assigned ieee80211_ptr, you won't
1512 * know whether it points to a wiphy your driver has registered 1517 * know whether it points to a wiphy your driver has registered
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,
548 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) 548 if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
549 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); 549 NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE);
550 550
551 if (dev->ops->get_antenna) { 551 if (dev->wiphy.available_antennas && dev->ops->get_antenna) {
552 u32 tx_ant = 0, rx_ant = 0; 552 u32 tx_ant = 0, rx_ant = 0;
553 int res; 553 int res;
554 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); 554 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)
1046 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && 1046 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
1047 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { 1047 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
1048 u32 tx_ant, rx_ant; 1048 u32 tx_ant, rx_ant;
1049 if (!rdev->ops->set_antenna) { 1049 if (!rdev->wiphy.available_antennas || !rdev->ops->set_antenna) {
1050 result = -EOPNOTSUPP; 1050 result = -EOPNOTSUPP;
1051 goto bad_res; 1051 goto bad_res;
1052 } 1052 }
@@ -1054,6 +1054,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1054 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); 1054 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
1055 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); 1055 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
1056 1056
1057 /* reject antenna configurations which don't match the
1058 * available antenna mask, except for the "all" mask */
1059 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas)) ||
1060 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas))) {
1061 result = -EINVAL;
1062 goto bad_res;
1063 }
1064
1065 tx_ant = tx_ant & rdev->wiphy.available_antennas;
1066 rx_ant = rx_ant & rdev->wiphy.available_antennas;
1067
1057 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); 1068 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
1058 if (result) 1069 if (result)
1059 goto bad_res; 1070 goto bad_res;