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