mwifiex: update AP WMM settings from BSS_START event
authorAvinash Patil <patila@marvell.com>
Wed, 3 Jun 2015 11:29:45 +0000 (16:59 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 8 Jun 2015 08:42:02 +0000 (11:42 +0300)
This was missing and would cause issue in WMM handling.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/mwifiex/uap_event.c

index 06ce3fe660f138d51873838eda532207d9665004..fee05f5f9343c63db1a6be026a79723def0804ac 100644 (file)
 #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 */