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