GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / net / wireless / marvell / mwifiex / scan.c
1 /*
2  * NXP Wireless LAN device driver: scan ioctl and command handling
3  *
4  * Copyright 2011-2020 NXP
5  *
6  * This software file (the "File") is distributed by NXP
7  * 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 static void
80 _dbg_security_flags(int log_level, const char *func, const char *desc,
81                     struct mwifiex_private *priv,
82                     struct mwifiex_bssdescriptor *bss_desc)
83 {
84         _mwifiex_dbg(priv->adapter, log_level,
85                      "info: %s: %s:\twpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s\tEncMode=%#x privacy=%#x\n",
86                      func, desc,
87                      bss_desc->bcn_wpa_ie ?
88                      bss_desc->bcn_wpa_ie->vend_hdr.element_id : 0,
89                      bss_desc->bcn_rsn_ie ?
90                      bss_desc->bcn_rsn_ie->ieee_hdr.element_id : 0,
91                      priv->sec_info.wep_enabled ? "e" : "d",
92                      priv->sec_info.wpa_enabled ? "e" : "d",
93                      priv->sec_info.wpa2_enabled ? "e" : "d",
94                      priv->sec_info.encryption_mode,
95                      bss_desc->privacy);
96 }
97 #define dbg_security_flags(mask, desc, priv, bss_desc) \
98         _dbg_security_flags(MWIFIEX_DBG_##mask, desc, __func__, priv, bss_desc)
99
100 static bool
101 has_ieee_hdr(struct ieee_types_generic *ie, u8 key)
102 {
103         return (ie && ie->ieee_hdr.element_id == key);
104 }
105
106 static bool
107 has_vendor_hdr(struct ieee_types_vendor_specific *ie, u8 key)
108 {
109         return (ie && ie->vend_hdr.element_id == key);
110 }
111
112 /*
113  * This function parses a given IE for a given OUI.
114  *
115  * This is used to parse a WPA/RSN IE to find if it has
116  * a given oui in PTK.
117  */
118 static u8
119 mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
120 {
121         u8 count;
122
123         count = iebody->ptk_cnt[0];
124
125         /* There could be multiple OUIs for PTK hence
126            1) Take the length.
127            2) Check all the OUIs for AES.
128            3) If one of them is AES then pass success. */
129         while (count) {
130                 if (!memcmp(iebody->ptk_body, oui, sizeof(iebody->ptk_body)))
131                         return MWIFIEX_OUI_PRESENT;
132
133                 --count;
134                 if (count)
135                         iebody = (struct ie_body *) ((u8 *) iebody +
136                                                 sizeof(iebody->ptk_body));
137         }
138
139         pr_debug("info: %s: OUI is not found in PTK\n", __func__);
140         return MWIFIEX_OUI_NOT_PRESENT;
141 }
142
143 /*
144  * This function checks if a given OUI is present in a RSN IE.
145  *
146  * The function first checks if a RSN IE is present or not in the
147  * BSS descriptor. It tries to locate the OUI only if such an IE is
148  * present.
149  */
150 static u8
151 mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
152 {
153         u8 *oui;
154         struct ie_body *iebody;
155         u8 ret = MWIFIEX_OUI_NOT_PRESENT;
156
157         if (has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN)) {
158                 iebody = (struct ie_body *)
159                          (((u8 *) bss_desc->bcn_rsn_ie->data) +
160                           RSN_GTK_OUI_OFFSET);
161                 oui = &mwifiex_rsn_oui[cipher][0];
162                 ret = mwifiex_search_oui_in_ie(iebody, oui);
163                 if (ret)
164                         return ret;
165         }
166         return ret;
167 }
168
169 /*
170  * This function checks if a given OUI is present in a WPA IE.
171  *
172  * The function first checks if a WPA IE is present or not in the
173  * BSS descriptor. It tries to locate the OUI only if such an IE is
174  * present.
175  */
176 static u8
177 mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
178 {
179         u8 *oui;
180         struct ie_body *iebody;
181         u8 ret = MWIFIEX_OUI_NOT_PRESENT;
182
183         if (has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC)) {
184                 iebody = (struct ie_body *)((u8 *)bss_desc->bcn_wpa_ie->data +
185                                             WPA_GTK_OUI_OFFSET);
186                 oui = &mwifiex_wpa_oui[cipher][0];
187                 ret = mwifiex_search_oui_in_ie(iebody, oui);
188                 if (ret)
189                         return ret;
190         }
191         return ret;
192 }
193
194 /*
195  * This function compares two SSIDs and checks if they match.
196  */
197 s32
198 mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
199 {
200         if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
201                 return -1;
202         return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
203 }
204
205 /*
206  * This function checks if wapi is enabled in driver and scanned network is
207  * compatible with it.
208  */
209 static bool
210 mwifiex_is_bss_wapi(struct mwifiex_private *priv,
211                     struct mwifiex_bssdescriptor *bss_desc)
212 {
213         if (priv->sec_info.wapi_enabled &&
214             has_ieee_hdr(bss_desc->bcn_wapi_ie, WLAN_EID_BSS_AC_ACCESS_DELAY))
215                 return true;
216         return false;
217 }
218
219 /*
220  * This function checks if driver is configured with no security mode and
221  * scanned network is compatible with it.
222  */
223 static bool
224 mwifiex_is_bss_no_sec(struct mwifiex_private *priv,
225                       struct mwifiex_bssdescriptor *bss_desc)
226 {
227         if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
228             !priv->sec_info.wpa2_enabled &&
229             !has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC) &&
230             !has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN) &&
231             !priv->sec_info.encryption_mode && !bss_desc->privacy) {
232                 return true;
233         }
234         return false;
235 }
236
237 /*
238  * This function checks if static WEP is enabled in driver and scanned network
239  * is compatible with it.
240  */
241 static bool
242 mwifiex_is_bss_static_wep(struct mwifiex_private *priv,
243                           struct mwifiex_bssdescriptor *bss_desc)
244 {
245         if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
246             !priv->sec_info.wpa2_enabled && bss_desc->privacy) {
247                 return true;
248         }
249         return false;
250 }
251
252 /*
253  * This function checks if wpa is enabled in driver and scanned network is
254  * compatible with it.
255  */
256 static bool
257 mwifiex_is_bss_wpa(struct mwifiex_private *priv,
258                    struct mwifiex_bssdescriptor *bss_desc)
259 {
260         if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled &&
261             !priv->sec_info.wpa2_enabled &&
262             has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC)
263            /*
264             * Privacy bit may NOT be set in some APs like
265             * LinkSys WRT54G && bss_desc->privacy
266             */
267          ) {
268                 dbg_security_flags(INFO, "WPA", priv, bss_desc);
269                 return true;
270         }
271         return false;
272 }
273
274 /*
275  * This function checks if wpa2 is enabled in driver and scanned network is
276  * compatible with it.
277  */
278 static bool
279 mwifiex_is_bss_wpa2(struct mwifiex_private *priv,
280                     struct mwifiex_bssdescriptor *bss_desc)
281 {
282         if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
283             priv->sec_info.wpa2_enabled &&
284             has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN)) {
285                 /*
286                  * Privacy bit may NOT be set in some APs like
287                  * LinkSys WRT54G && bss_desc->privacy
288                  */
289                 dbg_security_flags(INFO, "WAP2", priv, bss_desc);
290                 return true;
291         }
292         return false;
293 }
294
295 /*
296  * This function checks if adhoc AES is enabled in driver and scanned network is
297  * compatible with it.
298  */
299 static bool
300 mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv,
301                          struct mwifiex_bssdescriptor *bss_desc)
302 {
303         if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
304             !priv->sec_info.wpa2_enabled &&
305             !has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC) &&
306             !has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN) &&
307             !priv->sec_info.encryption_mode && bss_desc->privacy) {
308                 return true;
309         }
310         return false;
311 }
312
313 /*
314  * This function checks if dynamic WEP is enabled in driver and scanned network
315  * is compatible with it.
316  */
317 static bool
318 mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv,
319                            struct mwifiex_bssdescriptor *bss_desc)
320 {
321         if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
322             !priv->sec_info.wpa2_enabled &&
323             !has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC) &&
324             !has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN) &&
325             priv->sec_info.encryption_mode && bss_desc->privacy) {
326                 dbg_security_flags(INFO, "dynamic", priv, bss_desc);
327                 return true;
328         }
329         return false;
330 }
331
332 /*
333  * This function checks if a scanned network is compatible with the driver
334  * settings.
335  *
336  *   WEP     WPA    WPA2   ad-hoc encrypt                  Network
337  * enabled enabled enabled  AES    mode   Privacy WPA WPA2 Compatible
338  *    0       0       0      0     NONE      0     0   0   yes No security
339  *    0       1       0      0      x        1x    1   x   yes WPA (disable
340  *                                                         HT if no AES)
341  *    0       0       1      0      x        1x    x   1   yes WPA2 (disable
342  *                                                         HT if no AES)
343  *    0       0       0      1     NONE      1     0   0   yes Ad-hoc AES
344  *    1       0       0      0     NONE      1     0   0   yes Static WEP
345  *                                                         (disable HT)
346  *    0       0       0      0    !=NONE     1     0   0   yes Dynamic WEP
347  *
348  * Compatibility is not matched while roaming, except for mode.
349  */
350 static s32
351 mwifiex_is_network_compatible(struct mwifiex_private *priv,
352                               struct mwifiex_bssdescriptor *bss_desc, u32 mode)
353 {
354         struct mwifiex_adapter *adapter = priv->adapter;
355
356         bss_desc->disable_11n = false;
357
358         /* Don't check for compatibility if roaming */
359         if (priv->media_connected &&
360             (priv->bss_mode == NL80211_IFTYPE_STATION) &&
361             (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
362                 return 0;
363
364         if (priv->wps.session_enable) {
365                 mwifiex_dbg(adapter, IOCTL,
366                             "info: return success directly in WPS period\n");
367                 return 0;
368         }
369
370         if (bss_desc->chan_sw_ie_present) {
371                 mwifiex_dbg(adapter, INFO,
372                             "Don't connect to AP with WLAN_EID_CHANNEL_SWITCH\n");
373                 return -1;
374         }
375
376         if (mwifiex_is_bss_wapi(priv, bss_desc)) {
377                 mwifiex_dbg(adapter, INFO,
378                             "info: return success for WAPI AP\n");
379                 return 0;
380         }
381
382         if (bss_desc->bss_mode == mode) {
383                 if (mwifiex_is_bss_no_sec(priv, bss_desc)) {
384                         /* No security */
385                         return 0;
386                 } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) {
387                         /* Static WEP enabled */
388                         mwifiex_dbg(adapter, INFO,
389                                     "info: Disable 11n in WEP mode.\n");
390                         bss_desc->disable_11n = true;
391                         return 0;
392                 } else if (mwifiex_is_bss_wpa(priv, bss_desc)) {
393                         /* WPA enabled */
394                         if (((priv->adapter->config_bands & BAND_GN ||
395                               priv->adapter->config_bands & BAND_AN) &&
396                              bss_desc->bcn_ht_cap) &&
397                             !mwifiex_is_wpa_oui_present(bss_desc,
398                                                          CIPHER_SUITE_CCMP)) {
399
400                                 if (mwifiex_is_wpa_oui_present
401                                                 (bss_desc, CIPHER_SUITE_TKIP)) {
402                                         mwifiex_dbg(adapter, INFO,
403                                                     "info: Disable 11n if AES\t"
404                                                     "is not supported by AP\n");
405                                         bss_desc->disable_11n = true;
406                                 } else {
407                                         return -1;
408                                 }
409                         }
410                         return 0;
411                 } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) {
412                         /* WPA2 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_rsn_oui_present(bss_desc,
417                                                         CIPHER_SUITE_CCMP)) {
418
419                                 if (mwifiex_is_rsn_oui_present
420                                                 (bss_desc, CIPHER_SUITE_TKIP)) {
421                                         mwifiex_dbg(adapter, INFO,
422                                                     "info: Disable 11n if AES\t"
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_adhoc_aes(priv, bss_desc)) {
431                         /* Ad-hoc AES enabled */
432                         return 0;
433                 } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) {
434                         /* Dynamic WEP enabled */
435                         return 0;
436                 }
437
438                 /* Security doesn't match */
439                 dbg_security_flags(ERROR, "failed", priv, bss_desc);
440                 return -1;
441         }
442
443         /* Mode doesn't match */
444         return -1;
445 }
446
447 /*
448  * This function creates a channel list for the driver to scan, based
449  * on region/band information.
450  *
451  * This routine is used for any scan that is not provided with a
452  * specific channel list to scan.
453  */
454 static int
455 mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
456                                  const struct mwifiex_user_scan_cfg
457                                                         *user_scan_in,
458                                  struct mwifiex_chan_scan_param_set
459                                                         *scan_chan_list,
460                                  u8 filtered_scan)
461 {
462         enum nl80211_band band;
463         struct ieee80211_supported_band *sband;
464         struct ieee80211_channel *ch;
465         struct mwifiex_adapter *adapter = priv->adapter;
466         int chan_idx = 0, i;
467
468         for (band = 0; (band < NUM_NL80211_BANDS) ; band++) {
469
470                 if (!priv->wdev.wiphy->bands[band])
471                         continue;
472
473                 sband = priv->wdev.wiphy->bands[band];
474
475                 for (i = 0; (i < sband->n_channels) ; i++) {
476                         ch = &sband->channels[i];
477                         if (ch->flags & IEEE80211_CHAN_DISABLED)
478                                 continue;
479                         scan_chan_list[chan_idx].radio_type = band;
480
481                         if (user_scan_in &&
482                             user_scan_in->chan_list[0].scan_time)
483                                 scan_chan_list[chan_idx].max_scan_time =
484                                         cpu_to_le16((u16) user_scan_in->
485                                         chan_list[0].scan_time);
486                         else if ((ch->flags & IEEE80211_CHAN_NO_IR) ||
487                                  (ch->flags & IEEE80211_CHAN_RADAR))
488                                 scan_chan_list[chan_idx].max_scan_time =
489                                         cpu_to_le16(adapter->passive_scan_time);
490                         else
491                                 scan_chan_list[chan_idx].max_scan_time =
492                                         cpu_to_le16(adapter->active_scan_time);
493
494                         if (ch->flags & IEEE80211_CHAN_NO_IR)
495                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
496                                         |= (MWIFIEX_PASSIVE_SCAN |
497                                             MWIFIEX_HIDDEN_SSID_REPORT);
498                         else
499                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
500                                         &= ~MWIFIEX_PASSIVE_SCAN;
501                         scan_chan_list[chan_idx].chan_number =
502                                                         (u32) ch->hw_value;
503
504                         scan_chan_list[chan_idx].chan_scan_mode_bitmap
505                                         |= MWIFIEX_DISABLE_CHAN_FILT;
506
507                         if (filtered_scan &&
508                             !((ch->flags & IEEE80211_CHAN_NO_IR) ||
509                               (ch->flags & IEEE80211_CHAN_RADAR)))
510                                 scan_chan_list[chan_idx].max_scan_time =
511                                 cpu_to_le16(adapter->specific_scan_time);
512
513                         chan_idx++;
514                 }
515
516         }
517         return chan_idx;
518 }
519
520 /* This function creates a channel list tlv for bgscan config, based
521  * on region/band information.
522  */
523 static int
524 mwifiex_bgscan_create_channel_list(struct mwifiex_private *priv,
525                                    const struct mwifiex_bg_scan_cfg
526                                                 *bgscan_cfg_in,
527                                    struct mwifiex_chan_scan_param_set
528                                                 *scan_chan_list)
529 {
530         enum nl80211_band band;
531         struct ieee80211_supported_band *sband;
532         struct ieee80211_channel *ch;
533         struct mwifiex_adapter *adapter = priv->adapter;
534         int chan_idx = 0, i;
535
536         for (band = 0; (band < NUM_NL80211_BANDS); band++) {
537                 if (!priv->wdev.wiphy->bands[band])
538                         continue;
539
540                 sband = priv->wdev.wiphy->bands[band];
541
542                 for (i = 0; (i < sband->n_channels) ; i++) {
543                         ch = &sband->channels[i];
544                         if (ch->flags & IEEE80211_CHAN_DISABLED)
545                                 continue;
546                         scan_chan_list[chan_idx].radio_type = band;
547
548                         if (bgscan_cfg_in->chan_list[0].scan_time)
549                                 scan_chan_list[chan_idx].max_scan_time =
550                                         cpu_to_le16((u16)bgscan_cfg_in->
551                                         chan_list[0].scan_time);
552                         else if (ch->flags & IEEE80211_CHAN_NO_IR)
553                                 scan_chan_list[chan_idx].max_scan_time =
554                                         cpu_to_le16(adapter->passive_scan_time);
555                         else
556                                 scan_chan_list[chan_idx].max_scan_time =
557                                         cpu_to_le16(adapter->
558                                                     specific_scan_time);
559
560                         if (ch->flags & IEEE80211_CHAN_NO_IR)
561                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
562                                         |= MWIFIEX_PASSIVE_SCAN;
563                         else
564                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
565                                         &= ~MWIFIEX_PASSIVE_SCAN;
566
567                         scan_chan_list[chan_idx].chan_number =
568                                                         (u32)ch->hw_value;
569                         chan_idx++;
570                 }
571         }
572         return chan_idx;
573 }
574
575 /* This function appends rate TLV to scan config command. */
576 static int
577 mwifiex_append_rate_tlv(struct mwifiex_private *priv,
578                         struct mwifiex_scan_cmd_config *scan_cfg_out,
579                         u8 radio)
580 {
581         struct mwifiex_ie_types_rates_param_set *rates_tlv;
582         u8 rates[MWIFIEX_SUPPORTED_RATES], *tlv_pos;
583         u32 rates_size;
584
585         memset(rates, 0, sizeof(rates));
586
587         tlv_pos = (u8 *)scan_cfg_out->tlv_buf + scan_cfg_out->tlv_buf_len;
588
589         if (priv->scan_request)
590                 rates_size = mwifiex_get_rates_from_cfg80211(priv, rates,
591                                                              radio);
592         else
593                 rates_size = mwifiex_get_supported_rates(priv, rates);
594
595         mwifiex_dbg(priv->adapter, CMD,
596                     "info: SCAN_CMD: Rates size = %d\n",
597                 rates_size);
598         rates_tlv = (struct mwifiex_ie_types_rates_param_set *)tlv_pos;
599         rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
600         rates_tlv->header.len = cpu_to_le16((u16) rates_size);
601         memcpy(rates_tlv->rates, rates, rates_size);
602         scan_cfg_out->tlv_buf_len += sizeof(rates_tlv->header) + rates_size;
603
604         return rates_size;
605 }
606
607 /*
608  * This function constructs and sends multiple scan config commands to
609  * the firmware.
610  *
611  * Previous routines in the code flow have created a scan command configuration
612  * with any requested TLVs.  This function splits the channel TLV into maximum
613  * channels supported per scan lists and sends the portion of the channel TLV,
614  * along with the other TLVs, to the firmware.
615  */
616 static int
617 mwifiex_scan_channel_list(struct mwifiex_private *priv,
618                           u32 max_chan_per_scan, u8 filtered_scan,
619                           struct mwifiex_scan_cmd_config *scan_cfg_out,
620                           struct mwifiex_ie_types_chan_list_param_set
621                           *chan_tlv_out,
622                           struct mwifiex_chan_scan_param_set *scan_chan_list)
623 {
624         struct mwifiex_adapter *adapter = priv->adapter;
625         int ret = 0;
626         struct mwifiex_chan_scan_param_set *tmp_chan_list;
627         struct mwifiex_chan_scan_param_set *start_chan;
628         u32 tlv_idx, rates_size, cmd_no;
629         u32 total_scan_time;
630         u32 done_early;
631         u8 radio_type;
632
633         if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
634                 mwifiex_dbg(priv->adapter, ERROR,
635                             "info: Scan: Null detect: %p, %p, %p\n",
636                             scan_cfg_out, chan_tlv_out, scan_chan_list);
637                 return -1;
638         }
639
640         /* Check csa channel expiry before preparing scan list */
641         mwifiex_11h_get_csa_closed_channel(priv);
642
643         chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
644
645         /* Set the temp channel struct pointer to the start of the desired
646            list */
647         tmp_chan_list = scan_chan_list;
648
649         /* Loop through the desired channel list, sending a new firmware scan
650            commands for each max_chan_per_scan channels (or for 1,6,11
651            individually if configured accordingly) */
652         while (tmp_chan_list->chan_number) {
653
654                 tlv_idx = 0;
655                 total_scan_time = 0;
656                 radio_type = 0;
657                 chan_tlv_out->header.len = 0;
658                 start_chan = tmp_chan_list;
659                 done_early = false;
660
661                 /*
662                  * Construct the Channel TLV for the scan command.  Continue to
663                  * insert channel TLVs until:
664                  *   - the tlv_idx hits the maximum configured per scan command
665                  *   - the next channel to insert is 0 (end of desired channel
666                  *     list)
667                  *   - done_early is set (controlling individual scanning of
668                  *     1,6,11)
669                  */
670                 while (tlv_idx < max_chan_per_scan &&
671                        tmp_chan_list->chan_number && !done_early) {
672
673                         if (tmp_chan_list->chan_number == priv->csa_chan) {
674                                 tmp_chan_list++;
675                                 continue;
676                         }
677
678                         radio_type = tmp_chan_list->radio_type;
679                         mwifiex_dbg(priv->adapter, INFO,
680                                     "info: Scan: Chan(%3d), Radio(%d),\t"
681                                     "Mode(%d, %d), Dur(%d)\n",
682                                     tmp_chan_list->chan_number,
683                                     tmp_chan_list->radio_type,
684                                     tmp_chan_list->chan_scan_mode_bitmap
685                                     & MWIFIEX_PASSIVE_SCAN,
686                                     (tmp_chan_list->chan_scan_mode_bitmap
687                                     & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
688                                     le16_to_cpu(tmp_chan_list->max_scan_time));
689
690                         /* Copy the current channel TLV to the command being
691                            prepared */
692                         memcpy(chan_tlv_out->chan_scan_param + tlv_idx,
693                                tmp_chan_list,
694                                sizeof(chan_tlv_out->chan_scan_param));
695
696                         /* Increment the TLV header length by the size
697                            appended */
698                         le16_unaligned_add_cpu(&chan_tlv_out->header.len,
699                                                sizeof(
700                                                 chan_tlv_out->chan_scan_param));
701
702                         /*
703                          * The tlv buffer length is set to the number of bytes
704                          * of the between the channel tlv pointer and the start
705                          * of the tlv buffer.  This compensates for any TLVs
706                          * that were appended before the channel list.
707                          */
708                         scan_cfg_out->tlv_buf_len = (u32) ((u8 *) chan_tlv_out -
709                                                         scan_cfg_out->tlv_buf);
710
711                         /* Add the size of the channel tlv header and the data
712                            length */
713                         scan_cfg_out->tlv_buf_len +=
714                                 (sizeof(chan_tlv_out->header)
715                                  + le16_to_cpu(chan_tlv_out->header.len));
716
717                         /* Increment the index to the channel tlv we are
718                            constructing */
719                         tlv_idx++;
720
721                         /* Count the total scan time per command */
722                         total_scan_time +=
723                                 le16_to_cpu(tmp_chan_list->max_scan_time);
724
725                         done_early = false;
726
727                         /* Stop the loop if the *current* channel is in the
728                            1,6,11 set and we are not filtering on a BSSID
729                            or SSID. */
730                         if (!filtered_scan &&
731                             (tmp_chan_list->chan_number == 1 ||
732                              tmp_chan_list->chan_number == 6 ||
733                              tmp_chan_list->chan_number == 11))
734                                 done_early = true;
735
736                         /* Increment the tmp pointer to the next channel to
737                            be scanned */
738                         tmp_chan_list++;
739
740                         /* Stop the loop if the *next* channel is in the 1,6,11
741                            set.  This will cause it to be the only channel
742                            scanned on the next interation */
743                         if (!filtered_scan &&
744                             (tmp_chan_list->chan_number == 1 ||
745                              tmp_chan_list->chan_number == 6 ||
746                              tmp_chan_list->chan_number == 11))
747                                 done_early = true;
748                 }
749
750                 /* The total scan time should be less than scan command timeout
751                    value */
752                 if (total_scan_time > MWIFIEX_MAX_TOTAL_SCAN_TIME) {
753                         mwifiex_dbg(priv->adapter, ERROR,
754                                     "total scan time %dms\t"
755                                     "is over limit (%dms), scan skipped\n",
756                                     total_scan_time,
757                                     MWIFIEX_MAX_TOTAL_SCAN_TIME);
758                         ret = -1;
759                         break;
760                 }
761
762                 rates_size = mwifiex_append_rate_tlv(priv, scan_cfg_out,
763                                                      radio_type);
764
765                 priv->adapter->scan_channels = start_chan;
766
767                 /* Send the scan command to the firmware with the specified
768                    cfg */
769                 if (priv->adapter->ext_scan)
770                         cmd_no = HostCmd_CMD_802_11_SCAN_EXT;
771                 else
772                         cmd_no = HostCmd_CMD_802_11_SCAN;
773
774                 ret = mwifiex_send_cmd(priv, cmd_no, HostCmd_ACT_GEN_SET,
775                                        0, scan_cfg_out, false);
776
777                 /* rate IE is updated per scan command but same starting
778                  * pointer is used each time so that rate IE from earlier
779                  * scan_cfg_out->buf is overwritten with new one.
780                  */
781                 scan_cfg_out->tlv_buf_len -=
782                             sizeof(struct mwifiex_ie_types_header) + rates_size;
783
784                 if (ret) {
785                         mwifiex_cancel_pending_scan_cmd(adapter);
786                         break;
787                 }
788         }
789
790         if (ret)
791                 return -1;
792
793         return 0;
794 }
795
796 /*
797  * This function constructs a scan command configuration structure to use
798  * in scan commands.
799  *
800  * Application layer or other functions can invoke network scanning
801  * with a scan configuration supplied in a user scan configuration structure.
802  * This structure is used as the basis of one or many scan command configuration
803  * commands that are sent to the command processing module and eventually to the
804  * firmware.
805  *
806  * This function creates a scan command configuration structure  based on the
807  * following user supplied parameters (if present):
808  *      - SSID filter
809  *      - BSSID filter
810  *      - Number of Probes to be sent
811  *      - Channel list
812  *
813  * If the SSID or BSSID filter is not present, the filter is disabled/cleared.
814  * If the number of probes is not set, adapter default setting is used.
815  */
816 static void
817 mwifiex_config_scan(struct mwifiex_private *priv,
818                     const struct mwifiex_user_scan_cfg *user_scan_in,
819                     struct mwifiex_scan_cmd_config *scan_cfg_out,
820                     struct mwifiex_ie_types_chan_list_param_set **chan_list_out,
821                     struct mwifiex_chan_scan_param_set *scan_chan_list,
822                     u8 *max_chan_per_scan, u8 *filtered_scan,
823                     u8 *scan_current_only)
824 {
825         struct mwifiex_adapter *adapter = priv->adapter;
826         struct mwifiex_ie_types_num_probes *num_probes_tlv;
827         struct mwifiex_ie_types_scan_chan_gap *chan_gap_tlv;
828         struct mwifiex_ie_types_random_mac *random_mac_tlv;
829         struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
830         struct mwifiex_ie_types_bssid_list *bssid_tlv;
831         u8 *tlv_pos;
832         u32 num_probes;
833         u32 ssid_len;
834         u32 chan_idx;
835         u32 scan_type;
836         u16 scan_dur;
837         u8 channel;
838         u8 radio_type;
839         int i;
840         u8 ssid_filter;
841         struct mwifiex_ie_types_htcap *ht_cap;
842         struct mwifiex_ie_types_bss_mode *bss_mode;
843         const u8 zero_mac[6] = {0, 0, 0, 0, 0, 0};
844
845         /* The tlv_buf_len is calculated for each scan command.  The TLVs added
846            in this routine will be preserved since the routine that sends the
847            command will append channelTLVs at *chan_list_out.  The difference
848            between the *chan_list_out and the tlv_buf start will be used to
849            calculate the size of anything we add in this routine. */
850         scan_cfg_out->tlv_buf_len = 0;
851
852         /* Running tlv pointer.  Assigned to chan_list_out at end of function
853            so later routines know where channels can be added to the command
854            buf */
855         tlv_pos = scan_cfg_out->tlv_buf;
856
857         /* Initialize the scan as un-filtered; the flag is later set to TRUE
858            below if a SSID or BSSID filter is sent in the command */
859         *filtered_scan = false;
860
861         /* Initialize the scan as not being only on the current channel.  If
862            the channel list is customized, only contains one channel, and is
863            the active channel, this is set true and data flow is not halted. */
864         *scan_current_only = false;
865
866         if (user_scan_in) {
867                 u8 tmpaddr[ETH_ALEN];
868
869                 /* Default the ssid_filter flag to TRUE, set false under
870                    certain wildcard conditions and qualified by the existence
871                    of an SSID list before marking the scan as filtered */
872                 ssid_filter = true;
873
874                 /* Set the BSS type scan filter, use Adapter setting if
875                    unset */
876                 scan_cfg_out->bss_mode =
877                         (u8)(user_scan_in->bss_mode ?: adapter->scan_mode);
878
879                 /* Set the number of probes to send, use Adapter setting
880                    if unset */
881                 num_probes = user_scan_in->num_probes ?: adapter->scan_probes;
882
883                 /*
884                  * Set the BSSID filter to the incoming configuration,
885                  * if non-zero.  If not set, it will remain disabled
886                  * (all zeros).
887                  */
888                 memcpy(scan_cfg_out->specific_bssid,
889                        user_scan_in->specific_bssid,
890                        sizeof(scan_cfg_out->specific_bssid));
891
892                 memcpy(tmpaddr, scan_cfg_out->specific_bssid, ETH_ALEN);
893
894                 if (adapter->ext_scan &&
895                     !is_zero_ether_addr(tmpaddr)) {
896                         bssid_tlv =
897                                 (struct mwifiex_ie_types_bssid_list *)tlv_pos;
898                         bssid_tlv->header.type = cpu_to_le16(TLV_TYPE_BSSID);
899                         bssid_tlv->header.len = cpu_to_le16(ETH_ALEN);
900                         memcpy(bssid_tlv->bssid, user_scan_in->specific_bssid,
901                                ETH_ALEN);
902                         tlv_pos += sizeof(struct mwifiex_ie_types_bssid_list);
903                 }
904
905                 for (i = 0; i < user_scan_in->num_ssids; i++) {
906                         ssid_len = user_scan_in->ssid_list[i].ssid_len;
907
908                         wildcard_ssid_tlv =
909                                 (struct mwifiex_ie_types_wildcard_ssid_params *)
910                                 tlv_pos;
911                         wildcard_ssid_tlv->header.type =
912                                 cpu_to_le16(TLV_TYPE_WILDCARDSSID);
913                         wildcard_ssid_tlv->header.len = cpu_to_le16(
914                                 (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
915                                                          max_ssid_length)));
916
917                         /*
918                          * max_ssid_length = 0 tells firmware to perform
919                          * specific scan for the SSID filled, whereas
920                          * max_ssid_length = IEEE80211_MAX_SSID_LEN is for
921                          * wildcard scan.
922                          */
923                         if (ssid_len)
924                                 wildcard_ssid_tlv->max_ssid_length = 0;
925                         else
926                                 wildcard_ssid_tlv->max_ssid_length =
927                                                         IEEE80211_MAX_SSID_LEN;
928
929                         if (!memcmp(user_scan_in->ssid_list[i].ssid,
930                                     "DIRECT-", 7))
931                                 wildcard_ssid_tlv->max_ssid_length = 0xfe;
932
933                         memcpy(wildcard_ssid_tlv->ssid,
934                                user_scan_in->ssid_list[i].ssid, ssid_len);
935
936                         tlv_pos += (sizeof(wildcard_ssid_tlv->header)
937                                 + le16_to_cpu(wildcard_ssid_tlv->header.len));
938
939                         mwifiex_dbg(adapter, INFO,
940                                     "info: scan: ssid[%d]: %s, %d\n",
941                                     i, wildcard_ssid_tlv->ssid,
942                                     wildcard_ssid_tlv->max_ssid_length);
943
944                         /* Empty wildcard ssid with a maxlen will match many or
945                            potentially all SSIDs (maxlen == 32), therefore do
946                            not treat the scan as
947                            filtered. */
948                         if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
949                                 ssid_filter = false;
950                 }
951
952                 /*
953                  *  The default number of channels sent in the command is low to
954                  *  ensure the response buffer from the firmware does not
955                  *  truncate scan results.  That is not an issue with an SSID
956                  *  or BSSID filter applied to the scan results in the firmware.
957                  */
958                 memcpy(tmpaddr, scan_cfg_out->specific_bssid, ETH_ALEN);
959                 if ((i && ssid_filter) ||
960                     !is_zero_ether_addr(tmpaddr))
961                         *filtered_scan = true;
962
963                 if (user_scan_in->scan_chan_gap) {
964                         mwifiex_dbg(adapter, INFO,
965                                     "info: scan: channel gap = %d\n",
966                                     user_scan_in->scan_chan_gap);
967                         *max_chan_per_scan =
968                                         MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
969
970                         chan_gap_tlv = (void *)tlv_pos;
971                         chan_gap_tlv->header.type =
972                                          cpu_to_le16(TLV_TYPE_SCAN_CHANNEL_GAP);
973                         chan_gap_tlv->header.len =
974                                     cpu_to_le16(sizeof(chan_gap_tlv->chan_gap));
975                         chan_gap_tlv->chan_gap =
976                                      cpu_to_le16((user_scan_in->scan_chan_gap));
977                         tlv_pos +=
978                                   sizeof(struct mwifiex_ie_types_scan_chan_gap);
979                 }
980
981                 if (!ether_addr_equal(user_scan_in->random_mac, zero_mac)) {
982                         random_mac_tlv = (void *)tlv_pos;
983                         random_mac_tlv->header.type =
984                                          cpu_to_le16(TLV_TYPE_RANDOM_MAC);
985                         random_mac_tlv->header.len =
986                                     cpu_to_le16(sizeof(random_mac_tlv->mac));
987                         ether_addr_copy(random_mac_tlv->mac,
988                                         user_scan_in->random_mac);
989                         tlv_pos +=
990                                   sizeof(struct mwifiex_ie_types_random_mac);
991                 }
992         } else {
993                 scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
994                 num_probes = adapter->scan_probes;
995         }
996
997         /*
998          *  If a specific BSSID or SSID is used, the number of channels in the
999          *  scan command will be increased to the absolute maximum.
1000          */
1001         if (*filtered_scan) {
1002                 *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
1003         } else {
1004                 if (!priv->media_connected)
1005                         *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD;
1006                 else
1007                         *max_chan_per_scan =
1008                                         MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD / 2;
1009         }
1010
1011         if (adapter->ext_scan) {
1012                 bss_mode = (struct mwifiex_ie_types_bss_mode *)tlv_pos;
1013                 bss_mode->header.type = cpu_to_le16(TLV_TYPE_BSS_MODE);
1014                 bss_mode->header.len = cpu_to_le16(sizeof(bss_mode->bss_mode));
1015                 bss_mode->bss_mode = scan_cfg_out->bss_mode;
1016                 tlv_pos += sizeof(bss_mode->header) +
1017                            le16_to_cpu(bss_mode->header.len);
1018         }
1019
1020         /* If the input config or adapter has the number of Probes set,
1021            add tlv */
1022         if (num_probes) {
1023
1024                 mwifiex_dbg(adapter, INFO,
1025                             "info: scan: num_probes = %d\n",
1026                             num_probes);
1027
1028                 num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
1029                 num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
1030                 num_probes_tlv->header.len =
1031                         cpu_to_le16(sizeof(num_probes_tlv->num_probes));
1032                 num_probes_tlv->num_probes = cpu_to_le16((u16) num_probes);
1033
1034                 tlv_pos += sizeof(num_probes_tlv->header) +
1035                         le16_to_cpu(num_probes_tlv->header.len);
1036
1037         }
1038
1039         if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
1040             (priv->adapter->config_bands & BAND_GN ||
1041              priv->adapter->config_bands & BAND_AN)) {
1042                 ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
1043                 memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
1044                 ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
1045                 ht_cap->header.len =
1046                                 cpu_to_le16(sizeof(struct ieee80211_ht_cap));
1047                 radio_type =
1048                         mwifiex_band_to_radio_type(priv->adapter->config_bands);
1049                 mwifiex_fill_cap_info(priv, radio_type, &ht_cap->ht_cap);
1050                 tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
1051         }
1052
1053         /* Append vendor specific IE TLV */
1054         mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_SCAN, &tlv_pos);
1055
1056         /*
1057          * Set the output for the channel TLV to the address in the tlv buffer
1058          *   past any TLVs that were added in this function (SSID, num_probes).
1059          *   Channel TLVs will be added past this for each scan command,
1060          *   preserving the TLVs that were previously added.
1061          */
1062         *chan_list_out =
1063                 (struct mwifiex_ie_types_chan_list_param_set *) tlv_pos;
1064
1065         if (user_scan_in && user_scan_in->chan_list[0].chan_number) {
1066
1067                 mwifiex_dbg(adapter, INFO,
1068                             "info: Scan: Using supplied channel list\n");
1069
1070                 for (chan_idx = 0;
1071                      chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX &&
1072                      user_scan_in->chan_list[chan_idx].chan_number;
1073                      chan_idx++) {
1074
1075                         channel = user_scan_in->chan_list[chan_idx].chan_number;
1076                         scan_chan_list[chan_idx].chan_number = channel;
1077
1078                         radio_type =
1079                                 user_scan_in->chan_list[chan_idx].radio_type;
1080                         scan_chan_list[chan_idx].radio_type = radio_type;
1081
1082                         scan_type = user_scan_in->chan_list[chan_idx].scan_type;
1083
1084                         if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
1085                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
1086                                         |= (MWIFIEX_PASSIVE_SCAN |
1087                                             MWIFIEX_HIDDEN_SSID_REPORT);
1088                         else
1089                                 scan_chan_list[chan_idx].chan_scan_mode_bitmap
1090                                         &= ~MWIFIEX_PASSIVE_SCAN;
1091
1092                         scan_chan_list[chan_idx].chan_scan_mode_bitmap
1093                                 |= MWIFIEX_DISABLE_CHAN_FILT;
1094
1095                         if (user_scan_in->chan_list[chan_idx].scan_time) {
1096                                 scan_dur = (u16) user_scan_in->
1097                                         chan_list[chan_idx].scan_time;
1098                         } else {
1099                                 if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
1100                                         scan_dur = adapter->passive_scan_time;
1101                                 else if (*filtered_scan)
1102                                         scan_dur = adapter->specific_scan_time;
1103                                 else
1104                                         scan_dur = adapter->active_scan_time;
1105                         }
1106
1107                         scan_chan_list[chan_idx].min_scan_time =
1108                                 cpu_to_le16(scan_dur);
1109                         scan_chan_list[chan_idx].max_scan_time =
1110                                 cpu_to_le16(scan_dur);
1111                 }
1112
1113                 /* Check if we are only scanning the current channel */
1114                 if ((chan_idx == 1) &&
1115                     (user_scan_in->chan_list[0].chan_number ==
1116                      priv->curr_bss_params.bss_descriptor.channel)) {
1117                         *scan_current_only = true;
1118                         mwifiex_dbg(adapter, INFO,
1119                                     "info: Scan: Scanning current channel only\n");
1120                 }
1121         } else {
1122                 mwifiex_dbg(adapter, INFO,
1123                             "info: Scan: Creating full region channel list\n");
1124                 mwifiex_scan_create_channel_list(priv, user_scan_in,
1125                                                  scan_chan_list,
1126                                                  *filtered_scan);
1127         }
1128
1129 }
1130
1131 /*
1132  * This function inspects the scan response buffer for pointers to
1133  * expected TLVs.
1134  *
1135  * TLVs can be included at the end of the scan response BSS information.
1136  *
1137  * Data in the buffer is parsed pointers to TLVs that can potentially
1138  * be passed back in the response.
1139  */
1140 static void
1141 mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
1142                                      struct mwifiex_ie_types_data *tlv,
1143                                      u32 tlv_buf_size, u32 req_tlv_type,
1144                                      struct mwifiex_ie_types_data **tlv_data)
1145 {
1146         struct mwifiex_ie_types_data *current_tlv;
1147         u32 tlv_buf_left;
1148         u32 tlv_type;
1149         u32 tlv_len;
1150
1151         current_tlv = tlv;
1152         tlv_buf_left = tlv_buf_size;
1153         *tlv_data = NULL;
1154
1155         mwifiex_dbg(adapter, INFO,
1156                     "info: SCAN_RESP: tlv_buf_size = %d\n",
1157                     tlv_buf_size);
1158
1159         while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
1160
1161                 tlv_type = le16_to_cpu(current_tlv->header.type);
1162                 tlv_len = le16_to_cpu(current_tlv->header.len);
1163
1164                 if (sizeof(tlv->header) + tlv_len > tlv_buf_left) {
1165                         mwifiex_dbg(adapter, ERROR,
1166                                     "SCAN_RESP: TLV buffer corrupt\n");
1167                         break;
1168                 }
1169
1170                 if (req_tlv_type == tlv_type) {
1171                         switch (tlv_type) {
1172                         case TLV_TYPE_TSFTIMESTAMP:
1173                                 mwifiex_dbg(adapter, INFO,
1174                                             "info: SCAN_RESP: TSF\t"
1175                                             "timestamp TLV, len = %d\n",
1176                                             tlv_len);
1177                                 *tlv_data = current_tlv;
1178                                 break;
1179                         case TLV_TYPE_CHANNELBANDLIST:
1180                                 mwifiex_dbg(adapter, INFO,
1181                                             "info: SCAN_RESP: channel\t"
1182                                             "band list TLV, len = %d\n",
1183                                             tlv_len);
1184                                 *tlv_data = current_tlv;
1185                                 break;
1186                         default:
1187                                 mwifiex_dbg(adapter, ERROR,
1188                                             "SCAN_RESP: unhandled TLV = %d\n",
1189                                             tlv_type);
1190                                 /* Give up, this seems corrupted */
1191                                 return;
1192                         }
1193                 }
1194
1195                 if (*tlv_data)
1196                         break;
1197
1198
1199                 tlv_buf_left -= (sizeof(tlv->header) + tlv_len);
1200                 current_tlv =
1201                         (struct mwifiex_ie_types_data *) (current_tlv->data +
1202                                                           tlv_len);
1203
1204         }                       /* while */
1205 }
1206
1207 /*
1208  * This function parses provided beacon buffer and updates
1209  * respective fields in bss descriptor structure.
1210  */
1211 int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1212                                     struct mwifiex_bssdescriptor *bss_entry)
1213 {
1214         u8 element_id;
1215         struct ieee_types_fh_param_set *fh_param_set;
1216         struct ieee_types_ds_param_set *ds_param_set;
1217         struct ieee_types_cf_param_set *cf_param_set;
1218         struct ieee_types_ibss_param_set *ibss_param_set;
1219         u8 *current_ptr;
1220         u8 *rate;
1221         u8 element_len;
1222         u16 total_ie_len;
1223         u8 bytes_to_copy;
1224         u8 rate_size;
1225         u8 found_data_rate_ie;
1226         u32 bytes_left;
1227         struct ieee_types_vendor_specific *vendor_ie;
1228         const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
1229         const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
1230
1231         found_data_rate_ie = false;
1232         rate_size = 0;
1233         current_ptr = bss_entry->beacon_buf;
1234         bytes_left = bss_entry->beacon_buf_size;
1235
1236         /* Process variable IE */
1237         while (bytes_left >= 2) {
1238                 element_id = *current_ptr;
1239                 element_len = *(current_ptr + 1);
1240                 total_ie_len = element_len + sizeof(struct ieee_types_header);
1241
1242                 if (bytes_left < total_ie_len) {
1243                         mwifiex_dbg(adapter, ERROR,
1244                                     "err: InterpretIE: in processing\t"
1245                                     "IE, bytes left < IE length\n");
1246                         return -EINVAL;
1247                 }
1248                 switch (element_id) {
1249                 case WLAN_EID_SSID:
1250                         if (element_len > IEEE80211_MAX_SSID_LEN)
1251                                 return -EINVAL;
1252                         bss_entry->ssid.ssid_len = element_len;
1253                         memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
1254                                element_len);
1255                         mwifiex_dbg(adapter, INFO,
1256                                     "info: InterpretIE: ssid: %-32s\n",
1257                                     bss_entry->ssid.ssid);
1258                         break;
1259
1260                 case WLAN_EID_SUPP_RATES:
1261                         if (element_len > MWIFIEX_SUPPORTED_RATES)
1262                                 return -EINVAL;
1263                         memcpy(bss_entry->data_rates, current_ptr + 2,
1264                                element_len);
1265                         memcpy(bss_entry->supported_rates, current_ptr + 2,
1266                                element_len);
1267                         rate_size = element_len;
1268                         found_data_rate_ie = true;
1269                         break;
1270
1271                 case WLAN_EID_FH_PARAMS:
1272                         if (total_ie_len < sizeof(*fh_param_set))
1273                                 return -EINVAL;
1274                         fh_param_set =
1275                                 (struct ieee_types_fh_param_set *) current_ptr;
1276                         memcpy(&bss_entry->phy_param_set.fh_param_set,
1277                                fh_param_set,
1278                                sizeof(struct ieee_types_fh_param_set));
1279                         break;
1280
1281                 case WLAN_EID_DS_PARAMS:
1282                         if (total_ie_len < sizeof(*ds_param_set))
1283                                 return -EINVAL;
1284                         ds_param_set =
1285                                 (struct ieee_types_ds_param_set *) current_ptr;
1286
1287                         bss_entry->channel = ds_param_set->current_chan;
1288
1289                         memcpy(&bss_entry->phy_param_set.ds_param_set,
1290                                ds_param_set,
1291                                sizeof(struct ieee_types_ds_param_set));
1292                         break;
1293
1294                 case WLAN_EID_CF_PARAMS:
1295                         if (total_ie_len < sizeof(*cf_param_set))
1296                                 return -EINVAL;
1297                         cf_param_set =
1298                                 (struct ieee_types_cf_param_set *) current_ptr;
1299                         memcpy(&bss_entry->ss_param_set.cf_param_set,
1300                                cf_param_set,
1301                                sizeof(struct ieee_types_cf_param_set));
1302                         break;
1303
1304                 case WLAN_EID_IBSS_PARAMS:
1305                         if (total_ie_len < sizeof(*ibss_param_set))
1306                                 return -EINVAL;
1307                         ibss_param_set =
1308                                 (struct ieee_types_ibss_param_set *)
1309                                 current_ptr;
1310                         memcpy(&bss_entry->ss_param_set.ibss_param_set,
1311                                ibss_param_set,
1312                                sizeof(struct ieee_types_ibss_param_set));
1313                         break;
1314
1315                 case WLAN_EID_ERP_INFO:
1316                         if (!element_len)
1317                                 return -EINVAL;
1318                         bss_entry->erp_flags = *(current_ptr + 2);
1319                         break;
1320
1321                 case WLAN_EID_PWR_CONSTRAINT:
1322                         if (!element_len)
1323                                 return -EINVAL;
1324                         bss_entry->local_constraint = *(current_ptr + 2);
1325                         bss_entry->sensed_11h = true;
1326                         break;
1327
1328                 case WLAN_EID_CHANNEL_SWITCH:
1329                         bss_entry->chan_sw_ie_present = true;
1330                         fallthrough;
1331                 case WLAN_EID_PWR_CAPABILITY:
1332                 case WLAN_EID_TPC_REPORT:
1333                 case WLAN_EID_QUIET:
1334                         bss_entry->sensed_11h = true;
1335                     break;
1336
1337                 case WLAN_EID_EXT_SUPP_RATES:
1338                         /*
1339                          * Only process extended supported rate
1340                          * if data rate is already found.
1341                          * Data rate IE should come before
1342                          * extended supported rate IE
1343                          */
1344                         if (found_data_rate_ie) {
1345                                 if ((element_len + rate_size) >
1346                                     MWIFIEX_SUPPORTED_RATES)
1347                                         bytes_to_copy =
1348                                                 (MWIFIEX_SUPPORTED_RATES -
1349                                                  rate_size);
1350                                 else
1351                                         bytes_to_copy = element_len;
1352
1353                                 rate = (u8 *) bss_entry->data_rates;
1354                                 rate += rate_size;
1355                                 memcpy(rate, current_ptr + 2, bytes_to_copy);
1356
1357                                 rate = (u8 *) bss_entry->supported_rates;
1358                                 rate += rate_size;
1359                                 memcpy(rate, current_ptr + 2, bytes_to_copy);
1360                         }
1361                         break;
1362
1363                 case WLAN_EID_VENDOR_SPECIFIC:
1364                         vendor_ie = (struct ieee_types_vendor_specific *)
1365                                         current_ptr;
1366
1367                         /* 802.11 requires at least 3-byte OUI. */
1368                         if (element_len < sizeof(vendor_ie->vend_hdr.oui.oui))
1369                                 return -EINVAL;
1370
1371                         /* Not long enough for a match? Skip it. */
1372                         if (element_len < sizeof(wpa_oui))
1373                                 break;
1374
1375                         if (!memcmp(&vendor_ie->vend_hdr.oui, wpa_oui,
1376                                     sizeof(wpa_oui))) {
1377                                 bss_entry->bcn_wpa_ie =
1378                                         (struct ieee_types_vendor_specific *)
1379                                         current_ptr;
1380                                 bss_entry->wpa_offset = (u16)
1381                                         (current_ptr - bss_entry->beacon_buf);
1382                         } else if (!memcmp(&vendor_ie->vend_hdr.oui, wmm_oui,
1383                                     sizeof(wmm_oui))) {
1384                                 if (total_ie_len ==
1385                                     sizeof(struct ieee_types_wmm_parameter) ||
1386                                     total_ie_len ==
1387                                     sizeof(struct ieee_types_wmm_info))
1388                                         /*
1389                                          * Only accept and copy the WMM IE if
1390                                          * it matches the size expected for the
1391                                          * WMM Info IE or the WMM Parameter IE.
1392                                          */
1393                                         memcpy((u8 *) &bss_entry->wmm_ie,
1394                                                current_ptr, total_ie_len);
1395                         }
1396                         break;
1397                 case WLAN_EID_RSN:
1398                         bss_entry->bcn_rsn_ie =
1399                                 (struct ieee_types_generic *) current_ptr;
1400                         bss_entry->rsn_offset = (u16) (current_ptr -
1401                                                         bss_entry->beacon_buf);
1402                         break;
1403                 case WLAN_EID_BSS_AC_ACCESS_DELAY:
1404                         bss_entry->bcn_wapi_ie =
1405                                 (struct ieee_types_generic *) current_ptr;
1406                         bss_entry->wapi_offset = (u16) (current_ptr -
1407                                                         bss_entry->beacon_buf);
1408                         break;
1409                 case WLAN_EID_HT_CAPABILITY:
1410                         bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *)
1411                                         (current_ptr +
1412                                         sizeof(struct ieee_types_header));
1413                         bss_entry->ht_cap_offset = (u16) (current_ptr +
1414                                         sizeof(struct ieee_types_header) -
1415                                         bss_entry->beacon_buf);
1416                         break;
1417                 case WLAN_EID_HT_OPERATION:
1418                         bss_entry->bcn_ht_oper =
1419                                 (struct ieee80211_ht_operation *)(current_ptr +
1420                                         sizeof(struct ieee_types_header));
1421                         bss_entry->ht_info_offset = (u16) (current_ptr +
1422                                         sizeof(struct ieee_types_header) -
1423                                         bss_entry->beacon_buf);
1424                         break;
1425                 case WLAN_EID_VHT_CAPABILITY:
1426                         bss_entry->disable_11ac = false;
1427                         bss_entry->bcn_vht_cap =
1428                                 (void *)(current_ptr +
1429                                          sizeof(struct ieee_types_header));
1430                         bss_entry->vht_cap_offset =
1431                                         (u16)((u8 *)bss_entry->bcn_vht_cap -
1432                                               bss_entry->beacon_buf);
1433                         break;
1434                 case WLAN_EID_VHT_OPERATION:
1435                         bss_entry->bcn_vht_oper =
1436                                 (void *)(current_ptr +
1437                                          sizeof(struct ieee_types_header));
1438                         bss_entry->vht_info_offset =
1439                                         (u16)((u8 *)bss_entry->bcn_vht_oper -
1440                                               bss_entry->beacon_buf);
1441                         break;
1442                 case WLAN_EID_BSS_COEX_2040:
1443                         bss_entry->bcn_bss_co_2040 = current_ptr;
1444                         bss_entry->bss_co_2040_offset =
1445                                 (u16) (current_ptr - bss_entry->beacon_buf);
1446                         break;
1447                 case WLAN_EID_EXT_CAPABILITY:
1448                         bss_entry->bcn_ext_cap = current_ptr;
1449                         bss_entry->ext_cap_offset =
1450                                 (u16) (current_ptr - bss_entry->beacon_buf);
1451                         break;
1452                 case WLAN_EID_OPMODE_NOTIF:
1453                         bss_entry->oper_mode = (void *)current_ptr;
1454                         bss_entry->oper_mode_offset =
1455                                         (u16)((u8 *)bss_entry->oper_mode -
1456                                               bss_entry->beacon_buf);
1457                         break;
1458                 default:
1459                         break;
1460                 }
1461
1462                 current_ptr += total_ie_len;
1463                 bytes_left -= total_ie_len;
1464
1465         }       /* while (bytes_left > 2) */
1466         return 0;
1467 }
1468
1469 /*
1470  * This function converts radio type scan parameter to a band configuration
1471  * to be used in join command.
1472  */
1473 static u8
1474 mwifiex_radio_type_to_band(u8 radio_type)
1475 {
1476         switch (radio_type) {
1477         case HostCmd_SCAN_RADIO_TYPE_A:
1478                 return BAND_A;
1479         case HostCmd_SCAN_RADIO_TYPE_BG:
1480         default:
1481                 return BAND_G;
1482         }
1483 }
1484
1485 /*
1486  * This is an internal function used to start a scan based on an input
1487  * configuration.
1488  *
1489  * This uses the input user scan configuration information when provided in
1490  * order to send the appropriate scan commands to firmware to populate or
1491  * update the internal driver scan table.
1492  */
1493 int mwifiex_scan_networks(struct mwifiex_private *priv,
1494                           const struct mwifiex_user_scan_cfg *user_scan_in)
1495 {
1496         int ret;
1497         struct mwifiex_adapter *adapter = priv->adapter;
1498         struct cmd_ctrl_node *cmd_node;
1499         union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
1500         struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
1501         struct mwifiex_chan_scan_param_set *scan_chan_list;
1502         u8 filtered_scan;
1503         u8 scan_current_chan_only;
1504         u8 max_chan_per_scan;
1505
1506         if (adapter->scan_processing) {
1507                 mwifiex_dbg(adapter, WARN,
1508                             "cmd: Scan already in process...\n");
1509                 return -EBUSY;
1510         }
1511
1512         if (priv->scan_block) {
1513                 mwifiex_dbg(adapter, WARN,
1514                             "cmd: Scan is blocked during association...\n");
1515                 return -EBUSY;
1516         }
1517
1518         if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags) ||
1519             test_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags)) {
1520                 mwifiex_dbg(adapter, ERROR,
1521                             "Ignore scan. Card removed or firmware in bad state\n");
1522                 return -EFAULT;
1523         }
1524
1525         spin_lock_bh(&adapter->mwifiex_cmd_lock);
1526         adapter->scan_processing = true;
1527         spin_unlock_bh(&adapter->mwifiex_cmd_lock);
1528
1529         scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
1530                                GFP_KERNEL);
1531         if (!scan_cfg_out) {
1532                 ret = -ENOMEM;
1533                 goto done;
1534         }
1535
1536         scan_chan_list = kcalloc(MWIFIEX_USER_SCAN_CHAN_MAX,
1537                                  sizeof(struct mwifiex_chan_scan_param_set),
1538                                  GFP_KERNEL);
1539         if (!scan_chan_list) {
1540                 kfree(scan_cfg_out);
1541                 ret = -ENOMEM;
1542                 goto done;
1543         }
1544
1545         mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config,
1546                             &chan_list_out, scan_chan_list, &max_chan_per_scan,
1547                             &filtered_scan, &scan_current_chan_only);
1548
1549         ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
1550                                         &scan_cfg_out->config, chan_list_out,
1551                                         scan_chan_list);
1552
1553         /* Get scan command from scan_pending_q and put to cmd_pending_q */
1554         if (!ret) {
1555                 spin_lock_bh(&adapter->scan_pending_q_lock);
1556                 if (!list_empty(&adapter->scan_pending_q)) {
1557                         cmd_node = list_first_entry(&adapter->scan_pending_q,
1558                                                     struct cmd_ctrl_node, list);
1559                         list_del(&cmd_node->list);
1560                         spin_unlock_bh(&adapter->scan_pending_q_lock);
1561                         mwifiex_insert_cmd_to_pending_q(adapter, cmd_node);
1562                         queue_work(adapter->workqueue, &adapter->main_work);
1563
1564                         /* Perform internal scan synchronously */
1565                         if (!priv->scan_request) {
1566                                 mwifiex_dbg(adapter, INFO,
1567                                             "wait internal scan\n");
1568                                 mwifiex_wait_queue_complete(adapter, cmd_node);
1569                         }
1570                 } else {
1571                         spin_unlock_bh(&adapter->scan_pending_q_lock);
1572                 }
1573         }
1574
1575         kfree(scan_cfg_out);
1576         kfree(scan_chan_list);
1577 done:
1578         if (ret) {
1579                 spin_lock_bh(&adapter->mwifiex_cmd_lock);
1580                 adapter->scan_processing = false;
1581                 spin_unlock_bh(&adapter->mwifiex_cmd_lock);
1582         }
1583         return ret;
1584 }
1585
1586 /*
1587  * This function prepares a scan command to be sent to the firmware.
1588  *
1589  * This uses the scan command configuration sent to the command processing
1590  * module in command preparation stage to configure a scan command structure
1591  * to send to firmware.
1592  *
1593  * The fixed fields specifying the BSS type and BSSID filters as well as a
1594  * variable number/length of TLVs are sent in the command to firmware.
1595  *
1596  * Preparation also includes -
1597  *      - Setting command ID, and proper size
1598  *      - Ensuring correct endian-ness
1599  */
1600 int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
1601                             struct mwifiex_scan_cmd_config *scan_cfg)
1602 {
1603         struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan;
1604
1605         /* Set fixed field variables in scan command */
1606         scan_cmd->bss_mode = scan_cfg->bss_mode;
1607         memcpy(scan_cmd->bssid, scan_cfg->specific_bssid,
1608                sizeof(scan_cmd->bssid));
1609         memcpy(scan_cmd->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
1610
1611         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN);
1612
1613         /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
1614         cmd->size = cpu_to_le16((u16) (sizeof(scan_cmd->bss_mode)
1615                                           + sizeof(scan_cmd->bssid)
1616                                           + scan_cfg->tlv_buf_len + S_DS_GEN));
1617
1618         return 0;
1619 }
1620
1621 /*
1622  * This function checks compatibility of requested network with current
1623  * driver settings.
1624  */
1625 int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1626                                         struct mwifiex_bssdescriptor *bss_desc)
1627 {
1628         int ret = -1;
1629
1630         if (!bss_desc)
1631                 return -1;
1632
1633         if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band,
1634                              (u16) bss_desc->channel, 0))) {
1635                 switch (priv->bss_mode) {
1636                 case NL80211_IFTYPE_STATION:
1637                 case NL80211_IFTYPE_ADHOC:
1638                         ret = mwifiex_is_network_compatible(priv, bss_desc,
1639                                                             priv->bss_mode);
1640                         if (ret)
1641                                 mwifiex_dbg(priv->adapter, ERROR,
1642                                             "Incompatible network settings\n");
1643                         break;
1644                 default:
1645                         ret = 0;
1646                 }
1647         }
1648
1649         return ret;
1650 }
1651
1652 /* This function checks if SSID string contains all zeroes or length is zero */
1653 static bool mwifiex_is_hidden_ssid(struct cfg80211_ssid *ssid)
1654 {
1655         int idx;
1656
1657         for (idx = 0; idx < ssid->ssid_len; idx++) {
1658                 if (ssid->ssid[idx])
1659                         return false;
1660         }
1661
1662         return true;
1663 }
1664
1665 /* This function checks if any hidden SSID found in passive scan channels
1666  * and save those channels for specific SSID active scan
1667  */
1668 static int mwifiex_save_hidden_ssid_channels(struct mwifiex_private *priv,
1669                                              struct cfg80211_bss *bss)
1670 {
1671         struct mwifiex_bssdescriptor *bss_desc;
1672         int ret;
1673         int chid;
1674
1675         /* Allocate and fill new bss descriptor */
1676         bss_desc = kzalloc(sizeof(*bss_desc), GFP_KERNEL);
1677         if (!bss_desc)
1678                 return -ENOMEM;
1679
1680         ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
1681         if (ret)
1682                 goto done;
1683
1684         if (mwifiex_is_hidden_ssid(&bss_desc->ssid)) {
1685                 mwifiex_dbg(priv->adapter, INFO, "found hidden SSID\n");
1686                 for (chid = 0 ; chid < MWIFIEX_USER_SCAN_CHAN_MAX; chid++) {
1687                         if (priv->hidden_chan[chid].chan_number ==
1688                             bss->channel->hw_value)
1689                                 break;
1690
1691                         if (!priv->hidden_chan[chid].chan_number) {
1692                                 priv->hidden_chan[chid].chan_number =
1693                                         bss->channel->hw_value;
1694                                 priv->hidden_chan[chid].radio_type =
1695                                         bss->channel->band;
1696                                 priv->hidden_chan[chid].scan_type =
1697                                         MWIFIEX_SCAN_TYPE_ACTIVE;
1698                                 break;
1699                         }
1700                 }
1701         }
1702
1703 done:
1704         /* beacon_ie buffer was allocated in function
1705          * mwifiex_fill_new_bss_desc(). Free it now.
1706          */
1707         kfree(bss_desc->beacon_buf);
1708         kfree(bss_desc);
1709         return 0;
1710 }
1711
1712 static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1713                                           struct cfg80211_bss *bss)
1714 {
1715         struct mwifiex_bssdescriptor *bss_desc;
1716         int ret;
1717
1718         /* Allocate and fill new bss descriptor */
1719         bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), GFP_KERNEL);
1720         if (!bss_desc)
1721                 return -ENOMEM;
1722
1723         ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
1724         if (ret)
1725                 goto done;
1726
1727         ret = mwifiex_check_network_compatibility(priv, bss_desc);
1728         if (ret)
1729                 goto done;
1730
1731         spin_lock_bh(&priv->curr_bcn_buf_lock);
1732         /* Make a copy of current BSSID descriptor */
1733         memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
1734                sizeof(priv->curr_bss_params.bss_descriptor));
1735
1736         /* The contents of beacon_ie will be copied to its own buffer
1737          * in mwifiex_save_curr_bcn()
1738          */
1739         mwifiex_save_curr_bcn(priv);
1740         spin_unlock_bh(&priv->curr_bcn_buf_lock);
1741
1742 done:
1743         /* beacon_ie buffer was allocated in function
1744          * mwifiex_fill_new_bss_desc(). Free it now.
1745          */
1746         kfree(bss_desc->beacon_buf);
1747         kfree(bss_desc);
1748         return 0;
1749 }
1750
1751 static int
1752 mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
1753                                   u32 *bytes_left, u64 fw_tsf, u8 *radio_type,
1754                                   bool ext_scan, s32 rssi_val)
1755 {
1756         struct mwifiex_adapter *adapter = priv->adapter;
1757         struct mwifiex_chan_freq_power *cfp;
1758         struct cfg80211_bss *bss;
1759         u8 bssid[ETH_ALEN];
1760         s32 rssi;
1761         const u8 *ie_buf;
1762         size_t ie_len;
1763         u16 channel = 0;
1764         u16 beacon_size = 0;
1765         u32 curr_bcn_bytes;
1766         u32 freq;
1767         u16 beacon_period;
1768         u16 cap_info_bitmap;
1769         u8 *current_ptr;
1770         u64 timestamp;
1771         struct mwifiex_fixed_bcn_param *bcn_param;
1772         struct mwifiex_bss_priv *bss_priv;
1773
1774         if (*bytes_left >= sizeof(beacon_size)) {
1775                 /* Extract & convert beacon size from command buffer */
1776                 beacon_size = get_unaligned_le16((*bss_info));
1777                 *bytes_left -= sizeof(beacon_size);
1778                 *bss_info += sizeof(beacon_size);
1779         }
1780
1781         if (!beacon_size || beacon_size > *bytes_left) {
1782                 *bss_info += *bytes_left;
1783                 *bytes_left = 0;
1784                 return -EFAULT;
1785         }
1786
1787         /* Initialize the current working beacon pointer for this BSS
1788          * iteration
1789          */
1790         current_ptr = *bss_info;
1791
1792         /* Advance the return beacon pointer past the current beacon */
1793         *bss_info += beacon_size;
1794         *bytes_left -= beacon_size;
1795
1796         curr_bcn_bytes = beacon_size;
1797
1798         /* First 5 fields are bssid, RSSI(for legacy scan only),
1799          * time stamp, beacon interval, and capability information
1800          */
1801         if (curr_bcn_bytes < ETH_ALEN + sizeof(u8) +
1802             sizeof(struct mwifiex_fixed_bcn_param)) {
1803                 mwifiex_dbg(adapter, ERROR,
1804                             "InterpretIE: not enough bytes left\n");
1805                 return -EFAULT;
1806         }
1807
1808         memcpy(bssid, current_ptr, ETH_ALEN);
1809         current_ptr += ETH_ALEN;
1810         curr_bcn_bytes -= ETH_ALEN;
1811
1812         if (!ext_scan) {
1813                 rssi = (s32) *current_ptr;
1814                 rssi = (-rssi) * 100;           /* Convert dBm to mBm */
1815                 current_ptr += sizeof(u8);
1816                 curr_bcn_bytes -= sizeof(u8);
1817                 mwifiex_dbg(adapter, INFO,
1818                             "info: InterpretIE: RSSI=%d\n", rssi);
1819         } else {
1820                 rssi = rssi_val;
1821         }
1822
1823         bcn_param = (struct mwifiex_fixed_bcn_param *)current_ptr;
1824         current_ptr += sizeof(*bcn_param);
1825         curr_bcn_bytes -= sizeof(*bcn_param);
1826
1827         timestamp = le64_to_cpu(bcn_param->timestamp);
1828         beacon_period = le16_to_cpu(bcn_param->beacon_period);
1829
1830         cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
1831         mwifiex_dbg(adapter, INFO,
1832                     "info: InterpretIE: capabilities=0x%X\n",
1833                     cap_info_bitmap);
1834
1835         /* Rest of the current buffer are IE's */
1836         ie_buf = current_ptr;
1837         ie_len = curr_bcn_bytes;
1838         mwifiex_dbg(adapter, INFO,
1839                     "info: InterpretIE: IELength for this AP = %d\n",
1840                     curr_bcn_bytes);
1841
1842         while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
1843                 u8 element_id, element_len;
1844
1845                 element_id = *current_ptr;
1846                 element_len = *(current_ptr + 1);
1847                 if (curr_bcn_bytes < element_len +
1848                                 sizeof(struct ieee_types_header)) {
1849                         mwifiex_dbg(adapter, ERROR,
1850                                     "%s: bytes left < IE length\n", __func__);
1851                         return -EFAULT;
1852                 }
1853                 if (element_id == WLAN_EID_DS_PARAMS) {
1854                         channel = *(current_ptr +
1855                                     sizeof(struct ieee_types_header));
1856                         break;
1857                 }
1858
1859                 current_ptr += element_len + sizeof(struct ieee_types_header);
1860                 curr_bcn_bytes -= element_len +
1861                                         sizeof(struct ieee_types_header);
1862         }
1863
1864         if (channel) {
1865                 struct ieee80211_channel *chan;
1866                 u8 band;
1867
1868                 /* Skip entry if on csa closed channel */
1869                 if (channel == priv->csa_chan) {
1870                         mwifiex_dbg(adapter, WARN,
1871                                     "Dropping entry on csa closed channel\n");
1872                         return 0;
1873                 }
1874
1875                 band = BAND_G;
1876                 if (radio_type)
1877                         band = mwifiex_radio_type_to_band(*radio_type &
1878                                                           (BIT(0) | BIT(1)));
1879
1880                 cfp = mwifiex_get_cfp(priv, band, channel, 0);
1881
1882                 freq = cfp ? cfp->freq : 0;
1883
1884                 chan = ieee80211_get_channel(priv->wdev.wiphy, freq);
1885
1886                 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1887                         bss = cfg80211_inform_bss(priv->wdev.wiphy,
1888                                             chan, CFG80211_BSS_FTYPE_UNKNOWN,
1889                                             bssid, timestamp,
1890                                             cap_info_bitmap, beacon_period,
1891                                             ie_buf, ie_len, rssi, GFP_ATOMIC);
1892                         if (bss) {
1893                                 bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1894                                 bss_priv->band = band;
1895                                 bss_priv->fw_tsf = fw_tsf;
1896                                 if (priv->media_connected &&
1897                                     !memcmp(bssid, priv->curr_bss_params.
1898                                             bss_descriptor.mac_address,
1899                                             ETH_ALEN))
1900                                         mwifiex_update_curr_bss_params(priv,
1901                                                                        bss);
1902
1903                                 if ((chan->flags & IEEE80211_CHAN_RADAR) ||
1904                                     (chan->flags & IEEE80211_CHAN_NO_IR)) {
1905                                         mwifiex_dbg(adapter, INFO,
1906                                                     "radar or passive channel %d\n",
1907                                                     channel);
1908                                         mwifiex_save_hidden_ssid_channels(priv,
1909                                                                           bss);
1910                                 }
1911
1912                                 cfg80211_put_bss(priv->wdev.wiphy, bss);
1913                         }
1914                 }
1915         } else {
1916                 mwifiex_dbg(adapter, WARN, "missing BSS channel IE\n");
1917         }
1918
1919         return 0;
1920 }
1921
1922 static void mwifiex_complete_scan(struct mwifiex_private *priv)
1923 {
1924         struct mwifiex_adapter *adapter = priv->adapter;
1925
1926         adapter->survey_idx = 0;
1927         if (adapter->curr_cmd->wait_q_enabled) {
1928                 adapter->cmd_wait_q.status = 0;
1929                 if (!priv->scan_request) {
1930                         mwifiex_dbg(adapter, INFO,
1931                                     "complete internal scan\n");
1932                         mwifiex_complete_cmd(adapter, adapter->curr_cmd);
1933                 }
1934         }
1935 }
1936
1937 /* This function checks if any hidden SSID found in passive scan channels
1938  * and do specific SSID active scan for those channels
1939  */
1940 static int
1941 mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
1942 {
1943         int ret;
1944         struct mwifiex_adapter *adapter = priv->adapter;
1945         u8 id = 0;
1946         struct mwifiex_user_scan_cfg  *user_scan_cfg;
1947
1948         if (adapter->active_scan_triggered || !priv->scan_request ||
1949             priv->scan_aborting) {
1950                 adapter->active_scan_triggered = false;
1951                 return 0;
1952         }
1953
1954         if (!priv->hidden_chan[0].chan_number) {
1955                 mwifiex_dbg(adapter, INFO, "No BSS with hidden SSID found on DFS channels\n");
1956                 return 0;
1957         }
1958         user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
1959
1960         if (!user_scan_cfg)
1961                 return -ENOMEM;
1962
1963         for (id = 0; id < MWIFIEX_USER_SCAN_CHAN_MAX; id++) {
1964                 if (!priv->hidden_chan[id].chan_number)
1965                         break;
1966                 memcpy(&user_scan_cfg->chan_list[id],
1967                        &priv->hidden_chan[id],
1968                        sizeof(struct mwifiex_user_scan_chan));
1969         }
1970
1971         adapter->active_scan_triggered = true;
1972         if (priv->scan_request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
1973                 ether_addr_copy(user_scan_cfg->random_mac,
1974                                 priv->scan_request->mac_addr);
1975         user_scan_cfg->num_ssids = priv->scan_request->n_ssids;
1976         user_scan_cfg->ssid_list = priv->scan_request->ssids;
1977
1978         ret = mwifiex_scan_networks(priv, user_scan_cfg);
1979         kfree(user_scan_cfg);
1980
1981         memset(&priv->hidden_chan, 0, sizeof(priv->hidden_chan));
1982
1983         if (ret) {
1984                 dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
1985                 return ret;
1986         }
1987
1988         return 0;
1989 }
1990 static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1991 {
1992         struct mwifiex_adapter *adapter = priv->adapter;
1993         struct cmd_ctrl_node *cmd_node;
1994
1995         spin_lock_bh(&adapter->scan_pending_q_lock);
1996         if (list_empty(&adapter->scan_pending_q)) {
1997                 spin_unlock_bh(&adapter->scan_pending_q_lock);
1998
1999                 spin_lock_bh(&adapter->mwifiex_cmd_lock);
2000                 adapter->scan_processing = false;
2001                 spin_unlock_bh(&adapter->mwifiex_cmd_lock);
2002
2003                 mwifiex_active_scan_req_for_passive_chan(priv);
2004
2005                 if (!adapter->ext_scan)
2006                         mwifiex_complete_scan(priv);
2007
2008                 if (priv->scan_request) {
2009                         struct cfg80211_scan_info info = {
2010                                 .aborted = false,
2011                         };
2012
2013                         mwifiex_dbg(adapter, INFO,
2014                                     "info: notifying scan done\n");
2015                         cfg80211_scan_done(priv->scan_request, &info);
2016                         priv->scan_request = NULL;
2017                         priv->scan_aborting = false;
2018                 } else {
2019                         priv->scan_aborting = false;
2020                         mwifiex_dbg(adapter, INFO,
2021                                     "info: scan already aborted\n");
2022                 }
2023         } else if ((priv->scan_aborting && !priv->scan_request) ||
2024                    priv->scan_block) {
2025                 spin_unlock_bh(&adapter->scan_pending_q_lock);
2026
2027                 mwifiex_cancel_pending_scan_cmd(adapter);
2028
2029                 spin_lock_bh(&adapter->mwifiex_cmd_lock);
2030                 adapter->scan_processing = false;
2031                 spin_unlock_bh(&adapter->mwifiex_cmd_lock);
2032
2033                 if (!adapter->active_scan_triggered) {
2034                         if (priv->scan_request) {
2035                                 struct cfg80211_scan_info info = {
2036                                         .aborted = true,
2037                                 };
2038
2039                                 mwifiex_dbg(adapter, INFO,
2040                                             "info: aborting scan\n");
2041                                 cfg80211_scan_done(priv->scan_request, &info);
2042                                 priv->scan_request = NULL;
2043                                 priv->scan_aborting = false;
2044                         } else {
2045                                 priv->scan_aborting = false;
2046                                 mwifiex_dbg(adapter, INFO,
2047                                             "info: scan already aborted\n");
2048                         }
2049                 }
2050         } else {
2051                 /* Get scan command from scan_pending_q and put to
2052                  * cmd_pending_q
2053                  */
2054                 cmd_node = list_first_entry(&adapter->scan_pending_q,
2055                                             struct cmd_ctrl_node, list);
2056                 list_del(&cmd_node->list);
2057                 spin_unlock_bh(&adapter->scan_pending_q_lock);
2058                 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node);
2059         }
2060
2061         return;
2062 }
2063
2064 void mwifiex_cancel_scan(struct mwifiex_adapter *adapter)
2065 {
2066         struct mwifiex_private *priv;
2067         int i;
2068
2069         mwifiex_cancel_pending_scan_cmd(adapter);
2070
2071         if (adapter->scan_processing) {
2072                 spin_lock_bh(&adapter->mwifiex_cmd_lock);
2073                 adapter->scan_processing = false;
2074                 spin_unlock_bh(&adapter->mwifiex_cmd_lock);
2075                 for (i = 0; i < adapter->priv_num; i++) {
2076                         priv = adapter->priv[i];
2077                         if (!priv)
2078                                 continue;
2079                         if (priv->scan_request) {
2080                                 struct cfg80211_scan_info info = {
2081                                         .aborted = true,
2082                                 };
2083
2084                                 mwifiex_dbg(adapter, INFO,
2085                                             "info: aborting scan\n");
2086                                 cfg80211_scan_done(priv->scan_request, &info);
2087                                 priv->scan_request = NULL;
2088                                 priv->scan_aborting = false;
2089                         }
2090                 }
2091         }
2092 }
2093
2094 /*
2095  * This function handles the command response of scan.
2096  *
2097  * The response buffer for the scan command has the following
2098  * memory layout:
2099  *
2100  *      .-------------------------------------------------------------.
2101  *      |  Header (4 * sizeof(t_u16)):  Standard command response hdr |
2102  *      .-------------------------------------------------------------.
2103  *      |  BufSize (t_u16) : sizeof the BSS Description data          |
2104  *      .-------------------------------------------------------------.
2105  *      |  NumOfSet (t_u8) : Number of BSS Descs returned             |
2106  *      .-------------------------------------------------------------.
2107  *      |  BSSDescription data (variable, size given in BufSize)      |
2108  *      .-------------------------------------------------------------.
2109  *      |  TLV data (variable, size calculated using Header->Size,    |
2110  *      |            BufSize and sizeof the fixed fields above)       |
2111  *      .-------------------------------------------------------------.
2112  */
2113 int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
2114                             struct host_cmd_ds_command *resp)
2115 {
2116         int ret = 0;
2117         struct mwifiex_adapter *adapter = priv->adapter;
2118         struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
2119         struct mwifiex_ie_types_data *tlv_data;
2120         struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
2121         u8 *bss_info;
2122         u32 scan_resp_size;
2123         u32 bytes_left;
2124         u32 idx;
2125         u32 tlv_buf_size;
2126         struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
2127         struct chan_band_param_set *chan_band;
2128         u8 is_bgscan_resp;
2129         __le64 fw_tsf = 0;
2130         u8 *radio_type;
2131         struct cfg80211_wowlan_nd_match *pmatch;
2132         struct cfg80211_sched_scan_request *nd_config = NULL;
2133
2134         is_bgscan_resp = (le16_to_cpu(resp->command)
2135                           == HostCmd_CMD_802_11_BG_SCAN_QUERY);
2136         if (is_bgscan_resp)
2137                 scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
2138         else
2139                 scan_rsp = &resp->params.scan_resp;
2140
2141
2142         if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
2143                 mwifiex_dbg(adapter, ERROR,
2144                             "SCAN_RESP: too many AP returned (%d)\n",
2145                             scan_rsp->number_of_sets);
2146                 ret = -1;
2147                 goto check_next_scan;
2148         }
2149
2150         /* Check csa channel expiry before parsing scan response */
2151         mwifiex_11h_get_csa_closed_channel(priv);
2152
2153         bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
2154         mwifiex_dbg(adapter, INFO,
2155                     "info: SCAN_RESP: bss_descript_size %d\n",
2156                     bytes_left);
2157
2158         scan_resp_size = le16_to_cpu(resp->size);
2159
2160         mwifiex_dbg(adapter, INFO,
2161                     "info: SCAN_RESP: returned %d APs before parsing\n",
2162                     scan_rsp->number_of_sets);
2163
2164         bss_info = scan_rsp->bss_desc_and_tlv_buffer;
2165
2166         /*
2167          * The size of the TLV buffer is equal to the entire command response
2168          *   size (scan_resp_size) minus the fixed fields (sizeof()'s), the
2169          *   BSS Descriptions (bss_descript_size as bytesLef) and the command
2170          *   response header (S_DS_GEN)
2171          */
2172         tlv_buf_size = scan_resp_size - (bytes_left
2173                                          + sizeof(scan_rsp->bss_descript_size)
2174                                          + sizeof(scan_rsp->number_of_sets)
2175                                          + S_DS_GEN);
2176
2177         tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
2178                                                  bss_desc_and_tlv_buffer +
2179                                                  bytes_left);
2180
2181         /* Search the TLV buffer space in the scan response for any valid
2182            TLVs */
2183         mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
2184                                              TLV_TYPE_TSFTIMESTAMP,
2185                                              (struct mwifiex_ie_types_data **)
2186                                              &tsf_tlv);
2187
2188         /* Search the TLV buffer space in the scan response for any valid
2189            TLVs */
2190         mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
2191                                              TLV_TYPE_CHANNELBANDLIST,
2192                                              (struct mwifiex_ie_types_data **)
2193                                              &chan_band_tlv);
2194
2195 #ifdef CONFIG_PM
2196         if (priv->wdev.wiphy->wowlan_config)
2197                 nd_config = priv->wdev.wiphy->wowlan_config->nd_config;
2198 #endif
2199
2200         if (nd_config) {
2201                 adapter->nd_info =
2202                         kzalloc(sizeof(struct cfg80211_wowlan_nd_match) +
2203                                 sizeof(struct cfg80211_wowlan_nd_match *) *
2204                                 scan_rsp->number_of_sets, GFP_ATOMIC);
2205
2206                 if (adapter->nd_info)
2207                         adapter->nd_info->n_matches = scan_rsp->number_of_sets;
2208         }
2209
2210         for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
2211                 /*
2212                  * If the TSF TLV was appended to the scan results, save this
2213                  * entry's TSF value in the fw_tsf field. It is the firmware's
2214                  * TSF value at the time the beacon or probe response was
2215                  * received.
2216                  */
2217                 if (tsf_tlv)
2218                         memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
2219                                sizeof(fw_tsf));
2220
2221                 if (chan_band_tlv) {
2222                         chan_band = &chan_band_tlv->chan_band_param[idx];
2223                         radio_type = &chan_band->radio_type;
2224                 } else {
2225                         radio_type = NULL;
2226                 }
2227
2228                 if (chan_band_tlv && adapter->nd_info) {
2229                         adapter->nd_info->matches[idx] =
2230                                 kzalloc(sizeof(*pmatch) + sizeof(u32),
2231                                         GFP_ATOMIC);
2232
2233                         pmatch = adapter->nd_info->matches[idx];
2234
2235                         if (pmatch) {
2236                                 pmatch->n_channels = 1;
2237                                 pmatch->channels[0] = chan_band->chan_number;
2238                         }
2239                 }
2240
2241                 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
2242                                                         &bytes_left,
2243                                                         le64_to_cpu(fw_tsf),
2244                                                         radio_type, false, 0);
2245                 if (ret)
2246                         goto check_next_scan;
2247         }
2248
2249 check_next_scan:
2250         mwifiex_check_next_scan_command(priv);
2251         return ret;
2252 }
2253
2254 /*
2255  * This function prepares an extended scan command to be sent to the firmware
2256  *
2257  * This uses the scan command configuration sent to the command processing
2258  * module in command preparation stage to configure a extended scan command
2259  * structure to send to firmware.
2260  */
2261 int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
2262                                 struct host_cmd_ds_command *cmd,
2263                                 void *data_buf)
2264 {
2265         struct host_cmd_ds_802_11_scan_ext *ext_scan = &cmd->params.ext_scan;
2266         struct mwifiex_scan_cmd_config *scan_cfg = data_buf;
2267
2268         memcpy(ext_scan->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
2269
2270         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN_EXT);
2271
2272         /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
2273         cmd->size = cpu_to_le16((u16)(sizeof(ext_scan->reserved)
2274                                       + scan_cfg->tlv_buf_len + S_DS_GEN));
2275
2276         return 0;
2277 }
2278
2279 /* This function prepares an background scan config command to be sent
2280  * to the firmware
2281  */
2282 int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv,
2283                                       struct host_cmd_ds_command *cmd,
2284                                       void *data_buf)
2285 {
2286         struct host_cmd_ds_802_11_bg_scan_config *bgscan_config =
2287                                         &cmd->params.bg_scan_config;
2288         struct mwifiex_bg_scan_cfg *bgscan_cfg_in = data_buf;
2289         u8 *tlv_pos = bgscan_config->tlv;
2290         u8 num_probes;
2291         u32 ssid_len, chan_idx, scan_type, scan_dur, chan_num;
2292         int i;
2293         struct mwifiex_ie_types_num_probes *num_probes_tlv;
2294         struct mwifiex_ie_types_repeat_count *repeat_count_tlv;
2295         struct mwifiex_ie_types_min_rssi_threshold *rssi_threshold_tlv;
2296         struct mwifiex_ie_types_bgscan_start_later *start_later_tlv;
2297         struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
2298         struct mwifiex_ie_types_chan_list_param_set *chan_list_tlv;
2299         struct mwifiex_chan_scan_param_set *temp_chan;
2300
2301         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_CONFIG);
2302         cmd->size = cpu_to_le16(sizeof(*bgscan_config) + S_DS_GEN);
2303
2304         bgscan_config->action = cpu_to_le16(bgscan_cfg_in->action);
2305         bgscan_config->enable = bgscan_cfg_in->enable;
2306         bgscan_config->bss_type = bgscan_cfg_in->bss_type;
2307         bgscan_config->scan_interval =
2308                 cpu_to_le32(bgscan_cfg_in->scan_interval);
2309         bgscan_config->report_condition =
2310                 cpu_to_le32(bgscan_cfg_in->report_condition);
2311
2312         /*  stop sched scan  */
2313         if (!bgscan_config->enable)
2314                 return 0;
2315
2316         bgscan_config->chan_per_scan = bgscan_cfg_in->chan_per_scan;
2317
2318         num_probes = (bgscan_cfg_in->num_probes ? bgscan_cfg_in->
2319                       num_probes : priv->adapter->scan_probes);
2320
2321         if (num_probes) {
2322                 num_probes_tlv = (struct mwifiex_ie_types_num_probes *)tlv_pos;
2323                 num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
2324                 num_probes_tlv->header.len =
2325                         cpu_to_le16(sizeof(num_probes_tlv->num_probes));
2326                 num_probes_tlv->num_probes = cpu_to_le16((u16)num_probes);
2327
2328                 tlv_pos += sizeof(num_probes_tlv->header) +
2329                         le16_to_cpu(num_probes_tlv->header.len);
2330         }
2331
2332         if (bgscan_cfg_in->repeat_count) {
2333                 repeat_count_tlv =
2334                         (struct mwifiex_ie_types_repeat_count *)tlv_pos;
2335                 repeat_count_tlv->header.type =
2336                         cpu_to_le16(TLV_TYPE_REPEAT_COUNT);
2337                 repeat_count_tlv->header.len =
2338                         cpu_to_le16(sizeof(repeat_count_tlv->repeat_count));
2339                 repeat_count_tlv->repeat_count =
2340                         cpu_to_le16(bgscan_cfg_in->repeat_count);
2341
2342                 tlv_pos += sizeof(repeat_count_tlv->header) +
2343                         le16_to_cpu(repeat_count_tlv->header.len);
2344         }
2345
2346         if (bgscan_cfg_in->rssi_threshold) {
2347                 rssi_threshold_tlv =
2348                         (struct mwifiex_ie_types_min_rssi_threshold *)tlv_pos;
2349                 rssi_threshold_tlv->header.type =
2350                         cpu_to_le16(TLV_TYPE_RSSI_LOW);
2351                 rssi_threshold_tlv->header.len =
2352                         cpu_to_le16(sizeof(rssi_threshold_tlv->rssi_threshold));
2353                 rssi_threshold_tlv->rssi_threshold =
2354                         cpu_to_le16(bgscan_cfg_in->rssi_threshold);
2355
2356                 tlv_pos += sizeof(rssi_threshold_tlv->header) +
2357                         le16_to_cpu(rssi_threshold_tlv->header.len);
2358         }
2359
2360         for (i = 0; i < bgscan_cfg_in->num_ssids; i++) {
2361                 ssid_len = bgscan_cfg_in->ssid_list[i].ssid.ssid_len;
2362
2363                 wildcard_ssid_tlv =
2364                         (struct mwifiex_ie_types_wildcard_ssid_params *)tlv_pos;
2365                 wildcard_ssid_tlv->header.type =
2366                                 cpu_to_le16(TLV_TYPE_WILDCARDSSID);
2367                 wildcard_ssid_tlv->header.len = cpu_to_le16(
2368                                 (u16)(ssid_len + sizeof(wildcard_ssid_tlv->
2369                                                          max_ssid_length)));
2370
2371                 /* max_ssid_length = 0 tells firmware to perform
2372                  * specific scan for the SSID filled, whereas
2373                  * max_ssid_length = IEEE80211_MAX_SSID_LEN is for
2374                  * wildcard scan.
2375                  */
2376                 if (ssid_len)
2377                         wildcard_ssid_tlv->max_ssid_length = 0;
2378                 else
2379                         wildcard_ssid_tlv->max_ssid_length =
2380                                                 IEEE80211_MAX_SSID_LEN;
2381
2382                 memcpy(wildcard_ssid_tlv->ssid,
2383                        bgscan_cfg_in->ssid_list[i].ssid.ssid, ssid_len);
2384
2385                 tlv_pos += (sizeof(wildcard_ssid_tlv->header)
2386                                 + le16_to_cpu(wildcard_ssid_tlv->header.len));
2387         }
2388
2389         chan_list_tlv = (struct mwifiex_ie_types_chan_list_param_set *)tlv_pos;
2390
2391         if (bgscan_cfg_in->chan_list[0].chan_number) {
2392                 dev_dbg(priv->adapter->dev, "info: bgscan: Using supplied channel list\n");
2393
2394                 chan_list_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
2395
2396                 for (chan_idx = 0;
2397                      chan_idx < MWIFIEX_BG_SCAN_CHAN_MAX &&
2398                      bgscan_cfg_in->chan_list[chan_idx].chan_number;
2399                      chan_idx++) {
2400                         temp_chan = chan_list_tlv->chan_scan_param + chan_idx;
2401
2402                         /* Increment the TLV header length by size appended */
2403                         le16_unaligned_add_cpu(&chan_list_tlv->header.len,
2404                                                sizeof(
2405                                                chan_list_tlv->chan_scan_param));
2406
2407                         temp_chan->chan_number =
2408                                 bgscan_cfg_in->chan_list[chan_idx].chan_number;
2409                         temp_chan->radio_type =
2410                                 bgscan_cfg_in->chan_list[chan_idx].radio_type;
2411
2412                         scan_type =
2413                                 bgscan_cfg_in->chan_list[chan_idx].scan_type;
2414
2415                         if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
2416                                 temp_chan->chan_scan_mode_bitmap
2417                                         |= MWIFIEX_PASSIVE_SCAN;
2418                         else
2419                                 temp_chan->chan_scan_mode_bitmap
2420                                         &= ~MWIFIEX_PASSIVE_SCAN;
2421
2422                         if (bgscan_cfg_in->chan_list[chan_idx].scan_time) {
2423                                 scan_dur = (u16)bgscan_cfg_in->
2424                                         chan_list[chan_idx].scan_time;
2425                         } else {
2426                                 scan_dur = (scan_type ==
2427                                             MWIFIEX_SCAN_TYPE_PASSIVE) ?
2428                                             priv->adapter->passive_scan_time :
2429                                             priv->adapter->specific_scan_time;
2430                         }
2431
2432                         temp_chan->min_scan_time = cpu_to_le16(scan_dur);
2433                         temp_chan->max_scan_time = cpu_to_le16(scan_dur);
2434                 }
2435         } else {
2436                 dev_dbg(priv->adapter->dev,
2437                         "info: bgscan: Creating full region channel list\n");
2438                 chan_num =
2439                         mwifiex_bgscan_create_channel_list(priv, bgscan_cfg_in,
2440                                                            chan_list_tlv->
2441                                                            chan_scan_param);
2442                 le16_unaligned_add_cpu(&chan_list_tlv->header.len,
2443                                        chan_num *
2444                              sizeof(chan_list_tlv->chan_scan_param[0]));
2445         }
2446
2447         tlv_pos += (sizeof(chan_list_tlv->header)
2448                         + le16_to_cpu(chan_list_tlv->header.len));
2449
2450         if (bgscan_cfg_in->start_later) {
2451                 start_later_tlv =
2452                         (struct mwifiex_ie_types_bgscan_start_later *)tlv_pos;
2453                 start_later_tlv->header.type =
2454                         cpu_to_le16(TLV_TYPE_BGSCAN_START_LATER);
2455                 start_later_tlv->header.len =
2456                         cpu_to_le16(sizeof(start_later_tlv->start_later));
2457                 start_later_tlv->start_later =
2458                         cpu_to_le16(bgscan_cfg_in->start_later);
2459
2460                 tlv_pos += sizeof(start_later_tlv->header) +
2461                         le16_to_cpu(start_later_tlv->header.len);
2462         }
2463
2464         /* Append vendor specific IE TLV */
2465         mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_BGSCAN, &tlv_pos);
2466
2467         le16_unaligned_add_cpu(&cmd->size, tlv_pos - bgscan_config->tlv);
2468
2469         return 0;
2470 }
2471
2472 int mwifiex_stop_bg_scan(struct mwifiex_private *priv)
2473 {
2474         struct mwifiex_bg_scan_cfg *bgscan_cfg;
2475
2476         if (!priv->sched_scanning) {
2477                 dev_dbg(priv->adapter->dev, "bgscan already stopped!\n");
2478                 return 0;
2479         }
2480
2481         bgscan_cfg = kzalloc(sizeof(*bgscan_cfg), GFP_KERNEL);
2482         if (!bgscan_cfg)
2483                 return -ENOMEM;
2484
2485         bgscan_cfg->bss_type = MWIFIEX_BSS_MODE_INFRA;
2486         bgscan_cfg->action = MWIFIEX_BGSCAN_ACT_SET;
2487         bgscan_cfg->enable = false;
2488
2489         if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_BG_SCAN_CONFIG,
2490                              HostCmd_ACT_GEN_SET, 0, bgscan_cfg, true)) {
2491                 kfree(bgscan_cfg);
2492                 return -EFAULT;
2493         }
2494
2495         kfree(bgscan_cfg);
2496         priv->sched_scanning = false;
2497
2498         return 0;
2499 }
2500
2501 static void
2502 mwifiex_update_chan_statistics(struct mwifiex_private *priv,
2503                                struct mwifiex_ietypes_chanstats *tlv_stat)
2504 {
2505         struct mwifiex_adapter *adapter = priv->adapter;
2506         u8 i, num_chan;
2507         struct mwifiex_fw_chan_stats *fw_chan_stats;
2508         struct mwifiex_chan_stats chan_stats;
2509
2510         fw_chan_stats = (void *)((u8 *)tlv_stat +
2511                               sizeof(struct mwifiex_ie_types_header));
2512         num_chan = le16_to_cpu(tlv_stat->header.len) /
2513                                               sizeof(struct mwifiex_chan_stats);
2514
2515         for (i = 0 ; i < num_chan; i++) {
2516                 if (adapter->survey_idx >= adapter->num_in_chan_stats) {
2517                         mwifiex_dbg(adapter, WARN,
2518                                     "FW reported too many channel results (max %d)\n",
2519                                     adapter->num_in_chan_stats);
2520                         return;
2521                 }
2522                 chan_stats.chan_num = fw_chan_stats->chan_num;
2523                 chan_stats.bandcfg = fw_chan_stats->bandcfg;
2524                 chan_stats.flags = fw_chan_stats->flags;
2525                 chan_stats.noise = fw_chan_stats->noise;
2526                 chan_stats.total_bss = le16_to_cpu(fw_chan_stats->total_bss);
2527                 chan_stats.cca_scan_dur =
2528                                        le16_to_cpu(fw_chan_stats->cca_scan_dur);
2529                 chan_stats.cca_busy_dur =
2530                                        le16_to_cpu(fw_chan_stats->cca_busy_dur);
2531                 mwifiex_dbg(adapter, INFO,
2532                             "chan=%d, noise=%d, total_network=%d scan_duration=%d, busy_duration=%d\n",
2533                             chan_stats.chan_num,
2534                             chan_stats.noise,
2535                             chan_stats.total_bss,
2536                             chan_stats.cca_scan_dur,
2537                             chan_stats.cca_busy_dur);
2538                 memcpy(&adapter->chan_stats[adapter->survey_idx++], &chan_stats,
2539                        sizeof(struct mwifiex_chan_stats));
2540                 fw_chan_stats++;
2541         }
2542 }
2543
2544 /* This function handles the command response of extended scan */
2545 int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv,
2546                                 struct host_cmd_ds_command *resp)
2547 {
2548         struct mwifiex_adapter *adapter = priv->adapter;
2549         struct host_cmd_ds_802_11_scan_ext *ext_scan_resp;
2550         struct mwifiex_ie_types_header *tlv;
2551         struct mwifiex_ietypes_chanstats *tlv_stat;
2552         u16 buf_left, type, len;
2553
2554         struct host_cmd_ds_command *cmd_ptr;
2555         struct cmd_ctrl_node *cmd_node;
2556         bool complete_scan = false;
2557
2558         mwifiex_dbg(adapter, INFO, "info: EXT scan returns successfully\n");
2559
2560         ext_scan_resp = &resp->params.ext_scan;
2561
2562         tlv = (void *)ext_scan_resp->tlv_buffer;
2563         buf_left = le16_to_cpu(resp->size) - (sizeof(*ext_scan_resp) + S_DS_GEN
2564                                               - 1);
2565
2566         while (buf_left >= sizeof(struct mwifiex_ie_types_header)) {
2567                 type = le16_to_cpu(tlv->type);
2568                 len = le16_to_cpu(tlv->len);
2569
2570                 if (buf_left < (sizeof(struct mwifiex_ie_types_header) + len)) {
2571                         mwifiex_dbg(adapter, ERROR,
2572                                     "error processing scan response TLVs");
2573                         break;
2574                 }
2575
2576                 switch (type) {
2577                 case TLV_TYPE_CHANNEL_STATS:
2578                         tlv_stat = (void *)tlv;
2579                         mwifiex_update_chan_statistics(priv, tlv_stat);
2580                         break;
2581                 default:
2582                         break;
2583                 }
2584
2585                 buf_left -= len + sizeof(struct mwifiex_ie_types_header);
2586                 tlv = (void *)((u8 *)tlv + len +
2587                                sizeof(struct mwifiex_ie_types_header));
2588         }
2589
2590         spin_lock_bh(&adapter->cmd_pending_q_lock);
2591         spin_lock_bh(&adapter->scan_pending_q_lock);
2592         if (list_empty(&adapter->scan_pending_q)) {
2593                 complete_scan = true;
2594                 list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) {
2595                         cmd_ptr = (void *)cmd_node->cmd_skb->data;
2596                         if (le16_to_cpu(cmd_ptr->command) ==
2597                             HostCmd_CMD_802_11_SCAN_EXT) {
2598                                 mwifiex_dbg(adapter, INFO,
2599                                             "Scan pending in command pending list");
2600                                 complete_scan = false;
2601                                 break;
2602                         }
2603                 }
2604         }
2605         spin_unlock_bh(&adapter->scan_pending_q_lock);
2606         spin_unlock_bh(&adapter->cmd_pending_q_lock);
2607
2608         if (complete_scan)
2609                 mwifiex_complete_scan(priv);
2610
2611         return 0;
2612 }
2613
2614 /* This function This function handles the event extended scan report. It
2615  * parses extended scan results and informs to cfg80211 stack.
2616  */
2617 int mwifiex_handle_event_ext_scan_report(struct mwifiex_private *priv,
2618                                          void *buf)
2619 {
2620         int ret = 0;
2621         struct mwifiex_adapter *adapter = priv->adapter;
2622         u8 *bss_info;
2623         u32 bytes_left, bytes_left_for_tlv, idx;
2624         u16 type, len;
2625         struct mwifiex_ie_types_data *tlv;
2626         struct mwifiex_ie_types_bss_scan_rsp *scan_rsp_tlv;
2627         struct mwifiex_ie_types_bss_scan_info *scan_info_tlv;
2628         u8 *radio_type;
2629         u64 fw_tsf = 0;
2630         s32 rssi = 0;
2631         struct mwifiex_event_scan_result *event_scan = buf;
2632         u8 num_of_set = event_scan->num_of_set;
2633         u8 *scan_resp = buf + sizeof(struct mwifiex_event_scan_result);
2634         u16 scan_resp_size = le16_to_cpu(event_scan->buf_size);
2635
2636         if (num_of_set > MWIFIEX_MAX_AP) {
2637                 mwifiex_dbg(adapter, ERROR,
2638                             "EXT_SCAN: Invalid number of AP returned (%d)!!\n",
2639                             num_of_set);
2640                 ret = -1;
2641                 goto check_next_scan;
2642         }
2643
2644         bytes_left = scan_resp_size;
2645         mwifiex_dbg(adapter, INFO,
2646                     "EXT_SCAN: size %d, returned %d APs...",
2647                     scan_resp_size, num_of_set);
2648         mwifiex_dbg_dump(adapter, CMD_D, "EXT_SCAN buffer:", buf,
2649                          scan_resp_size +
2650                          sizeof(struct mwifiex_event_scan_result));
2651
2652         tlv = (struct mwifiex_ie_types_data *)scan_resp;
2653
2654         for (idx = 0; idx < num_of_set && bytes_left; idx++) {
2655                 type = le16_to_cpu(tlv->header.type);
2656                 len = le16_to_cpu(tlv->header.len);
2657                 if (bytes_left < sizeof(struct mwifiex_ie_types_header) + len) {
2658                         mwifiex_dbg(adapter, ERROR,
2659                                     "EXT_SCAN: Error bytes left < TLV length\n");
2660                         break;
2661                 }
2662                 scan_rsp_tlv = NULL;
2663                 scan_info_tlv = NULL;
2664                 bytes_left_for_tlv = bytes_left;
2665
2666                 /* BSS response TLV with beacon or probe response buffer
2667                  * at the initial position of each descriptor
2668                  */
2669                 if (type != TLV_TYPE_BSS_SCAN_RSP)
2670                         break;
2671
2672                 bss_info = (u8 *)tlv;
2673                 scan_rsp_tlv = (struct mwifiex_ie_types_bss_scan_rsp *)tlv;
2674                 tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
2675                 bytes_left_for_tlv -=
2676                                 (len + sizeof(struct mwifiex_ie_types_header));
2677
2678                 while (bytes_left_for_tlv >=
2679                        sizeof(struct mwifiex_ie_types_header) &&
2680                        le16_to_cpu(tlv->header.type) != TLV_TYPE_BSS_SCAN_RSP) {
2681                         type = le16_to_cpu(tlv->header.type);
2682                         len = le16_to_cpu(tlv->header.len);
2683                         if (bytes_left_for_tlv <
2684                             sizeof(struct mwifiex_ie_types_header) + len) {
2685                                 mwifiex_dbg(adapter, ERROR,
2686                                             "EXT_SCAN: Error in processing TLV,\t"
2687                                             "bytes left < TLV length\n");
2688                                 scan_rsp_tlv = NULL;
2689                                 bytes_left_for_tlv = 0;
2690                                 continue;
2691                         }
2692                         switch (type) {
2693                         case TLV_TYPE_BSS_SCAN_INFO:
2694                                 scan_info_tlv =
2695                                   (struct mwifiex_ie_types_bss_scan_info *)tlv;
2696                                 if (len !=
2697                                  sizeof(struct mwifiex_ie_types_bss_scan_info) -
2698                                  sizeof(struct mwifiex_ie_types_header)) {
2699                                         bytes_left_for_tlv = 0;
2700                                         continue;
2701                                 }
2702                                 break;
2703                         default:
2704                                 break;
2705                         }
2706                         tlv = (struct mwifiex_ie_types_data *)(tlv->data + len);
2707                         bytes_left -=
2708                                 (len + sizeof(struct mwifiex_ie_types_header));
2709                         bytes_left_for_tlv -=
2710                                 (len + sizeof(struct mwifiex_ie_types_header));
2711                 }
2712
2713                 if (!scan_rsp_tlv)
2714                         break;
2715
2716                 /* Advance pointer to the beacon buffer length and
2717                  * update the bytes count so that the function
2718                  * wlan_interpret_bss_desc_with_ie() can handle the
2719                  * scan buffer withut any change
2720                  */
2721                 bss_info += sizeof(u16);
2722                 bytes_left -= sizeof(u16);
2723
2724                 if (scan_info_tlv) {
2725                         rssi = (s32)(s16)(le16_to_cpu(scan_info_tlv->rssi));
2726                         rssi *= 100;           /* Convert dBm to mBm */
2727                         mwifiex_dbg(adapter, INFO,
2728                                     "info: InterpretIE: RSSI=%d\n", rssi);
2729                         fw_tsf = le64_to_cpu(scan_info_tlv->tsf);
2730                         radio_type = &scan_info_tlv->radio_type;
2731                 } else {
2732                         radio_type = NULL;
2733                 }
2734                 ret = mwifiex_parse_single_response_buf(priv, &bss_info,
2735                                                         &bytes_left, fw_tsf,
2736                                                         radio_type, true, rssi);
2737                 if (ret)
2738                         goto check_next_scan;
2739         }
2740
2741 check_next_scan:
2742         if (!event_scan->more_event)
2743                 mwifiex_check_next_scan_command(priv);
2744
2745         return ret;
2746 }
2747
2748 /*
2749  * This function prepares command for background scan query.
2750  *
2751  * Preparation includes -
2752  *      - Setting command ID and proper size
2753  *      - Setting background scan flush parameter
2754  *      - Ensuring correct endian-ness
2755  */
2756 int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
2757 {
2758         struct host_cmd_ds_802_11_bg_scan_query *bg_query =
2759                 &cmd->params.bg_scan_query;
2760
2761         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY);
2762         cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_bg_scan_query)
2763                                 + S_DS_GEN);
2764
2765         bg_query->flush = 1;
2766
2767         return 0;
2768 }
2769
2770 /*
2771  * This function inserts scan command node to the scan pending queue.
2772  */
2773 void
2774 mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
2775                        struct cmd_ctrl_node *cmd_node)
2776 {
2777         struct mwifiex_adapter *adapter = priv->adapter;
2778
2779         cmd_node->wait_q_enabled = true;
2780         cmd_node->condition = &adapter->scan_wait_q_woken;
2781         spin_lock_bh(&adapter->scan_pending_q_lock);
2782         list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
2783         spin_unlock_bh(&adapter->scan_pending_q_lock);
2784 }
2785
2786 /*
2787  * This function sends a scan command for all available channels to the
2788  * firmware, filtered on a specific SSID.
2789  */
2790 static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
2791                                       struct cfg80211_ssid *req_ssid)
2792 {
2793         struct mwifiex_adapter *adapter = priv->adapter;
2794         int ret;
2795         struct mwifiex_user_scan_cfg *scan_cfg;
2796
2797         if (adapter->scan_processing) {
2798                 mwifiex_dbg(adapter, WARN,
2799                             "cmd: Scan already in process...\n");
2800                 return -EBUSY;
2801         }
2802
2803         if (priv->scan_block) {
2804                 mwifiex_dbg(adapter, WARN,
2805                             "cmd: Scan is blocked during association...\n");
2806                 return -EBUSY;
2807         }
2808
2809         scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
2810         if (!scan_cfg)
2811                 return -ENOMEM;
2812
2813         scan_cfg->ssid_list = req_ssid;
2814         scan_cfg->num_ssids = 1;
2815
2816         ret = mwifiex_scan_networks(priv, scan_cfg);
2817
2818         kfree(scan_cfg);
2819         return ret;
2820 }
2821
2822 /*
2823  * Sends IOCTL request to start a scan.
2824  *
2825  * This function allocates the IOCTL request buffer, fills it
2826  * with requisite parameters and calls the IOCTL handler.
2827  *
2828  * Scan command can be issued for both normal scan and specific SSID
2829  * scan, depending upon whether an SSID is provided or not.
2830  */
2831 int mwifiex_request_scan(struct mwifiex_private *priv,
2832                          struct cfg80211_ssid *req_ssid)
2833 {
2834         int ret;
2835
2836         if (mutex_lock_interruptible(&priv->async_mutex)) {
2837                 mwifiex_dbg(priv->adapter, ERROR,
2838                             "%s: acquire semaphore fail\n",
2839                             __func__);
2840                 return -1;
2841         }
2842
2843         priv->adapter->scan_wait_q_woken = false;
2844
2845         if (req_ssid && req_ssid->ssid_len != 0)
2846                 /* Specific SSID scan */
2847                 ret = mwifiex_scan_specific_ssid(priv, req_ssid);
2848         else
2849                 /* Normal scan */
2850                 ret = mwifiex_scan_networks(priv, NULL);
2851
2852         mutex_unlock(&priv->async_mutex);
2853
2854         return ret;
2855 }
2856
2857 /*
2858  * This function appends the vendor specific IE TLV to a buffer.
2859  */
2860 int
2861 mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
2862                             u16 vsie_mask, u8 **buffer)
2863 {
2864         int id, ret_len = 0;
2865         struct mwifiex_ie_types_vendor_param_set *vs_param_set;
2866
2867         if (!buffer)
2868                 return 0;
2869         if (!(*buffer))
2870                 return 0;
2871
2872         /*
2873          * Traverse through the saved vendor specific IE array and append
2874          * the selected(scan/assoc/adhoc) IE as TLV to the command
2875          */
2876         for (id = 0; id < MWIFIEX_MAX_VSIE_NUM; id++) {
2877                 if (priv->vs_ie[id].mask & vsie_mask) {
2878                         vs_param_set =
2879                                 (struct mwifiex_ie_types_vendor_param_set *)
2880                                 *buffer;
2881                         vs_param_set->header.type =
2882                                 cpu_to_le16(TLV_TYPE_PASSTHROUGH);
2883                         vs_param_set->header.len =
2884                                 cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
2885                                 & 0x00FF) + 2);
2886                         if (le16_to_cpu(vs_param_set->header.len) >
2887                                 MWIFIEX_MAX_VSIE_LEN) {
2888                                 mwifiex_dbg(priv->adapter, ERROR,
2889                                             "Invalid param length!\n");
2890                                 break;
2891                         }
2892
2893                         memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
2894                                le16_to_cpu(vs_param_set->header.len));
2895                         *buffer += le16_to_cpu(vs_param_set->header.len) +
2896                                    sizeof(struct mwifiex_ie_types_header);
2897                         ret_len += le16_to_cpu(vs_param_set->header.len) +
2898                                    sizeof(struct mwifiex_ie_types_header);
2899                 }
2900         }
2901         return ret_len;
2902 }
2903
2904 /*
2905  * This function saves a beacon buffer of the current BSS descriptor.
2906  *
2907  * The current beacon buffer is saved so that it can be restored in the
2908  * following cases that makes the beacon buffer not to contain the current
2909  * ssid's beacon buffer.
2910  *      - The current ssid was not found somehow in the last scan.
2911  *      - The current ssid was the last entry of the scan table and overloaded.
2912  */
2913 void
2914 mwifiex_save_curr_bcn(struct mwifiex_private *priv)
2915 {
2916         struct mwifiex_bssdescriptor *curr_bss =
2917                 &priv->curr_bss_params.bss_descriptor;
2918
2919         if (!curr_bss->beacon_buf_size)
2920                 return;
2921
2922         /* allocate beacon buffer at 1st time; or if it's size has changed */
2923         if (!priv->curr_bcn_buf ||
2924             priv->curr_bcn_size != curr_bss->beacon_buf_size) {
2925                 priv->curr_bcn_size = curr_bss->beacon_buf_size;
2926
2927                 kfree(priv->curr_bcn_buf);
2928                 priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
2929                                              GFP_ATOMIC);
2930                 if (!priv->curr_bcn_buf)
2931                         return;
2932         }
2933
2934         memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
2935                curr_bss->beacon_buf_size);
2936         mwifiex_dbg(priv->adapter, INFO,
2937                     "info: current beacon saved %d\n",
2938                     priv->curr_bcn_size);
2939
2940         curr_bss->beacon_buf = priv->curr_bcn_buf;
2941
2942         /* adjust the pointers in the current BSS descriptor */
2943         if (curr_bss->bcn_wpa_ie)
2944                 curr_bss->bcn_wpa_ie =
2945                         (struct ieee_types_vendor_specific *)
2946                         (curr_bss->beacon_buf +
2947                          curr_bss->wpa_offset);
2948
2949         if (curr_bss->bcn_rsn_ie)
2950                 curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
2951                         (curr_bss->beacon_buf +
2952                          curr_bss->rsn_offset);
2953
2954         if (curr_bss->bcn_ht_cap)
2955                 curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
2956                         (curr_bss->beacon_buf +
2957                          curr_bss->ht_cap_offset);
2958
2959         if (curr_bss->bcn_ht_oper)
2960                 curr_bss->bcn_ht_oper = (struct ieee80211_ht_operation *)
2961                         (curr_bss->beacon_buf +
2962                          curr_bss->ht_info_offset);
2963
2964         if (curr_bss->bcn_vht_cap)
2965                 curr_bss->bcn_vht_cap = (void *)(curr_bss->beacon_buf +
2966                                                  curr_bss->vht_cap_offset);
2967
2968         if (curr_bss->bcn_vht_oper)
2969                 curr_bss->bcn_vht_oper = (void *)(curr_bss->beacon_buf +
2970                                                   curr_bss->vht_info_offset);
2971
2972         if (curr_bss->bcn_bss_co_2040)
2973                 curr_bss->bcn_bss_co_2040 =
2974                         (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset);
2975
2976         if (curr_bss->bcn_ext_cap)
2977                 curr_bss->bcn_ext_cap = curr_bss->beacon_buf +
2978                         curr_bss->ext_cap_offset;
2979
2980         if (curr_bss->oper_mode)
2981                 curr_bss->oper_mode = (void *)(curr_bss->beacon_buf +
2982                                                curr_bss->oper_mode_offset);
2983 }
2984
2985 /*
2986  * This function frees the current BSS descriptor beacon buffer.
2987  */
2988 void
2989 mwifiex_free_curr_bcn(struct mwifiex_private *priv)
2990 {
2991         kfree(priv->curr_bcn_buf);
2992         priv->curr_bcn_buf = NULL;
2993 }