From debfc6008169f324721372e5f6917852ac78291a Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 3 Jun 2015 16:59:45 +0530 Subject: [PATCH] mwifiex: update AP WMM settings from BSS_START event This was missing and would cause issue in WMM handling. Signed-off-by: Avinash Patil Signed-off-by: Cathy Luo Signed-off-by: Kalle Valo --- drivers/net/wireless/mwifiex/uap_event.c | 63 ++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c index 06ce3fe660f1..fee05f5f9343 100644 --- a/drivers/net/wireless/mwifiex/uap_event.c +++ b/drivers/net/wireless/mwifiex/uap_event.c @@ -21,8 +21,70 @@ #include "main.h" #include "11n.h" +#define MWIFIEX_BSS_START_EVT_FIX_SIZE 12 +static int mwifiex_check_uap_capabilties(struct mwifiex_private *priv, + struct sk_buff *event) +{ + int evt_len; + u8 *curr; + u16 tlv_len; + struct mwifiex_ie_types_data *tlv_hdr; + struct ieee_types_wmm_parameter *wmm_param_ie = NULL; + int mask = IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK; + + priv->wmm_enabled = false; + skb_pull(event, MWIFIEX_BSS_START_EVT_FIX_SIZE); + evt_len = event->len; + curr = event->data; + + mwifiex_dbg_dump(priv->adapter, EVT_D, "uap capabilties:", + event->data, event->len); + + while ((evt_len >= sizeof(tlv_hdr->header))) { + tlv_hdr = (struct mwifiex_ie_types_data *)curr; + tlv_len = le16_to_cpu(tlv_hdr->header.len); + + if (evt_len < tlv_len + sizeof(tlv_hdr->header)) + break; + + switch (le16_to_cpu(tlv_hdr->header.type)) { + case WLAN_EID_HT_CAPABILITY: + priv->ap_11n_enabled = true; + break; + + case WLAN_EID_VHT_CAPABILITY: + priv->ap_11ac_enabled = true; + break; + case WLAN_EID_VENDOR_SPECIFIC: + /* Point the regular IEEE IE 2 bytes into the Marvell IE + * and setup the IEEE IE type and length byte fields + */ + wmm_param_ie = (void *)(curr + 2); + wmm_param_ie->vend_hdr.len = (u8)tlv_len; + wmm_param_ie->vend_hdr.element_id = + WLAN_EID_VENDOR_SPECIFIC; + mwifiex_dbg(priv->adapter, EVENT, + "info: check uap capabilities:\t" + "wmm parameter set count: %d\n", + wmm_param_ie->qos_info_bitmap & mask); + + mwifiex_wmm_setup_ac_downgrade(priv); + priv->wmm_enabled = true; + mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie); + break; + + default: + break; + } + + curr += (tlv_len + sizeof(tlv_hdr->header)); + evt_len -= (tlv_len + sizeof(tlv_hdr->header)); + } + + return 0; +} /* * This function handles AP interface specific events generated by firmware. @@ -134,6 +196,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) ETH_ALEN); if (priv->hist_data) mwifiex_hist_data_reset(priv); + mwifiex_check_uap_capabilties(priv, adapter->event_skb); break; case EVENT_UAP_MIC_COUNTERMEASURES: /* For future development */ -- 2.20.1