Patchwork wpa_supplicant: add ibss_ht_mode

login
register
mail settings
Submitter Simon Wunderlich
Date Nov. 28, 2012, 3:52 p.m.
Message ID <1354117926-6537-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Download mbox | patch
Permalink /patch/202485/
State Superseded
Headers show

Comments

Simon Wunderlich - Nov. 28, 2012, 3:52 p.m.
iw/join ibss supports for a quite a while now, but wpa_supplicant
doesn't: setting the HT mode in IBSS mode. With this new option,
it is possible to set HT20, HT40+ or HT40- when using IBSS.

This gives quite impressive performance boosts on modules which
support 802.11n/HT-IBSS.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 src/common/defs.h               |   12 +++++++++
 src/drivers/driver.h            |    6 +++++
 src/drivers/driver_nl80211.c    |   27 ++++++++++++++++++++
 wpa_supplicant/config.c         |   53 +++++++++++++++++++++++++++++++++++++++
 wpa_supplicant/config_ssid.h    |   10 ++++++++
 wpa_supplicant/wpa_supplicant.c |    1 +
 6 files changed, 109 insertions(+)
Antonio Quartulli - Dec. 2, 2012, 1:02 a.m.
On Wed, Nov 28, 2012 at 04:52:06PM +0100, Simon Wunderlich wrote:
> iw/join ibss supports for a quite a while now, but wpa_supplicant
> doesn't: setting the HT mode in IBSS mode. With this new option,
> it is possible to set HT20, HT40+ or HT40- when using IBSS.
> 
> This gives quite impressive performance boosts on modules which
> support 802.11n/HT-IBSS.
> 
> Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>

Hello Simon,

thank yiou for sending this patch. I actually need the same mod and at
the moment I was using a personal hack...

For us using IBSS/RSN, having HT20/40+- configurable in wpa_supplicant is a
must!


Cheers,

Patch

diff --git a/src/common/defs.h b/src/common/defs.h
index 85e9932..59eedb4 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -317,4 +317,16 @@  enum wpa_ctrl_req_type {
 /* Maximum number of EAP methods to store for EAP server user information */
 #define EAP_MAX_METHODS 8
 
+
+/**
+ *  enum ht_mode - channel width and offset
+ */
+enum ht_mode {
+	CHAN_UNDEFINED = 0,
+	CHAN_NO_HT,
+	CHAN_HT20,
+	CHAN_HT40PLUS,
+	CHAN_HT40MINUS,
+};
+
 #endif /* DEFS_H */
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 7ee71aa..af059bc 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -559,6 +559,12 @@  struct wpa_driver_associate_params {
 	 */
 	const u8 *htcaps;       /* struct ieee80211_ht_capabilities * */
 	const u8 *htcaps_mask;  /* struct ieee80211_ht_capabilities * */
+
+	/**
+	 * HT mode - used to set HT mode for IBSS
+	 */
+
+	enum ht_mode ibss_ht_mode;
 };
 
 enum hide_ssid {
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 297f677..d7d7bb9 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -6682,6 +6682,33 @@  retry:
 			params->wpa_ie);
 	}
 
+	if (params->ibss_ht_mode) {
+		unsigned int htval;
+		char *ht_mode = "";
+
+		switch (params->ibss_ht_mode) {
+		default:
+		case CHAN_NO_HT:
+			htval = NL80211_CHAN_NO_HT;
+			ht_mode = "NOHT";
+			break;
+		case CHAN_HT20:
+			htval = NL80211_CHAN_HT20;
+			ht_mode = "HT20";
+			break;
+		case CHAN_HT40PLUS:
+			htval = NL80211_CHAN_HT40PLUS;
+			ht_mode = "HT40+";
+			break;
+		case CHAN_HT40MINUS:
+			htval = NL80211_CHAN_HT40MINUS;
+			ht_mode = "HT40-";
+			break;
+		}
+		wpa_printf(MSG_DEBUG, "  * ht_mode=%s", ht_mode);
+		NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, htval);
+	}
+
 	ret = send_and_recv_msgs(drv, msg, NULL, NULL);
 	msg = NULL;
 	if (ret) {
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index e157845..c7574d0 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1469,6 +1469,57 @@  static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
 
 #endif /* CONFIG_P2P */
 
+static int wpa_config_parse_ibss_ht_mode(const struct parse_data *data,
+					 struct wpa_ssid *ssid, int line,
+					 const char *value)
+{
+	int htval = 0;
+
+	if (os_strcmp(value, "NOHT") == 0)
+		htval = CHAN_NO_HT;
+	else if (os_strcmp(value, "HT20") == 0)
+		htval = CHAN_HT20;
+	else if (os_strcmp(value, "HT40-") == 0)
+		htval = CHAN_HT40MINUS;
+	else if (os_strcmp(value, "HT40+") == 0)
+		htval = CHAN_HT40PLUS;
+	else {
+		wpa_printf(MSG_ERROR,
+			   "Line %d: no ht_mode configured.", line);
+		return -1;
+	}
+
+	wpa_printf(MSG_MSGDUMP, "ibss_ht_mode: 0x%x", htval);
+	ssid->ibss_ht_mode = htval;
+	return 0;
+}
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_ibss_ht_mode(const struct parse_data *data,
+					    struct wpa_ssid *ssid)
+{
+	char *val;
+	switch (ssid->ibss_ht_mode) {
+	default:
+		val = NULL;
+		break;
+	case CHAN_NO_HT:
+		val = "NOHT";
+		break;
+	case CHAN_HT20:
+		val = "HT20";
+		break;
+	case CHAN_HT40MINUS:
+		val = "HT40-";
+		break;
+	case CHAN_HT40PLUS:
+		val = "HT40+";
+		break;
+	}
+	return val ? os_strdup(val) : NULL;
+}
+#endif /* NO_CONFIG_WRITE */
+
 /* Helper macros for network block parser */
 
 #ifdef OFFSET
@@ -1628,6 +1679,7 @@  static const struct parse_data ssid_fields[] = {
 	{ INT_RANGE(peerkey, 0, 1) },
 	{ INT_RANGE(mixed_cell, 0, 1) },
 	{ INT_RANGE(frequency, 0, 10000) },
+	{ FUNC(ibss_ht_mode) },
 	{ INT(wpa_ptk_rekey) },
 	{ STR(bgscan) },
 	{ INT_RANGE(ignore_broadcast_ssid, 0, 2) },
@@ -2034,6 +2086,7 @@  void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
 	ssid->eap_workaround = DEFAULT_EAP_WORKAROUND;
 	ssid->eap.fragment_size = DEFAULT_FRAGMENT_SIZE;
 #endif /* IEEE8021X_EAPOL */
+	ssid->ibss_ht_mode = DEFAULT_IBSS_HT_MODE;
 #ifdef CONFIG_HT_OVERRIDES
 	ssid->disable_ht = DEFAULT_DISABLE_HT;
 	ssid->disable_ht40 = DEFAULT_DISABLE_HT40;
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index a9a477a..60c2c23 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -26,6 +26,7 @@ 
 #define DEFAULT_FRAGMENT_SIZE 1398
 
 #define DEFAULT_BG_SCAN_PERIOD -1
+#define DEFAULT_IBSS_HT_MODE CHAN_UNDEFINED /* undefined */
 #define DEFAULT_DISABLE_HT 0
 #define DEFAULT_DISABLE_HT40 0
 #define DEFAULT_DISABLE_MAX_AMSDU -1 /* no change */
@@ -477,6 +478,15 @@  struct wpa_ssid {
 	 */
 	int export_keys;
 
+	/**
+	 * ibss_ht_mode - definition of HT mode in IBSS
+	 *
+	 * Use the given HT mode for IBSS networks. The driver will
+	 * adapt to other stations if neccesary, but advertise the
+	 * configured HT mode (HT20/HT40-/HT40+/NOHT).
+	 */
+	int ibss_ht_mode;
+
 #ifdef CONFIG_HT_OVERRIDES
 	/**
 	 * disable_ht - Disable HT (IEEE 802.11n) for this network
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 784a471..49d8b4b 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1541,6 +1541,7 @@  void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 	if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
 	    params.freq == 0)
 		params.freq = ssid->frequency; /* Initial channel for IBSS */
+	params.ibss_ht_mode = ssid->ibss_ht_mode;
 	params.wpa_ie = wpa_ie;
 	params.wpa_ie_len = wpa_ie_len;
 	params.pairwise_suite = cipher_pairwise;