Patchwork [PATCHv2] wpa_supplicant: add ibss_ht_mode

login
register
mail settings
Submitter Simon Wunderlich
Date Dec. 5, 2012, 10:11 a.m.
Message ID <1354702265-29200-1-git-send-email-siwu@hrz.tu-chemnitz.de>
Download mbox | patch
Permalink /patch/203813/
State Under Review
Headers show

Comments

Simon Wunderlich - Dec. 5, 2012, 10:11 a.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-hostap: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
I'm reposting this patch, this time with the "Signed-hostap".
If there is anything else off, please tell me - thanks!
---
 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(+)
Jouni Malinen - Dec. 25, 2012, 10:33 a.m.
On Wed, Dec 05, 2012 at 11:11:05AM +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.

Does this need to be user configurable parameter? Wouldn't it be simpler
to just enable HT mode by default if the driver supports it and the
regulatory domain allows such use? As far as HT40 is concerned, I would
not enable it by default at least on 2.4 GHz band. It could reasonable
to have a configuration item for it in 5 GHz, but that shouldn't require
selection between HT40+ and HT40- since that can be determined from how
the channels have been defined.
Simon Wunderlich - Dec. 31, 2012, midnight
Hey Jouni,

thanks for reviewing,

On Tue, Dec 25, 2012 at 12:33:44PM +0200, Jouni Malinen wrote:
> On Wed, Dec 05, 2012 at 11:11:05AM +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.
> 
> Does this need to be user configurable parameter? Wouldn't it be simpler
> to just enable HT mode by default if the driver supports it and the
> regulatory domain allows such use? As far as HT40 is concerned, I would
> not enable it by default at least on 2.4 GHz band. It could reasonable
> to have a configuration item for it in 5 GHz, but that shouldn't require
> selection between HT40+ and HT40- since that can be determined from how
> the channels have been defined.

Hmm, auto detection/automatically using HT mode when available, at least
HT20, would be a good IMHO. Maybe we should change mac80211 accordingly
and not wpa_supplicant to set HT mode if available.

As for HT40 in 2.4 GHz, I know there has been a debate whether this can
be considered a "good thing", but I think it should be allowed to configure
this - after all it's technically possible, and we should not do politics and
disallow it (maybe discourage/don't set it on default, thou).

HT40+/HT40- should be set as we do for hostapd too. Many channels allow both
modes, and we might want to choose the right channel, no? If one station
configures to HT40+ and the other HT40- (for whatever reason), they will
only talk to each other in HT20, and users will have a hard time finding out
why. :)

To summarise, I agree using HT mode by default is a good idea, but I'd argue
having the option to configure HT20/HT40 or extension channels should still
be possible as for the reasons above.

How should we proceed? What do others think?

Cheers,
	Simon

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;