>From 06dbffa3c7be111e549a59dd5fad1fc8ba70b538 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Wed, 9 Dec 2015 12:20:33 -0800 Subject: [PATCH 1/3] nl80211: Fetch antenna configuration This makes the current antenna mask configuration available to hostapd. Signed-off-by: Ben Greear --- src/drivers/driver.h | 12 ++++++++++++ src/drivers/driver_nl80211_capa.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 6fd72c5..7dd4f9c 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -164,6 +164,18 @@ struct hostapd_hw_modes { u16 ht_capab; /** + * conf_tx_ant - Configured TX Antenna mask + * 0 means not reported by driver. + */ + u32 conf_tx_ant; + + /** + * conf_rx_ant - Configured RX Antenna mask + * 0 means not reported by driver + */ + u32 conf_rx_ant; + + /** * mcs_set - MCS (IEEE 802.11n) rate parameters */ u8 mcs_set[16]; diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index 8c3ba49..b28a494 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -989,6 +989,7 @@ struct phy_info_arg { struct hostapd_hw_modes *modes; int last_mode, last_chan_idx; int failed; + u32 conf_tx_ant, conf_rx_ant; }; static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa, @@ -1171,7 +1172,8 @@ static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb) } -static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band) +static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band, + struct hostapd_hw_modes **mode_used) { struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; struct hostapd_hw_modes *mode; @@ -1210,6 +1212,8 @@ static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band) } else mode = &phy_info->modes[*(phy_info->num_modes) - 1]; + *mode_used = mode; + nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band), nla_len(nl_band), NULL); @@ -1238,18 +1242,44 @@ static int phy_info_handler(struct nl_msg *msg, void *arg) struct phy_info_arg *phy_info = arg; struct nlattr *nl_band; int rem_band; + u32 tx, rx; nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX] && + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX]) { + tx = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX]); + rx = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX]); + wpa_printf(MSG_DEBUG, "Available Antennas: TX %#x RX %#x", + tx, rx); + } + + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] && + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) { + tx = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]); + rx = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]); + wpa_printf(MSG_DEBUG, "Configured Antennas: TX %#x RX %#x", + tx, rx); + phy_info->conf_tx_ant = tx; + phy_info->conf_rx_ant = rx; + } + if (!tb_msg[NL80211_ATTR_WIPHY_BANDS]) return NL_SKIP; nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) { - int res = phy_info_band(phy_info, nl_band); + struct hostapd_hw_modes *mode = NULL; + int res = phy_info_band(phy_info, nl_band, &mode); + if (res != NL_OK) return res; + + if (mode) { + mode->conf_tx_ant = phy_info->conf_tx_ant; + mode->conf_rx_ant = phy_info->conf_rx_ant; + } } return NL_SKIP; @@ -1652,6 +1682,8 @@ nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags) .modes = NULL, .last_mode = -1, .failed = 0, + .conf_tx_ant = 0, + .conf_rx_ant = 0, }; *num_modes = 0; -- 1.9.1