[PATCHv2] wpa_supplicant: add ibss_ht_mode
Simon Wunderlich
simon.wunderlich
Wed Dec 5 02:11:05 PST 2012
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 at 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(+)
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;
--
1.7.10.4
More information about the Hostap
mailing list