cfg80211: allow passing frame type to cfg80211_inform_bss()
[linux-2.6-block.git] / drivers / net / wireless / mwifiex / scan.c
1 /*
2  * Marvell Wireless LAN device driver: scan ioctl and command handling
3  *
4  * Copyright (C) 2011-2014, Marvell International Ltd.
5  *
6  * This software file (the "File") is distributed by Marvell International
7  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8  * (the "License").  You may use, redistribute and/or modify this File in
9  * accordance with the terms and conditions of the License, a copy of which
10  * is available by writing to the Free Software Foundation, Inc.,
11  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13  *
14  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
17  * this warranty disclaimer.
18  */
19
20 #include "decl.h"
21 #include "ioctl.h"
22 #include "util.h"
23 #include "fw.h"
24 #include "main.h"
25 #include "11n.h"
26 #include "cfg80211.h"
27
28 /* The maximum number of channels the firmware can scan per command */
29 #define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN   14
30
31 #define MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD       4
32
33 /* Memory needed to store a max sized Channel List TLV for a firmware scan */
34 #define CHAN_TLV_MAX_SIZE  (sizeof(struct mwifiex_ie_types_header)         \
35                                 + (MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN     \
36                                 *sizeof(struct mwifiex_chan_scan_param_set)))
37
38 /* Memory needed to store supported rate */
39 #define RATE_TLV_MAX_SIZE   (sizeof(struct mwifiex_ie_types_rates_param_set) \
40                                 + HOSTCMD_SUPPORTED_RATES)
41
42 /* Memory needed to store a max number/size WildCard SSID TLV for a firmware
43         scan */
44 #define WILDCARD_SSID_TLV_MAX_SIZE  \
45         (MWIFIEX_MAX_SSID_LIST_LENGTH *                                 \
46                 (sizeof(struct mwifiex_ie_types_wildcard_ssid_params)   \
47                         + IEEE80211_MAX_SSID_LEN))
48
49 /* Maximum memory needed for a mwifiex_scan_cmd_config with all TLVs at max */
50 #define MAX_SCAN_CFG_ALLOC (sizeof(struct mwifiex_scan_cmd_config)        \
51                                 + sizeof(struct mwifiex_ie_types_num_probes)   \
52                                 + sizeof(struct mwifiex_ie_types_htcap)       \
53                                 + CHAN_TLV_MAX_SIZE                 \
54                                 + RATE_TLV_MAX_SIZE                 \
55                                 + WILDCARD_SSID_TLV_MAX_SIZE)
56
57
58 union mwifiex_scan_cmd_config_tlv {
59         /* Scan configuration (variable length) */
60         struct mwifiex_scan_cmd_config config;
61         /* Max allocated block */
62         u8 config_alloc_buf[MAX_SCAN_CFG_ALLOC];
63 };
64
65 enum cipher_suite {
66         CIPHER_SUITE_TKIP,
67         CIPHER_SUITE_CCMP,
68         CIPHER_SUITE_MAX
69 };
70 static u8 mwifiex_wpa_oui[CIPHER_SUITE_MAX][4] = {
71         { 0x00, 0x50, 0xf2, 0x02 },     /* TKIP */
72         { 0x00, 0x50, 0xf2, 0x04 },     /* AES  */
73 };
74 static u8 mwifiex_rsn_oui[CIPHER_SUITE_MAX][4] = {
75         { 0x00, 0x0f, 0xac, 0x02 },     /* TKIP */
76         { 0x00, 0x0f, 0xac, 0x04 },     /* AES  */
77 };
78
79 /*
80  * This function parses a given IE for a given OUI.
81  *
82  * This is used to parse a WPA/RSN IE to find if it has
83  * a given oui in PTK.
84  */
85 static u8
86 mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
87 {
88         u8 count;
89
90         count = iebody->ptk_cnt[0];
91
92         /* There could be multiple OUIs for PTK hence
93            1) Take the length.
94            2) Check all the OUIs for AES.
95            3) If one of them is AES then pass success. */
96         while (count) {
97                 if (!memcmp(iebody->ptk_body, oui, sizeof(iebody->ptk_body)))
98                         return MWIFIEX_OUI_PRESENT;
99
100                 --count;
101                 if (count)
102                         iebody = (struct ie_body *) ((u8 *) iebody +
103                                                 sizeof(iebody->ptk_body));
104         }
105
106         pr_debug("info: %s: OUI is not found in PTK\n", __func__);
107         return MWIFIEX_OUI_NOT_PRESENT;
108 }
109
110 /*
111  * This function checks if a given OUI is present in a RSN IE.
112  *
113  * The function first checks if a RSN IE is present or not in the
114  * BSS descriptor. It tries to locate the OUI only if such an IE is
115  * present.
116  */
117 static u8
118 mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
119 {
120         u8 *oui;
121         struct ie_body *iebody;
122         u8 ret = MWIFIEX_OUI_NOT_PRESENT;
123
124         if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).
125                                         ieee_hdr.element_id == WLAN_EID_RSN))) {
126                 iebody = (struct ie_body *)
127                          (((u8 *) bss_desc->bcn_rsn_ie->data) +
128                           RSN_GTK_OUI_OFFSET);
129                 oui = &mwifiex_rsn_oui[cipher][0];
130                 ret = mwifiex_search_oui_in_ie(iebody, oui);
131                 if (ret)
132                         return ret;
133         }
134         return ret;
135 }
136
137 /*
138  * This function checks if a given OUI is present in a WPA IE.
139  *
140  * The function first checks if a WPA IE is present or not in the
141  * BSS descriptor. It tries to locate the OUI only if such an IE is
142  * present.
143  */
144 static u8
145 mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
146 {
147         u8 *oui;
148         struct ie_body *iebody;
149         u8 ret = MWIFIEX_OUI_NOT_PRESENT;
150
151         if (((bss_desc->bcn_wpa_ie) &&
152              ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id ==
153               WLAN_EID_VENDOR_SPECIFIC))) {
154                 iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data;
155                 oui = &mwifiex_wpa_oui[cipher][0];
156                 ret = mwifiex_search_oui_in_ie(iebody, oui);
157                 if (ret)
158                         return ret;
159         }
160         return ret;
161 }
162
163 /*
164  * This function compares two SSIDs and checks if they match.
165  */
166 s32
167 mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
168 {
169         if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
170                 return -1;
171         return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
172 }
173
174 /*
175  * This function checks if wapi is enabled in driver and scanned network is
176  * compatible with it.
177  */
178 static bool
179 mwifiex_is_bss_wapi(struct mwifiex_private *priv,
180                     struct mwifiex_bssdescriptor *bss_desc)
181 {
182         if (priv->sec_info.wapi_enabled &&
183             (bss_desc->bcn_wapi_ie &&
184              ((*(bss_desc->bcn_wapi_ie)).ieee_hdr.element_id ==
185                         WLAN_EID_BSS_AC_ACCESS_DELAY))) {
186                 return true;
187         }
188         return false;
189 }
190
191 /*
192  * This function checks if driver is configured with no security mode and
193  * scanned network is compatible with it.
194  */
195 static bool
196 mwifiex_is_bss_no_sec(struct mwifiex_private *priv,
197                       struct mwifiex_bssdescriptor *bss_desc)
198 {
199         if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
200             !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
201                 ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
202                  WLAN_EID_VENDOR_SPECIFIC)) &&
203             ((!bss_desc->bcn_rsn_ie) ||
204                 ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id !=
205                  WLAN_EID_RSN)) &&
206             !priv->sec_info.encryption_mode && !bss_desc->privacy) {
207                 return true;
208         }
209         return false;
210 }
211
212 /*
213  * This function checks if static WEP is enabled in driver and scanned network
214  * is compatible with it.
215  */
216 static bool
217 mwifiex_is_bss_static_wep(struct mwifiex_private *priv,
218                           struct mwifiex_bssdescriptor *bss_desc)
219 {
220         if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
221             !priv->sec_info.wpa2_enabled && bss_desc->privacy) {
222                 return true;
223         }
224         return false;
225 }
226
227 /*
228  * This function checks if wpa is enabled in driver and scanned network is
229  * compatible with it.
230  */
231 static bool
232 mwifiex_is_bss_wpa(struct mwifiex_private *priv,
233                    struct mwifiex_bssdescriptor *bss_desc)
234 {
235         if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled &&
236             !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) &&
237             ((*(bss_desc->bcn_wpa_ie)).
238              vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC))
239            /*
240             * Privacy bit may NOT be set in some APs like
241             * LinkSys WRT54G && bss_desc->privacy
242             */
243          ) {
244                 dev_dbg(priv->adapter->dev, "info: %s: WPA:"
245                         " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
246                         "EncMode=%#x privacy=%#x\n", __func__,
247                         (bss_desc->bcn_wpa_ie) ?
248                         (*(bss_desc->bcn_wpa_ie)).
249                         vend_hdr.element_id : 0,
250                         (bss_desc->bcn_rsn_ie) ?
251                         (*(bss_desc->bcn_rsn_ie)).
252                         ieee_hdr.element_id : 0,
253                         (priv->sec_info.wep_enabled) ? "e" : "d",
254                         (priv->sec_info.wpa_enabled) ? "e" : "d",
255                         (priv->sec_info.wpa2_enabled) ? "e" : "d",
256                         priv->sec_info.encryption_mode,
257                         bss_desc->privacy);
258                 return true;
259         }
260         return false;
261 }
262
263 /*
264  * This function checks if wpa2 is enabled in driver and scanned network is
265  * compatible with it.
266  */
267 static bool
268 mwifiex_is_bss_wpa2(struct mwifiex_private *priv,
269                     struct mwifiex_bssdescriptor *bss_desc)
270 {
271         if (!priv->sec_info.wep_enabled &&
272             !priv->sec_info.wpa_enabled &&
273             priv->sec_info.wpa2_enabled &&
274             ((bss_desc->bcn_rsn_ie) &&
275              ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) {
276                 /*
277                  * Privacy bit may NOT be set in some APs like
278                  * LinkSys WRT54G && bss_desc->privacy
279                  */
280                 dev_dbg(priv->adapter->dev, "info: %s: WPA2: "
281                         " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
282                         "EncMode=%#x privacy=%#x\n", __func__,
283                         (bss_desc->bcn_wpa_ie) ?
284                         (*(bss_desc->bcn_wpa_ie)).
285                         vend_hdr.element_id : 0,
286                         (bss_desc->bcn_rsn_ie) ?
287                         (*(bss_desc->bcn_rsn_ie)).
288                         ieee_hdr.element_id : 0,
289                         (priv->sec_info.wep_enabled) ? "e" : "d",
290                         (priv->sec_info.wpa_enabled) ? "e" : "d",
291                         (priv->sec_info.wpa2_enabled) ? "e" : "d",
292                         priv->sec_info.encryption_mode,
293                         bss_desc->privacy);
294                 return true;
295         }
296         return false;
297 }
298
299 /*
300  * This function checks if adhoc AES is enabled in driver and scanned network is
301  * compatible with it.
302  */
303 static bool
304 mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv,
305                          struct mwifiex_bssdescriptor *bss_desc)
306 {
307         if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
308             !priv->sec_info.wpa2_enabled &&
309             ((!bss_desc->bcn_wpa_ie) ||
310              ((*(bss_desc->bcn_wpa_ie)).
311               vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) &&
312             ((!bss_desc->bcn_rsn_ie) ||
313              ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
314             !priv->sec_info.encryption_mode && bss_desc->privacy) {
315                 return true;
316         }
317         return false;
318 }
319
320 /*
321  * This function checks if dynamic WEP is enabled in driver and scanned network
322  * is compatible with it.
323  */
324 static bool
325 mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv,
326                            struct mwifiex_bssdescriptor *bss_desc)
327 {
328         if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
329             !priv->sec_info.wpa2_enabled &&
330             ((!bss_desc->bcn_wpa_ie) ||
331              ((*(bss_desc->bcn_wpa_ie)).
332               vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) &&
333             ((!bss_desc->bcn_rsn_ie) ||
334              ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
335             priv->sec_info.encryption_mode && bss_desc->privacy) {
336                 dev_dbg(priv->adapter->dev, "info: %s: dynamic "
337                         "WEP: wpa_ie=%#x wpa2_ie=%#x "
338                         "EncMode=%#x privacy=%#x\n",
339                         __func__,
340                         (bss_desc->bcn_wpa_ie) ?
341                         (*(bss_desc->bcn_wpa_ie)).
342                         vend_hdr.element_id : 0,
343                         (bss_desc->bcn_rsn_ie) ?
344                         (*(bss_desc->bcn_rsn_ie)).
345                         ieee_hdr.element_id : 0,
346                         priv->sec_info.encryption_mode,
347                         bss_desc->privacy);
348                 return true;
349         }
350         return false;
351 }
352
353 /*
354  * This function checks if a scanned network is compatible with the driver
355  * settings.
356  *
357  *   WEP     WPA    WPA2   ad-hoc encrypt                  Network
358  * enabled enabled enabled  AES    mode   Privacy WPA WPA2 Compatible
359  *    0       0       0      0     NONE      0     0   0   yes No security
360  *    0       1       0      0      x        1x    1   x   yes WPA (disable
361  *                                                         HT if no AES)
362  *    0       0       1      0      x        1x    x   1   yes WPA2 (disable
363  *                                                         HT if no AES)
364  *    0       0       0      1     NONE      1     0   0   yes Ad-hoc AES
365  *    1       0       0      0     NONE      1     0   0   yes Static WEP
366  *                                                         (disable HT)
367  *    0       0       0      0    !=NONE     1     0   0   yes Dynamic WEP
368  *
369  * Compatibility is not matched while roaming, except for mode.
370  */
371 static s32
372 mwifiex_is_network_compatible(struct mwifiex_private *priv,
373                               struct mwifiex_bssdescriptor *bss_desc, u32 mode)
374 {
375         struct mwifiex_adapter *adapter = priv->adapter;
376
377         bss_desc->disable_11n = false;
378
379         /* Don't check for compatibility if roaming */
380         if (priv->media_connected &&
381             (priv->bss_mode == NL80211_IFTYPE_STATION) &&
382             (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
383                 return 0;
384
385         if (priv->wps.session_enable) {
386                 dev_dbg(adapter->dev,
387                         "info: return success directly in WPS period\n");
388                 return 0;
389         }
390
391         if (bss_desc->chan_sw_ie_present) {
392                 dev_err(adapter->dev,
393                         "Don't connect to AP with WLAN_EID_CHANNEL_SWITCH\n");
394                 return -1;
395         }
396
397         if (mwifiex_is_bss_wapi(priv, bss_desc)) {
398                 dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
399                 return 0;
400         }
401
402         if (bss_desc->bss_mode == mode) {
403                 if (mwifiex_is_bss_no_sec(priv, bss_desc)) {
404                         /* No security */
405                         return 0;
406                 } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) {
407                         /* Static WEP enabled */
408                         dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
409                         bss_desc->disable_11n = true;
410                         return 0;
411                 } else if (mwifiex_is_bss_wpa(priv, bss_desc)) {
412                         /* WPA enabled */
413                         if (((priv->adapter->config_bands & BAND_GN ||
414                               priv->adapter->config_bands & BAND_AN) &&
415                              bss_desc->bcn_ht_cap) &&
416                             !mwifiex_is_wpa_oui_present(bss_desc,
417                                                          CIPHER_SUITE_CCMP)) {
418
419                                 if (mwifiex_is_wpa_oui_present
420                                                 (bss_desc, CIPHER_SUITE_TKIP)) {
421                                         dev_dbg(adapter->dev,
422                                                 "info: Disable 11n if AES "
423                                                 "is not supported by AP\n");
424                                         bss_desc->disable_11n = true;
425                                 } else {
426                                         return -1;
427                                 }
428                         }
429                         return 0;
430                 } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) {
431                         /* WPA2 enabled */
432                         if (((priv->adapter->config_bands & BAND_GN ||
433                               priv->adapter->config_bands & BAND_AN) &&
434                              bss_desc->bcn_ht_cap) &&
435                             !mwifiex_is_rsn_oui_present(bss_desc,
436                                                         CIPHER_SUITE_CCMP)) {
437
438                                 if (mwifiex_is_rsn_oui_present
439                                                 (bss_desc, CIPHER_SUITE_TKIP)) {
440                                         dev_dbg(adapter->dev,
441                                                 "info: Disable 11n if AES "
442                                                 "is not supported by AP\n");
443                                         bss_desc->disable_11n = true;
444                                 } else {
445                                         return -1;
446                                 }
447                         }
448                         return 0;
449                 } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) {
450                         /* Ad-hoc AES enabled */
451                         return 0;
452                 } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) {
453                         /* Dynamic WEP enabled */
454                         return 0;
455                 }
456
457                 /* Security doesn't match */
458                 dev_dbg(adapter->dev,
459                         "info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s "
460                         "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__,
461                         (bss_desc->bcn_wpa_ie) ?
462                         (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0,
463                         (bss_desc->bcn_rsn_ie) ?
464                         (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0,
465                         (priv->sec_info.wep_enabled) ? "e" : "d",
466                         (priv->sec_info.wpa_enabled) ? "e" : "d",
467                         (priv->sec_info.wpa2_enabled) ? "e" : "d",
468                         priv->sec_info.encryption_mode, bss_desc->privacy);
469                 return -1;
470         }
471
472         /* Mode doesn't match */
473         return -1;
474 }
475
476 /*
477  * This function creates a channel list for the driver to scan, based
478  * on region/band information.
479  *
480  * This routine is used for any scan that is not provided with a
481  * specific channel list to scan.
482  */
483 static int
484 mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
485                                  const struct mwifiex_user_scan_cfg
486                                                         *user_scan_in,
487                                  struct mwifiex_chan_scan_param_set
488                                                         *scan_chan_list,
489                                  u8 filtered_scan)
490 {
491         enum ieee80211_band band;
492         struct ieee80211_supported_band *sband;
493         struct ieee80211_channel *ch;
494         struct mwifiex_adapter *adapter = priv->adapter;
495         int chan_idx = 0, i;
496
497         for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) {
498
499                 if (!priv->wdev->wiphy->bands[band])
500                         continue;
501
502                 sband = priv->wdev->wiphy->bands[band];
503
504                 for (i = 0; (i < sband->n_channels) ; i++) {
505                         ch = &sband->channels[i];
506                         if (ch->flags & IEEE80211_CHAN_DISABLED)
507                                 continue;
508                         scan_chan_list[chan_idx].radio_type = band;
509
510                         if (user_scan_in &&
511                             user_scan_in->chan_list[0].scan_time)
512                                 scan_chan_list[chan_idx].max_scan_time =
513                                         cpu_to_le16((u16) user_scan_in->
514                                         chan_list[0].scan_time);
515                         else if (ch->flags & IEEE80211_CHAN_NO_IR)
516                                 scan_chan_list[chan_idx].max_scan_time =
517                                         cpu_to_le16(adapter->passive_scan_time);
518                         else
519                                 scan_chan_list[chan_idx].max_scan_time =
520                                         cpu_to_le16(adapter->active_scan_time);
521
522                         if (ch->flags & IEEE80211_CHAN_NO_IR)
523                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
524                                         |= MWIFIEX_PASSIVE_SCAN;
525                         else
526                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
527                                         &= ~MWIFIEX_PASSIVE_SCAN;
528                         scan_chan_list[chan_idx].chan_number =
529                                                         (u32) ch->hw_value;
530                         if (filtered_scan) {
531                                 scan_chan_list[chan_idx].max_scan_time =
532                                 cpu_to_le16(adapter->specific_scan_time);
533                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
534                                         |= MWIFIEX_DISABLE_CHAN_FILT;
535                         }
536                         chan_idx++;
537                 }
538
539         }
540         return chan_idx;
541 }
542
543 /* This function appends rate TLV to scan config command. */
544 static int
545 mwifiex_append_rate_tlv(struct mwifiex_private *priv,
546                         struct mwifiex_scan_cmd_config *scan_cfg_out,
547                         u8 radio)
548 {
549         struct mwifiex_ie_types_rates_param_set *rates_tlv;
550         u8 rates[MWIFIEX_SUPPORTED_RATES], *tlv_pos;
551         u32 rates_size;
552
553         memset(rates, 0, sizeof(rates));
554
555         tlv_pos = (u8 *)scan_cfg_out->tlv_buf + scan_cfg_out->tlv_buf_len;
556
557         if (priv->scan_request)
558                 rates_size = mwifiex_get_rates_from_cfg80211(priv, rates,
559                                                              radio);
560         else
561                 rates_size = mwifiex_get_supported_rates(priv, rates);
562
563         dev_dbg(priv->adapter->dev, "info: SCAN_CMD: Rates size = %d\n",
564                 rates_size);
565         rates_tlv = (struct mwifiex_ie_types_rates_param_set *)tlv_pos;
566         rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
567         rates_tlv->header.len = cpu_to_le16((u16) rates_size);
568         memcpy(rates_tlv->rates, rates, rates_size);
569         scan_cfg_out->tlv_buf_len += sizeof(rates_tlv->header) + rates_size;
570
571         return rates_size;
572 }
573
574 /*
575  * This function constructs and sends multiple scan config commands to
576  * the firmware.
577  *
578  * Previous routines in the code flow have created a scan command configuration
579  * with any requested TLVs.  This function splits the channel TLV into maximum
580  * channels supported per scan lists and sends the portion of the channel TLV,
581  * along with the other TLVs, to the firmware.
582  */
583 static int
584 mwifiex_scan_channel_list(struct mwifiex_private *priv,
585                           u32 max_chan_per_scan, u8 filtered_scan,
586                           struct mwifiex_scan_cmd_config *scan_cfg_out,
587                           struct mwifiex_ie_types_chan_list_param_set
588                           *chan_tlv_out,
589                           struct mwifiex_chan_scan_param_set *scan_chan_list)
590 {
591         struct mwifiex_adapter *adapter = priv->adapter;
592         int ret = 0;
593         struct mwifiex_chan_scan_param_set *tmp_chan_list;
594         struct mwifiex_chan_scan_param_set *start_chan;
595         struct cmd_ctrl_node *cmd_node, *tmp_node;
596         unsigned long flags;
597         u32 tlv_idx, rates_size, cmd_no;
598         u32 total_scan_time;
599         u32 done_early;
600         u8 radio_type;
601
602         if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
603                 dev_dbg(priv->adapter->dev,
604                         "info: Scan: Null detect: %p, %p, %p\n",
605                        scan_cfg_out, chan_tlv_out, scan_chan_list);
606                 return -1;
607         }
608
609         /* Check csa channel expiry before preparing scan list */
610         mwifiex_11h_get_csa_closed_channel(priv);
611
612         chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
613
614         /* Set the temp channel struct pointer to the start of the desired
615            list */
616         tmp_chan_list = scan_chan_list;
617
618         /* Loop through the desired channel list, sending a new firmware scan
619            commands for each max_chan_per_scan channels (or for 1,6,11
620            individually if configured accordingly) */
621         while (tmp_chan_list->chan_number) {
622
623                 tlv_idx = 0;
624                 total_scan_time = 0;
625                 radio_type = 0;
626                 chan_tlv_out->header.len = 0;
627                 start_chan = tmp_chan_list;
628                 done_early = false;
629
630                 /*
631                  * Construct the Channel TLV for the scan command.  Continue to
632                  * insert channel TLVs until:
633                  *   - the tlv_idx hits the maximum configured per scan command
634                  *   - the next channel to insert is 0 (end of desired channel
635                  *     list)
636                  *   - done_early is set (controlling individual scanning of
637                  *     1,6,11)
638                  */
639                 while (tlv_idx < max_chan_per_scan &&
640                        tmp_chan_list->chan_number && !done_early) {
641
642                         if (tmp_chan_list->chan_number == priv->csa_chan) {
643                                 tmp_chan_list++;
644                                 continue;
645                         }
646
647                         radio_type = tmp_chan_list->radio_type;
648                         dev_dbg(priv->adapter->dev,
649                                 "info: Scan: Chan(%3d), Radio(%d),"
650                                 " Mode(%d, %d), Dur(%d)\n",
651                                 tmp_chan_list->chan_number,
652                                 tmp_chan_list->radio_type,
653                                 tmp_chan_list->chan_scan_mode_bitmap
654                                 & MWIFIEX_PASSIVE_SCAN,
655                                 (tmp_chan_list->chan_scan_mode_bitmap
656                                  & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
657                                 le16_to_cpu(tmp_chan_list->max_scan_time));
658
659                         /* Copy the current channel TLV to the command being
660                            prepared */
661                         memcpy(chan_tlv_out->chan_scan_param + tlv_idx,
662                                tmp_chan_list,
663                                sizeof(chan_tlv_out->chan_scan_param));
664
665                         /* Increment the TLV header length by the size
666                            appended */
667                         le16_add_cpu(&chan_tlv_out->header.len,
668                                      sizeof(chan_tlv_out->chan_scan_param));
669
670                         /*
671                          * The tlv buffer length is set to the number of bytes
672                          * of the between the channel tlv pointer and the start
673                          * of the tlv buffer.  This compensates for any TLVs
674                          * that were appended before the channel list.
675                          */
676                         scan_cfg_out->tlv_buf_len = (u32) ((u8 *) chan_tlv_out -
677                                                         scan_cfg_out->tlv_buf);
678
679                         /* Add the size of the channel tlv header and the data
680                            length */
681                         scan_cfg_out->tlv_buf_len +=
682                                 (sizeof(chan_tlv_out->header)
683                                  + le16_to_cpu(chan_tlv_out->header.len));
684
685                         /* Increment the index to the channel tlv we are
686                            constructing */
687                         tlv_idx++;
688
689                         /* Count the total scan time per command */
690                         total_scan_time +=
691                                 le16_to_cpu(tmp_chan_list->max_scan_time);
692
693                         done_early = false;
694
695                         /* Stop the loop if the *current* channel is in the
696                            1,6,11 set and we are not filtering on a BSSID
697                            or SSID. */
698                         if (!filtered_scan &&
699                             (tmp_chan_list->chan_number == 1 ||
700                              tmp_chan_list->chan_number == 6 ||
701                              tmp_chan_list->chan_number == 11))
702                                 done_early = true;
703
704                         /* Increment the tmp pointer to the next channel to
705                            be scanned */
706                         tmp_chan_list++;
707
708                         /* Stop the loop if the *next* channel is in the 1,6,11
709                            set.  This will cause it to be the only channel
710                            scanned on the next interation */
711                         if (!filtered_scan &&
712                             (tmp_chan_list->chan_number == 1 ||
713                              tmp_chan_list->chan_number == 6 ||
714                              tmp_chan_list->chan_number == 11))
715                                 done_early = true;
716                 }
717
718                 /* The total scan time should be less than scan command timeout
719                    value */
720                 if (total_scan_time > MWIFIEX_MAX_TOTAL_SCAN_TIME) {
721                         dev_err(priv->adapter->dev, "total scan time %dms"
722                                 " is over limit (%dms), scan skipped\n",
723                                 total_scan_time, MWIFIEX_MAX_TOTAL_SCAN_TIME);
724                         ret = -1;
725                         break;
726                 }
727
728                 rates_size = mwifiex_append_rate_tlv(priv, scan_cfg_out,
729                                                      radio_type);
730
731                 priv->adapter->scan_channels = start_chan;
732
733                 /* Send the scan command to the firmware with the specified
734                    cfg */
735                 if (priv->adapter->ext_scan)
736                         cmd_no = HostCmd_CMD_802_11_SCAN_EXT;
737                 else
738                         cmd_no = HostCmd_CMD_802_11_SCAN;
739
740                 ret = mwifiex_send_cmd(priv, cmd_no, HostCmd_ACT_GEN_SET,
741                                        0, scan_cfg_out, false);
742
743                 /* rate IE is updated per scan command but same starting
744                  * pointer is used each time so that rate IE from earlier
745                  * scan_cfg_out->buf is overwritten with new one.
746                  */
747                 scan_cfg_out->tlv_buf_len -=
748                             sizeof(struct mwifiex_ie_types_header) + rates_size;
749
750                 if (ret) {
751                         spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
752                         list_for_each_entry_safe(cmd_node, tmp_node,
753                                                  &adapter->scan_pending_q,
754                                                  list) {
755                                 list_del(&cmd_node->list);
756                                 cmd_node->wait_q_enabled = false;
757                                 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
758                         }
759                         spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
760                                                flags);
761                         break;
762                 }
763         }
764
765         if (ret)
766                 return -1;
767
768         return 0;
769 }
770
771 /*
772  * This function constructs a scan command configuration structure to use
773  * in scan commands.
774  *
775  * Application layer or other functions can invoke network scanning
776  * with a scan configuration supplied in a user scan configuration structure.
777  * This structure is used as the basis of one or many scan command configuration
778  * commands that are sent to the command processing module and eventually to the
779  * firmware.
780  *
781  * This function creates a scan command configuration structure  based on the
782  * following user supplied parameters (if present):
783  *      - SSID filter
784  *      - BSSID filter
785  *      - Number of Probes to be sent
786  *      - Channel list
787  *
788  * If the SSID or BSSID filter is not present, the filter is disabled/cleared.
789  * If the number of probes is not set, adapter default setting is used.
790  */
791 static void
792 mwifiex_config_scan(struct mwifiex_private *priv,
793                     const struct mwifiex_user_scan_cfg *user_scan_in,
794                     struct mwifiex_scan_cmd_config *scan_cfg_out,
795                     struct mwifiex_ie_types_chan_list_param_set **chan_list_out,
796                     struct mwifiex_chan_scan_param_set *scan_chan_list,
797                     u8 *max_chan_per_scan, u8 *filtered_scan,
798                     u8 *scan_current_only)
799 {
800         struct mwifiex_adapter *adapter = priv->adapter;
801         struct mwifiex_ie_types_num_probes *num_probes_tlv;
802         struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
803         struct mwifiex_ie_types_bssid_list *bssid_tlv;
804         u8 *tlv_pos;
805         u32 num_probes;
806         u32 ssid_len;
807         u32 chan_idx;
808         u32 chan_num;
809         u32 scan_type;
810         u16 scan_dur;
811         u8 channel;
812         u8 radio_type;
813         int i;
814         u8 ssid_filter;
815         struct mwifiex_ie_types_htcap *ht_cap;
816
817         /* The tlv_buf_len is calculated for each scan command.  The TLVs added
818            in this routine will be preserved since the routine that sends the
819            command will append channelTLVs at *chan_list_out.  The difference
820            between the *chan_list_out and the tlv_buf start will be used to
821            calculate the size of anything we add in this routine. */
822         scan_cfg_out->tlv_buf_len = 0;
823
824         /* Running tlv pointer.  Assigned to chan_list_out at end of function
825            so later routines know where channels can be added to the command
826            buf */
827         tlv_pos = scan_cfg_out->tlv_buf;
828
829         /* Initialize the scan as un-filtered; the flag is later set to TRUE
830            below if a SSID or BSSID filter is sent in the command */
831         *filtered_scan = false;
832
833         /* Initialize the scan as not being only on the current channel.  If
834            the channel list is customized, only contains one channel, and is
835            the active channel, this is set true and data flow is not halted. */
836         *scan_current_only = false;
837
838         if (user_scan_in) {
839
840                 /* Default the ssid_filter flag to TRUE, set false under
841                    certain wildcard conditions and qualified by the existence
842                    of an SSID list before marking the scan as filtered */
843                 ssid_filter = true;
844
845                 /* Set the BSS type scan filter, use Adapter setting if
846                    unset */
847                 scan_cfg_out->bss_mode =
848                         (user_scan_in->bss_mode ? (u8) user_scan_in->
849                          bss_mode : (u8) adapter->scan_mode);
850
851                 /* Set the number of probes to send, use Adapter setting
852                    if unset */
853                 num_probes =
854                         (user_scan_in->num_probes ? user_scan_in->
855                          num_probes : adapter->scan_probes);
856
857                 /*
858                  * Set the BSSID filter to the incoming configuration,
859                  * if non-zero.  If not set, it will remain disabled
860                  * (all zeros).
861                  */
862                 memcpy(scan_cfg_out->specific_bssid,
863                        user_scan_in->specific_bssid,
864                        sizeof(scan_cfg_out->specific_bssid));
865
866                 if (adapter->ext_scan &&
867                     !is_zero_ether_addr(scan_cfg_out->specific_bssid)) {
868                         bssid_tlv =
869                                 (struct mwifiex_ie_types_bssid_list *)tlv_pos;
870                         bssid_tlv->header.type = cpu_to_le16(TLV_TYPE_BSSID);
871                         bssid_tlv->header.len = cpu_to_le16(ETH_ALEN);
872                         memcpy(bssid_tlv->bssid, user_scan_in->specific_bssid,
873                                ETH_ALEN);
874                         tlv_pos += sizeof(struct mwifiex_ie_types_bssid_list);
875                 }
876
877                 for (i = 0; i < user_scan_in->num_ssids; i++) {
878                         ssid_len = user_scan_in->ssid_list[i].ssid_len;
879
880                         wildcard_ssid_tlv =
881                                 (struct mwifiex_ie_types_wildcard_ssid_params *)
882                                 tlv_pos;
883                         wildcard_ssid_tlv->header.type =
884                                 cpu_to_le16(TLV_TYPE_WILDCARDSSID);
885                         wildcard_ssid_tlv->header.len = cpu_to_le16(
886                                 (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
887                                                          max_ssid_length)));
888
889                         /*
890                          * max_ssid_length = 0 tells firmware to perform
891                          * specific scan for the SSID filled, whereas
892                          * max_ssid_length = IEEE80211_MAX_SSID_LEN is for
893                          * wildcard scan.
894                          */
895                         if (ssid_len)
896                                 wildcard_ssid_tlv->max_ssid_length = 0;
897                         else
898                                 wildcard_ssid_tlv->max_ssid_length =
899                                                         IEEE80211_MAX_SSID_LEN;
900
901                         memcpy(wildcard_ssid_tlv->ssid,
902                                user_scan_in->ssid_list[i].ssid, ssid_len);
903
904                         tlv_pos += (sizeof(wildcard_ssid_tlv->header)
905                                 + le16_to_cpu(wildcard_ssid_tlv->header.len));
906
907                         dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n",
908                                 i, wildcard_ssid_tlv->ssid,
909                                 wildcard_ssid_tlv->max_ssid_length);
910
911                         /* Empty wildcard ssid with a maxlen will match many or
912                            potentially all SSIDs (maxlen == 32), therefore do
913                            not treat the scan as
914                            filtered. */
915                         if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
916                                 ssid_filter = false;
917                 }
918
919                 /*
920                  *  The default number of channels sent in the command is low to
921                  *  ensure the response buffer from the firmware does not
922                  *  truncate scan results.  That is not an issue with an SSID
923                  *  or BSSID filter applied to the scan results in the firmware.
924                  */
925                 if ((i && ssid_filter) ||
926                     !is_zero_ether_addr(scan_cfg_out->specific_bssid))
927                         *filtered_scan = true;
928         } else {
929                 scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
930                 num_probes = adapter->scan_probes;
931         }
932
933         /*
934          *  If a specific BSSID or SSID is used, the number of channels in the
935          *  scan command will be increased to the absolute maximum.
936          */
937         if (*filtered_scan)
938                 *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
939         else
940                 *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD;
941
942         /* If the input config or adapter has the number of Probes set,
943            add tlv */
944         if (num_probes) {
945
946                 dev_dbg(adapter->dev, "info: scan: num_probes = %d\n",
947                         num_probes);
948
949                 num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
950                 num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
951                 num_probes_tlv->header.len =
952                         cpu_to_le16(sizeof(num_probes_tlv->num_probes));
953                 num_probes_tlv->num_probes = cpu_to_le16((u16) num_probes);
954
955                 tlv_pos += sizeof(num_probes_tlv->header) +
956                         le16_to_cpu(num_probes_tlv->header.len);
957
958         }
959
960         if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
961             (priv->adapter->config_bands & BAND_GN ||
962              priv->adapter->config_bands & BAND_AN)) {
963                 ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
964                 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
965                 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
966                 ht_cap->header.len =
967                                 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
968                 radio_type =
969                         mwifiex_band_to_radio_type(priv->adapter->config_bands);
970                 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
971                 tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
972         }
973
974         /* Append vendor specific IE TLV */
975         mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_SCAN, &tlv_pos);
976
977         /*
978          * Set the output for the channel TLV to the address in the tlv buffer
979          *   past any TLVs that were added in this function (SSID, num_probes).
980          *   Channel TLVs will be added past this for each scan command,
981          *   preserving the TLVs that were previously added.
982          */
983         *chan_list_out =
984                 (struct mwifiex_ie_types_chan_list_param_set *) tlv_pos;
985
986         if (user_scan_in && user_scan_in->chan_list[0].chan_number) {
987
988                 dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n");
989
990                 for (chan_idx = 0;
991                      chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX &&
992                      user_scan_in->chan_list[chan_idx].chan_number;
993                      chan_idx++) {
994
995                         channel = user_scan_in->chan_list[chan_idx].chan_number;
996                         (scan_chan_list + chan_idx)->chan_number = channel;
997
998                         radio_type =
999                                 user_scan_in->chan_list[chan_idx].radio_type;
1000                         (scan_chan_list + chan_idx)->radio_type = radio_type;
1001
1002                         scan_type = user_scan_in->chan_list[chan_idx].scan_type;
1003
1004                         if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
1005                                 (scan_chan_list +
1006                                  chan_idx)->chan_scan_mode_bitmap
1007                                         |= MWIFIEX_PASSIVE_SCAN;
1008                         else
1009                                 (scan_chan_list +
1010                                  chan_idx)->chan_scan_mode_bitmap
1011                                         &= ~MWIFIEX_PASSIVE_SCAN;
1012
1013                         if (*filtered_scan)
1014                                 (scan_chan_list +
1015                                  chan_idx)->chan_scan_mode_bitmap
1016                                         |= MWIFIEX_DISABLE_CHAN_FILT;
1017
1018                         if (user_scan_in->chan_list[chan_idx].scan_time) {
1019                                 scan_dur = (u16) user_scan_in->
1020                                         chan_list[chan_idx].scan_time;
1021                         } else {
1022                                 if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
1023                                         scan_dur = adapter->passive_scan_time;
1024                                 else if (*filtered_scan)
1025                                         scan_dur = adapter->specific_scan_time;
1026                                 else
1027                                         scan_dur = adapter->active_scan_time;
1028                         }
1029
1030                         (scan_chan_list + chan_idx)->min_scan_time =
1031                                 cpu_to_le16(scan_dur);
1032                         (scan_chan_list + chan_idx)->max_scan_time =
1033                                 cpu_to_le16(scan_dur);
1034                 }
1035
1036                 /* Check if we are only scanning the current channel */
1037                 if ((chan_idx == 1) &&
1038                     (user_scan_in->chan_list[0].chan_number ==
1039                      priv->curr_bss_params.bss_descriptor.channel)) {
1040                         *scan_current_only = true;
1041                         dev_dbg(adapter->dev,
1042                                 "info: Scan: Scanning current channel only\n");
1043                 }
1044                 chan_num = chan_idx;
1045         } else {
1046                 dev_dbg(adapter->dev,
1047                         "info: Scan: Creating full region channel list\n");
1048                 chan_num = mwifiex_scan_create_channel_list(priv, user_scan_in,
1049                                                             scan_chan_list,
1050                                                             *filtered_scan);
1051         }
1052
1053         /*
1054          * In associated state we will reduce the number of channels scanned per
1055          * scan command to 1 to avoid any traffic delay/loss.
1056          */
1057         if (priv->media_connected)
1058                         *max_chan_per_scan = 1;
1059 }
1060
1061 /*
1062  * This function inspects the scan response buffer for pointers to
1063  * expected TLVs.
1064  *
1065  * TLVs can be included at the end of the scan response BSS information.
1066  *
1067  * Data in the buffer is parsed pointers to TLVs that can potentially
1068  * be passed back in the response.
1069  */
1070 static void
1071 mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
1072                                      struct mwifiex_ie_types_data *tlv,
1073                                      u32 tlv_buf_size, u32 req_tlv_type,
1074                                      struct mwifiex_ie_types_data **tlv_data)
1075 {
1076         struct mwifiex_ie_types_data *current_tlv;
1077         u32 tlv_buf_left;
1078         u32 tlv_type;
1079         u32 tlv_len;
1080
1081         current_tlv = tlv;
1082         tlv_buf_left = tlv_buf_size;
1083         *tlv_data = NULL;
1084
1085         dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n",
1086                 tlv_buf_size);
1087
1088         while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
1089
1090                 tlv_type = le16_to_cpu(current_tlv->header.type);
1091                 tlv_len = le16_to_cpu(current_tlv->header.len);
1092
1093                 if (sizeof(tlv->header) + tlv_len > tlv_buf_left) {
1094                         dev_err(adapter->dev, "SCAN_RESP: TLV buffer corrupt\n");
1095                         break;
1096                 }
1097
1098                 if (req_tlv_type == tlv_type) {
1099                         switch (tlv_type) {
1100                         case TLV_TYPE_TSFTIMESTAMP:
1101                                 dev_dbg(adapter->dev, "info: SCAN_RESP: TSF "
1102                                         "timestamp TLV, len = %d\n", tlv_len);
1103                                 *tlv_data = current_tlv;
1104                                 break;
1105                         case TLV_TYPE_CHANNELBANDLIST:
1106                                 dev_dbg(adapter->dev, "info: SCAN_RESP: channel"
1107                                         " band list TLV, len = %d\n", tlv_len);
1108                                 *tlv_data = current_tlv;
1109                                 break;
1110                         default:
1111                                 dev_err(adapter->dev,
1112                                         "SCAN_RESP: unhandled TLV = %d\n",
1113                                        tlv_type);
1114                                 /* Give up, this seems corrupted */
1115                                 return;
1116                         }
1117                 }
1118
1119                 if (*tlv_data)
1120                         break;
1121
1122
1123                 tlv_buf_left -= (sizeof(tlv->header) + tlv_len);
1124                 current_tlv =
1125                         (struct mwifiex_ie_types_data *) (current_tlv->data +
1126                                                           tlv_len);
1127
1128         }                       /* while */
1129 }
1130
1131 /*
1132  * This function parses provided beacon buffer and updates
1133  * respective fields in bss descriptor structure.
1134  */
1135 int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1136                                     struct mwifiex_bssdescriptor *bss_entry)
1137 {
1138         int ret = 0;
1139         u8 element_id;
1140         struct ieee_types_fh_param_set *fh_param_set;
1141         struct ieee_types_ds_param_set *ds_param_set;
1142         struct ieee_types_cf_param_set *cf_param_set;
1143         struct ieee_types_ibss_param_set *ibss_param_set;
1144         u8 *current_ptr;
1145         u8 *rate;
1146         u8 element_len;
1147         u16 total_ie_len;
1148         u8 bytes_to_copy;
1149         u8 rate_size;
1150         u8 found_data_rate_ie;
1151         u32 bytes_left;
1152         struct ieee_types_vendor_specific *vendor_ie;
1153         const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
1154         const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
1155
1156         found_data_rate_ie = false;
1157         rate_size = 0;
1158         current_ptr = bss_entry->beacon_buf;
1159         bytes_left = bss_entry->beacon_buf_size;
1160
1161         /* Process variable IE */
1162         while (bytes_left >= 2) {
1163                 element_id = *current_ptr;
1164                 element_len = *(current_ptr + 1);
1165                 total_ie_len = element_len + sizeof(struct ieee_types_header);
1166
1167                 if (bytes_left < total_ie_len) {
1168                         dev_err(adapter->dev, "err: InterpretIE: in processing"
1169                                 " IE, bytes left < IE length\n");
1170                         return -1;
1171                 }
1172                 switch (element_id) {
1173                 case WLAN_EID_SSID:
1174                         bss_entry->ssid.ssid_len = element_len;
1175                         memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
1176                                element_len);
1177                         dev_dbg(adapter->dev,
1178                                 "info: InterpretIE: ssid: %-32s\n",
1179                                 bss_entry->ssid.ssid);
1180                         break;
1181
1182                 case WLAN_EID_SUPP_RATES:
1183                         memcpy(bss_entry->data_rates, current_ptr + 2,
1184                                element_len);
1185                         memcpy(bss_entry->supported_rates, current_ptr + 2,
1186                                element_len);
1187                         rate_size = element_len;
1188                         found_data_rate_ie = true;
1189                         break;
1190
1191                 case WLAN_EID_FH_PARAMS:
1192                         fh_param_set =
1193                                 (struct ieee_types_fh_param_set *) current_ptr;
1194                         memcpy(&bss_entry->phy_param_set.fh_param_set,
1195                                fh_param_set,
1196                                sizeof(struct ieee_types_fh_param_set));
1197                         break;
1198
1199                 case WLAN_EID_DS_PARAMS:
1200                         ds_param_set =
1201                                 (struct ieee_types_ds_param_set *) current_ptr;
1202
1203                         bss_entry->channel = ds_param_set->current_chan;
1204
1205                         memcpy(&bss_entry->phy_param_set.ds_param_set,
1206                                ds_param_set,
1207                                sizeof(struct ieee_types_ds_param_set));
1208                         break;
1209
1210                 case WLAN_EID_CF_PARAMS:
1211                         cf_param_set =
1212                                 (struct ieee_types_cf_param_set *) current_ptr;
1213                         memcpy(&bss_entry->ss_param_set.cf_param_set,
1214                                cf_param_set,
1215                                sizeof(struct ieee_types_cf_param_set));
1216                         break;
1217
1218                 case WLAN_EID_IBSS_PARAMS:
1219                         ibss_param_set =
1220                                 (struct ieee_types_ibss_param_set *)
1221                                 current_ptr;
1222                         memcpy(&bss_entry->ss_param_set.ibss_param_set,
1223                                ibss_param_set,
1224                                sizeof(struct ieee_types_ibss_param_set));
1225                         break;
1226
1227                 case WLAN_EID_ERP_INFO:
1228                         bss_entry->erp_flags = *(current_ptr + 2);
1229                         break;
1230
1231                 case WLAN_EID_PWR_CONSTRAINT:
1232                         bss_entry->local_constraint = *(current_ptr + 2);
1233                         bss_entry->sensed_11h = true;
1234                         break;
1235
1236                 case WLAN_EID_CHANNEL_SWITCH:
1237                         bss_entry->chan_sw_ie_present = true;
1238                 case WLAN_EID_PWR_CAPABILITY:
1239                 case WLAN_EID_TPC_REPORT:
1240                 case WLAN_EID_QUIET:
1241                         bss_entry->sensed_11h = true;
1242                     break;
1243
1244                 case WLAN_EID_EXT_SUPP_RATES:
1245                         /*
1246                          * Only process extended supported rate
1247                          * if data rate is already found.
1248                          * Data rate IE should come before
1249                          * extended supported rate IE
1250                          */
1251                         if (found_data_rate_ie) {
1252                                 if ((element_len + rate_size) >
1253                                     MWIFIEX_SUPPORTED_RATES)
1254                                         bytes_to_copy =
1255                                                 (MWIFIEX_SUPPORTED_RATES -
1256                                                  rate_size);
1257                                 else
1258                                         bytes_to_copy = element_len;
1259
1260                                 rate = (u8 *) bss_entry->data_rates;
1261                                 rate += rate_size;
1262                                 memcpy(rate, current_ptr + 2, bytes_to_copy);
1263
1264                                 rate = (u8 *) bss_entry->supported_rates;
1265                                 rate += rate_size;
1266                                 memcpy(rate, current_ptr + 2, bytes_to_copy);
1267                         }
1268                         break;
1269
1270                 case WLAN_EID_VENDOR_SPECIFIC:
1271                         vendor_ie = (struct ieee_types_vendor_specific *)
1272                                         current_ptr;
1273
1274                         if (!memcmp
1275                             (vendor_ie->vend_hdr.oui, wpa_oui,
1276                              sizeof(wpa_oui))) {
1277                                 bss_entry->bcn_wpa_ie =
1278                                         (struct ieee_types_vendor_specific *)
1279                                         current_ptr;
1280                                 bss_entry->wpa_offset = (u16)
1281                                         (current_ptr - bss_entry->beacon_buf);
1282                         } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
1283                                     sizeof(wmm_oui))) {
1284                                 if (total_ie_len ==
1285                                     sizeof(struct ieee_types_wmm_parameter) ||
1286                                     total_ie_len ==
1287                                     sizeof(struct ieee_types_wmm_info))
1288                                         /*
1289                                          * Only accept and copy the WMM IE if
1290                                          * it matches the size expected for the
1291                                          * WMM Info IE or the WMM Parameter IE.
1292                                          */
1293                                         memcpy((u8 *) &bss_entry->wmm_ie,
1294                                                current_ptr, total_ie_len);
1295                         }
1296                         break;
1297                 case WLAN_EID_RSN:
1298                         bss_entry->bcn_rsn_ie =
1299                                 (struct ieee_types_generic *) current_ptr;
1300                         bss_entry->rsn_offset = (u16) (current_ptr -
1301                                                         bss_entry->beacon_buf);
1302                         break;
1303                 case WLAN_EID_BSS_AC_ACCESS_DELAY:
1304                         bss_entry->bcn_wapi_ie =
1305                                 (struct ieee_types_generic *) current_ptr;
1306                         bss_entry->wapi_offset = (u16) (current_ptr -
1307                                                         bss_entry->beacon_buf);
1308                         break;
1309                 case WLAN_EID_HT_CAPABILITY:
1310                         bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *)
1311                                         (current_ptr +
1312                                         sizeof(struct ieee_types_header));
1313                         bss_entry->ht_cap_offset = (u16) (current_ptr +
1314                                         sizeof(struct ieee_types_header) -
1315                                         bss_entry->beacon_buf);
1316                         break;
1317                 case WLAN_EID_HT_OPERATION:
1318                         bss_entry->bcn_ht_oper =
1319                                 (struct ieee80211_ht_operation *)(current_ptr +
1320                                         sizeof(struct ieee_types_header));
1321                         bss_entry->ht_info_offset = (u16) (current_ptr +
1322                                         sizeof(struct ieee_types_header) -
1323                                         bss_entry->beacon_buf);
1324                         break;
1325                 case WLAN_EID_VHT_CAPABILITY:
1326                         bss_entry->disable_11ac = false;
1327                         bss_entry->bcn_vht_cap =
1328                                 (void *)(current_ptr +
1329                                          sizeof(struct ieee_types_header));
1330                         bss_entry->vht_cap_offset =
1331                                         (u16)((u8 *)bss_entry->bcn_vht_cap -
1332                                               bss_entry->beacon_buf);
1333                         break;
1334                 case WLAN_EID_VHT_OPERATION:
1335                         bss_entry->bcn_vht_oper =
1336                                 (void *)(current_ptr +
1337                                          sizeof(struct ieee_types_header));
1338                         bss_entry->vht_info_offset =
1339                                         (u16)((u8 *)bss_entry->bcn_vht_oper -
1340                                               bss_entry->beacon_buf);
1341                         break;
1342                 case WLAN_EID_BSS_COEX_2040:
1343                         bss_entry->bcn_bss_co_2040 = current_ptr;
1344                         bss_entry->bss_co_2040_offset =
1345                                 (u16) (current_ptr - bss_entry->beacon_buf);
1346                         break;
1347                 case WLAN_EID_EXT_CAPABILITY:
1348                         bss_entry->bcn_ext_cap = current_ptr;
1349                         bss_entry->ext_cap_offset =
1350                                 (u16) (current_ptr - bss_entry->beacon_buf);
1351                         break;
1352                 case WLAN_EID_OPMODE_NOTIF:
1353                         bss_entry->oper_mode = (void *)current_ptr;
1354                         bss_entry->oper_mode_offset =
1355                                         (u16)((u8 *)bss_entry->oper_mode -
1356                                               bss_entry->beacon_buf);
1357                         break;
1358                 default:
1359                         break;
1360                 }
1361
1362                 current_ptr += element_len + 2;
1363
1364                 /* Need to account for IE ID and IE Len */
1365                 bytes_left -= (element_len + 2);
1366
1367         }       /* while (bytes_left > 2) */
1368         return ret;
1369 }
1370
1371 /*
1372  * This function converts radio type scan parameter to a band configuration
1373  * to be used in join command.
1374  */
1375 static u8
1376 mwifiex_radio_type_to_band(u8 radio_type)
1377 {
1378         switch (radio_type) {
1379         case HostCmd_SCAN_RADIO_TYPE_A:
1380                 return BAND_A;
1381         case HostCmd_SCAN_RADIO_TYPE_BG:
1382         default:
1383                 return BAND_G;
1384         }
1385 }
1386
1387 /*
1388  * This is an internal function used to start a scan based on an input
1389  * configuration.
1390  *
1391  * This uses the input user scan configuration information when provided in
1392  * order to send the appropriate scan commands to firmware to populate or
1393  * update the internal driver scan table.
1394  */
1395 int mwifiex_scan_networks(struct mwifiex_private *priv,
1396                           const struct mwifiex_user_scan_cfg *user_scan_in)
1397 {
1398         int ret;
1399         struct mwifiex_adapter *adapter = priv->adapter;
1400         struct cmd_ctrl_node *cmd_node;
1401         union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
1402         struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
1403         struct mwifiex_chan_scan_param_set *scan_chan_list;
1404         u8 filtered_scan;
1405         u8 scan_current_chan_only;
1406         u8 max_chan_per_scan;
1407         unsigned long flags;
1408
1409         if (adapter->scan_processing) {
1410                 dev_err(adapter->dev, "cmd: Scan already in process...\n");
1411                 return -EBUSY;
1412         }
1413
1414         if (priv->scan_block) {
1415                 dev_err(adapter->dev,
1416                         "cmd: Scan is blocked during association...\n");
1417                 return -EBUSY;
1418         }
1419
1420         spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1421         adapter->scan_processing = true;
1422         spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1423
1424         scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
1425                                GFP_KERNEL);
1426         if (!scan_cfg_out) {
1427                 ret = -ENOMEM;
1428                 goto done;
1429         }
1430
1431         scan_chan_list = kcalloc(MWIFIEX_USER_SCAN_CHAN_MAX,
1432                                  sizeof(struct mwifiex_chan_scan_param_set),
1433                                  GFP_KERNEL);
1434         if (!scan_chan_list) {
1435                 kfree(scan_cfg_out);
1436                 ret = -ENOMEM;
1437                 goto done;
1438         }
1439
1440         mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config,
1441                             &chan_list_out, scan_chan_list, &max_chan_per_scan,
1442                             &filtered_scan, &scan_current_chan_only);
1443
1444         ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
1445                                         &scan_cfg_out->config, chan_list_out,
1446                                         scan_chan_list);
1447
1448         /* Get scan command from scan_pending_q and put to cmd_pending_q */
1449         if (!ret) {
1450                 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1451                 if (!list_empty(&adapter->scan_pending_q)) {
1452                         cmd_node = list_first_entry(&adapter->scan_pending_q,
1453                                                     struct cmd_ctrl_node, list);
1454                         list_del(&cmd_node->list);
1455                         spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1456                                                flags);
1457                         mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1458                                                         true);
1459                         queue_work(adapter->workqueue, &adapter->main_work);
1460
1461                         /* Perform internal scan synchronously */
1462                         if (!priv->scan_request) {
1463                                 dev_dbg(adapter->dev, "wait internal scan\n");
1464                                 mwifiex_wait_queue_complete(adapter, cmd_node);
1465                         }
1466                 } else {
1467                         spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1468                                                flags);
1469                 }
1470         }
1471
1472         kfree(scan_cfg_out);
1473         kfree(scan_chan_list);
1474 done:
1475         if (ret) {
1476                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1477                 adapter->scan_processing = false;
1478                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1479         }
1480         return ret;
1481 }
1482
1483 /*
1484  * This function prepares a scan command to be sent to the firmware.
1485  *
1486  * This uses the scan command configuration sent to the command processing
1487  * module in command preparation stage to configure a scan command structure
1488  * to send to firmware.
1489  *
1490  * The fixed fields specifying the BSS type and BSSID filters as well as a
1491  * variable number/length of TLVs are sent in the command to firmware.
1492  *
1493  * Preparation also includes -
1494  *      - Setting command ID, and proper size
1495  *      - Ensuring correct endian-ness
1496  */
1497 int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
1498                             struct mwifiex_scan_cmd_config *scan_cfg)
1499 {
1500         struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan;
1501
1502         /* Set fixed field variables in scan command */
1503         scan_cmd->bss_mode = scan_cfg->bss_mode;
1504         memcpy(scan_cmd->bssid, scan_cfg->specific_bssid,
1505                sizeof(scan_cmd->bssid));
1506         memcpy(scan_cmd->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
1507
1508         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN);
1509
1510         /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
1511         cmd->size = cpu_to_le16((u16) (sizeof(scan_cmd->bss_mode)
1512                                           + sizeof(scan_cmd->bssid)
1513                                           + scan_cfg->tlv_buf_len + S_DS_GEN));
1514
1515         return 0;
1516 }
1517
1518 /*
1519  * This function checks compatibility of requested network with current
1520  * driver settings.
1521  */
1522 int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1523                                         struct mwifiex_bssdescriptor *bss_desc)
1524 {
1525         int ret = -1;
1526
1527         if (!bss_desc)
1528                 return -1;
1529
1530         if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band,
1531                              (u16) bss_desc->channel, 0))) {
1532                 switch (priv->bss_mode) {
1533                 case NL80211_IFTYPE_STATION:
1534                 case NL80211_IFTYPE_ADHOC:
1535                         ret = mwifiex_is_network_compatible(priv, bss_desc,
1536                                                             priv->bss_mode);
1537                         if (ret)
1538                                 dev_err(priv->adapter->dev,
1539                                         "Incompatible network settings\n");
1540                         break;
1541                 default:
1542                         ret = 0;
1543                 }
1544         }
1545
1546         return ret;
1547 }
1548
1549 static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1550                                           struct cfg80211_bss *bss)
1551 {
1552         struct mwifiex_bssdescriptor *bss_desc;
1553         int ret;
1554         unsigned long flags;
1555
1556         /* Allocate and fill new bss descriptor */
1557         bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), GFP_KERNEL);
1558         if (!bss_desc)
1559                 return -ENOMEM;
1560
1561         ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
1562         if (ret)
1563                 goto done;
1564
1565         ret = mwifiex_check_network_compatibility(priv, bss_desc);
1566         if (ret)
1567                 goto done;
1568
1569         spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
1570         /* Make a copy of current BSSID descriptor */
1571         memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
1572                sizeof(priv->curr_bss_params.bss_descriptor));
1573
1574         /* The contents of beacon_ie will be copied to its own buffer
1575          * in mwifiex_save_curr_bcn()
1576          */
1577         mwifiex_save_curr_bcn(priv);
1578         spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
1579
1580 done:
1581         /* beacon_ie buffer was allocated in function
1582          * mwifiex_fill_new_bss_desc(). Free it now.
1583          */
1584         kfree(bss_desc->beacon_buf);
1585         kfree(bss_desc);
1586         return 0;
1587 }
1588
1589 static int
1590 mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
1591                                   u32 *bytes_left, u64 fw_tsf, u8 *radio_type,
1592                                   bool ext_scan, s32 rssi_val)
1593 {
1594         struct mwifiex_adapter *adapter = priv->adapter;
1595         struct mwifiex_chan_freq_power *cfp;
1596         struct cfg80211_bss *bss;
1597         u8 bssid[ETH_ALEN];
1598         s32 rssi;
1599         const u8 *ie_buf;
1600         size_t ie_len;
1601         u16 channel = 0;
1602         u16 beacon_size = 0;
1603         u32 curr_bcn_bytes;
1604         u32 freq;
1605         u16 beacon_period;
1606         u16 cap_info_bitmap;
1607         u8 *current_ptr;
1608         u64 timestamp;
1609         struct mwifiex_fixed_bcn_param *bcn_param;
1610         struct mwifiex_bss_priv *bss_priv;
1611
1612         if (*bytes_left >= sizeof(beacon_size)) {
1613                 /* Extract & convert beacon size from command buffer */
1614                 memcpy(&beacon_size, *bss_info, sizeof(beacon_size));
1615                 *bytes_left -= sizeof(beacon_size);
1616                 *bss_info += sizeof(beacon_size);
1617         }
1618
1619         if (!beacon_size || beacon_size > *bytes_left) {
1620                 *bss_info += *bytes_left;
1621                 *bytes_left = 0;
1622                 return -EFAULT;
1623         }
1624
1625         /* Initialize the current working beacon pointer for this BSS
1626          * iteration
1627          */
1628         current_ptr = *bss_info;
1629
1630         /* Advance the return beacon pointer past the current beacon */
1631         *bss_info += beacon_size;
1632         *bytes_left -= beacon_size;
1633
1634         curr_bcn_bytes = beacon_size;
1635
1636         /* First 5 fields are bssid, RSSI(for legacy scan only),
1637          * time stamp, beacon interval, and capability information
1638          */
1639         if (curr_bcn_bytes < ETH_ALEN + sizeof(u8) +
1640             sizeof(struct mwifiex_fixed_bcn_param)) {
1641                 dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
1642                 return -EFAULT;
1643         }
1644
1645         memcpy(bssid, current_ptr, ETH_ALEN);
1646         current_ptr += ETH_ALEN;
1647         curr_bcn_bytes -= ETH_ALEN;
1648
1649         if (!ext_scan) {
1650                 rssi = (s32) *current_ptr;
1651                 rssi = (-rssi) * 100;           /* Convert dBm to mBm */
1652                 current_ptr += sizeof(u8);
1653                 curr_bcn_bytes -= sizeof(u8);
1654                 dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi);
1655         } else {
1656                 rssi = rssi_val;
1657         }
1658
1659         bcn_param = (struct mwifiex_fixed_bcn_param *)current_ptr;
1660         current_ptr += sizeof(*bcn_param);
1661         curr_bcn_bytes -= sizeof(*bcn_param);
1662
1663         timestamp = le64_to_cpu(bcn_param->timestamp);
1664         beacon_period = le16_to_cpu(bcn_param->beacon_period);
1665
1666         cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
1667         dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
1668                 cap_info_bitmap);
1669
1670         /* Rest of the current buffer are IE's */
1671         ie_buf = current_ptr;
1672         ie_len = curr_bcn_bytes;
1673         dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
1674                 curr_bcn_bytes);
1675
1676         while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
1677                 u8 element_id, element_len;
1678
1679                 element_id = *current_ptr;
1680                 element_len = *(current_ptr + 1);
1681                 if (curr_bcn_bytes < element_len +
1682                                 sizeof(struct ieee_types_header)) {
1683                         dev_err(adapter->dev,
1684                                 "%s: bytes left < IE length\n", __func__);
1685                         return -EFAULT;
1686                 }
1687                 if (element_id == WLAN_EID_DS_PARAMS) {
1688                         channel = *(current_ptr +
1689                                     sizeof(struct ieee_types_header));
1690                         break;
1691                 }
1692
1693                 current_ptr += element_len + sizeof(struct ieee_types_header);
1694                 curr_bcn_bytes -= element_len +
1695                                         sizeof(struct ieee_types_header);
1696         }
1697
1698         if (channel) {
1699                 struct ieee80211_channel *chan;
1700                 u8 band;
1701
1702                 /* Skip entry if on csa closed channel */
1703                 if (channel == priv->csa_chan) {
1704                         dev_dbg(adapter->dev,
1705                                 "Dropping entry on csa closed channel\n");
1706                         return 0;
1707                 }
1708
1709                 band = BAND_G;
1710                 if (radio_type)
1711                         band = mwifiex_radio_type_to_band(*radio_type &
1712                                                           (BIT(0) | BIT(1)));
1713
1714                 cfp = mwifiex_get_cfp(priv, band, channel, 0);
1715
1716                 freq = cfp ? cfp->freq : 0;
1717
1718                 chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
1719
1720                 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1721                         bss = cfg80211_inform_bss(priv->wdev->wiphy,
1722                                             chan, CFG80211_BSS_FTYPE_UNKNOWN,
1723                                             bssid, timestamp,
1724                                             cap_info_bitmap, beacon_period,
1725                                             ie_buf, ie_len, rssi, GFP_KERNEL);
1726                         bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1727                         bss_priv->band = band;
1728                         bss_priv->fw_tsf = fw_tsf;
1729                         if (priv->media_connected &&
1730                             !memcmp(bssid, priv->curr_bss_params.bss_descriptor
1731                                     .mac_address, ETH_ALEN))
1732                                 mwifiex_update_curr_bss_params(priv, bss);
1733                         cfg80211_put_bss(priv->wdev->wiphy, bss);
1734                 }
1735         } else {
1736                 dev_dbg(adapter->dev, "missing BSS channel IE\n");
1737         }
1738
1739         return 0;
1740 }
1741
1742 static void mwifiex_complete_scan(struct mwifiex_private *priv)
1743 {
1744         struct mwifiex_adapter *adapter = priv->adapter;
1745
1746         if (adapter->curr_cmd->wait_q_enabled) {
1747                 adapter->cmd_wait_q.status = 0;
1748                 if (!priv->scan_request) {
1749                         dev_dbg(adapter->dev, "complete internal scan\n");
1750                         mwifiex_complete_cmd(adapter, adapter->curr_cmd);
1751                 }
1752         }
1753 }
1754
1755 static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1756 {
1757         struct mwifiex_adapter *adapter = priv->adapter;
1758         struct cmd_ctrl_node *cmd_node;
1759         unsigned long flags;
1760
1761         spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1762         if (list_empty(&adapter->scan_pending_q)) {
1763                 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1764                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1765                 adapter->scan_processing = false;
1766                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1767
1768                 if (!adapter->ext_scan)
1769                         mwifiex_complete_scan(priv);
1770
1771                 if (priv->report_scan_result)
1772                         priv->report_scan_result = false;
1773
1774                 if (priv->scan_request) {
1775                         dev_dbg(adapter->dev, "info: notifying scan done\n");
1776                         cfg80211_scan_done(priv->scan_request, 0);
1777                         priv->scan_request = NULL;
1778                 } else {
1779                         priv->scan_aborting = false;
1780                         dev_dbg(adapter->dev, "info: scan already aborted\n");
1781                 }
1782         } else {
1783                 if ((priv->scan_aborting && !priv->scan_request) ||
1784                     priv->scan_block) {
1785                         spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1786                                                flags);
1787                         adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
1788                         mod_timer(&priv->scan_delay_timer, jiffies);
1789                         dev_dbg(priv->adapter->dev,
1790                                 "info: %s: triggerring scan abort\n", __func__);
1791                 } else if (!mwifiex_wmm_lists_empty(adapter) &&
1792                            (priv->scan_request && (priv->scan_request->flags &
1793                                             NL80211_SCAN_FLAG_LOW_PRIORITY))) {
1794                         spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1795                                                flags);
1796                         adapter->scan_delay_cnt = 1;
1797                         mod_timer(&priv->scan_delay_timer, jiffies +
1798                                   msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
1799                         dev_dbg(priv->adapter->dev,
1800                                 "info: %s: deferring scan\n", __func__);
1801                 } else {
1802                         /* Get scan command from scan_pending_q and put to
1803                          * cmd_pending_q
1804                          */
1805                         cmd_node = list_first_entry(&adapter->scan_pending_q,
1806                                                     struct cmd_ctrl_node, list);
1807                         list_del(&cmd_node->list);
1808                         spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1809                                                flags);
1810                         mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1811                                                         true);
1812                 }
1813         }
1814
1815         return;
1816 }
1817
1818 /*
1819  * This function handles the command response of scan.
1820  *
1821  * The response buffer for the scan command has the following
1822  * memory layout:
1823  *
1824  *      .-------------------------------------------------------------.
1825  *      |  Header (4 * sizeof(t_u16)):  Standard command response hdr |
1826  *      .-------------------------------------------------------------.
1827  *      |  BufSize (t_u16) : sizeof the BSS Description data          |
1828  *      .-------------------------------------------------------------.
1829  *      |  NumOfSet (t_u8) : Number of BSS Descs returned             |
1830  *      .-------------------------------------------------------------.
1831  *      |  BSSDescription data (variable, size given in BufSize)      |
1832  *      .-------------------------------------------------------------.
1833  *      |  TLV data (variable, size calculated using Header->Size,    |
1834  *      |            BufSize and sizeof the fixed fields above)       |
1835  *      .-------------------------------------------------------------.
1836  */
1837 int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1838                             struct host_cmd_ds_command *resp)
1839 {
1840         int ret = 0;
1841         struct mwifiex_adapter *adapter = priv->adapter;
1842         struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
1843         struct mwifiex_ie_types_data *tlv_data;
1844         struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
1845         u8 *bss_info;
1846         u32 scan_resp_size;
1847         u32 bytes_left;
1848         u32 idx;
1849         u32 tlv_buf_size;
1850         struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
1851         struct chan_band_param_set *chan_band;
1852         u8 is_bgscan_resp;
1853         __le64 fw_tsf = 0;
1854         u8 *radio_type;
1855
1856         is_bgscan_resp = (le16_to_cpu(resp->command)
1857                           == HostCmd_CMD_802_11_BG_SCAN_QUERY);
1858         if (is_bgscan_resp)
1859                 scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
1860         else
1861                 scan_rsp = &resp->params.scan_resp;
1862
1863
1864         if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
1865                 dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
1866                         scan_rsp->number_of_sets);
1867                 ret = -1;
1868                 goto check_next_scan;
1869         }
1870
1871         /* Check csa channel expiry before parsing scan response */
1872         mwifiex_11h_get_csa_closed_channel(priv);
1873
1874         bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
1875         dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
1876                 bytes_left);
1877
1878         scan_resp_size = le16_to_cpu(resp->size);
1879
1880         dev_dbg(adapter->dev,
1881                 "info: SCAN_RESP: returned %d APs before parsing\n",
1882                 scan_rsp->number_of_sets);
1883
1884         bss_info = scan_rsp->bss_desc_and_tlv_buffer;
1885
1886         /*
1887          * The size of the TLV buffer is equal to the entire command response
1888          *   size (scan_resp_size) minus the fixed fields (sizeof()'s), the
1889          *   BSS Descriptions (bss_descript_size as bytesLef) and the command
1890          *   response header (S_DS_GEN)
1891          */
1892         tlv_buf_size = scan_resp_size - (bytes_left
1893                                          + sizeof(scan_rsp->bss_descript_size)
1894                                          + sizeof(scan_rsp->number_of_sets)
1895                                          + S_DS_GEN);
1896
1897         tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
1898                                                  bss_desc_and_tlv_buffer +
1899                                                  bytes_left);
1900
1901         /* Search the TLV buffer space in the scan response for any valid
1902            TLVs */
1903         mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
1904                                              TLV_TYPE_TSFTIMESTAMP,
1905                                              (struct mwifiex_ie_types_data **)
1906                                              &tsf_tlv);
1907
1908         /* Search the TLV buffer space in the scan response for any valid
1909            TLVs */
1910         mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
1911                                              TLV_TYPE_CHANNELBANDLIST,
1912                                              (struct mwifiex_ie_types_data **)
1913                                              &chan_band_tlv);
1914
1915         for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
1916                 /*
1917                  * If the TSF TLV was appended to the scan results, save this
1918                  * entry's TSF value in the fw_tsf field. It is the firmware's
1919                  * TSF value at the time the beacon or probe response was
1920                  * received.
1921                  */
1922                 if (tsf_tlv)
1923                         memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
1924                                sizeof(fw_tsf));
1925
1926                 if (chan_band_tlv) {
1927                         chan_band = &chan_band_tlv->chan_band_param[idx];
1928                         radio_type = &chan_band->radio_type;
1929                 } else {
1930                         radio_type = NULL;
1931                 }
1932
1933                 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
1934                                                         &bytes_left,
1935                                                         le64_to_cpu(fw_tsf),
1936                                                         radio_type, false, 0);
1937                 if (ret)
1938                         goto check_next_scan;
1939         }
1940
1941 check_next_scan:
1942         mwifiex_check_next_scan_command(priv);
1943         return ret;
1944 }
1945
1946 /*
1947  * This function prepares an extended scan command to be sent to the firmware
1948  *
1949  * This uses the scan command configuration sent to the command processing
1950  * module in command preparation stage to configure a extended scan command
1951  * structure to send to firmware.
1952  */
1953 int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1954                                 struct host_cmd_ds_command *cmd,
1955                                 void *data_buf)
1956 {
1957         struct host_cmd_ds_802_11_scan_ext *ext_scan = &cmd->params.ext_scan;
1958         struct mwifiex_scan_cmd_config *scan_cfg = data_buf;
1959
1960         memcpy(ext_scan->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
1961
1962         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN_EXT);
1963
1964         /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
1965         cmd->size = cpu_to_le16((u16)(sizeof(ext_scan->reserved)
1966                                       + scan_cfg->tlv_buf_len + S_DS_GEN));
1967
1968         return 0;
1969 }
1970
1971 /* This function handles the command response of extended scan */
1972 int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv)
1973 {
1974         dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n");
1975
1976         mwifiex_complete_scan(priv);
1977
1978         return 0;
1979 }
1980
1981 /* This function This function handles the event extended scan report. It
1982  * parses extended scan results and informs to cfg80211 stack.
1983  */
1984 int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv,
1985                                          void *buf)
1986 {
1987         int ret = 0;
1988         struct mwifiex_adapter *adapter = priv->adapter;
1989         u8 *bss_info;
1990         u32 bytes_left, bytes_left_for_tlv, idx;
1991         u16 type, len;
1992         struct mwifiex_ie_types_data *tlv;
1993         struct mwifiex_ie_types_bss_scan_rsp *scan_rsp_tlv;
1994         struct mwifiex_ie_types_bss_scan_info *scan_info_tlv;
1995         u8 *radio_type;
1996         u64 fw_tsf = 0;
1997         s32 rssi = 0;
1998         struct mwifiex_event_scan_result *event_scan = buf;
1999         u8 num_of_set = event_scan->num_of_set;
2000         u8 *scan_resp = buf + sizeof(struct mwifiex_event_scan_result);
2001         u16 scan_resp_size = le16_to_cpu(event_scan->buf_size);
2002
2003         if (num_of_set > MWIFIEX_MAX_AP) {
2004                 dev_err(adapter->dev,
2005                         "EXT_SCAN: Invalid number of AP returned (%d)!!\n",
2006                         num_of_set);
2007                 ret = -1;
2008                 goto check_next_scan;
2009         }
2010
2011         bytes_left = scan_resp_size;
2012         dev_dbg(adapter->dev,
2013                 "EXT_SCAN: size %d, returned %d APs...",
2014                 scan_resp_size, num_of_set);
2015
2016         tlv = (struct mwifiex_ie_types_data *)scan_resp;
2017
2018         for (idx = 0; idx < num_of_set && bytes_left; idx++) {
2019                 type = le16_to_cpu(tlv->header.type);
2020                 len = le16_to_cpu(tlv->header.len);
2021                 if (bytes_left < sizeof(struct mwifiex_ie_types_header) + len) {
2022                         dev_err(adapter->dev, "EXT_SCAN: Error bytes left < TLV length\n");
2023                         break;
2024                 }
2025                 scan_rsp_tlv = NULL;
2026                 scan_info_tlv = NULL;
2027                 bytes_left_for_tlv = bytes_left;
2028
2029                 /* BSS response TLV with beacon or probe response buffer
2030                  * at the initial position of each descriptor
2031                  */
2032                 if (type != TLV_TYPE_BSS_SCAN_RSP)
2033                         break;
2034
2035                 bss_info = (u8 *)tlv;
2036                 scan_rsp_tlv = (struct mwifiex_ie_types_bss_scan_rsp *)tlv;
2037                 tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
2038                 bytes_left_for_tlv -=
2039                                 (len + sizeof(struct mwifiex_ie_types_header));
2040
2041                 while (bytes_left_for_tlv >=
2042                        sizeof(struct mwifiex_ie_types_header) &&
2043                        le16_to_cpu(tlv->header.type) != TLV_TYPE_BSS_SCAN_RSP) {
2044                         type = le16_to_cpu(tlv->header.type);
2045                         len = le16_to_cpu(tlv->header.len);
2046                         if (bytes_left_for_tlv <
2047                             sizeof(struct mwifiex_ie_types_header) + len) {
2048                                 dev_err(adapter->dev,
2049                                         "EXT_SCAN: Error in processing TLV, bytes left < TLV length\n");
2050                                 scan_rsp_tlv = NULL;
2051                                 bytes_left_for_tlv = 0;
2052                                 continue;
2053                         }
2054                         switch (type) {
2055                         case TLV_TYPE_BSS_SCAN_INFO:
2056                                 scan_info_tlv =
2057                                   (struct mwifiex_ie_types_bss_scan_info *)tlv;
2058                                 if (len !=
2059                                  sizeof(struct mwifiex_ie_types_bss_scan_info) -
2060                                  sizeof(struct mwifiex_ie_types_header)) {
2061                                         bytes_left_for_tlv = 0;
2062                                         continue;
2063                                 }
2064                                 break;
2065                         default:
2066                                 break;
2067                         }
2068                         tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
2069                         bytes_left -=
2070                                 (len + sizeof(struct mwifiex_ie_types_header));
2071                         bytes_left_for_tlv -=
2072                                 (len + sizeof(struct mwifiex_ie_types_header));
2073                 }
2074
2075                 if (!scan_rsp_tlv)
2076                         break;
2077
2078                 /* Advance pointer to the beacon buffer length and
2079                  * update the bytes count so that the function
2080                  * wlan_interpret_bss_desc_with_ie() can handle the
2081                  * scan buffer withut any change
2082                  */
2083                 bss_info += sizeof(u16);
2084                 bytes_left -= sizeof(u16);
2085
2086                 if (scan_info_tlv) {
2087                         rssi = (s32)(s16)(le16_to_cpu(scan_info_tlv->rssi));
2088                         rssi *= 100;           /* Convert dBm to mBm */
2089                         dev_dbg(adapter->dev,
2090                                 "info: InterpretIE: RSSI=%d\n", rssi);
2091                         fw_tsf = le64_to_cpu(scan_info_tlv->tsf);
2092                         radio_type = &scan_info_tlv->radio_type;
2093                 } else {
2094                         radio_type = NULL;
2095                 }
2096                 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
2097                                                         &bytes_left, fw_tsf,
2098                                                         radio_type, true, rssi);
2099                 if (ret)
2100                         goto check_next_scan;
2101         }
2102
2103 check_next_scan:
2104         if (!event_scan->more_event)
2105                 mwifiex_check_next_scan_command(priv);
2106
2107         return ret;
2108 }
2109
2110 /*
2111  * This function prepares command for background scan query.
2112  *
2113  * Preparation includes -
2114  *      - Setting command ID and proper size
2115  *      - Setting background scan flush parameter
2116  *      - Ensuring correct endian-ness
2117  */
2118 int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
2119 {
2120         struct host_cmd_ds_802_11_bg_scan_query *bg_query =
2121                 &cmd->params.bg_scan_query;
2122
2123         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY);
2124         cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_bg_scan_query)
2125                                 + S_DS_GEN);
2126
2127         bg_query->flush = 1;
2128
2129         return 0;
2130 }
2131
2132 /*
2133  * This function inserts scan command node to the scan pending queue.
2134  */
2135 void
2136 mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
2137                        struct cmd_ctrl_node *cmd_node)
2138 {
2139         struct mwifiex_adapter *adapter = priv->adapter;
2140         unsigned long flags;
2141
2142         cmd_node->wait_q_enabled = true;
2143         cmd_node->condition = &adapter->scan_wait_q_woken;
2144         spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
2145         list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
2146         spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
2147 }
2148
2149 /*
2150  * This function sends a scan command for all available channels to the
2151  * firmware, filtered on a specific SSID.
2152  */
2153 static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2154                                       struct cfg80211_ssid *req_ssid)
2155 {
2156         struct mwifiex_adapter *adapter = priv->adapter;
2157         int ret;
2158         struct mwifiex_user_scan_cfg *scan_cfg;
2159
2160         if (adapter->scan_processing) {
2161                 dev_err(adapter->dev, "cmd: Scan already in process...\n");
2162                 return -EBUSY;
2163         }
2164
2165         if (priv->scan_block) {
2166                 dev_err(adapter->dev,
2167                         "cmd: Scan is blocked during association...\n");
2168                 return -EBUSY;
2169         }
2170
2171         scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
2172         if (!scan_cfg)
2173                 return -ENOMEM;
2174
2175         scan_cfg->ssid_list = req_ssid;
2176         scan_cfg->num_ssids = 1;
2177
2178         ret = mwifiex_scan_networks(priv, scan_cfg);
2179
2180         kfree(scan_cfg);
2181         return ret;
2182 }
2183
2184 /*
2185  * Sends IOCTL request to start a scan.
2186  *
2187  * This function allocates the IOCTL request buffer, fills it
2188  * with requisite parameters and calls the IOCTL handler.
2189  *
2190  * Scan command can be issued for both normal scan and specific SSID
2191  * scan, depending upon whether an SSID is provided or not.
2192  */
2193 int mwifiex_request_scan(struct mwifiex_private *priv,
2194                          struct cfg80211_ssid *req_ssid)
2195 {
2196         int ret;
2197
2198         if (down_interruptible(&priv->async_sem)) {
2199                 dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
2200                         __func__);
2201                 return -1;
2202         }
2203
2204         priv->adapter->scan_wait_q_woken = false;
2205
2206         if (req_ssid && req_ssid->ssid_len != 0)
2207                 /* Specific SSID scan */
2208                 ret = mwifiex_scan_specific_ssid(priv, req_ssid);
2209         else
2210                 /* Normal scan */
2211                 ret = mwifiex_scan_networks(priv, NULL);
2212
2213         up(&priv->async_sem);
2214
2215         return ret;
2216 }
2217
2218 /*
2219  * This function appends the vendor specific IE TLV to a buffer.
2220  */
2221 int
2222 mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
2223                             u16 vsie_mask, u8 **buffer)
2224 {
2225         int id, ret_len = 0;
2226         struct mwifiex_ie_types_vendor_param_set *vs_param_set;
2227
2228         if (!buffer)
2229                 return 0;
2230         if (!(*buffer))
2231                 return 0;
2232
2233         /*
2234          * Traverse through the saved vendor specific IE array and append
2235          * the selected(scan/assoc/adhoc) IE as TLV to the command
2236          */
2237         for (id = 0; id < MWIFIEX_MAX_VSIE_NUM; id++) {
2238                 if (priv->vs_ie[id].mask & vsie_mask) {
2239                         vs_param_set =
2240                                 (struct mwifiex_ie_types_vendor_param_set *)
2241                                 *buffer;
2242                         vs_param_set->header.type =
2243                                 cpu_to_le16(TLV_TYPE_PASSTHROUGH);
2244                         vs_param_set->header.len =
2245                                 cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
2246                                 & 0x00FF) + 2);
2247                         memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
2248                                le16_to_cpu(vs_param_set->header.len));
2249                         *buffer += le16_to_cpu(vs_param_set->header.len) +
2250                                    sizeof(struct mwifiex_ie_types_header);
2251                         ret_len += le16_to_cpu(vs_param_set->header.len) +
2252                                    sizeof(struct mwifiex_ie_types_header);
2253                 }
2254         }
2255         return ret_len;
2256 }
2257
2258 /*
2259  * This function saves a beacon buffer of the current BSS descriptor.
2260  *
2261  * The current beacon buffer is saved so that it can be restored in the
2262  * following cases that makes the beacon buffer not to contain the current
2263  * ssid's beacon buffer.
2264  *      - The current ssid was not found somehow in the last scan.
2265  *      - The current ssid was the last entry of the scan table and overloaded.
2266  */
2267 void
2268 mwifiex_save_curr_bcn(struct mwifiex_private *priv)
2269 {
2270         struct mwifiex_bssdescriptor *curr_bss =
2271                 &priv->curr_bss_params.bss_descriptor;
2272
2273         if (!curr_bss->beacon_buf_size)
2274                 return;
2275
2276         /* allocate beacon buffer at 1st time; or if it's size has changed */
2277         if (!priv->curr_bcn_buf ||
2278             priv->curr_bcn_size != curr_bss->beacon_buf_size) {
2279                 priv->curr_bcn_size = curr_bss->beacon_buf_size;
2280
2281                 kfree(priv->curr_bcn_buf);
2282                 priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
2283                                              GFP_ATOMIC);
2284                 if (!priv->curr_bcn_buf)
2285                         return;
2286         }
2287
2288         memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
2289                curr_bss->beacon_buf_size);
2290         dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
2291                 priv->curr_bcn_size);
2292
2293         curr_bss->beacon_buf = priv->curr_bcn_buf;
2294
2295         /* adjust the pointers in the current BSS descriptor */
2296         if (curr_bss->bcn_wpa_ie)
2297                 curr_bss->bcn_wpa_ie =
2298                         (struct ieee_types_vendor_specific *)
2299                         (curr_bss->beacon_buf +
2300                          curr_bss->wpa_offset);
2301
2302         if (curr_bss->bcn_rsn_ie)
2303                 curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
2304                         (curr_bss->beacon_buf +
2305                          curr_bss->rsn_offset);
2306
2307         if (curr_bss->bcn_ht_cap)
2308                 curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
2309                         (curr_bss->beacon_buf +
2310                          curr_bss->ht_cap_offset);
2311
2312         if (curr_bss->bcn_ht_oper)
2313                 curr_bss->bcn_ht_oper = (struct ieee80211_ht_operation *)
2314                         (curr_bss->beacon_buf +
2315                          curr_bss->ht_info_offset);
2316
2317         if (curr_bss->bcn_vht_cap)
2318                 curr_bss->bcn_vht_cap = (void *)(curr_bss->beacon_buf +
2319                                                  curr_bss->vht_cap_offset);
2320
2321         if (curr_bss->bcn_vht_oper)
2322                 curr_bss->bcn_vht_oper = (void *)(curr_bss->beacon_buf +
2323                                                   curr_bss->vht_info_offset);
2324
2325         if (curr_bss->bcn_bss_co_2040)
2326                 curr_bss->bcn_bss_co_2040 =
2327                         (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset);
2328
2329         if (curr_bss->bcn_ext_cap)
2330                 curr_bss->bcn_ext_cap = curr_bss->beacon_buf +
2331                         curr_bss->ext_cap_offset;
2332
2333         if (curr_bss->oper_mode)
2334                 curr_bss->oper_mode = (void *)(curr_bss->beacon_buf +
2335                                                curr_bss->oper_mode_offset);
2336 }
2337
2338 /*
2339  * This function frees the current BSS descriptor beacon buffer.
2340  */
2341 void
2342 mwifiex_free_curr_bcn(struct mwifiex_private *priv)
2343 {
2344         kfree(priv->curr_bcn_buf);
2345         priv->curr_bcn_buf = NULL;
2346 }