diff options
-rw-r--r-- | include/net/cfg80211.h | 5 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 15 |
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 | */ |
1472 | struct wiphy { | 1475 | struct 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; |