wpa_supplicant: allow overriding HT STBC capabilities

Message ID 20181030131640.14901-1-sergey.matyukevich.os@quantenna.com
State New
Headers show
Series
  • wpa_supplicant: allow overriding HT STBC capabilities
Related show

Commit Message

Sergey Matyukevich Oct. 30, 2018, 1:16 p.m.
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 <sergey.matyukevich.os@quantenna.com>
---
 tests/hwsim/test_ap_ht.py          |  2 +-
 tests/hwsim/wpasupplicant.py       |  3 ++-
 wpa_supplicant/config.c            |  4 +++
 wpa_supplicant/config_file.c       |  2 ++
 wpa_supplicant/config_ssid.h       | 16 ++++++++++++
 wpa_supplicant/wpa_cli.c           |  2 +-
 wpa_supplicant/wpa_supplicant.c    | 51 ++++++++++++++++++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant.conf | 14 +++++++++++
 8 files changed, 91 insertions(+), 3 deletions(-)

Patch

diff --git a/tests/hwsim/test_ap_ht.py b/tests/hwsim/test_ap_ht.py
index 11440ffaf..f3dc7eec6 100644
--- a/tests/hwsim/test_ap_ht.py
+++ b/tests/hwsim/test_ap_ht.py
@@ -848,7 +848,7 @@  def test_ap_require_ht(dev, apdev):
                    ht_mcs="0x01 00 00 00 00 00 00 00 00 00",
                    disable_max_amsdu="1", ampdu_factor="2",
                    ampdu_density="1", disable_ht40="1", disable_sgi="1",
-                   disable_ldpc="1")
+                   disable_ldpc="1", rx_stbc="2", tx_stbc="1")
 
 @remote_compatible
 def test_ap_require_ht_limited_rates(dev, apdev):
diff --git a/tests/hwsim/wpasupplicant.py b/tests/hwsim/wpasupplicant.py
index 78b5f6dc3..1a6cee01c 100644
--- a/tests/hwsim/wpasupplicant.py
+++ b/tests/hwsim/wpasupplicant.py
@@ -1031,7 +1031,8 @@  class WpaSupplicant:
                        "dpp_csign", "dpp_csign_expiry",
                        "dpp_netaccesskey", "dpp_netaccesskey_expiry",
                        "group_mgmt", "owe_group",
-                       "roaming_consortium_selection" ]
+                       "roaming_consortium_selection",
+                       "rx_stbc", "tx_stbc" ]
         for field in not_quoted:
             if field in kwargs and kwargs[field]:
                 self.set_network(id, field, kwargs[field])
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index ced77ebda..8a4f4086d 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2267,6 +2267,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) },
@@ -2786,6 +2788,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 aa73f9df6..76f0c6d72 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -886,6 +886,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 d2a52d760..6a1a331e3 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 */
@@ -682,6 +684,20 @@  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.
+	 */
+	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.
+	 */
+	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 05e3ebf2f..7352a402c 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 eed973590..3d292f9a1 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -4468,6 +4468,55 @@  static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
 	return 0;
 }
 
+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,
@@ -4493,6 +4542,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 4f5916025..2f52a3e3f 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1381,6 +1381,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 7.3.2.56.2 in IEEE Std 802.11n-2009.
+# -1 = Do not make any changes.
+# 0 = Set if not supported
+# 1 = Set if supported
+#
+# rx_stbc: Allow overriding STBC support for RX streams
+# Value: 0-3, see 7.3.2.56.2 in IEEE Std 802.11n-2009.
+# -1 = Do not make any changes.
+# 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)