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