Commit a7ffac95 authored by Bruno Randolf's avatar Bruno Randolf Committed by John W. Linville

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: default avatarBruno 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: default avatarJohn W. Linville <linville@tuxdriver.com>
parent a08e7ade
...@@ -1468,6 +1468,9 @@ struct ieee80211_txrx_stypes { ...@@ -1468,6 +1468,9 @@ struct ieee80211_txrx_stypes {
* @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or
* transmitted through nl80211, points to an array indexed by interface * transmitted through nl80211, points to an array indexed by interface
* type * type
*
* @available_antennas: bitmap of antennas which are available to configure.
* antenna configuration commands will be rejected unless this is set.
*/ */
struct wiphy { struct wiphy {
/* assign these fields before you register the wiphy */ /* assign these fields before you register the wiphy */
...@@ -1507,6 +1510,8 @@ struct wiphy { ...@@ -1507,6 +1510,8 @@ struct wiphy {
u8 max_num_pmkids; u8 max_num_pmkids;
u32 available_antennas;
/* If multiple wiphys are registered and you're handed e.g. /* If multiple wiphys are registered and you're handed e.g.
* a regular netdev with assigned ieee80211_ptr, you won't * a regular netdev with assigned ieee80211_ptr, you won't
* know whether it points to a wiphy your driver has registered * know whether it points to a wiphy your driver has registered
......
...@@ -548,7 +548,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, ...@@ -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) if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL)
NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); 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; u32 tx_ant = 0, rx_ant = 0;
int res; int res;
res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant); 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,7 +1046,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
u32 tx_ant, rx_ant; u32 tx_ant, rx_ant;
if (!rdev->ops->set_antenna) { if (!rdev->wiphy.available_antennas || !rdev->ops->set_antenna) {
result = -EOPNOTSUPP; result = -EOPNOTSUPP;
goto bad_res; goto bad_res;
} }
...@@ -1054,6 +1054,17 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) ...@@ -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]); tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); 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); result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
if (result) if (result)
goto bad_res; goto bad_res;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment