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