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