diff options
-rw-r--r-- | include/net/cfg80211.h | 12 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 17 |
2 files changed, 19 insertions, 10 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 924d60366233..bcc9f448ec4e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1482,8 +1482,13 @@ struct ieee80211_txrx_stypes { | |||
1482 | * transmitted through nl80211, points to an array indexed by interface | 1482 | * transmitted through nl80211, points to an array indexed by interface |
1483 | * type | 1483 | * type |
1484 | * | 1484 | * |
1485 | * @available_antennas: bitmap of antennas which are available to configure. | 1485 | * @available_antennas_tx: bitmap of antennas which are available to be |
1486 | * antenna configuration commands will be rejected unless this is set. | 1486 | * configured as TX antennas. Antenna configuration commands will be |
1487 | * rejected unless this or @available_antennas_rx is set. | ||
1488 | * | ||
1489 | * @available_antennas_rx: bitmap of antennas which are available to be | ||
1490 | * configured as RX antennas. Antenna configuration commands will be | ||
1491 | * rejected unless this or @available_antennas_tx is set. | ||
1487 | * | 1492 | * |
1488 | * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation | 1493 | * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation |
1489 | * may request, if implemented. | 1494 | * may request, if implemented. |
@@ -1528,7 +1533,8 @@ struct wiphy { | |||
1528 | 1533 | ||
1529 | u8 max_num_pmkids; | 1534 | u8 max_num_pmkids; |
1530 | 1535 | ||
1531 | u32 available_antennas; | 1536 | u32 available_antennas_tx; |
1537 | u32 available_antennas_rx; | ||
1532 | 1538 | ||
1533 | /* If multiple wiphys are registered and you're handed e.g. | 1539 | /* If multiple wiphys are registered and you're handed e.g. |
1534 | * a regular netdev with assigned ieee80211_ptr, you won't | 1540 | * a regular netdev with assigned ieee80211_ptr, you won't |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6a5d6fa11e46..8d2f5f8d8080 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -605,7 +605,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
605 | if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) | 605 | if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) |
606 | NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); | 606 | NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); |
607 | 607 | ||
608 | if (dev->wiphy.available_antennas && dev->ops->get_antenna) { | 608 | if ((dev->wiphy.available_antennas_tx || |
609 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { | ||
609 | u32 tx_ant = 0, rx_ant = 0; | 610 | u32 tx_ant = 0, rx_ant = 0; |
610 | int res; | 611 | int res; |
611 | res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); | 612 | res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); |
@@ -1107,7 +1108,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1107 | if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && | 1108 | if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && |
1108 | info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { | 1109 | info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { |
1109 | u32 tx_ant, rx_ant; | 1110 | u32 tx_ant, rx_ant; |
1110 | if (!rdev->wiphy.available_antennas || !rdev->ops->set_antenna) { | 1111 | if ((!rdev->wiphy.available_antennas_tx && |
1112 | !rdev->wiphy.available_antennas_rx) || | ||
1113 | !rdev->ops->set_antenna) { | ||
1111 | result = -EOPNOTSUPP; | 1114 | result = -EOPNOTSUPP; |
1112 | goto bad_res; | 1115 | goto bad_res; |
1113 | } | 1116 | } |
@@ -1116,15 +1119,15 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1116 | rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); | 1119 | rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); |
1117 | 1120 | ||
1118 | /* reject antenna configurations which don't match the | 1121 | /* reject antenna configurations which don't match the |
1119 | * available antenna mask, except for the "all" mask */ | 1122 | * available antenna masks, except for the "all" mask */ |
1120 | if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas)) || | 1123 | if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) || |
1121 | (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas))) { | 1124 | (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) { |
1122 | result = -EINVAL; | 1125 | result = -EINVAL; |
1123 | goto bad_res; | 1126 | goto bad_res; |
1124 | } | 1127 | } |
1125 | 1128 | ||
1126 | tx_ant = tx_ant & rdev->wiphy.available_antennas; | 1129 | tx_ant = tx_ant & rdev->wiphy.available_antennas_tx; |
1127 | rx_ant = rx_ant & rdev->wiphy.available_antennas; | 1130 | rx_ant = rx_ant & rdev->wiphy.available_antennas_rx; |
1128 | 1131 | ||
1129 | result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); | 1132 | result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant); |
1130 | if (result) | 1133 | if (result) |