From: Xinming Hu <[email protected]>
It is observed that hostapd failed to setup with management frame
protection mode enabled when using mwifiex.
This is because hostapd will try to install IGTK using
cfg80211 set_default_mgmt_key handler.
we have already support IGTK install in set_key handler, so just work
around this issue by add an empty cfg80211_set_default_mgmt_key handler.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Li Long <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 5f3c1d3..ab7643d 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -415,6 +415,18 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
}
/*
+ * CFG802.11 operation handler to set default mgmt key.
+ */
+static int
+mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
+ struct net_device *netdev,
+ u8 key_index)
+{
+ wiphy_dbg(wiphy, "set default mgmt key, key index=%d\n", key_index);
+ return 0;
+}
+
+/*
* This function sends domain information to the firmware.
*
* The following information are passed to the firmware -
@@ -3280,6 +3292,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
.leave_ibss = mwifiex_cfg80211_leave_ibss,
.add_key = mwifiex_cfg80211_add_key,
.del_key = mwifiex_cfg80211_del_key,
+ .set_default_mgmt_key = mwifiex_cfg80211_set_default_mgmt_key,
.mgmt_tx = mwifiex_cfg80211_mgmt_tx,
.mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register,
.remain_on_channel = mwifiex_cfg80211_remain_on_channel,
--
1.8.1.4
From: Xinming Hu <[email protected]>
This patch add cfg80211 set_mac_acl handler for AP mode, this handler
will be used by user space application to configure accept/deny mac
address list throgh nl80211/cfg80211.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 61 +++++++++++++++++++++++++++++++++
drivers/net/wireless/mwifiex/decl.h | 5 +++
drivers/net/wireless/mwifiex/fw.h | 9 +++++
drivers/net/wireless/mwifiex/ioctl.h | 6 ++++
drivers/net/wireless/mwifiex/uap_cmd.c | 25 ++++++++++++++
5 files changed, 106 insertions(+)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index f933159..d1a684a 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1621,6 +1621,64 @@ static int mwifiex_cfg80211_set_txq_params(struct wiphy *wiphy,
return 0;
}
+/* cfg80211 operation handler for set_mac_acl.
+ * function sets station mac address filter params to FW.
+ */
+static int mwifiex_cfg80211_set_mac_acl(struct wiphy *wiphy,
+ struct net_device *dev,
+ const struct cfg80211_acl_data *params)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct mwifiex_ds_mac_filter *mac_filter;
+
+ if (!priv || !params)
+ return -EINVAL;
+
+ if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) {
+ wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__);
+ return -EINVAL;
+ }
+
+ mac_filter = kzalloc(sizeof(*mac_filter), GFP_KERNEL);
+ if (!mac_filter)
+ return -ENOMEM;
+
+ wiphy_dbg(wiphy, "set_mac_acl, n_acl_entries=%d, acl_policy=%d\n",
+ params->n_acl_entries, params->acl_policy);
+
+ mac_filter->mac_count = (params->n_acl_entries <=
+ MWIFIEX_MAX_MAC_FILTER_NUM) ?
+ params->n_acl_entries :
+ MWIFIEX_MAX_MAC_FILTER_NUM;
+
+ switch (params->acl_policy) {
+ case NL80211_ACL_POLICY_DENY_UNLESS_LISTED:
+ mac_filter->filter_mode = MWIFIEX_MAC_FILTER_MODE_ALLOW_MAC;
+ break;
+ case NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED:
+ mac_filter->filter_mode = MWIFIEX_MAC_FILTER_MODE_BLOCK_MAC;
+ break;
+ default:
+ wiphy_err(wiphy, "unknown ACL policy\n");
+ kfree(mac_filter);
+ return -EINVAL;
+ }
+
+ memcpy(mac_filter->mac_list, params->mac_addrs,
+ sizeof(struct mac_address) * mac_filter->mac_count);
+
+ if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
+ HostCmd_ACT_GEN_SET,
+ UAP_MAC_FILTER_I, mac_filter, false)) {
+ wiphy_err(wiphy, "Failed to set AP mac acl params\n");
+ kfree(mac_filter);
+ return -1;
+ }
+
+ kfree(mac_filter);
+ return 0;
+}
+
/* cfg80211 operation handler for del_station.
* Function deauthenticates station which value is provided in mac parameter.
* If mac is NULL/broadcast, all stations in associated station list are
@@ -3374,6 +3432,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
.stop_ap = mwifiex_cfg80211_stop_ap,
.change_beacon = mwifiex_cfg80211_change_beacon,
.set_txq_params = mwifiex_cfg80211_set_txq_params,
+ .set_mac_acl = mwifiex_cfg80211_set_mac_acl,
.set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
.set_antenna = mwifiex_cfg80211_set_antenna,
.del_station = mwifiex_cfg80211_del_station,
@@ -3487,6 +3546,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
wiphy->cipher_suites = mwifiex_cipher_suites;
wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
+ wiphy->max_acl_mac_addrs = MWIFIEX_MAX_MAC_FILTER_NUM;
+
ether_addr_copy(wiphy->perm_addr, adapter->perm_addr);
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 0059d6f..b364a2c 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -110,6 +110,11 @@
#define MWIFIEX_A_BAND_START_FREQ 5000
+#define MWIFIEX_MAC_FILTER_MODE_DISABLE 0
+#define MWIFIEX_MAC_FILTER_MODE_ALLOW_MAC 1
+#define MWIFIEX_MAC_FILTER_MODE_BLOCK_MAC 2
+#define MWIFIEX_MAX_MAC_FILTER_NUM 16
+
enum mwifiex_bss_type {
MWIFIEX_BSS_TYPE_STA = 0,
MWIFIEX_BSS_TYPE_UAP = 1,
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 2a38964..408c1eb 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -117,6 +117,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define UAP_BSS_PARAMS_I 0
#define UAP_CUSTOM_IE_I 1
#define UAP_WMM_PARAMS_I 2
+#define UAP_MAC_FILTER_I 3
#define MWIFIEX_AUTO_IDX_MASK 0xffff
#define MWIFIEX_DELETE_MASK 0x0000
#define MGMT_MASK_ASSOC_REQ 0x01
@@ -148,6 +149,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
#define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48)
#define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51)
+#define TLV_TYPE_UAP_MAC_FILTER (PROPRIETARY_TLV_BASE_ID + 56)
#define TLV_TYPE_UAP_AO_TIMER (PROPRIETARY_TLV_BASE_ID + 57)
#define TLV_TYPE_UAP_WEP_KEY (PROPRIETARY_TLV_BASE_ID + 59)
#define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
@@ -1553,6 +1555,13 @@ struct mwifiex_ie_types_wmmcap {
struct mwifiex_types_wmm_info wmm_info;
} __packed;
+struct mwifiex_ie_types_mac_filter {
+ struct mwifiex_ie_types_header header;
+ u8 filter_mode;
+ u8 mac_count;
+ u8 mac_list[0];
+} __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 9795220..4d51775 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -402,6 +402,12 @@ struct mwifiex_ds_mef_cfg {
struct mwifiex_mef_entry *mef_entry;
};
+struct mwifiex_ds_mac_filter {
+ u8 filter_mode;
+ u8 mac_count;
+ struct mac_address mac_list[MWIFIEX_MAX_MAC_FILTER_NUM];
+};
+
#define MWIFIEX_MAX_VSIE_LEN (256)
#define MWIFIEX_MAX_VSIE_NUM (8)
#define MWIFIEX_VSIE_MASK_CLEAR 0x00
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 82e4797..0cffcb9 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -677,6 +677,27 @@ static int mwifiex_uap_wmm_ie_prepare(u8 *tlv, void *cmd_buf, u16 *cmd_size)
return 0;
}
+/* This function prepare mac address filter tlv */
+static int
+mwifiex_uap_mac_filter_prepare(u8 *tlv, void *cmd_buf, u16 *cmd_size)
+{
+ struct mwifiex_ds_mac_filter *mac_acl = cmd_buf;
+ struct mwifiex_ie_types_mac_filter *mac_filter = (void *)tlv;
+
+ mac_filter->header.type = cpu_to_le16(TLV_TYPE_UAP_MAC_FILTER);
+ mac_filter->filter_mode = mac_acl->filter_mode;
+ mac_filter->mac_count = mac_acl->mac_count;
+ memcpy(&mac_filter->mac_list, mac_acl->mac_list,
+ ETH_ALEN * mac_filter->mac_count);
+ mac_filter->header.len =
+ cpu_to_le16(sizeof(mac_filter->filter_mode) +
+ sizeof(mac_filter->mac_count) +
+ ETH_ALEN * mac_filter->mac_count);
+ *cmd_size += sizeof(*mac_filter) + ETH_ALEN * mac_filter->mac_count;
+
+ return 0;
+}
+
/* This function parses custom IEs from IE list and prepares command buffer */
static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size)
{
@@ -732,6 +753,10 @@ mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action,
mwifiex_uap_wmm_ie_prepare(tlv, cmd_buf, &cmd_size);
cmd->size = cpu_to_le16(cmd_size);
break;
+ case UAP_MAC_FILTER_I:
+ mwifiex_uap_mac_filter_prepare(tlv, cmd_buf, &cmd_size);
+ cmd->size = cpu_to_le16(cmd_size);
+ break;
default:
return -1;
}
--
1.8.1.4
On Thu, 2015-02-12 at 23:45 +0530, Avinash Patil wrote:
> From: Xinming Hu <[email protected]>
>
> It is observed that hostapd failed to setup with management frame
> protection mode enabled when using mwifiex.
>
> This is because hostapd will try to install IGTK using
> cfg80211 set_default_mgmt_key handler.
>
> we have already support IGTK install in set_key handler, so just work
> around this issue by add an empty cfg80211_set_default_mgmt_key handler.
I believe that this is incorrect since the key should only be installed
for TX after this handler, not in the set_key handler. This should make
a difference in the case of rekeying? Perhaps hostapd doesn't actually
program the key until rekeying with all stations finishes though.
johannes
DQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IEpvaGFubmVzIEJlcmcgW21h
aWx0bzpqb2hhbm5lc0BzaXBzb2x1dGlvbnMubmV0XQ0KPiBTZW50OiBGcmlkYXksIEZlYnJ1YXJ5
IDEzLCAyMDE1IDExOjM3IFBNDQo+IFRvOiBBdmluYXNoIFBhdGlsDQo+IENjOiBsaW51eC13aXJl
bGVzc0B2Z2VyLmtlcm5lbC5vcmc7IEFtaXRrdW1hciBLYXJ3YXI7IENhdGh5IEx1bzsgWGlubWlu
ZyBIdTsNCj4gTGkgTG9uZw0KPiBTdWJqZWN0OiBSZTogW1BBVENIIDEvM10gbXdpZmlleDogYWRk
IGNmZzgwMjExIHNldF9kZWZhdWx0X21nbXRfa2V5IGhhbmRsZXINCj4gDQo+IE9uIFRodSwgMjAx
NS0wMi0xMiBhdCAyMzo0NSArMDUzMCwgQXZpbmFzaCBQYXRpbCB3cm90ZToNCj4gPiBGcm9tOiBY
aW5taW5nIEh1IDxodXhtQG1hcnZlbGwuY29tPg0KPiA+DQo+ID4gSXQgaXMgb2JzZXJ2ZWQgdGhh
dCBob3N0YXBkIGZhaWxlZCB0byBzZXR1cCB3aXRoIG1hbmFnZW1lbnQgZnJhbWUNCj4gPiBwcm90
ZWN0aW9uIG1vZGUgZW5hYmxlZCB3aGVuIHVzaW5nIG13aWZpZXguDQo+ID4NCj4gPiBUaGlzIGlz
IGJlY2F1c2UgaG9zdGFwZCB3aWxsIHRyeSB0byBpbnN0YWxsIElHVEsgdXNpbmcNCj4gPiBjZmc4
MDIxMSBzZXRfZGVmYXVsdF9tZ210X2tleSBoYW5kbGVyLg0KPiA+DQo+ID4gd2UgaGF2ZSBhbHJl
YWR5IHN1cHBvcnQgSUdUSyBpbnN0YWxsIGluIHNldF9rZXkgaGFuZGxlciwgc28ganVzdCB3b3Jr
DQo+ID4gYXJvdW5kIHRoaXMgaXNzdWUgYnkgYWRkIGFuIGVtcHR5IGNmZzgwMjExX3NldF9kZWZh
dWx0X21nbXRfa2V5IGhhbmRsZXIuDQo+IA0KPiBJIGJlbGlldmUgdGhhdCB0aGlzIGlzIGluY29y
cmVjdCBzaW5jZSB0aGUga2V5IHNob3VsZCBvbmx5IGJlIGluc3RhbGxlZCBmb3IgVFgNCj4gYWZ0
ZXIgdGhpcyBoYW5kbGVyLCBub3QgaW4gdGhlIHNldF9rZXkgaGFuZGxlci4gVGhpcyBzaG91bGQg
bWFrZSBhIGRpZmZlcmVuY2UNCj4gaW4gdGhlIGNhc2Ugb2YgcmVrZXlpbmc/IFBlcmhhcHMgaG9z
dGFwZCBkb2Vzbid0IGFjdHVhbGx5IHByb2dyYW0gdGhlIGtleQ0KPiB1bnRpbCByZWtleWluZyB3
aXRoIGFsbCBzdGF0aW9ucyBmaW5pc2hlcyB0aG91Z2guDQo+IA0KPiBqb2hhbm5lcw0KDQpUaGFu
a3MgZm9yIHJldmlldyBjb21tZW50cywgSm9oYW5uZXMuDQpXZSB3aWxsIGltcGxlbWVudCBkZWZh
dWx0X21nbXQgaGFuZGxlciBpbiBhIHdheSB5b3UgaGF2ZSBzdWdnZXN0ZWQgYW5kIHNlbmQgdjIu
DQoNClJlZ2FyZHMsDQpBdmluYXNoLg0K
From: Xinming Hu <[email protected]>
This patch add cfg80211 set_txq_params handler for mwifiex.
This will be used to configure WMM AC parameters in AP mode.
Signed-off-by: Xinming Hu <[email protected]>
Signed-off-by: Cathy Luo <[email protected]>
Signed-off-by: Avinash Patil <[email protected]>
---
drivers/net/wireless/mwifiex/cfg80211.c | 70 ++++++++++++++++++++++++++++++
drivers/net/wireless/mwifiex/decl.h | 11 +++++
drivers/net/wireless/mwifiex/fw.h | 2 +
drivers/net/wireless/mwifiex/ioctl.h | 1 +
drivers/net/wireless/mwifiex/sta_cmdresp.c | 37 ++++++++++++++++
drivers/net/wireless/mwifiex/uap_cmd.c | 20 +++++++++
drivers/net/wireless/mwifiex/wmm.h | 11 -----
7 files changed, 141 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index ab7643d..f933159 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1552,6 +1552,75 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
return 0;
}
+/* cfg80211 operation handler for set_txq_params.
+ * Function retrieves and sets modified AP WMM params to FW.
+ */
+static int mwifiex_cfg80211_set_txq_params(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct ieee80211_txq_params *params)
+{
+ struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+ struct mwifiex_types_wmm_info *wmm_info;
+ u8 ac;
+
+ if (!priv || !params)
+ return -EINVAL;
+
+ if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) {
+ wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__);
+ return -EINVAL;
+ }
+
+ wmm_info = &priv->bss_cfg.ap_wmm_params;
+ memset(wmm_info, 0, sizeof(*wmm_info));
+
+ if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
+ HostCmd_ACT_GEN_GET,
+ UAP_WMM_PARAMS_I, wmm_info, true)) {
+ wiphy_err(wiphy, "Failed to Get AP wmm params\n");
+ return -1;
+ }
+
+ switch (params->ac) {
+ case NL80211_AC_VO:
+ ac = 3;
+ break;
+ case NL80211_AC_VI:
+ ac = 2;
+ break;
+ case NL80211_AC_BK:
+ ac = 1;
+ break;
+ case NL80211_AC_BE:
+ ac = 0;
+ break;
+ default:
+ wiphy_err(wiphy, "unknown ac in set_txq_params\n");
+ return -EINVAL;
+ }
+
+ wiphy_dbg(wiphy,
+ "set_txq_params ac=%d, txop=%d, cw min=%d, max=%d, aifs=%d\n",
+ ac, params->txop, params->cwmin, params->cwmax, params->aifs);
+
+ memset(&wmm_info->ac_params[ac], 0, sizeof(wmm_info->ac_params[ac]));
+ wmm_info->ac_params[ac].aci_aifsn_bitmap = params->aifs & MWIFIEX_AIFSN;
+ wmm_info->ac_params[ac].ecw_bitmap |= ilog2(params->cwmin + 1) &
+ MWIFIEX_ECW_MIN;
+ wmm_info->ac_params[ac].ecw_bitmap |= (ilog2(params->cwmax + 1) << 4) &
+ MWIFIEX_ECW_MAX;
+ wmm_info->ac_params[ac].tx_op_limit = cpu_to_le16(params->txop);
+
+ if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
+ HostCmd_ACT_GEN_SET,
+ UAP_WMM_PARAMS_I, wmm_info, false)) {
+ wiphy_err(wiphy, "Failed to set AP wmm params\n");
+ return -1;
+ }
+
+ return 0;
+}
+
/* cfg80211 operation handler for del_station.
* Function deauthenticates station which value is provided in mac parameter.
* If mac is NULL/broadcast, all stations in associated station list are
@@ -3304,6 +3373,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
.start_ap = mwifiex_cfg80211_start_ap,
.stop_ap = mwifiex_cfg80211_stop_ap,
.change_beacon = mwifiex_cfg80211_change_beacon,
+ .set_txq_params = mwifiex_cfg80211_set_txq_params,
.set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
.set_antenna = mwifiex_cfg80211_set_antenna,
.del_station = mwifiex_cfg80211_del_station,
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 88d0ead..0059d6f 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -183,6 +183,17 @@ struct mwifiex_txinfo {
u64 cookie;
};
+enum ieee_types_wmm_aciaifsn_bitmasks {
+ MWIFIEX_AIFSN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
+ MWIFIEX_ACM = BIT(4),
+ MWIFIEX_ACI = (BIT(5) | BIT(6)),
+};
+
+enum ieee_types_wmm_ecw_bitmasks {
+ MWIFIEX_ECW_MIN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
+ MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)),
+};
+
enum mwifiex_wmm_ac_e {
WMM_AC_BK,
WMM_AC_BE,
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index df553e8..2a38964 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -116,6 +116,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define UAP_BSS_PARAMS_I 0
#define UAP_CUSTOM_IE_I 1
+#define UAP_WMM_PARAMS_I 2
#define MWIFIEX_AUTO_IDX_MASK 0xffff
#define MWIFIEX_DELETE_MASK 0x0000
#define MGMT_MASK_ASSOC_REQ 0x01
@@ -174,6 +175,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197)
#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
#define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198)
+#define TLV_TYPE_AP_WMM_PARAM (PROPRIETARY_TLV_BASE_ID + 208)
#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index d2b05c3..9795220 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -114,6 +114,7 @@ struct mwifiex_uap_bss_param {
u32 ps_sta_ao_timer;
u8 qos_info;
struct mwifiex_types_wmm_info wmm_info;
+ struct mwifiex_types_wmm_info ap_wmm_params;
};
enum {
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 5f8da59..4a7b1a6 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -943,6 +943,42 @@ static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
return 0;
}
+/* This function handles the command response of set_cfg_data */
+static int mwifiex_ret_uap_sys_config(struct mwifiex_private *priv,
+ struct host_cmd_ds_command *resp)
+{
+ struct host_cmd_ds_sys_config *uap_sys_config =
+ &resp->params.uap_sys_config;
+ struct mwifiex_ie_types_wmmcap *wmm_cap =
+ (void *)uap_sys_config->tlv;
+ struct mwifiex_types_wmm_info *wmm_info = &wmm_cap->wmm_info;
+ int ac;
+
+ if (le16_to_cpu(uap_sys_config->action) != HostCmd_ACT_GEN_GET ||
+ le16_to_cpu(wmm_cap->header.type) != TLV_TYPE_AP_WMM_PARAM)
+ return 0;
+
+ if (le16_to_cpu(wmm_cap->header.len) < sizeof(*wmm_info)) {
+ dev_err(priv->adapter->dev,
+ "fw don't support ap wmm parameter configuration\n");
+ return -1;
+ }
+
+ for (ac = 0; ac < 4; ac++) {
+ dev_dbg(priv->adapter->dev,
+ "ac=%d, tx_op=%d, cw_min=%d, cw_max=%d, aci_aifsn=%d\n",
+ ac, le16_to_cpu(wmm_info->ac_params[ac].tx_op_limit),
+ wmm_info->ac_params[ac].ecw_bitmap & MWIFIEX_ECW_MIN,
+ wmm_info->ac_params[ac].ecw_bitmap &
+ MWIFIEX_ECW_MAX >> 4,
+ wmm_info->ac_params[ac].aci_aifsn_bitmap);
+ }
+
+ memcpy(&priv->bss_cfg.ap_wmm_params, wmm_info, sizeof(*wmm_info));
+
+ return 0;
+}
+
/*
* This function handles the command responses.
*
@@ -1103,6 +1139,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
ret = mwifiex_ret_subsc_evt(priv, resp);
break;
case HostCmd_CMD_UAP_SYS_CONFIG:
+ ret = mwifiex_ret_uap_sys_config(priv, resp);
break;
case HostCmd_CMD_UAP_BSS_START:
adapter->tx_lock_flag = false;
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index f5c2af0..82e4797 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -661,6 +661,22 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
return 0;
}
+/* This function parses WMM IE */
+static int mwifiex_uap_wmm_ie_prepare(u8 *tlv, void *cmd_buf, u16 *cmd_size)
+{
+ struct mwifiex_types_wmm_info *wmm_info = cmd_buf;
+ struct mwifiex_ie_types_wmmcap *wmm_cap = (void *)tlv;
+
+ wmm_cap->header.type = cpu_to_le16(TLV_TYPE_AP_WMM_PARAM);
+ wmm_cap->header.len = cpu_to_le16(sizeof(wmm_cap->wmm_info));
+ memcpy(&wmm_cap->wmm_info, wmm_info,
+ sizeof(wmm_cap->wmm_info));
+ *cmd_size += sizeof(struct mwifiex_ie_types_wmmcap);
+ tlv += sizeof(struct mwifiex_ie_types_wmmcap);
+
+ return 0;
+}
+
/* This function parses custom IEs from IE list and prepares command buffer */
static int mwifiex_uap_custom_ie_prepare(u8 *tlv, void *cmd_buf, u16 *ie_size)
{
@@ -712,6 +728,10 @@ mwifiex_cmd_uap_sys_config(struct host_cmd_ds_command *cmd, u16 cmd_action,
return -1;
cmd->size = cpu_to_le16(ie_size);
break;
+ case UAP_WMM_PARAMS_I:
+ mwifiex_uap_wmm_ie_prepare(tlv, cmd_buf, &cmd_size);
+ cmd->size = cpu_to_le16(cmd_size);
+ break;
default:
return -1;
}
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index 569bd73..a8e615f 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -20,17 +20,6 @@
#ifndef _MWIFIEX_WMM_H_
#define _MWIFIEX_WMM_H_
-enum ieee_types_wmm_aciaifsn_bitmasks {
- MWIFIEX_AIFSN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
- MWIFIEX_ACM = BIT(4),
- MWIFIEX_ACI = (BIT(5) | BIT(6)),
-};
-
-enum ieee_types_wmm_ecw_bitmasks {
- MWIFIEX_ECW_MIN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
- MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)),
-};
-
static const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
/*
--
1.8.1.4
On Tue, Mar 31, 2015 at 07:33:39AM -0700, Avinash Patil wrote:
> We feel set_default_key_mgmt handler is required for devices which supports 2 pair of GTKs.
Why would a device not support multiple GTKs/IGTKs? It does not sound
possible to implement RSN correctly without such support.. AP side could
kind of try to work with only a single GTK/IGTK, but non-AP STA would
not handle GTK/IGTK rekeying. In any case, IEEE Std 802.11-2012 seems to
be pretty clear on the assumption being that the device (including
AP-only cases) supports multiple GTK/IGTK. The authenticator state
machines use key index values 1 and 2 and swap between these when doing
rekeying.
--
Jouni Malinen PGP id EFC895FA
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogSm9oYW5uZXMgQmVyZyBb
bWFpbHRvOmpvaGFubmVzQHNpcHNvbHV0aW9ucy5uZXRdDQo+IFNlbnQ6IEZyaWRheSwgRmVicnVh
cnkgMTMsIDIwMTUgMTE6MzcgUE0NCj4gVG86IEF2aW5hc2ggUGF0aWwNCj4gQ2M6IGxpbnV4LXdp
cmVsZXNzQHZnZXIua2VybmVsLm9yZzsgQW1pdGt1bWFyIEthcndhcjsgQ2F0aHkgTHVvOyBYaW5t
aW5nIEh1Ow0KPiBMaSBMb25nDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggMS8zXSBtd2lmaWV4OiBh
ZGQgY2ZnODAyMTEgc2V0X2RlZmF1bHRfbWdtdF9rZXkgaGFuZGxlcg0KPiANCj4gT24gVGh1LCAy
MDE1LTAyLTEyIGF0IDIzOjQ1ICswNTMwLCBBdmluYXNoIFBhdGlsIHdyb3RlOg0KPiA+IEZyb206
IFhpbm1pbmcgSHUgPGh1eG1AbWFydmVsbC5jb20+DQo+ID4NCj4gPiBJdCBpcyBvYnNlcnZlZCB0
aGF0IGhvc3RhcGQgZmFpbGVkIHRvIHNldHVwIHdpdGggbWFuYWdlbWVudCBmcmFtZQ0KPiA+IHBy
b3RlY3Rpb24gbW9kZSBlbmFibGVkIHdoZW4gdXNpbmcgbXdpZmlleC4NCj4gPg0KPiA+IFRoaXMg
aXMgYmVjYXVzZSBob3N0YXBkIHdpbGwgdHJ5IHRvIGluc3RhbGwgSUdUSyB1c2luZw0KPiA+IGNm
ZzgwMjExIHNldF9kZWZhdWx0X21nbXRfa2V5IGhhbmRsZXIuDQo+ID4NCj4gPiB3ZSBoYXZlIGFs
cmVhZHkgc3VwcG9ydCBJR1RLIGluc3RhbGwgaW4gc2V0X2tleSBoYW5kbGVyLCBzbyBqdXN0IHdv
cmsNCj4gPiBhcm91bmQgdGhpcyBpc3N1ZSBieSBhZGQgYW4gZW1wdHkgY2ZnODAyMTFfc2V0X2Rl
ZmF1bHRfbWdtdF9rZXkgaGFuZGxlci4NCj4gDQo+IEkgYmVsaWV2ZSB0aGF0IHRoaXMgaXMgaW5j
b3JyZWN0IHNpbmNlIHRoZSBrZXkgc2hvdWxkIG9ubHkgYmUgaW5zdGFsbGVkIGZvciBUWA0KPiBh
ZnRlciB0aGlzIGhhbmRsZXIsIG5vdCBpbiB0aGUgc2V0X2tleSBoYW5kbGVyLiBUaGlzIHNob3Vs
ZCBtYWtlIGEgZGlmZmVyZW5jZQ0KPiBpbiB0aGUgY2FzZSBvZiByZWtleWluZz8gUGVyaGFwcyBo
b3N0YXBkIGRvZXNuJ3QgYWN0dWFsbHkgcHJvZ3JhbSB0aGUga2V5DQo+IHVudGlsIHJla2V5aW5n
IHdpdGggYWxsIHN0YXRpb25zIGZpbmlzaGVzIHRob3VnaC4NCiANCkkgYmVsaWV2ZSB0aGF0IHNl
dF9kZWZ1YWx0X21nbXRfa2V5IGFuZCBjb3JyZXNwb25kaW5nIGNoYW5nZXMgaW4gaG9zdGFwZCAm
IGNmZzgwMjExIGFyZSBkZXNpZ25lZCB3aXRoIGZvY3VzIG9uIG1hYzgwMjExLg0KT3VyIGRlc2ln
biBpcyBhIGJpdCBkaWZmZXJlbnQgaW4gYSB3YXkgYWxsIFBNRiBpcyBoYW5kbGVkIGluIEZXOyBh
bHNvIHdlIGRvbid0IHN1cHBvcnQgdHdvIHBhaXIgb2YgR1RLL0lHVEtzLg0KV2UgYWxyZWFkeSBo
YXZlIGluc3RhbGxlZCBJR1RLIHRvIEZXIGluIGFkZF9rZXkgaGFuZGxlci4NCg0KPiBqb2hhbm5l
cw0KDQo=
SGkgSm9oYW5uZXMsDQoNCkNvdWxkIHlvdSBwbGVhc2UgY2hlY2sgb3VyIHJlc3BvbnNlPw0KV2Ug
ZmVlbCBzZXRfZGVmYXVsdF9rZXlfbWdtdCBoYW5kbGVyIGlzIHJlcXVpcmVkIGZvciBkZXZpY2Vz
IHdoaWNoIHN1cHBvcnRzIDIgcGFpciBvZiBHVEtzLg0KSG93IGRvIHdlIHdvcmsgYXJvdW5kIHRo
aXM/DQoNClRoYW5rcywNCkF2aW5hc2gNCg0KPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0K
PiBGcm9tOiBBdmluYXNoIFBhdGlsDQo+IFNlbnQ6IFR1ZXNkYXksIE1hcmNoIDE3LCAyMDE1IDQ6
NTUgUE0NCj4gVG86ICdKb2hhbm5lcyBCZXJnJw0KPiBDYzogbGludXgtd2lyZWxlc3NAdmdlci5r
ZXJuZWwub3JnOyBBbWl0a3VtYXIgS2Fyd2FyOyBDYXRoeSBMdW87IFhpbm1pbmcgSHU7DQo+IExp
IExvbmcNCj4gU3ViamVjdDogUkU6IFtQQVRDSCAxLzNdIG13aWZpZXg6IGFkZCBjZmc4MDIxMSBz
ZXRfZGVmYXVsdF9tZ210X2tleSBoYW5kbGVyDQo+IA0KPiANCj4gDQo+ID4gLS0tLS1PcmlnaW5h
bCBNZXNzYWdlLS0tLS0NCj4gPiBGcm9tOiBKb2hhbm5lcyBCZXJnIFttYWlsdG86am9oYW5uZXNA
c2lwc29sdXRpb25zLm5ldF0NCj4gPiBTZW50OiBGcmlkYXksIEZlYnJ1YXJ5IDEzLCAyMDE1IDEx
OjM3IFBNDQo+ID4gVG86IEF2aW5hc2ggUGF0aWwNCj4gPiBDYzogbGludXgtd2lyZWxlc3NAdmdl
ci5rZXJuZWwub3JnOyBBbWl0a3VtYXIgS2Fyd2FyOyBDYXRoeSBMdW87DQo+ID4gWGlubWluZyBI
dTsgTGkgTG9uZw0KPiA+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggMS8zXSBtd2lmaWV4OiBhZGQgY2Zn
ODAyMTEgc2V0X2RlZmF1bHRfbWdtdF9rZXkNCj4gPiBoYW5kbGVyDQo+ID4NCj4gPiBPbiBUaHUs
IDIwMTUtMDItMTIgYXQgMjM6NDUgKzA1MzAsIEF2aW5hc2ggUGF0aWwgd3JvdGU6DQo+ID4gPiBG
cm9tOiBYaW5taW5nIEh1IDxodXhtQG1hcnZlbGwuY29tPg0KPiA+ID4NCj4gPiA+IEl0IGlzIG9i
c2VydmVkIHRoYXQgaG9zdGFwZCBmYWlsZWQgdG8gc2V0dXAgd2l0aCBtYW5hZ2VtZW50IGZyYW1l
DQo+ID4gPiBwcm90ZWN0aW9uIG1vZGUgZW5hYmxlZCB3aGVuIHVzaW5nIG13aWZpZXguDQo+ID4g
Pg0KPiA+ID4gVGhpcyBpcyBiZWNhdXNlIGhvc3RhcGQgd2lsbCB0cnkgdG8gaW5zdGFsbCBJR1RL
IHVzaW5nDQo+ID4gPiBjZmc4MDIxMSBzZXRfZGVmYXVsdF9tZ210X2tleSBoYW5kbGVyLg0KPiA+
ID4NCj4gPiA+IHdlIGhhdmUgYWxyZWFkeSBzdXBwb3J0IElHVEsgaW5zdGFsbCBpbiBzZXRfa2V5
IGhhbmRsZXIsIHNvIGp1c3QNCj4gPiA+IHdvcmsgYXJvdW5kIHRoaXMgaXNzdWUgYnkgYWRkIGFu
IGVtcHR5IGNmZzgwMjExX3NldF9kZWZhdWx0X21nbXRfa2V5DQo+IGhhbmRsZXIuDQo+ID4NCj4g
PiBJIGJlbGlldmUgdGhhdCB0aGlzIGlzIGluY29ycmVjdCBzaW5jZSB0aGUga2V5IHNob3VsZCBv
bmx5IGJlDQo+ID4gaW5zdGFsbGVkIGZvciBUWCBhZnRlciB0aGlzIGhhbmRsZXIsIG5vdCBpbiB0
aGUgc2V0X2tleSBoYW5kbGVyLiBUaGlzDQo+ID4gc2hvdWxkIG1ha2UgYSBkaWZmZXJlbmNlIGlu
IHRoZSBjYXNlIG9mIHJla2V5aW5nPyBQZXJoYXBzIGhvc3RhcGQNCj4gPiBkb2Vzbid0IGFjdHVh
bGx5IHByb2dyYW0gdGhlIGtleSB1bnRpbCByZWtleWluZyB3aXRoIGFsbCBzdGF0aW9ucyBmaW5p
c2hlcw0KPiB0aG91Z2guDQo+IA0KPiBJIGJlbGlldmUgdGhhdCBzZXRfZGVmdWFsdF9tZ210X2tl
eSBhbmQgY29ycmVzcG9uZGluZyBjaGFuZ2VzIGluIGhvc3RhcGQgJg0KPiBjZmc4MDIxMSBhcmUg
ZGVzaWduZWQgd2l0aCBmb2N1cyBvbiBtYWM4MDIxMS4NCj4gT3VyIGRlc2lnbiBpcyBhIGJpdCBk
aWZmZXJlbnQgaW4gYSB3YXkgYWxsIFBNRiBpcyBoYW5kbGVkIGluIEZXOyBhbHNvIHdlIGRvbid0
DQo+IHN1cHBvcnQgdHdvIHBhaXIgb2YgR1RLL0lHVEtzLg0KPiBXZSBhbHJlYWR5IGhhdmUgaW5z
dGFsbGVkIElHVEsgdG8gRlcgaW4gYWRkX2tleSBoYW5kbGVyLg0KPiANCj4gPiBqb2hhbm5lcw0K
DQo=