[PATCH] hostapd: take configured antenna set into consideration
greearb at candelatech.com
greearb at candelatech.com
Wed Dec 9 12:20:33 PST 2015
From: Ben Greear <greearb at candelatech.com>
If user has configured TX antennas to be less than what
hardware advertises, the MCS reported by hardware will
be too large. So, remove MCS sets accordingly.
Signed-off-by: Ben Greear <greearb at candelatech.com>
---
src/ap/ieee802_11_ht.c | 21 +++++++++++++++++++++
src/ap/ieee802_11_vht.c | 19 +++++++++++++++++++
src/drivers/driver.h | 10 ++++++++++
src/drivers/driver_nl80211_capa.c | 32 ++++++++++++++++++++++++++++++--
4 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c
index 11fde2a..1aebb3a 100644
--- a/src/ap/ieee802_11_ht.c
+++ b/src/ap/ieee802_11_ht.c
@@ -25,6 +25,7 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
{
struct ieee80211_ht_capabilities *cap;
u8 *pos = eid;
+ int i;
if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode ||
hapd->conf->disable_11n)
@@ -40,6 +41,26 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
os_memcpy(cap->supported_mcs_set, hapd->iface->current_mode->mcs_set,
16);
+ /* Disable all MCS rates that are out of the configured
+ nss (antenna) range. */
+ if (hapd->iface->current_mode->conf_tx_ant &&
+ hapd->iface->current_mode->conf_rx_ant) {
+ int msk = hapd->iface->current_mode->conf_tx_ant &
+ hapd->iface->current_mode->conf_rx_ant;
+ for (i = 7; i >= 0; i--) {
+ if (msk & (1<<i))
+ break;
+ if (cap->supported_mcs_set[i]) {
+ wpa_printf(MSG_DEBUG, "Decreasing MCS set due to configured antennas:"
+ " conf-tx-ant: 0x%x conf-rx-ant: 0x%x mcs-set for nss: %i",
+ hapd->iface->current_mode->conf_tx_ant,
+ hapd->iface->current_mode->conf_rx_ant,
+ i + 1);
+ cap->supported_mcs_set[i] = 0;
+ }
+ }
+ }
+
/* TODO: ht_extended_capabilities (now fully disabled) */
/* TODO: tx_bf_capability_info (now fully disabled) */
/* TODO: asel_capabilities (now fully disabled) */
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c
index 5bf1b5d..cdd5f55 100644
--- a/src/ap/ieee802_11_vht.c
+++ b/src/ap/ieee802_11_vht.c
@@ -24,6 +24,7 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid)
struct ieee80211_vht_capabilities *cap;
struct hostapd_hw_modes *mode = hapd->iface->current_mode;
u8 *pos = eid;
+ int i;
if (!mode)
return eid;
@@ -52,6 +53,24 @@ u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid)
/* Supported MCS set comes from hw */
os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8);
+ /* Disable all MCS rates that are out of the configured
+ nss (antenna) range. */
+ if (mode->conf_tx_ant) {
+ for (i = 7; i > 0; i--) {
+ if (mode->conf_tx_ant & (1 << (i - 1)))
+ break;
+ cap->vht_supported_mcs_set.tx_map |= (0x3 << i);
+ }
+ }
+
+ if (mode->conf_rx_ant) {
+ for (i = 7; i > 0; i--) {
+ if (mode->conf_rx_ant & (1 << (i - 1)))
+ break;
+ cap->vht_supported_mcs_set.rx_map |= (0x3 << i);
+ }
+ }
+
pos += sizeof(*cap);
return pos;
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 9413733..e58c112 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -155,6 +155,16 @@ struct hostapd_hw_modes {
u16 ht_capab;
/**
+ * conf_tx_ant - Configured TX Antenna mask. 0 means not reported by driver
+ */
+ int conf_tx_ant;
+
+ /**
+ * conf_rx_ant - Configured RX Antenna mask. 0 means not reported by driver
+ */
+ int 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 4cf3123..9008a50 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -933,6 +933,8 @@ struct phy_info_arg {
u16 *num_modes;
struct hostapd_hw_modes *modes;
int last_mode, last_chan_idx;
+ int conf_tx_ant;
+ int conf_rx_ant;
};
static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
@@ -1115,7 +1117,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;
@@ -1152,6 +1155,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);
@@ -1183,14 +1188,35 @@ static int phy_info_handler(struct nl_msg *msg, void *arg)
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])
+ wpa_printf(MSG_DEBUG, "Available Antennas: TX %#x RX %#x",
+ nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX]),
+ nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX]));
+
+ if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
+ tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+ wpa_printf(MSG_DEBUG, "Configured Antennas: TX %#x RX %#x",
+ nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]),
+ nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]));
+ phy_info->conf_tx_ant = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]);
+ phy_info->conf_rx_ant = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_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;
@@ -1566,6 +1592,8 @@ nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
.num_modes = num_modes,
.modes = NULL,
.last_mode = -1,
+ .conf_tx_ant = 0,
+ .conf_rx_ant = 0,
};
*num_modes = 0;
--
2.1.0
More information about the Hostap
mailing list