}
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 */
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;
#include <linux/wait.h>
#include <linux/timer.h>
#include <linux/ieee80211.h>
+#include <net/mac80211.h>
#define MWIFIEX_MAX_BSS_NUM (3)
#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
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_ */
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:
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;
config->rts_threshold = 0x7FFF;
config->frag_threshold = 0x7FFF;
config->retry_limit = 0x7F;
+ config->qos_info = 0xFF;
}
/* This function parses BSS related parameters from structure
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.
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;
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);