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