From: Amitkumar Karwar <[email protected]>
It is observed that same htcapinfo ie is included in beacon for
HT20, HT40+ and HT40- ibss networks. This patch makes sure that
we will not advertise 40Mhz flags while creating/joining ibss
network in HT20 mode.
Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/11n.c | 4 +++-
drivers/net/wireless/mwifiex/join.c | 10 ++++++++++
2 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 245a371..9cd6216 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -53,7 +53,9 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
sizeof(sband->ht_cap.mcs));
if (priv->bss_mode == NL80211_IFTYPE_STATION ||
- sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+ (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 &&
+ (priv->adapter->sec_chan_offset !=
+ IEEE80211_HT_PARAM_CHA_SEC_NONE)))
/* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 88664ae..3c7cabe 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -969,6 +969,16 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
priv->adapter->config_bands);
mwifiex_fill_cap_info(priv, radio_type, ht_cap);
+ if (adapter->sec_chan_offset ==
+ IEEE80211_HT_PARAM_CHA_SEC_NONE) {
+ u16 tmp_ht_cap;
+
+ tmp_ht_cap = le16_to_cpu(ht_cap->ht_cap.cap_info);
+ tmp_ht_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ tmp_ht_cap &= ~IEEE80211_HT_CAP_SGI_40;
+ ht_cap->ht_cap.cap_info = cpu_to_le16(tmp_ht_cap);
+ }
+
pos += sizeof(struct mwifiex_ie_types_htcap);
cmd_append_size += sizeof(struct mwifiex_ie_types_htcap);
--
1.7.0.2
From: Avinash Patil <[email protected]>
This patch adds support for parsing WMM IEs from hostapd
and setting them to FW via sys configure command.
Patch also sets wiphy flag to advertise AP uAPSD support.
Signed-off-by: Avinash Patil <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 2 +
drivers/net/wireless/mwifiex/decl.h | 18 ++++++++++++
drivers/net/wireless/mwifiex/fw.h | 11 +++----
drivers/net/wireless/mwifiex/ioctl.h | 3 +-
drivers/net/wireless/mwifiex/main.h | 4 +++
drivers/net/wireless/mwifiex/uap_cmd.c | 44 +++++++++++++++++++++++++++++++
6 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index a875499..c4edb28 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1327,6 +1327,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
}
mwifiex_set_ht_params(priv, bss_cfg, params);
+ mwifiex_set_wmm_params(priv, bss_cfg, params);
if (params->inactivity_timeout > 0) {
/* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */
@@ -2261,6 +2262,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
+ WIPHY_FLAG_AP_UAPSD |
WIPHY_FLAG_CUSTOM_REGULATORY |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index e9357d8..e8a569a 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -26,6 +26,7 @@
#include <linux/wait.h>
#include <linux/timer.h>
#include <linux/ieee80211.h>
+#include <net/mac80211.h>
#define MWIFIEX_MAX_BSS_NUM (3)
@@ -58,6 +59,8 @@
#define MWIFIEX_RTS_MAX_VALUE (2347)
#define MWIFIEX_FRAG_MIN_VALUE (256)
#define MWIFIEX_FRAG_MAX_VALUE (2346)
+#define MWIFIEX_WMM_VERSION 0x01
+#define MWIFIEX_WMM_SUBTYPE 0x01
#define MWIFIEX_RETRY_LIMIT 14
#define MWIFIEX_SDIO_BLOCK_SIZE 256
@@ -126,4 +129,19 @@ enum mwifiex_wmm_ac_e {
WMM_AC_VI,
WMM_AC_VO
} __packed;
+
+struct ieee_types_wmm_ac_parameters {
+ u8 aci_aifsn_bitmap;
+ u8 ecw_bitmap;
+ __le16 tx_op_limit;
+} __packed;
+
+struct mwifiex_types_wmm_info {
+ u8 oui[4];
+ u8 subtype;
+ u8 version;
+ u8 qos_info;
+ u8 reserved;
+ struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_NUM_ACS];
+} __packed;
#endif /* !_MWIFIEX_DECL_H_ */
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 4dc8e2e..41c85dd 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1131,12 +1131,6 @@ struct ieee_types_vendor_header {
u8 version;
} __packed;
-struct ieee_types_wmm_ac_parameters {
- u8 aci_aifsn_bitmap;
- u8 ecw_bitmap;
- __le16 tx_op_limit;
-} __packed;
-
struct ieee_types_wmm_parameter {
/*
* WMM Parameter IE - Vendor Specific Header:
@@ -1186,6 +1180,11 @@ struct mwifiex_ie_types_htcap {
struct ieee80211_ht_cap ht_cap;
} __packed;
+struct mwifiex_ie_types_wmmcap {
+ struct mwifiex_ie_types_header header;
+ struct mwifiex_types_wmm_info wmm_info;
+} __packed;
+
struct mwifiex_ie_types_htinfo {
struct mwifiex_ie_types_header header;
struct ieee80211_ht_operation ht_oper;
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 4e31c60..6095b3e 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -20,7 +20,6 @@
#ifndef _MWIFIEX_IOCTL_H_
#define _MWIFIEX_IOCTL_H_
-#include <net/mac80211.h>
#include <net/lib80211.h>
enum {
@@ -107,6 +106,8 @@ struct mwifiex_uap_bss_param {
u8 rates[MWIFIEX_SUPPORTED_RATES];
u32 sta_ao_timer;
u32 ps_sta_ao_timer;
+ u8 qos_info;
+ struct mwifiex_types_wmm_info wmm_info;
};
enum {
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 1b3cfc8..d717c98 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -890,6 +890,10 @@ void mwifiex_set_ht_params(struct mwifiex_private *priv,
struct cfg80211_ap_settings *params);
void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
struct cfg80211_ap_settings *params);
+void
+mwifiex_set_wmm_params(struct mwifiex_private *priv,
+ struct mwifiex_uap_bss_param *bss_cfg,
+ struct cfg80211_ap_settings *params);
/*
* This function checks if the queuing is RA based or not.
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 8dd7224..6e76a15 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -219,6 +219,7 @@ void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config)
config->rts_threshold = 0x7FFF;
config->frag_threshold = 0x7FFF;
config->retry_limit = 0x7F;
+ config->qos_info = 0xFF;
}
/* This function parses BSS related parameters from structure
@@ -297,6 +298,38 @@ mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size)
return;
}
+/* This function parses WMM related parameters from cfg80211_ap_settings
+ * structure and updates bss_config structure.
+ */
+void
+mwifiex_set_wmm_params(struct mwifiex_private *priv,
+ struct mwifiex_uap_bss_param *bss_cfg,
+ struct cfg80211_ap_settings *params)
+{
+ const u8 *vendor_ie;
+ struct ieee_types_header *wmm_ie;
+ u8 wmm_oui[] = {0x00, 0x50, 0xf2, 0x02};
+
+ vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
+ WLAN_OUI_TYPE_MICROSOFT_WMM,
+ params->beacon.tail,
+ params->beacon.tail_len);
+ if (vendor_ie) {
+ wmm_ie = (struct ieee_types_header *)vendor_ie;
+ memcpy(&bss_cfg->wmm_info, wmm_ie + 1,
+ sizeof(bss_cfg->wmm_info));
+ priv->wmm_enabled = 1;
+ } else {
+ memset(&bss_cfg->wmm_info, 0, sizeof(bss_cfg->wmm_info));
+ memcpy(&bss_cfg->wmm_info.oui, wmm_oui, sizeof(wmm_oui));
+ bss_cfg->wmm_info.subtype = MWIFIEX_WMM_SUBTYPE;
+ bss_cfg->wmm_info.version = MWIFIEX_WMM_VERSION;
+ priv->wmm_enabled = 0;
+ }
+
+ bss_cfg->qos_info = 0x00;
+ return;
+}
/* This function parses BSS related parameters from structure
* and prepares TLVs specific to WEP encryption.
* These TLVs are appended to command buffer.
@@ -354,6 +387,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
struct host_cmd_tlv_rates *tlv_rates;
struct host_cmd_tlv_ageout_timer *ao_timer, *ps_ao_timer;
struct mwifiex_ie_types_htcap *htcap;
+ struct mwifiex_ie_types_wmmcap *wmm_cap;
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
int i;
u16 cmd_size = *param_size;
@@ -507,6 +541,16 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
tlv += sizeof(struct mwifiex_ie_types_htcap);
}
+ if (bss_cfg->wmm_info.qos_info != 0xFF) {
+ wmm_cap = (struct mwifiex_ie_types_wmmcap *)tlv;
+ wmm_cap->header.type = cpu_to_le16(WLAN_EID_VENDOR_SPECIFIC);
+ wmm_cap->header.len = cpu_to_le16(sizeof(wmm_cap->wmm_info));
+ memcpy(&wmm_cap->wmm_info, &bss_cfg->wmm_info,
+ sizeof(wmm_cap->wmm_info));
+ cmd_size += sizeof(struct mwifiex_ie_types_wmmcap);
+ tlv += sizeof(struct mwifiex_ie_types_wmmcap);
+ }
+
if (bss_cfg->sta_ao_timer) {
ao_timer = (struct host_cmd_tlv_ageout_timer *)tlv;
ao_timer->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AO_TIMER);
--
1.7.0.2
Obviously this is a very old patch, but I was just looking at users of
cfg80211_find_vendor_ie() and realized you have a bug here:
> + vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
> + WLAN_OUI_TYPE_MICROSOFT_
> WMM,
> + params->beacon.tail,
> + params-
> >beacon.tail_len);
> + if (vendor_ie) {
> + wmm_ie = (struct ieee_types_header *)vendor_ie;
> + memcpy(&bss_cfg->wmm_info, wmm_ie + 1,
> + sizeof(bss_cfg->wmm_info));
> + priv->wmm_enabled = 1;
You need to check that the vendor_ie is actually long enough.
johannes
SGkgSm9oYW5uZXMsDQoNCj4gRnJvbTogSm9oYW5uZXMgQmVyZyBbbWFpbHRvOmpvaGFubmVzQHNp
cHNvbHV0aW9ucy5uZXRdDQo+IFNlbnQ6IFdlZG5lc2RheSwgU2VwdGVtYmVyIDE0LCAyMDE2IDM6
MjUgUE0NCj4gVG86IEJpbmcgWmhhbzsgbGludXgtd2lyZWxlc3NAdmdlci5rZXJuZWwub3JnDQo+
IENjOiBKb2huIFcuIExpbnZpbGxlOyBBbWl0a3VtYXIgS2Fyd2FyOyBBdmluYXNoIFBhdGlsOyBO
aXNoYW50DQo+IFNhcm11a2FkYW07IEZyYW5rIEh1YW5nDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0gg
Mi8yXSBtd2lmaWV4OiBwYXJzZSBXTU0gSUVzIGZyb20gaG9zdGFwZCBmb3IgbXdpZmlleA0KPiBB
UA0KPiANCj4gT2J2aW91c2x5IHRoaXMgaXMgYSB2ZXJ5IG9sZCBwYXRjaCwgYnV0IEkgd2FzIGp1
c3QgbG9va2luZyBhdCB1c2VycyBvZg0KPiBjZmc4MDIxMV9maW5kX3ZlbmRvcl9pZSgpIGFuZCBy
ZWFsaXplZCB5b3UgaGF2ZSBhIGJ1ZyBoZXJlOg0KPiANCj4gPiArCXZlbmRvcl9pZSA9IGNmZzgw
MjExX2ZpbmRfdmVuZG9yX2llKFdMQU5fT1VJX01JQ1JPU09GVCwNCj4gPiArCQkJCQnCoMKgwqDC
oFdMQU5fT1VJX1RZUEVfTUlDUk9TT0ZUXw0KPiA+IFdNTSwNCj4gPiArCQkJCQnCoMKgwqDCoHBh
cmFtcy0+YmVhY29uLnRhaWwsDQo+ID4gKwkJCQkJwqDCoMKgwqBwYXJhbXMtDQo+ID4gPmJlYWNv
bi50YWlsX2xlbik7DQo+ID4gKwlpZiAodmVuZG9yX2llKSB7DQo+ID4gKwkJd21tX2llID0gKHN0
cnVjdCBpZWVlX3R5cGVzX2hlYWRlciAqKXZlbmRvcl9pZTsNCj4gPiArCQltZW1jcHkoJmJzc19j
ZmctPndtbV9pbmZvLCB3bW1faWUgKyAxLA0KPiA+ICsJCcKgwqDCoMKgwqDCoMKgc2l6ZW9mKGJz
c19jZmctPndtbV9pbmZvKSk7DQo+ID4gKwkJcHJpdi0+d21tX2VuYWJsZWQgPSAxOw0KPiANCj4g
WW91IG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgdmVuZG9yX2llIGlzIGFjdHVhbGx5IGxvbmcgZW5v
dWdoLg0KPiANCg0KU3VyZS4gSSB3aWxsIHByZXBhcmUgYSBwYXRjaCB0byBhZGRyZXNzIHRoaXMu
IA0KDQpSZWdhcmRzLA0KQW1pdGt1bWFyIEthcndhcg0K