From cdeea70f59d0f84d1f5a9f51502a8c5aa0d69bcb Mon Sep 17 00:00:00 2001 From: Sergey Matyukevich Date: Tue, 30 Oct 2018 13:16:47 +0000 Subject: [PATCH] wpa_supplicant: Allow overriding HT STBC capabilities Allow user to override STBC configuration for Rx and Tx spatial streams. Add new configuration options to test for HT capability overrides. Signed-off-by: Sergey Matyukevich --- wpa_supplicant/config.c | 4 +++ wpa_supplicant/config_file.c | 2 ++ wpa_supplicant/config_ssid.h | 18 ++++++++++ wpa_supplicant/wpa_cli.c | 2 +- wpa_supplicant/wpa_supplicant.c | 54 ++++++++++++++++++++++++++++++ wpa_supplicant/wpa_supplicant.conf | 14 ++++++++ 6 files changed, 93 insertions(+), 1 deletion(-) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 0f71e9fb6..46792e7f0 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2331,6 +2331,8 @@ static const struct parse_data ssid_fields[] = { { INT_RANGE(disable_sgi, 0, 1) }, { INT_RANGE(disable_ldpc, 0, 1) }, { INT_RANGE(ht40_intolerant, 0, 1) }, + { INT_RANGE(tx_stbc, -1, 1) }, + { INT_RANGE(rx_stbc, -1, 3) }, { INT_RANGE(disable_max_amsdu, -1, 1) }, { INT_RANGE(ampdu_factor, -1, 3) }, { INT_RANGE(ampdu_density, -1, 7) }, @@ -2851,6 +2853,8 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) ssid->disable_ht40 = DEFAULT_DISABLE_HT40; ssid->disable_sgi = DEFAULT_DISABLE_SGI; ssid->disable_ldpc = DEFAULT_DISABLE_LDPC; + ssid->tx_stbc = DEFAULT_TX_STBC; + ssid->rx_stbc = DEFAULT_RX_STBC; ssid->disable_max_amsdu = DEFAULT_DISABLE_MAX_AMSDU; ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR; ssid->ampdu_density = DEFAULT_AMPDU_DENSITY; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 8bc7a35fd..91cb4482d 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -895,6 +895,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) INT_DEF(disable_sgi, DEFAULT_DISABLE_SGI); INT_DEF(disable_ldpc, DEFAULT_DISABLE_LDPC); INT(ht40_intolerant); + INT_DEF(tx_stbc, DEFAULT_TX_STBC); + INT_DEF(rx_stbc, DEFAULT_RX_STBC); INT_DEF(disable_max_amsdu, DEFAULT_DISABLE_MAX_AMSDU); INT_DEF(ampdu_factor, DEFAULT_AMPDU_FACTOR); INT_DEF(ampdu_density, DEFAULT_AMPDU_DENSITY); diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 5205b0746..deba9d973 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -33,6 +33,8 @@ #define DEFAULT_DISABLE_HT40 0 #define DEFAULT_DISABLE_SGI 0 #define DEFAULT_DISABLE_LDPC 0 +#define DEFAULT_TX_STBC -1 /* no change */ +#define DEFAULT_RX_STBC -1 /* no change */ #define DEFAULT_DISABLE_MAX_AMSDU -1 /* no change */ #define DEFAULT_AMPDU_FACTOR -1 /* no change */ #define DEFAULT_AMPDU_DENSITY -1 /* no change */ @@ -693,6 +695,22 @@ struct wpa_ssid { * By default (empty string): Use whatever the OS has configured. */ char *ht_mcs; + + /** + * tx_stbc - Indicate STBC support for TX streams + * + * Value: -1..1, by default (-1): use whatever the OS or card has + * configured. See IEEE Std 802.11-2016, 9.4.2.56.2. + */ + int tx_stbc; + + /** + * rx_stbc - Indicate STBC support for RX streams + * + * Value: -1..3, by default (-1): use whatever the OS or card has + * configured. See IEEE Std 802.11-2016, 9.4.2.56.2. + */ + int rx_stbc; #endif /* CONFIG_HT_OVERRIDES */ #ifdef CONFIG_VHT_OVERRIDES diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 8d6afb9c5..8e64d0d05 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -1412,7 +1412,7 @@ static const char *network_fields[] = { #ifdef CONFIG_HT_OVERRIDES "disable_ht", "disable_ht40", "disable_sgi", "disable_ldpc", "ht40_intolerant", "disable_max_amsdu", "ampdu_factor", - "ampdu_density", "ht_mcs", + "ampdu_density", "ht_mcs", "rx_stbc", "tx_stbc", #endif /* CONFIG_HT_OVERRIDES */ #ifdef CONFIG_VHT_OVERRIDES "disable_vht", "vht_capa", "vht_capa_mask", "vht_rx_mcs_nss_1", diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 9beb4e575..5d511043c 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -4511,6 +4511,58 @@ static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s, } +static int wpa_set_tx_stbc(struct wpa_supplicant *wpa_s, + struct ieee80211_ht_capabilities *htcaps, + struct ieee80211_ht_capabilities *htcaps_mask, + int tx_stbc) +{ + le16 msk = host_to_le16(HT_CAP_INFO_TX_STBC); + + wpa_msg(wpa_s, MSG_DEBUG, "set_tx_stbc: %d", tx_stbc); + + if (tx_stbc == -1) + return 0; + + if (tx_stbc < 0 || tx_stbc > 1) { + wpa_msg(wpa_s, MSG_ERROR, + "tx_stbc: %d out of range. Must be 0-1 or -1", tx_stbc); + return -EINVAL; + } + + htcaps_mask->ht_capabilities_info |= msk; + htcaps->ht_capabilities_info &= ~msk; + htcaps->ht_capabilities_info |= (tx_stbc << 7) & msk; + + return 0; +} + + +static int wpa_set_rx_stbc(struct wpa_supplicant *wpa_s, + struct ieee80211_ht_capabilities *htcaps, + struct ieee80211_ht_capabilities *htcaps_mask, + int rx_stbc) +{ + le16 msk = host_to_le16(HT_CAP_INFO_RX_STBC_MASK); + + wpa_msg(wpa_s, MSG_DEBUG, "set_rx_stbc: %d", rx_stbc); + + if (rx_stbc == -1) + return 0; + + if (rx_stbc < 0 || rx_stbc > 3) { + wpa_msg(wpa_s, MSG_ERROR, + "rx_stbc: %d out of range. Must be 0-3 or -1", rx_stbc); + return -EINVAL; + } + + htcaps_mask->ht_capabilities_info |= msk; + htcaps->ht_capabilities_info &= ~msk; + htcaps->ht_capabilities_info |= (rx_stbc << 8) & msk; + + return 0; +} + + void wpa_supplicant_apply_ht_overrides( struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_driver_associate_params *params) @@ -4535,6 +4587,8 @@ void wpa_supplicant_apply_ht_overrides( wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40); wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi); wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc); + wpa_set_rx_stbc(wpa_s, htcaps, htcaps_mask, ssid->rx_stbc); + wpa_set_tx_stbc(wpa_s, htcaps, htcaps_mask, ssid->tx_stbc); if (ssid->ht40_intolerant) { le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT); diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index ffe5d2e0c..57d6cbf1d 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -1388,6 +1388,20 @@ fast_reauth=1 # Treated as hint by the kernel. # -1 = Do not make any changes. # 0-3 = Set AMPDU density (aka factor) to specified value. +# +# tx_stbc: Allow overriding STBC support for TX streams +# Value: 0-1, see IEEE Std 802.11-2016, 9.4.2.56.2. +# -1 = Do not make any changes (default) +# 0 = Set if not supported +# 1 = Set if supported +# +# rx_stbc: Allow overriding STBC support for RX streams +# Value: 0-3, see IEEE Std 802.11-2016, 9.4.2.56.2. +# -1 = Do not make any changes (default) +# 0 = Set if not supported +# 1 = Set for support of one spatial stream +# 2 = Set for support of one and two spatial streams +# 3 = Set for support of one, two and three spatial streams # disable_vht: Whether VHT should be disabled. # 0 = VHT enabled (if AP supports it)