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