Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wl_cfg80211.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
18 
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20 
21 #include <linux/kernel.h>
22 #include <linux/if_arp.h>
23 #include <linux/sched.h>
24 #include <linux/kthread.h>
25 #include <linux/netdevice.h>
26 #include <linux/bitops.h>
27 #include <linux/etherdevice.h>
28 #include <linux/ieee80211.h>
29 #include <linux/uaccess.h>
30 #include <net/cfg80211.h>
31 #include <net/netlink.h>
32 
33 #include <brcmu_utils.h>
34 #include <defs.h>
35 #include <brcmu_wifi.h>
36 #include "dhd.h"
37 #include "wl_cfg80211.h"
38 
39 #define BRCMF_SCAN_IE_LEN_MAX 2048
40 #define BRCMF_PNO_VERSION 2
41 #define BRCMF_PNO_TIME 30
42 #define BRCMF_PNO_REPEAT 4
43 #define BRCMF_PNO_FREQ_EXPO_MAX 3
44 #define BRCMF_PNO_MAX_PFN_COUNT 16
45 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
46 #define BRCMF_PNO_HIDDEN_BIT 2
47 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
48 #define BRCMF_PNO_SCAN_COMPLETE 1
49 #define BRCMF_PNO_SCAN_INCOMPLETE 0
50 
51 #define TLV_LEN_OFF 1 /* length offset */
52 #define TLV_HDR_LEN 2 /* header length */
53 #define TLV_BODY_OFF 2 /* body offset */
54 #define TLV_OUI_LEN 3 /* oui id length */
55 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56 #define WPA_OUI_TYPE 1
57 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58 #define WME_OUI_TYPE 2
59 
60 #define VS_IE_FIXED_HDR_LEN 6
61 #define WPA_IE_VERSION_LEN 2
62 #define WPA_IE_MIN_OUI_LEN 4
63 #define WPA_IE_SUITE_COUNT_LEN 2
64 
65 #define WPA_CIPHER_NONE 0 /* None */
66 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
67 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
68 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
69 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
70 
71 #define RSN_AKM_NONE 0 /* None (IBSS) */
72 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
73 #define RSN_AKM_PSK 2 /* Pre-shared Key */
74 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
75 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
76 
77 #define VNDR_IE_CMD_LEN 4 /* length of the set command
78  * string :"add", "del" (+ NUL)
79  */
80 #define VNDR_IE_COUNT_OFFSET 4
81 #define VNDR_IE_PKTFLAG_OFFSET 8
82 #define VNDR_IE_VSIE_OFFSET 12
83 #define VNDR_IE_HDR_SIZE 12
84 #define VNDR_IE_BEACON_FLAG 0x1
85 #define VNDR_IE_PRBRSP_FLAG 0x2
86 #define MAX_VNDR_IE_NUMBER 5
87 
88 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
89 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
90 
91 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
92  (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
93 
94 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
95 
96 static u32 brcmf_dbg_level = WL_DBG_ERR;
97 
98 static bool check_sys_up(struct wiphy *wiphy)
99 {
100  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
101  if (!test_bit(WL_STATUS_READY, &cfg->status)) {
102  WL_INFO("device is not ready : status (%d)\n",
103  (int)cfg->status);
104  return false;
105  }
106  return true;
107 }
108 
109 #define CHAN2G(_channel, _freq, _flags) { \
110  .band = IEEE80211_BAND_2GHZ, \
111  .center_freq = (_freq), \
112  .hw_value = (_channel), \
113  .flags = (_flags), \
114  .max_antenna_gain = 0, \
115  .max_power = 30, \
116 }
117 
118 #define CHAN5G(_channel, _flags) { \
119  .band = IEEE80211_BAND_5GHZ, \
120  .center_freq = 5000 + (5 * (_channel)), \
121  .hw_value = (_channel), \
122  .flags = (_flags), \
123  .max_antenna_gain = 0, \
124  .max_power = 30, \
125 }
127 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
128 #define RATETAB_ENT(_rateid, _flags) \
129  { \
130  .bitrate = RATE_TO_BASE100KBPS(_rateid), \
131  .hw_value = (_rateid), \
132  .flags = (_flags), \
133  }
134 
135 static struct ieee80211_rate __wl_rates[] = {
148 };
150 #define wl_a_rates (__wl_rates + 4)
151 #define wl_a_rates_size 8
152 #define wl_g_rates (__wl_rates + 0)
153 #define wl_g_rates_size 12
154 
155 static struct ieee80211_channel __wl_2ghz_channels[] = {
156  CHAN2G(1, 2412, 0),
157  CHAN2G(2, 2417, 0),
158  CHAN2G(3, 2422, 0),
159  CHAN2G(4, 2427, 0),
160  CHAN2G(5, 2432, 0),
161  CHAN2G(6, 2437, 0),
162  CHAN2G(7, 2442, 0),
163  CHAN2G(8, 2447, 0),
164  CHAN2G(9, 2452, 0),
165  CHAN2G(10, 2457, 0),
166  CHAN2G(11, 2462, 0),
167  CHAN2G(12, 2467, 0),
168  CHAN2G(13, 2472, 0),
169  CHAN2G(14, 2484, 0),
170 };
171 
172 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
173  CHAN5G(34, 0), CHAN5G(36, 0),
174  CHAN5G(38, 0), CHAN5G(40, 0),
175  CHAN5G(42, 0), CHAN5G(44, 0),
176  CHAN5G(46, 0), CHAN5G(48, 0),
177  CHAN5G(52, 0), CHAN5G(56, 0),
178  CHAN5G(60, 0), CHAN5G(64, 0),
179  CHAN5G(100, 0), CHAN5G(104, 0),
180  CHAN5G(108, 0), CHAN5G(112, 0),
181  CHAN5G(116, 0), CHAN5G(120, 0),
182  CHAN5G(124, 0), CHAN5G(128, 0),
183  CHAN5G(132, 0), CHAN5G(136, 0),
184  CHAN5G(140, 0), CHAN5G(149, 0),
185  CHAN5G(153, 0), CHAN5G(157, 0),
186  CHAN5G(161, 0), CHAN5G(165, 0),
187  CHAN5G(184, 0), CHAN5G(188, 0),
188  CHAN5G(192, 0), CHAN5G(196, 0),
189  CHAN5G(200, 0), CHAN5G(204, 0),
190  CHAN5G(208, 0), CHAN5G(212, 0),
191  CHAN5G(216, 0),
192 };
193 
194 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
195  CHAN5G(32, 0), CHAN5G(34, 0),
196  CHAN5G(36, 0), CHAN5G(38, 0),
197  CHAN5G(40, 0), CHAN5G(42, 0),
198  CHAN5G(44, 0), CHAN5G(46, 0),
199  CHAN5G(48, 0), CHAN5G(50, 0),
200  CHAN5G(52, 0), CHAN5G(54, 0),
201  CHAN5G(56, 0), CHAN5G(58, 0),
202  CHAN5G(60, 0), CHAN5G(62, 0),
203  CHAN5G(64, 0), CHAN5G(66, 0),
204  CHAN5G(68, 0), CHAN5G(70, 0),
205  CHAN5G(72, 0), CHAN5G(74, 0),
206  CHAN5G(76, 0), CHAN5G(78, 0),
207  CHAN5G(80, 0), CHAN5G(82, 0),
208  CHAN5G(84, 0), CHAN5G(86, 0),
209  CHAN5G(88, 0), CHAN5G(90, 0),
210  CHAN5G(92, 0), CHAN5G(94, 0),
211  CHAN5G(96, 0), CHAN5G(98, 0),
212  CHAN5G(100, 0), CHAN5G(102, 0),
213  CHAN5G(104, 0), CHAN5G(106, 0),
214  CHAN5G(108, 0), CHAN5G(110, 0),
215  CHAN5G(112, 0), CHAN5G(114, 0),
216  CHAN5G(116, 0), CHAN5G(118, 0),
217  CHAN5G(120, 0), CHAN5G(122, 0),
218  CHAN5G(124, 0), CHAN5G(126, 0),
219  CHAN5G(128, 0), CHAN5G(130, 0),
220  CHAN5G(132, 0), CHAN5G(134, 0),
221  CHAN5G(136, 0), CHAN5G(138, 0),
222  CHAN5G(140, 0), CHAN5G(142, 0),
223  CHAN5G(144, 0), CHAN5G(145, 0),
224  CHAN5G(146, 0), CHAN5G(147, 0),
225  CHAN5G(148, 0), CHAN5G(149, 0),
226  CHAN5G(150, 0), CHAN5G(151, 0),
227  CHAN5G(152, 0), CHAN5G(153, 0),
228  CHAN5G(154, 0), CHAN5G(155, 0),
229  CHAN5G(156, 0), CHAN5G(157, 0),
230  CHAN5G(158, 0), CHAN5G(159, 0),
231  CHAN5G(160, 0), CHAN5G(161, 0),
232  CHAN5G(162, 0), CHAN5G(163, 0),
233  CHAN5G(164, 0), CHAN5G(165, 0),
234  CHAN5G(166, 0), CHAN5G(168, 0),
235  CHAN5G(170, 0), CHAN5G(172, 0),
236  CHAN5G(174, 0), CHAN5G(176, 0),
237  CHAN5G(178, 0), CHAN5G(180, 0),
238  CHAN5G(182, 0), CHAN5G(184, 0),
239  CHAN5G(186, 0), CHAN5G(188, 0),
240  CHAN5G(190, 0), CHAN5G(192, 0),
241  CHAN5G(194, 0), CHAN5G(196, 0),
242  CHAN5G(198, 0), CHAN5G(200, 0),
243  CHAN5G(202, 0), CHAN5G(204, 0),
244  CHAN5G(206, 0), CHAN5G(208, 0),
245  CHAN5G(210, 0), CHAN5G(212, 0),
246  CHAN5G(214, 0), CHAN5G(216, 0),
247  CHAN5G(218, 0), CHAN5G(220, 0),
248  CHAN5G(222, 0), CHAN5G(224, 0),
249  CHAN5G(226, 0), CHAN5G(228, 0),
250 };
251 
252 static struct ieee80211_supported_band __wl_band_2ghz = {
253  .band = IEEE80211_BAND_2GHZ,
254  .channels = __wl_2ghz_channels,
255  .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
256  .bitrates = wl_g_rates,
257  .n_bitrates = wl_g_rates_size,
258 };
259 
260 static struct ieee80211_supported_band __wl_band_5ghz_a = {
261  .band = IEEE80211_BAND_5GHZ,
262  .channels = __wl_5ghz_a_channels,
263  .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
264  .bitrates = wl_a_rates,
265  .n_bitrates = wl_a_rates_size,
266 };
267 
268 static struct ieee80211_supported_band __wl_band_5ghz_n = {
269  .band = IEEE80211_BAND_5GHZ,
270  .channels = __wl_5ghz_n_channels,
271  .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
272  .bitrates = wl_a_rates,
273  .n_bitrates = wl_a_rates_size,
274 };
275 
276 static const u32 __wl_cipher_suites[] = {
282 };
284 /* tag_ID/length/value_buffer tuple */
285 struct brcmf_tlv {
287  u8 len;
288  u8 data[1];
289 };
291 /* Vendor specific ie. id = 221, oui and type defines exact ie */
292 struct brcmf_vs_tlv {
295  u8 oui[3];
296  u8 oui_type;
297 };
301  u32 ie_len; /* total length including id & length field */
302  struct brcmf_vs_tlv vndrie;
303 };
306  u32 count;
307  struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
308 };
309 
310 /* Quarter dBm units to mW
311  * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
312  * Table is offset so the last entry is largest mW value that fits in
313  * a u16.
314  */
316 #define QDBM_OFFSET 153 /* Offset for first entry */
317 #define QDBM_TABLE_LEN 40 /* Table size */
318 
319 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
320  * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
321  */
322 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
323 
324 /* Largest mW value that will round down to the last table entry,
325  * QDBM_OFFSET + QDBM_TABLE_LEN-1.
326  * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
327  * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
328  */
329 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
330 
331 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
332 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
333 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
334 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
335 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
336 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
337 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
338 };
339 
340 static u16 brcmf_qdbm_to_mw(u8 qdbm)
341 {
342  uint factor = 1;
343  int idx = qdbm - QDBM_OFFSET;
344 
345  if (idx >= QDBM_TABLE_LEN)
346  /* clamp to max u16 mW value */
347  return 0xFFFF;
348 
349  /* scale the qdBm index up to the range of the table 0-40
350  * where an offset of 40 qdBm equals a factor of 10 mW.
351  */
352  while (idx < 0) {
353  idx += 40;
354  factor *= 10;
355  }
356 
357  /* return the mW value scaled down to the correct factor of 10,
358  * adding in factor/2 to get proper rounding.
359  */
360  return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
361 }
362 
363 static u8 brcmf_mw_to_qdbm(u16 mw)
364 {
365  u8 qdbm;
366  int offset;
367  uint mw_uint = mw;
368  uint boundary;
369 
370  /* handle boundary case */
371  if (mw_uint <= 1)
372  return 0;
373 
374  offset = QDBM_OFFSET;
375 
376  /* move mw into the range of the table */
377  while (mw_uint < QDBM_TABLE_LOW_BOUND) {
378  mw_uint *= 10;
379  offset -= 40;
380  }
381 
382  for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
383  boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
384  nqdBm_to_mW_map[qdbm]) / 2;
385  if (mw_uint < boundary)
386  break;
387  }
388 
389  qdbm += (u8) offset;
390 
391  return qdbm;
392 }
393 
394 /* function for reading/writing a single u32 from/to the dongle */
395 static int
396 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
397 {
398  int err;
399  __le32 par_le = cpu_to_le32(*par);
400 
401  err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
402  *par = le32_to_cpu(par_le);
403 
404  return err;
405 }
406 
407 static s32
408 brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name,
409  void *param, s32 paramlen,
410  void *buf, s32 buflen, s32 bssidx)
411 {
412  s32 err = -ENOMEM;
413  u32 len;
414 
415  len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
416  buf, buflen, bssidx);
417  BUG_ON(!len);
418  if (len > 0)
419  err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
420  if (err)
421  WL_ERR("error (%d)\n", err);
422 
423  return err;
424 }
425 
426 static s32
427 brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name,
428  void *param, s32 paramlen,
429  void *buf, s32 buflen, s32 bssidx)
430 {
431  s32 err = -ENOMEM;
432  u32 len;
433 
434  len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
435  buf, buflen, bssidx);
436  BUG_ON(!len);
437  if (len > 0)
438  err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len);
439  if (err)
440  WL_ERR("error (%d)\n", err);
441 
442  return err;
443 }
444 
445 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
446  struct brcmf_wsec_key_le *key_le)
447 {
448  key_le->index = cpu_to_le32(key->index);
449  key_le->len = cpu_to_le32(key->len);
450  key_le->algo = cpu_to_le32(key->algo);
451  key_le->flags = cpu_to_le32(key->flags);
452  key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
453  key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
454  key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
455  memcpy(key_le->data, key->data, sizeof(key->data));
456  memcpy(key_le->ea, key->ea, sizeof(key->ea));
457 }
458 
459 static int
460 send_key_to_dongle(struct brcmf_cfg80211_info *cfg, s32 bssidx,
461  struct net_device *ndev, struct brcmf_wsec_key *key)
462 {
463  int err;
464  struct brcmf_wsec_key_le key_le;
465 
466  convert_key_from_CPU(key, &key_le);
467 
468  err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
469  sizeof(key_le),
470  cfg->extra_buf,
471  WL_EXTRA_BUF_MAX, bssidx);
472 
473  if (err)
474  WL_ERR("wsec_key error (%d)\n", err);
475  return err;
476 }
477 
478 static s32
479 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
480  enum nl80211_iftype type, u32 *flags,
481  struct vif_params *params)
482 {
483  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
484  s32 infra = 0;
485  s32 ap = 0;
486  s32 err = 0;
487 
488  WL_TRACE("Enter, ndev=%p, type=%d\n", ndev, type);
489 
490  switch (type) {
492  case NL80211_IFTYPE_WDS:
493  WL_ERR("type (%d) : currently we do not support this type\n",
494  type);
495  return -EOPNOTSUPP;
497  cfg->conf->mode = WL_MODE_IBSS;
498  infra = 0;
499  break;
501  cfg->conf->mode = WL_MODE_BSS;
502  infra = 1;
503  break;
504  case NL80211_IFTYPE_AP:
505  cfg->conf->mode = WL_MODE_AP;
506  ap = 1;
507  break;
508  default:
509  err = -EINVAL;
510  goto done;
511  }
512 
513  if (ap) {
515  if (!cfg->ap_info)
516  cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
517  GFP_KERNEL);
518  if (!cfg->ap_info) {
519  err = -ENOMEM;
520  goto done;
521  }
522  WL_INFO("IF Type = AP\n");
523  } else {
524  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
525  if (err) {
526  WL_ERR("WLC_SET_INFRA error (%d)\n", err);
527  err = -EAGAIN;
528  goto done;
529  }
530  WL_INFO("IF Type = %s\n",
531  (cfg->conf->mode == WL_MODE_IBSS) ?
532  "Adhoc" : "Infra");
533  }
534  ndev->ieee80211_ptr->iftype = type;
535 
536 done:
537  WL_TRACE("Exit\n");
538 
539  return err;
540 }
541 
542 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
543 {
544  s8 buf[BRCMF_DCMD_SMLEN];
545  u32 len;
546  s32 err = 0;
547  __le32 val_le;
548 
549  val_le = cpu_to_le32(val);
550  len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
551  sizeof(buf));
552  BUG_ON(!len);
553 
554  err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
555  if (err)
556  WL_ERR("error (%d)\n", err);
557 
558  return err;
559 }
560 
561 static s32
562 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
563 {
564  union {
565  s8 buf[BRCMF_DCMD_SMLEN];
566  __le32 val;
567  } var;
568  u32 len;
569  u32 data_null;
570  s32 err = 0;
571 
572  len =
573  brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
574  sizeof(var.buf));
575  BUG_ON(!len);
576  err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
577  if (err)
578  WL_ERR("error (%d)\n", err);
579 
580  *retval = le32_to_cpu(var.val);
581 
582  return err;
583 }
584 
585 static s32
586 brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val,
587  s32 bssidx)
588 {
589  s8 buf[BRCMF_DCMD_SMLEN];
590  __le32 val_le;
591 
592  val_le = cpu_to_le32(val);
593 
594  return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le,
595  sizeof(val_le), buf, sizeof(buf),
596  bssidx);
597 }
598 
599 static s32
600 brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val,
601  s32 bssidx)
602 {
603  s8 buf[BRCMF_DCMD_SMLEN];
604  s32 err;
605  __le32 val_le;
606 
607  memset(buf, 0, sizeof(buf));
608  err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf,
609  sizeof(buf), bssidx);
610  if (err == 0) {
611  memcpy(&val_le, buf, sizeof(val_le));
612  *val = le32_to_cpu(val_le);
613  }
614  return err;
615 }
616 
617 
618 /*
619  * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this
620  * should return the ndev matching bssidx.
621  */
622 static s32
623 brcmf_find_bssidx(struct brcmf_cfg80211_info *cfg, struct net_device *ndev)
624 {
625  return 0;
626 }
627 
628 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
629 {
630  s32 err = 0;
631  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
632 
633  if (test_bit(WL_STATUS_READY, &cfg->status)) {
634  err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
635  if (err) {
636  WL_ERR("fail to set mpc\n");
637  return;
638  }
639  WL_INFO("MPC : %d\n", mpc);
640  }
641 }
642 
643 static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
644  struct brcmf_ssid *ssid)
645 {
646  memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
647  params_le->bss_type = DOT11_BSSTYPE_ANY;
648  params_le->scan_type = 0;
649  params_le->channel_num = 0;
650  params_le->nprobes = cpu_to_le32(-1);
651  params_le->active_time = cpu_to_le32(-1);
652  params_le->passive_time = cpu_to_le32(-1);
653  params_le->home_time = cpu_to_le32(-1);
654  if (ssid && ssid->SSID_len) {
655  params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
656  memcpy(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
657  }
658 }
659 
660 static s32
661 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
662  s32 paramlen, void *bufptr, s32 buflen)
663 {
664  s32 iolen;
665 
666  iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
667  BUG_ON(!iolen);
668 
669  return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
670 }
671 
672 static s32
673 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
674  s32 paramlen, void *bufptr, s32 buflen)
675 {
676  s32 iolen;
677 
678  iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
679  BUG_ON(!iolen);
680 
681  return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
682 }
683 
684 static s32
685 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
686  struct brcmf_ssid *ssid, u16 action)
687 {
688  s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
689  offsetof(struct brcmf_iscan_params_le, params_le);
691  s32 err = 0;
692 
693  if (ssid && ssid->SSID_len)
694  params_size += sizeof(struct brcmf_ssid);
695  params = kzalloc(params_size, GFP_KERNEL);
696  if (!params)
697  return -ENOMEM;
698  BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
699 
700  brcmf_iscan_prep(&params->params_le, ssid);
701 
703  params->action = cpu_to_le16(action);
704  params->scan_duration = cpu_to_le16(0);
705 
706  err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
707  iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
708  if (err) {
709  if (err == -EBUSY)
710  WL_INFO("system busy : iscan canceled\n");
711  else
712  WL_ERR("error (%d)\n", err);
713  }
714 
715  kfree(params);
716  return err;
717 }
718 
719 static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
720 {
721  struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
722  struct net_device *ndev = cfg_to_ndev(cfg);
723  struct brcmf_ssid ssid;
724  __le32 passive_scan;
725  s32 err = 0;
726 
727  /* Broadcast scan by default */
728  memset(&ssid, 0, sizeof(ssid));
729 
730  iscan->state = WL_ISCAN_STATE_SCANING;
731 
732  passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
733  err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_SET_PASSIVE_SCAN,
734  &passive_scan, sizeof(passive_scan));
735  if (err) {
736  WL_ERR("error (%d)\n", err);
737  return err;
738  }
739  brcmf_set_mpc(ndev, 0);
740  cfg->iscan_kickstart = true;
741  err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
742  if (err) {
743  brcmf_set_mpc(ndev, 1);
744  cfg->iscan_kickstart = false;
745  return err;
746  }
747  mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
748  iscan->timer_on = 1;
749  return err;
750 }
751 
752 static s32
753 brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
755  struct cfg80211_ssid *this_ssid)
756 {
757  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
758  struct cfg80211_ssid *ssids;
759  struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
760  __le32 passive_scan;
761  bool iscan_req;
762  bool spec_scan;
763  s32 err = 0;
764  u32 SSID_len;
765 
766  if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
767  WL_ERR("Scanning already : status (%lu)\n", cfg->status);
768  return -EAGAIN;
769  }
771  WL_ERR("Scanning being aborted : status (%lu)\n",
772  cfg->status);
773  return -EAGAIN;
774  }
775  if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
776  WL_ERR("Connecting : status (%lu)\n",
777  cfg->status);
778  return -EAGAIN;
779  }
780 
781  iscan_req = false;
782  spec_scan = false;
783  if (request) {
784  /* scan bss */
785  ssids = request->ssids;
786  if (cfg->iscan_on && (!ssids || !ssids->ssid_len))
787  iscan_req = true;
788  } else {
789  /* scan in ibss */
790  /* we don't do iscan in ibss */
791  ssids = this_ssid;
792  }
793 
794  cfg->scan_request = request;
796  if (iscan_req) {
797  err = brcmf_do_iscan(cfg);
798  if (!err)
799  return err;
800  else
801  goto scan_out;
802  } else {
803  WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
804  ssids->ssid, ssids->ssid_len);
805  memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
806  SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
807  sr->ssid_le.SSID_len = cpu_to_le32(0);
808  if (SSID_len) {
809  memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
810  sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
811  spec_scan = true;
812  } else {
813  WL_SCAN("Broadcast scan\n");
814  }
815 
816  passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
818  &passive_scan, sizeof(passive_scan));
819  if (err) {
820  WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
821  goto scan_out;
822  }
823  brcmf_set_mpc(ndev, 0);
824  err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
825  sizeof(sr->ssid_le));
826  if (err) {
827  if (err == -EBUSY)
828  WL_INFO("system busy : scan for \"%s\" "
829  "canceled\n", sr->ssid_le.SSID);
830  else
831  WL_ERR("WLC_SCAN error (%d)\n", err);
832 
833  brcmf_set_mpc(ndev, 1);
834  goto scan_out;
835  }
836  }
837 
838  return 0;
839 
840 scan_out:
842  cfg->scan_request = NULL;
843  return err;
844 }
845 
846 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
847  struct cfg80211_scan_request *request)
848 {
849  u32 n_ssids;
850  u32 n_channels;
851  s32 i;
852  s32 offset;
853  u16 chanspec;
854  u16 channel;
855  struct ieee80211_channel *req_channel;
856  char *ptr;
857  struct brcmf_ssid_le ssid_le;
858 
859  memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
860  params_le->bss_type = DOT11_BSSTYPE_ANY;
861  params_le->scan_type = 0;
862  params_le->channel_num = 0;
863  params_le->nprobes = cpu_to_le32(-1);
864  params_le->active_time = cpu_to_le32(-1);
865  params_le->passive_time = cpu_to_le32(-1);
866  params_le->home_time = cpu_to_le32(-1);
867  memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
868 
869  /* if request is null exit so it will be all channel broadcast scan */
870  if (!request)
871  return;
872 
873  n_ssids = request->n_ssids;
874  n_channels = request->n_channels;
875  /* Copy channel array if applicable */
876  WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
877  if (n_channels > 0) {
878  for (i = 0; i < n_channels; i++) {
879  chanspec = 0;
880  req_channel = request->channels[i];
882  req_channel->center_freq);
883  if (req_channel->band == IEEE80211_BAND_2GHZ)
884  chanspec |= WL_CHANSPEC_BAND_2G;
885  else
886  chanspec |= WL_CHANSPEC_BAND_5G;
887 
888  if (req_channel->flags & IEEE80211_CHAN_NO_HT40) {
889  chanspec |= WL_CHANSPEC_BW_20;
890  chanspec |= WL_CHANSPEC_CTL_SB_NONE;
891  } else {
892  chanspec |= WL_CHANSPEC_BW_40;
893  if (req_channel->flags &
895  chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
896  else
897  chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
898  }
899 
900  chanspec |= (channel & WL_CHANSPEC_CHAN_MASK);
901  WL_SCAN("Chan : %d, Channel spec: %x\n",
902  channel, chanspec);
903  params_le->channel_list[i] = cpu_to_le16(chanspec);
904  }
905  } else {
906  WL_SCAN("Scanning all channels\n");
907  }
908  /* Copy ssid array if applicable */
909  WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
910  if (n_ssids > 0) {
911  offset = offsetof(struct brcmf_scan_params_le, channel_list) +
912  n_channels * sizeof(u16);
913  offset = roundup(offset, sizeof(u32));
914  ptr = (char *)params_le + offset;
915  for (i = 0; i < n_ssids; i++) {
916  memset(&ssid_le, 0, sizeof(ssid_le));
917  ssid_le.SSID_len =
918  cpu_to_le32(request->ssids[i].ssid_len);
919  memcpy(ssid_le.SSID, request->ssids[i].ssid,
920  request->ssids[i].ssid_len);
921  if (!ssid_le.SSID_len)
922  WL_SCAN("%d: Broadcast scan\n", i);
923  else
924  WL_SCAN("%d: scan for %s size =%d\n", i,
925  ssid_le.SSID, ssid_le.SSID_len);
926  memcpy(ptr, &ssid_le, sizeof(ssid_le));
927  ptr += sizeof(ssid_le);
928  }
929  } else {
930  WL_SCAN("Broadcast scan %p\n", request->ssids);
931  if ((request->ssids) && request->ssids->ssid_len) {
932  WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
933  request->ssids->ssid_len);
934  params_le->ssid_le.SSID_len =
935  cpu_to_le32(request->ssids->ssid_len);
936  memcpy(&params_le->ssid_le.SSID, request->ssids->ssid,
937  request->ssids->ssid_len);
938  }
939  }
940  /* Adding mask to channel numbers */
941  params_le->channel_num =
943  (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
944 }
945 
946 static s32
947 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
948  struct net_device *ndev,
949  bool aborted, bool fw_abort)
950 {
951  struct brcmf_scan_params_le params_le;
952  struct cfg80211_scan_request *scan_request;
953  s32 err = 0;
954 
955  WL_SCAN("Enter\n");
956 
957  /* clear scan request, because the FW abort can cause a second call */
958  /* to this functon and might cause a double cfg80211_scan_done */
959  scan_request = cfg->scan_request;
960  cfg->scan_request = NULL;
961 
962  if (timer_pending(&cfg->escan_timeout))
964 
965  if (fw_abort) {
966  /* Do a scan abort to stop the driver's scan engine */
967  WL_SCAN("ABORT scan in firmware\n");
968  memset(&params_le, 0, sizeof(params_le));
969  memcpy(params_le.bssid, ether_bcast, ETH_ALEN);
970  params_le.bss_type = DOT11_BSSTYPE_ANY;
971  params_le.scan_type = 0;
972  params_le.channel_num = cpu_to_le32(1);
973  params_le.nprobes = cpu_to_le32(1);
974  params_le.active_time = cpu_to_le32(-1);
975  params_le.passive_time = cpu_to_le32(-1);
976  params_le.home_time = cpu_to_le32(-1);
977  /* Scan is aborted by setting channel_list[0] to -1 */
978  params_le.channel_list[0] = cpu_to_le16(-1);
979  /* E-Scan (or anyother type) can be aborted by SCAN */
980  err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &params_le,
981  sizeof(params_le));
982  if (err)
983  WL_ERR("Scan abort failed\n");
984  }
985  /*
986  * e-scan can be initiated by scheduled scan
987  * which takes precedence.
988  */
989  if (cfg->sched_escan) {
990  WL_SCAN("scheduled scan completed\n");
991  cfg->sched_escan = false;
992  if (!aborted)
993  cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
994  brcmf_set_mpc(ndev, 1);
995  } else if (scan_request) {
996  WL_SCAN("ESCAN Completed scan: %s\n",
997  aborted ? "Aborted" : "Done");
998  cfg80211_scan_done(scan_request, aborted);
999  brcmf_set_mpc(ndev, 1);
1000  }
1002  WL_ERR("Scan complete while device not scanning\n");
1003  return -EPERM;
1004  }
1005 
1006  return err;
1007 }
1008 
1009 static s32
1010 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
1011  struct cfg80211_scan_request *request, u16 action)
1012 {
1013  s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1014  offsetof(struct brcmf_escan_params_le, params_le);
1015  struct brcmf_escan_params_le *params;
1016  s32 err = 0;
1017 
1018  WL_SCAN("E-SCAN START\n");
1019 
1020  if (request != NULL) {
1021  /* Allocate space for populating ssids in struct */
1022  params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1023 
1024  /* Allocate space for populating ssids in struct */
1025  params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
1026  }
1027 
1028  params = kzalloc(params_size, GFP_KERNEL);
1029  if (!params) {
1030  err = -ENOMEM;
1031  goto exit;
1032  }
1033  BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1034  brcmf_escan_prep(&params->params_le, request);
1036  params->action = cpu_to_le16(action);
1037  params->sync_id = cpu_to_le16(0x1234);
1038 
1039  err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
1041  if (err) {
1042  if (err == -EBUSY)
1043  WL_INFO("system busy : escan canceled\n");
1044  else
1045  WL_ERR("error (%d)\n", err);
1046  }
1047 
1048  kfree(params);
1049 exit:
1050  return err;
1051 }
1052 
1053 static s32
1054 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1055  struct net_device *ndev, struct cfg80211_scan_request *request)
1056 {
1057  s32 err;
1058  __le32 passive_scan;
1059  struct brcmf_scan_results *results;
1060 
1061  WL_SCAN("Enter\n");
1062  cfg->escan_info.ndev = ndev;
1063  cfg->escan_info.wiphy = wiphy;
1064  cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
1065  passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1067  &passive_scan, sizeof(passive_scan));
1068  if (err) {
1069  WL_ERR("error (%d)\n", err);
1070  return err;
1071  }
1072  brcmf_set_mpc(ndev, 0);
1073  results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1074  results->version = 0;
1075  results->count = 0;
1077 
1078  err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
1079  if (err)
1080  brcmf_set_mpc(ndev, 1);
1081  return err;
1082 }
1083 
1084 static s32
1085 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
1086  struct cfg80211_scan_request *request,
1087  struct cfg80211_ssid *this_ssid)
1088 {
1089  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1090  struct cfg80211_ssid *ssids;
1091  struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
1092  __le32 passive_scan;
1093  bool escan_req;
1094  bool spec_scan;
1095  s32 err;
1096  u32 SSID_len;
1097 
1098  WL_SCAN("START ESCAN\n");
1099 
1100  if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
1101  WL_ERR("Scanning already : status (%lu)\n", cfg->status);
1102  return -EAGAIN;
1103  }
1104  if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
1105  WL_ERR("Scanning being aborted : status (%lu)\n",
1106  cfg->status);
1107  return -EAGAIN;
1108  }
1109  if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
1110  WL_ERR("Connecting : status (%lu)\n",
1111  cfg->status);
1112  return -EAGAIN;
1113  }
1114 
1115  /* Arm scan timeout timer */
1116  mod_timer(&cfg->escan_timeout, jiffies +
1117  WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1118 
1119  escan_req = false;
1120  if (request) {
1121  /* scan bss */
1122  ssids = request->ssids;
1123  escan_req = true;
1124  } else {
1125  /* scan in ibss */
1126  /* we don't do escan in ibss */
1127  ssids = this_ssid;
1128  }
1129 
1130  cfg->scan_request = request;
1132  if (escan_req) {
1133  err = brcmf_do_escan(cfg, wiphy, ndev, request);
1134  if (!err)
1135  return err;
1136  else
1137  goto scan_out;
1138  } else {
1139  WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
1140  ssids->ssid, ssids->ssid_len);
1141  memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1142  SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1143  sr->ssid_le.SSID_len = cpu_to_le32(0);
1144  spec_scan = false;
1145  if (SSID_len) {
1146  memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1147  sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1148  spec_scan = true;
1149  } else
1150  WL_SCAN("Broadcast scan\n");
1151 
1152  passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1154  &passive_scan, sizeof(passive_scan));
1155  if (err) {
1156  WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1157  goto scan_out;
1158  }
1159  brcmf_set_mpc(ndev, 0);
1160  err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
1161  sizeof(sr->ssid_le));
1162  if (err) {
1163  if (err == -EBUSY)
1164  WL_INFO("BUSY: scan for \"%s\" canceled\n",
1165  sr->ssid_le.SSID);
1166  else
1167  WL_ERR("WLC_SCAN error (%d)\n", err);
1168 
1169  brcmf_set_mpc(ndev, 1);
1170  goto scan_out;
1171  }
1172  }
1173 
1174  return 0;
1175 
1176 scan_out:
1178  if (timer_pending(&cfg->escan_timeout))
1180  cfg->scan_request = NULL;
1181  return err;
1182 }
1183 
1184 static s32
1185 brcmf_cfg80211_scan(struct wiphy *wiphy,
1186  struct cfg80211_scan_request *request)
1187 {
1188  struct net_device *ndev = request->wdev->netdev;
1189  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1190  s32 err = 0;
1191 
1192  WL_TRACE("Enter\n");
1193 
1194  if (!check_sys_up(wiphy))
1195  return -EIO;
1196 
1197  if (cfg->iscan_on)
1198  err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
1199  else if (cfg->escan_on)
1200  err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1201 
1202  if (err)
1203  WL_ERR("scan error (%d)\n", err);
1204 
1205  WL_TRACE("Exit\n");
1206  return err;
1207 }
1208 
1209 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1210 {
1211  s32 err = 0;
1212 
1213  err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
1214  if (err)
1215  WL_ERR("Error (%d)\n", err);
1216 
1217  return err;
1218 }
1219 
1220 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1221 {
1222  s32 err = 0;
1223 
1224  err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
1225  if (err)
1226  WL_ERR("Error (%d)\n", err);
1227 
1228  return err;
1229 }
1230 
1231 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1232 {
1233  s32 err = 0;
1234  u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
1235 
1236  err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
1237  if (err) {
1238  WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
1239  return err;
1240  }
1241  return err;
1242 }
1243 
1244 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1245 {
1246  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1247  struct net_device *ndev = cfg_to_ndev(cfg);
1248  s32 err = 0;
1249 
1250  WL_TRACE("Enter\n");
1251  if (!check_sys_up(wiphy))
1252  return -EIO;
1253 
1254  if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1255  (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1256  cfg->conf->rts_threshold = wiphy->rts_threshold;
1257  err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1258  if (!err)
1259  goto done;
1260  }
1261  if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1262  (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1263  cfg->conf->frag_threshold = wiphy->frag_threshold;
1264  err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1265  if (!err)
1266  goto done;
1267  }
1268  if (changed & WIPHY_PARAM_RETRY_LONG
1269  && (cfg->conf->retry_long != wiphy->retry_long)) {
1270  cfg->conf->retry_long = wiphy->retry_long;
1271  err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1272  if (!err)
1273  goto done;
1274  }
1275  if (changed & WIPHY_PARAM_RETRY_SHORT
1276  && (cfg->conf->retry_short != wiphy->retry_short)) {
1277  cfg->conf->retry_short = wiphy->retry_short;
1278  err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1279  if (!err)
1280  goto done;
1281  }
1282 
1283 done:
1284  WL_TRACE("Exit\n");
1285  return err;
1286 }
1287 
1288 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1289 {
1290  memset(prof, 0, sizeof(*prof));
1291 }
1292 
1293 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
1294  size_t *join_params_size)
1295 {
1296  u16 chanspec = 0;
1297 
1298  if (ch != 0) {
1299  if (ch <= CH_MAX_2G_CHANNEL)
1300  chanspec |= WL_CHANSPEC_BAND_2G;
1301  else
1302  chanspec |= WL_CHANSPEC_BAND_5G;
1303 
1304  chanspec |= WL_CHANSPEC_BW_20;
1305  chanspec |= WL_CHANSPEC_CTL_SB_NONE;
1306 
1307  *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
1308  sizeof(u16);
1309 
1310  chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
1311  join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1312  join_params->params_le.chanspec_num = cpu_to_le32(1);
1313 
1314  WL_CONN("join_params->params.chanspec_list[0]= %#X,"
1315  "channel %d, chanspec %#X\n",
1316  chanspec, ch, chanspec);
1317  }
1318 }
1319 
1320 static void brcmf_link_down(struct brcmf_cfg80211_info *cfg)
1321 {
1322  struct net_device *ndev = NULL;
1323  s32 err = 0;
1324 
1325  WL_TRACE("Enter\n");
1326 
1327  if (cfg->link_up) {
1328  ndev = cfg_to_ndev(cfg);
1329  WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
1330  err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
1331  if (err)
1332  WL_ERR("WLC_DISASSOC failed (%d)\n", err);
1333  cfg->link_up = false;
1334  }
1335  WL_TRACE("Exit\n");
1336 }
1337 
1338 static s32
1339 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1340  struct cfg80211_ibss_params *params)
1341 {
1342  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1343  struct brcmf_cfg80211_profile *profile = cfg->profile;
1344  struct brcmf_join_params join_params;
1345  size_t join_params_size = 0;
1346  s32 err = 0;
1347  s32 wsec = 0;
1348  s32 bcnprd;
1349 
1350  WL_TRACE("Enter\n");
1351  if (!check_sys_up(wiphy))
1352  return -EIO;
1353 
1354  if (params->ssid)
1355  WL_CONN("SSID: %s\n", params->ssid);
1356  else {
1357  WL_CONN("SSID: NULL, Not supported\n");
1358  return -EOPNOTSUPP;
1359  }
1360 
1362 
1363  if (params->bssid)
1364  WL_CONN("BSSID: %pM\n", params->bssid);
1365  else
1366  WL_CONN("No BSSID specified\n");
1367 
1368  if (params->channel)
1369  WL_CONN("channel: %d\n", params->channel->center_freq);
1370  else
1371  WL_CONN("no channel specified\n");
1372 
1373  if (params->channel_fixed)
1374  WL_CONN("fixed channel required\n");
1375  else
1376  WL_CONN("no fixed channel required\n");
1377 
1378  if (params->ie && params->ie_len)
1379  WL_CONN("ie len: %d\n", params->ie_len);
1380  else
1381  WL_CONN("no ie specified\n");
1382 
1383  if (params->beacon_interval)
1384  WL_CONN("beacon interval: %d\n", params->beacon_interval);
1385  else
1386  WL_CONN("no beacon interval specified\n");
1387 
1388  if (params->basic_rates)
1389  WL_CONN("basic rates: %08X\n", params->basic_rates);
1390  else
1391  WL_CONN("no basic rates specified\n");
1392 
1393  if (params->privacy)
1394  WL_CONN("privacy required\n");
1395  else
1396  WL_CONN("no privacy required\n");
1397 
1398  /* Configure Privacy for starter */
1399  if (params->privacy)
1400  wsec |= WEP_ENABLED;
1401 
1402  err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1403  if (err) {
1404  WL_ERR("wsec failed (%d)\n", err);
1405  goto done;
1406  }
1407 
1408  /* Configure Beacon Interval for starter */
1409  if (params->beacon_interval)
1410  bcnprd = params->beacon_interval;
1411  else
1412  bcnprd = 100;
1413 
1414  err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
1415  if (err) {
1416  WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1417  goto done;
1418  }
1419 
1420  /* Configure required join parameter */
1421  memset(&join_params, 0, sizeof(struct brcmf_join_params));
1422 
1423  /* SSID */
1424  profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1425  memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1426  memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1427  join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1428  join_params_size = sizeof(join_params.ssid_le);
1429 
1430  /* BSSID */
1431  if (params->bssid) {
1432  memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1433  join_params_size = sizeof(join_params.ssid_le) +
1435  memcpy(profile->bssid, params->bssid, ETH_ALEN);
1436  } else {
1437  memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1438  memset(profile->bssid, 0, ETH_ALEN);
1439  }
1440 
1441  /* Channel */
1442  if (params->channel) {
1443  u32 target_channel;
1444 
1445  cfg->channel =
1447  params->channel->center_freq);
1448  if (params->channel_fixed) {
1449  /* adding chanspec */
1450  brcmf_ch_to_chanspec(cfg->channel,
1451  &join_params, &join_params_size);
1452  }
1453 
1454  /* set channel for starter */
1455  target_channel = cfg->channel;
1456  err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1457  &target_channel);
1458  if (err) {
1459  WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1460  goto done;
1461  }
1462  } else
1463  cfg->channel = 0;
1464 
1465  cfg->ibss_starter = false;
1466 
1467 
1468  err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1469  &join_params, join_params_size);
1470  if (err) {
1471  WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1472  goto done;
1473  }
1474 
1475 done:
1476  if (err)
1478  WL_TRACE("Exit\n");
1479  return err;
1480 }
1481 
1482 static s32
1483 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1484 {
1485  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1486  s32 err = 0;
1487 
1488  WL_TRACE("Enter\n");
1489  if (!check_sys_up(wiphy))
1490  return -EIO;
1491 
1492  brcmf_link_down(cfg);
1493 
1494  WL_TRACE("Exit\n");
1495 
1496  return err;
1497 }
1498 
1499 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1500  struct cfg80211_connect_params *sme)
1501 {
1502  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1503  struct brcmf_cfg80211_profile *profile = cfg->profile;
1504  struct brcmf_cfg80211_security *sec;
1505  s32 val = 0;
1506  s32 err = 0;
1507 
1508  if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1510  else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1512  else
1513  val = WPA_AUTH_DISABLED;
1514  WL_CONN("setting wpa_auth to 0x%0x\n", val);
1515  err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1516  if (err) {
1517  WL_ERR("set wpa_auth failed (%d)\n", err);
1518  return err;
1519  }
1520  sec = &profile->sec;
1521  sec->wpa_versions = sme->crypto.wpa_versions;
1522  return err;
1523 }
1524 
1525 static s32 brcmf_set_auth_type(struct net_device *ndev,
1526  struct cfg80211_connect_params *sme)
1527 {
1528  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1529  struct brcmf_cfg80211_profile *profile = cfg->profile;
1530  struct brcmf_cfg80211_security *sec;
1531  s32 val = 0;
1532  s32 err = 0;
1533 
1534  switch (sme->auth_type) {
1536  val = 0;
1537  WL_CONN("open system\n");
1538  break;
1540  val = 1;
1541  WL_CONN("shared key\n");
1542  break;
1544  val = 2;
1545  WL_CONN("automatic\n");
1546  break;
1548  WL_CONN("network eap\n");
1549  default:
1550  val = 2;
1551  WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1552  break;
1553  }
1554 
1555  err = brcmf_dev_intvar_set(ndev, "auth", val);
1556  if (err) {
1557  WL_ERR("set auth failed (%d)\n", err);
1558  return err;
1559  }
1560  sec = &profile->sec;
1561  sec->auth_type = sme->auth_type;
1562  return err;
1563 }
1564 
1565 static s32
1566 brcmf_set_set_cipher(struct net_device *ndev,
1567  struct cfg80211_connect_params *sme)
1568 {
1569  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1570  struct brcmf_cfg80211_profile *profile = cfg->profile;
1571  struct brcmf_cfg80211_security *sec;
1572  s32 pval = 0;
1573  s32 gval = 0;
1574  s32 err = 0;
1575 
1576  if (sme->crypto.n_ciphers_pairwise) {
1577  switch (sme->crypto.ciphers_pairwise[0]) {
1580  pval = WEP_ENABLED;
1581  break;
1583  pval = TKIP_ENABLED;
1584  break;
1586  pval = AES_ENABLED;
1587  break;
1589  pval = AES_ENABLED;
1590  break;
1591  default:
1592  WL_ERR("invalid cipher pairwise (%d)\n",
1593  sme->crypto.ciphers_pairwise[0]);
1594  return -EINVAL;
1595  }
1596  }
1597  if (sme->crypto.cipher_group) {
1598  switch (sme->crypto.cipher_group) {
1601  gval = WEP_ENABLED;
1602  break;
1604  gval = TKIP_ENABLED;
1605  break;
1607  gval = AES_ENABLED;
1608  break;
1610  gval = AES_ENABLED;
1611  break;
1612  default:
1613  WL_ERR("invalid cipher group (%d)\n",
1614  sme->crypto.cipher_group);
1615  return -EINVAL;
1616  }
1617  }
1618 
1619  WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1620  err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1621  if (err) {
1622  WL_ERR("error (%d)\n", err);
1623  return err;
1624  }
1625 
1626  sec = &profile->sec;
1627  sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1628  sec->cipher_group = sme->crypto.cipher_group;
1629 
1630  return err;
1631 }
1632 
1633 static s32
1634 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1635 {
1636  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1637  struct brcmf_cfg80211_profile *profile = cfg->profile;
1638  struct brcmf_cfg80211_security *sec;
1639  s32 val = 0;
1640  s32 err = 0;
1641 
1642  if (sme->crypto.n_akm_suites) {
1643  err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1644  if (err) {
1645  WL_ERR("could not get wpa_auth (%d)\n", err);
1646  return err;
1647  }
1648  if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1649  switch (sme->crypto.akm_suites[0]) {
1650  case WLAN_AKM_SUITE_8021X:
1651  val = WPA_AUTH_UNSPECIFIED;
1652  break;
1653  case WLAN_AKM_SUITE_PSK:
1654  val = WPA_AUTH_PSK;
1655  break;
1656  default:
1657  WL_ERR("invalid cipher group (%d)\n",
1658  sme->crypto.cipher_group);
1659  return -EINVAL;
1660  }
1661  } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1662  switch (sme->crypto.akm_suites[0]) {
1663  case WLAN_AKM_SUITE_8021X:
1664  val = WPA2_AUTH_UNSPECIFIED;
1665  break;
1666  case WLAN_AKM_SUITE_PSK:
1667  val = WPA2_AUTH_PSK;
1668  break;
1669  default:
1670  WL_ERR("invalid cipher group (%d)\n",
1671  sme->crypto.cipher_group);
1672  return -EINVAL;
1673  }
1674  }
1675 
1676  WL_CONN("setting wpa_auth to %d\n", val);
1677  err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1678  if (err) {
1679  WL_ERR("could not set wpa_auth (%d)\n", err);
1680  return err;
1681  }
1682  }
1683  sec = &profile->sec;
1684  sec->wpa_auth = sme->crypto.akm_suites[0];
1685 
1686  return err;
1687 }
1688 
1689 static s32
1690 brcmf_set_sharedkey(struct net_device *ndev,
1691  struct cfg80211_connect_params *sme)
1692 {
1693  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1694  struct brcmf_cfg80211_profile *profile = cfg->profile;
1695  struct brcmf_cfg80211_security *sec;
1696  struct brcmf_wsec_key key;
1697  s32 val;
1698  s32 err = 0;
1699  s32 bssidx;
1700 
1701  WL_CONN("key len (%d)\n", sme->key_len);
1702 
1703  if (sme->key_len == 0)
1704  return 0;
1705 
1706  sec = &profile->sec;
1707  WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1708  sec->wpa_versions, sec->cipher_pairwise);
1709 
1711  return 0;
1712 
1713  if (!(sec->cipher_pairwise &
1715  return 0;
1716 
1717  memset(&key, 0, sizeof(key));
1718  key.len = (u32) sme->key_len;
1719  key.index = (u32) sme->key_idx;
1720  if (key.len > sizeof(key.data)) {
1721  WL_ERR("Too long key length (%u)\n", key.len);
1722  return -EINVAL;
1723  }
1724  memcpy(key.data, sme->key, key.len);
1725  key.flags = BRCMF_PRIMARY_KEY;
1726  switch (sec->cipher_pairwise) {
1728  key.algo = CRYPTO_ALGO_WEP1;
1729  break;
1731  key.algo = CRYPTO_ALGO_WEP128;
1732  break;
1733  default:
1734  WL_ERR("Invalid algorithm (%d)\n",
1735  sme->crypto.ciphers_pairwise[0]);
1736  return -EINVAL;
1737  }
1738  /* Set the new key/index */
1739  WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1740  key.len, key.index, key.algo);
1741  WL_CONN("key \"%s\"\n", key.data);
1742  bssidx = brcmf_find_bssidx(cfg, ndev);
1743  err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1744  if (err)
1745  return err;
1746 
1747  if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1748  WL_CONN("set auth_type to shared key\n");
1749  val = WL_AUTH_SHARED_KEY; /* shared key */
1750  err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx);
1751  if (err)
1752  WL_ERR("set auth failed (%d)\n", err);
1753  }
1754  return err;
1755 }
1756 
1757 static s32
1758 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1759  struct cfg80211_connect_params *sme)
1760 {
1761  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1762  struct brcmf_cfg80211_profile *profile = cfg->profile;
1763  struct ieee80211_channel *chan = sme->channel;
1764  struct brcmf_join_params join_params;
1765  size_t join_params_size;
1766  struct brcmf_ssid ssid;
1767 
1768  s32 err = 0;
1769 
1770  WL_TRACE("Enter\n");
1771  if (!check_sys_up(wiphy))
1772  return -EIO;
1773 
1774  if (!sme->ssid) {
1775  WL_ERR("Invalid ssid\n");
1776  return -EOPNOTSUPP;
1777  }
1778 
1780 
1781  if (chan) {
1782  cfg->channel =
1784  WL_CONN("channel (%d), center_req (%d)\n",
1785  cfg->channel, chan->center_freq);
1786  } else
1787  cfg->channel = 0;
1788 
1789  WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1790 
1791  err = brcmf_set_wpa_version(ndev, sme);
1792  if (err) {
1793  WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1794  goto done;
1795  }
1796 
1797  err = brcmf_set_auth_type(ndev, sme);
1798  if (err) {
1799  WL_ERR("wl_set_auth_type failed (%d)\n", err);
1800  goto done;
1801  }
1802 
1803  err = brcmf_set_set_cipher(ndev, sme);
1804  if (err) {
1805  WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1806  goto done;
1807  }
1808 
1809  err = brcmf_set_key_mgmt(ndev, sme);
1810  if (err) {
1811  WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1812  goto done;
1813  }
1814 
1815  err = brcmf_set_sharedkey(ndev, sme);
1816  if (err) {
1817  WL_ERR("brcmf_set_sharedkey failed (%d)\n", err);
1818  goto done;
1819  }
1820 
1821  memset(&join_params, 0, sizeof(join_params));
1822  join_params_size = sizeof(join_params.ssid_le);
1823 
1824  profile->ssid.SSID_len = min_t(u32,
1825  sizeof(ssid.SSID), (u32)sme->ssid_len);
1826  memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1827  memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1828  join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1829 
1830  memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1831 
1832  if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1833  WL_CONN("ssid \"%s\", len (%d)\n",
1834  ssid.SSID, ssid.SSID_len);
1835 
1836  brcmf_ch_to_chanspec(cfg->channel,
1837  &join_params, &join_params_size);
1838  err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1839  &join_params, join_params_size);
1840  if (err)
1841  WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1842 
1843 done:
1844  if (err)
1846  WL_TRACE("Exit\n");
1847  return err;
1848 }
1849 
1850 static s32
1851 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1852  u16 reason_code)
1853 {
1854  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1855  struct brcmf_cfg80211_profile *profile = cfg->profile;
1856  struct brcmf_scb_val_le scbval;
1857  s32 err = 0;
1858 
1859  WL_TRACE("Enter. Reason code = %d\n", reason_code);
1860  if (!check_sys_up(wiphy))
1861  return -EIO;
1862 
1864 
1865  memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1866  scbval.val = cpu_to_le32(reason_code);
1867  err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1868  sizeof(struct brcmf_scb_val_le));
1869  if (err)
1870  WL_ERR("error (%d)\n", err);
1871 
1872  cfg->link_up = false;
1873 
1874  WL_TRACE("Exit\n");
1875  return err;
1876 }
1877 
1878 static s32
1879 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1880  enum nl80211_tx_power_setting type, s32 mbm)
1881 {
1882 
1883  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1884  struct net_device *ndev = cfg_to_ndev(cfg);
1885  u16 txpwrmw;
1886  s32 err = 0;
1887  s32 disable = 0;
1888  s32 dbm = MBM_TO_DBM(mbm);
1889 
1890  WL_TRACE("Enter\n");
1891  if (!check_sys_up(wiphy))
1892  return -EIO;
1893 
1894  switch (type) {
1896  break;
1899  if (dbm < 0) {
1900  WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1901  err = -EINVAL;
1902  goto done;
1903  }
1904  break;
1905  }
1906  /* Make sure radio is off or on as far as software is concerned */
1907  disable = WL_RADIO_SW_DISABLE << 16;
1908  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1909  if (err)
1910  WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1911 
1912  if (dbm > 0xffff)
1913  txpwrmw = 0xffff;
1914  else
1915  txpwrmw = (u16) dbm;
1916  err = brcmf_dev_intvar_set(ndev, "qtxpower",
1917  (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1918  if (err)
1919  WL_ERR("qtxpower error (%d)\n", err);
1920  cfg->conf->tx_power = dbm;
1921 
1922 done:
1923  WL_TRACE("Exit\n");
1924  return err;
1925 }
1926 
1927 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1928 {
1929  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1930  struct net_device *ndev = cfg_to_ndev(cfg);
1931  s32 txpwrdbm;
1932  u8 result;
1933  s32 err = 0;
1934 
1935  WL_TRACE("Enter\n");
1936  if (!check_sys_up(wiphy))
1937  return -EIO;
1938 
1939  err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1940  if (err) {
1941  WL_ERR("error (%d)\n", err);
1942  goto done;
1943  }
1944 
1945  result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1946  *dbm = (s32) brcmf_qdbm_to_mw(result);
1947 
1948 done:
1949  WL_TRACE("Exit\n");
1950  return err;
1951 }
1952 
1953 static s32
1954 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1955  u8 key_idx, bool unicast, bool multicast)
1956 {
1957  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1958  u32 index;
1959  u32 wsec;
1960  s32 err = 0;
1961  s32 bssidx;
1962 
1963  WL_TRACE("Enter\n");
1964  WL_CONN("key index (%d)\n", key_idx);
1965  if (!check_sys_up(wiphy))
1966  return -EIO;
1967 
1968  bssidx = brcmf_find_bssidx(cfg, ndev);
1969  err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1970  if (err) {
1971  WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1972  goto done;
1973  }
1974 
1975  if (wsec & WEP_ENABLED) {
1976  /* Just select a new current key */
1977  index = key_idx;
1978  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1979  &index);
1980  if (err)
1981  WL_ERR("error (%d)\n", err);
1982  }
1983 done:
1984  WL_TRACE("Exit\n");
1985  return err;
1986 }
1987 
1988 static s32
1989 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1990  u8 key_idx, const u8 *mac_addr, struct key_params *params)
1991 {
1992  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1993  struct brcmf_wsec_key key;
1994  struct brcmf_wsec_key_le key_le;
1995  s32 err = 0;
1996  s32 bssidx;
1997 
1998  memset(&key, 0, sizeof(key));
1999  key.index = (u32) key_idx;
2000  /* Instead of bcast for ea address for default wep keys,
2001  driver needs it to be Null */
2002  if (!is_multicast_ether_addr(mac_addr))
2003  memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2004  key.len = (u32) params->key_len;
2005  bssidx = brcmf_find_bssidx(cfg, ndev);
2006  /* check for key index change */
2007  if (key.len == 0) {
2008  /* key delete */
2009  err = send_key_to_dongle(cfg, bssidx, ndev, &key);
2010  if (err)
2011  WL_ERR("key delete error (%d)\n", err);
2012  } else {
2013  if (key.len > sizeof(key.data)) {
2014  WL_ERR("Invalid key length (%d)\n", key.len);
2015  return -EINVAL;
2016  }
2017 
2018  WL_CONN("Setting the key index %d\n", key.index);
2019  memcpy(key.data, params->key, key.len);
2020 
2021  if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
2022  u8 keybuf[8];
2023  memcpy(keybuf, &key.data[24], sizeof(keybuf));
2024  memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2025  memcpy(&key.data[16], keybuf, sizeof(keybuf));
2026  }
2027 
2028  /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2029  if (params->seq && params->seq_len == 6) {
2030  /* rx iv */
2031  u8 *ivptr;
2032  ivptr = (u8 *) params->seq;
2033  key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2034  (ivptr[3] << 8) | ivptr[2];
2035  key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2036  key.iv_initialized = true;
2037  }
2038 
2039  switch (params->cipher) {
2041  key.algo = CRYPTO_ALGO_WEP1;
2042  WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2043  break;
2045  key.algo = CRYPTO_ALGO_WEP128;
2046  WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2047  break;
2049  key.algo = CRYPTO_ALGO_TKIP;
2050  WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2051  break;
2053  key.algo = CRYPTO_ALGO_AES_CCM;
2054  WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2055  break;
2057  key.algo = CRYPTO_ALGO_AES_CCM;
2058  WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
2059  break;
2060  default:
2061  WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
2062  return -EINVAL;
2063  }
2064  convert_key_from_CPU(&key, &key_le);
2065 
2067  err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
2068  sizeof(key_le),
2069  cfg->extra_buf,
2070  WL_EXTRA_BUF_MAX, bssidx);
2071  if (err)
2072  WL_ERR("wsec_key error (%d)\n", err);
2073  }
2074  return err;
2075 }
2076 
2077 static s32
2078 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2079  u8 key_idx, bool pairwise, const u8 *mac_addr,
2080  struct key_params *params)
2081 {
2082  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2083  struct brcmf_wsec_key key;
2084  s32 val;
2085  s32 wsec;
2086  s32 err = 0;
2087  u8 keybuf[8];
2088  s32 bssidx;
2089 
2090  WL_TRACE("Enter\n");
2091  WL_CONN("key index (%d)\n", key_idx);
2092  if (!check_sys_up(wiphy))
2093  return -EIO;
2094 
2095  if (mac_addr) {
2096  WL_TRACE("Exit");
2097  return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2098  }
2099  memset(&key, 0, sizeof(key));
2100 
2101  key.len = (u32) params->key_len;
2102  key.index = (u32) key_idx;
2103 
2104  if (key.len > sizeof(key.data)) {
2105  WL_ERR("Too long key length (%u)\n", key.len);
2106  err = -EINVAL;
2107  goto done;
2108  }
2109  memcpy(key.data, params->key, key.len);
2110 
2111  key.flags = BRCMF_PRIMARY_KEY;
2112  switch (params->cipher) {
2114  key.algo = CRYPTO_ALGO_WEP1;
2115  val = WEP_ENABLED;
2116  WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2117  break;
2119  key.algo = CRYPTO_ALGO_WEP128;
2120  val = WEP_ENABLED;
2121  WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2122  break;
2124  if (cfg->conf->mode != WL_MODE_AP) {
2125  WL_CONN("Swapping key\n");
2126  memcpy(keybuf, &key.data[24], sizeof(keybuf));
2127  memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2128  memcpy(&key.data[16], keybuf, sizeof(keybuf));
2129  }
2130  key.algo = CRYPTO_ALGO_TKIP;
2131  val = TKIP_ENABLED;
2132  WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2133  break;
2135  key.algo = CRYPTO_ALGO_AES_CCM;
2136  val = AES_ENABLED;
2137  WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2138  break;
2140  key.algo = CRYPTO_ALGO_AES_CCM;
2141  val = AES_ENABLED;
2142  WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
2143  break;
2144  default:
2145  WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
2146  err = -EINVAL;
2147  goto done;
2148  }
2149 
2150  bssidx = brcmf_find_bssidx(cfg, ndev);
2151  err = send_key_to_dongle(cfg, bssidx, ndev, &key);
2152  if (err)
2153  goto done;
2154 
2155  err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
2156  if (err) {
2157  WL_ERR("get wsec error (%d)\n", err);
2158  goto done;
2159  }
2160  wsec |= val;
2161  err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
2162  if (err) {
2163  WL_ERR("set wsec error (%d)\n", err);
2164  goto done;
2165  }
2166 
2167 done:
2168  WL_TRACE("Exit\n");
2169  return err;
2170 }
2171 
2172 static s32
2173 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2174  u8 key_idx, bool pairwise, const u8 *mac_addr)
2175 {
2176  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2177  struct brcmf_wsec_key key;
2178  s32 err = 0;
2179  s32 bssidx;
2180 
2181  WL_TRACE("Enter\n");
2182  if (!check_sys_up(wiphy))
2183  return -EIO;
2184 
2185  memset(&key, 0, sizeof(key));
2186 
2187  key.index = (u32) key_idx;
2188  key.flags = BRCMF_PRIMARY_KEY;
2189  key.algo = CRYPTO_ALGO_OFF;
2190 
2191  WL_CONN("key index (%d)\n", key_idx);
2192 
2193  /* Set the new key/index */
2194  bssidx = brcmf_find_bssidx(cfg, ndev);
2195  err = send_key_to_dongle(cfg, bssidx, ndev, &key);
2196  if (err) {
2197  if (err == -EINVAL) {
2198  if (key.index >= DOT11_MAX_DEFAULT_KEYS)
2199  /* we ignore this key index in this case */
2200  WL_ERR("invalid key index (%d)\n", key_idx);
2201  }
2202  /* Ignore this error, may happen during DISASSOC */
2203  err = -EAGAIN;
2204  }
2205 
2206  WL_TRACE("Exit\n");
2207  return err;
2208 }
2209 
2210 static s32
2211 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2212  u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2213  void (*callback) (void *cookie, struct key_params * params))
2214 {
2215  struct key_params params;
2216  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2217  struct brcmf_cfg80211_profile *profile = cfg->profile;
2218  struct brcmf_cfg80211_security *sec;
2219  s32 wsec;
2220  s32 err = 0;
2221  s32 bssidx;
2222 
2223  WL_TRACE("Enter\n");
2224  WL_CONN("key index (%d)\n", key_idx);
2225  if (!check_sys_up(wiphy))
2226  return -EIO;
2227 
2228  memset(&params, 0, sizeof(params));
2229 
2230  bssidx = brcmf_find_bssidx(cfg, ndev);
2231  err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
2232  if (err) {
2233  WL_ERR("WLC_GET_WSEC error (%d)\n", err);
2234  /* Ignore this error, may happen during DISASSOC */
2235  err = -EAGAIN;
2236  goto done;
2237  }
2238  switch (wsec & ~SES_OW_ENABLED) {
2239  case WEP_ENABLED:
2240  sec = &profile->sec;
2243  WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2244  } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2246  WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2247  }
2248  break;
2249  case TKIP_ENABLED:
2250  params.cipher = WLAN_CIPHER_SUITE_TKIP;
2251  WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2252  break;
2253  case AES_ENABLED:
2255  WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2256  break;
2257  default:
2258  WL_ERR("Invalid algo (0x%x)\n", wsec);
2259  err = -EINVAL;
2260  goto done;
2261  }
2262  callback(cookie, &params);
2263 
2264 done:
2265  WL_TRACE("Exit\n");
2266  return err;
2267 }
2268 
2269 static s32
2270 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2271  struct net_device *ndev, u8 key_idx)
2272 {
2273  WL_INFO("Not supported\n");
2274 
2275  return -EOPNOTSUPP;
2276 }
2277 
2278 static s32
2279 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2280  u8 *mac, struct station_info *sinfo)
2281 {
2282  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2283  struct brcmf_cfg80211_profile *profile = cfg->profile;
2284  struct brcmf_scb_val_le scb_val;
2285  int rssi;
2286  s32 rate;
2287  s32 err = 0;
2288  u8 *bssid = profile->bssid;
2289  struct brcmf_sta_info_le *sta_info_le;
2290 
2291  WL_TRACE("Enter, MAC %pM\n", mac);
2292  if (!check_sys_up(wiphy))
2293  return -EIO;
2294 
2295  if (cfg->conf->mode == WL_MODE_AP) {
2296  err = brcmf_dev_iovar_getbuf(ndev, "sta_info", mac, ETH_ALEN,
2297  cfg->dcmd_buf,
2298  WL_DCMD_LEN_MAX);
2299  if (err < 0) {
2300  WL_ERR("GET STA INFO failed, %d\n", err);
2301  goto done;
2302  }
2303  sta_info_le = (struct brcmf_sta_info_le *)cfg->dcmd_buf;
2304 
2306  sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000;
2307  if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) {
2309  sinfo->connected_time = le32_to_cpu(sta_info_le->in);
2310  }
2311  WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
2312  sinfo->inactive_time, sinfo->connected_time);
2313  } else if (cfg->conf->mode == WL_MODE_BSS) {
2314  if (memcmp(mac, bssid, ETH_ALEN)) {
2315  WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2316  mac, bssid);
2317  err = -ENOENT;
2318  goto done;
2319  }
2320  /* Report the current tx rate */
2321  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
2322  if (err) {
2323  WL_ERR("Could not get rate (%d)\n", err);
2324  goto done;
2325  } else {
2326  sinfo->filled |= STATION_INFO_TX_BITRATE;
2327  sinfo->txrate.legacy = rate * 5;
2328  WL_CONN("Rate %d Mbps\n", rate / 2);
2329  }
2330 
2331  if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) {
2332  memset(&scb_val, 0, sizeof(scb_val));
2333  err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
2334  sizeof(scb_val));
2335  if (err) {
2336  WL_ERR("Could not get rssi (%d)\n", err);
2337  goto done;
2338  } else {
2339  rssi = le32_to_cpu(scb_val.val);
2340  sinfo->filled |= STATION_INFO_SIGNAL;
2341  sinfo->signal = rssi;
2342  WL_CONN("RSSI %d dBm\n", rssi);
2343  }
2344  }
2345  } else
2346  err = -EPERM;
2347 done:
2348  WL_TRACE("Exit\n");
2349  return err;
2350 }
2351 
2352 static s32
2353 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2354  bool enabled, s32 timeout)
2355 {
2356  s32 pm;
2357  s32 err = 0;
2358  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2359 
2360  WL_TRACE("Enter\n");
2361 
2362  /*
2363  * Powersave enable/disable request is coming from the
2364  * cfg80211 even before the interface is up. In that
2365  * scenario, driver will be storing the power save
2366  * preference in cfg struct to apply this to
2367  * FW later while initializing the dongle
2368  */
2369  cfg->pwr_save = enabled;
2370  if (!test_bit(WL_STATUS_READY, &cfg->status)) {
2371 
2372  WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
2373  goto done;
2374  }
2375 
2376  pm = enabled ? PM_FAST : PM_OFF;
2377  WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
2378 
2379  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
2380  if (err) {
2381  if (err == -ENODEV)
2382  WL_ERR("net_device is not ready yet\n");
2383  else
2384  WL_ERR("error (%d)\n", err);
2385  }
2386 done:
2387  WL_TRACE("Exit\n");
2388  return err;
2389 }
2390 
2391 static s32
2392 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2393  const u8 *addr,
2394  const struct cfg80211_bitrate_mask *mask)
2395 {
2396  struct brcm_rateset_le rateset_le;
2397  s32 rate;
2398  s32 val;
2399  s32 err_bg;
2400  s32 err_a;
2401  u32 legacy;
2402  s32 err = 0;
2403 
2404  WL_TRACE("Enter\n");
2405  if (!check_sys_up(wiphy))
2406  return -EIO;
2407 
2408  /* addr param is always NULL. ignore it */
2409  /* Get current rateset */
2410  err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
2411  sizeof(rateset_le));
2412  if (err) {
2413  WL_ERR("could not get current rateset (%d)\n", err);
2414  goto done;
2415  }
2416 
2417  legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2418  if (!legacy)
2419  legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2420  0xFFFF);
2421 
2422  val = wl_g_rates[legacy - 1].bitrate * 100000;
2423 
2424  if (val < le32_to_cpu(rateset_le.count))
2425  /* Select rate by rateset index */
2426  rate = rateset_le.rates[val] & 0x7f;
2427  else
2428  /* Specified rate in bps */
2429  rate = val / 500000;
2430 
2431  WL_CONN("rate %d mbps\n", rate / 2);
2432 
2433  /*
2434  *
2435  * Set rate override,
2436  * Since the is a/b/g-blind, both a/bg_rate are enforced.
2437  */
2438  err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
2439  err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
2440  if (err_bg && err_a) {
2441  WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2442  err = err_bg | err_a;
2443  }
2444 
2445 done:
2446  WL_TRACE("Exit\n");
2447  return err;
2448 }
2449 
2450 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2451  struct brcmf_bss_info_le *bi)
2452 {
2453  struct wiphy *wiphy = cfg_to_wiphy(cfg);
2454  struct ieee80211_channel *notify_channel;
2455  struct cfg80211_bss *bss;
2457  s32 err = 0;
2458  u16 channel;
2459  u32 freq;
2460  u16 notify_capability;
2461  u16 notify_interval;
2462  u8 *notify_ie;
2463  size_t notify_ielen;
2464  s32 notify_signal;
2465 
2466  if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2467  WL_ERR("Bss info is larger than buffer. Discarding\n");
2468  return 0;
2469  }
2470 
2471  channel = bi->ctl_ch ? bi->ctl_ch :
2473 
2474  if (channel <= CH_MAX_2G_CHANNEL)
2475  band = wiphy->bands[IEEE80211_BAND_2GHZ];
2476  else
2477  band = wiphy->bands[IEEE80211_BAND_5GHZ];
2478 
2479  freq = ieee80211_channel_to_frequency(channel, band->band);
2480  notify_channel = ieee80211_get_channel(wiphy, freq);
2481 
2482  notify_capability = le16_to_cpu(bi->capability);
2483  notify_interval = le16_to_cpu(bi->beacon_period);
2484  notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2485  notify_ielen = le32_to_cpu(bi->ie_length);
2486  notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2487 
2488  WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2489  bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2490  bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2491  WL_CONN("Channel: %d(%d)\n", channel, freq);
2492  WL_CONN("Capability: %X\n", notify_capability);
2493  WL_CONN("Beacon interval: %d\n", notify_interval);
2494  WL_CONN("Signal: %d\n", notify_signal);
2495 
2496  bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2497  0, notify_capability, notify_interval, notify_ie,
2498  notify_ielen, notify_signal, GFP_KERNEL);
2499 
2500  if (!bss)
2501  return -ENOMEM;
2502 
2503  cfg80211_put_bss(bss);
2504 
2505  return err;
2506 }
2507 
2508 static struct brcmf_bss_info_le *
2509 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2510 {
2511  if (bss == NULL)
2512  return list->bss_info_le;
2513  return (struct brcmf_bss_info_le *)((unsigned long)bss +
2514  le32_to_cpu(bss->length));
2515 }
2516 
2517 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2518 {
2519  struct brcmf_scan_results *bss_list;
2520  struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2521  s32 err = 0;
2522  int i;
2523 
2524  bss_list = cfg->bss_list;
2525  if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2526  WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2527  bss_list->version);
2528  return -EOPNOTSUPP;
2529  }
2530  WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2531  for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2532  bi = next_bss_le(bss_list, bi);
2533  err = brcmf_inform_single_bss(cfg, bi);
2534  if (err)
2535  break;
2536  }
2537  return err;
2538 }
2539 
2540 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2541  struct net_device *ndev, const u8 *bssid)
2542 {
2543  struct wiphy *wiphy = cfg_to_wiphy(cfg);
2544  struct ieee80211_channel *notify_channel;
2545  struct brcmf_bss_info_le *bi = NULL;
2547  struct cfg80211_bss *bss;
2548  u8 *buf = NULL;
2549  s32 err = 0;
2550  u16 channel;
2551  u32 freq;
2552  u16 notify_capability;
2553  u16 notify_interval;
2554  u8 *notify_ie;
2555  size_t notify_ielen;
2556  s32 notify_signal;
2557 
2558  WL_TRACE("Enter\n");
2559 
2560  buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2561  if (buf == NULL) {
2562  err = -ENOMEM;
2563  goto CleanUp;
2564  }
2565 
2566  *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2567 
2569  if (err) {
2570  WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2571  goto CleanUp;
2572  }
2573 
2574  bi = (struct brcmf_bss_info_le *)(buf + 4);
2575 
2576  channel = bi->ctl_ch ? bi->ctl_ch :
2578 
2579  if (channel <= CH_MAX_2G_CHANNEL)
2580  band = wiphy->bands[IEEE80211_BAND_2GHZ];
2581  else
2582  band = wiphy->bands[IEEE80211_BAND_5GHZ];
2583 
2584  freq = ieee80211_channel_to_frequency(channel, band->band);
2585  notify_channel = ieee80211_get_channel(wiphy, freq);
2586 
2587  notify_capability = le16_to_cpu(bi->capability);
2588  notify_interval = le16_to_cpu(bi->beacon_period);
2589  notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2590  notify_ielen = le32_to_cpu(bi->ie_length);
2591  notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2592 
2593  WL_CONN("channel: %d(%d)\n", channel, freq);
2594  WL_CONN("capability: %X\n", notify_capability);
2595  WL_CONN("beacon interval: %d\n", notify_interval);
2596  WL_CONN("signal: %d\n", notify_signal);
2597 
2598  bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2599  0, notify_capability, notify_interval,
2600  notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2601 
2602  if (!bss) {
2603  err = -ENOMEM;
2604  goto CleanUp;
2605  }
2606 
2607  cfg80211_put_bss(bss);
2608 
2609 CleanUp:
2610 
2611  kfree(buf);
2612 
2613  WL_TRACE("Exit\n");
2614 
2615  return err;
2616 }
2617 
2618 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg)
2619 {
2620  return cfg->conf->mode == WL_MODE_IBSS;
2621 }
2622 
2623 /*
2624  * Traverse a string of 1-byte tag/1-byte length/variable-length value
2625  * triples, returning a pointer to the substring whose first element
2626  * matches tag
2627  */
2628 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2629 {
2630  struct brcmf_tlv *elt;
2631  int totlen;
2632 
2633  elt = (struct brcmf_tlv *) buf;
2634  totlen = buflen;
2635 
2636  /* find tagged parameter */
2637  while (totlen >= TLV_HDR_LEN) {
2638  int len = elt->len;
2639 
2640  /* validate remaining totlen */
2641  if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2642  return elt;
2643 
2644  elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2645  totlen -= (len + TLV_HDR_LEN);
2646  }
2647 
2648  return NULL;
2649 }
2650 
2651 /* Is any of the tlvs the expected entry? If
2652  * not update the tlvs buffer pointer/length.
2653  */
2654 static bool
2655 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2656  u8 *oui, u32 oui_len, u8 type)
2657 {
2658  /* If the contents match the OUI and the type */
2659  if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2660  !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2661  type == ie[TLV_BODY_OFF + oui_len]) {
2662  return true;
2663  }
2664 
2665  if (tlvs == NULL)
2666  return false;
2667  /* point to the next ie */
2668  ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2669  /* calculate the length of the rest of the buffer */
2670  *tlvs_len -= (int)(ie - *tlvs);
2671  /* update the pointer to the start of the buffer */
2672  *tlvs = ie;
2673 
2674  return false;
2675 }
2677 struct brcmf_vs_tlv *
2679 {
2680  struct brcmf_tlv *ie;
2681 
2682  while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_WPA))) {
2683  if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2685  return (struct brcmf_vs_tlv *)ie;
2686  }
2687  return NULL;
2688 }
2689 
2690 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2691 {
2692  struct brcmf_cfg80211_profile *profile = cfg->profile;
2693  struct brcmf_bss_info_le *bi;
2694  struct brcmf_ssid *ssid;
2695  struct brcmf_tlv *tim;
2697  u8 dtim_period;
2698  size_t ie_len;
2699  u8 *ie;
2700  s32 err = 0;
2701 
2702  WL_TRACE("Enter\n");
2703  if (brcmf_is_ibssmode(cfg))
2704  return err;
2705 
2706  ssid = &profile->ssid;
2707 
2709  err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_GET_BSS_INFO,
2710  cfg->extra_buf, WL_EXTRA_BUF_MAX);
2711  if (err) {
2712  WL_ERR("Could not get bss info %d\n", err);
2713  goto update_bss_info_out;
2714  }
2715 
2716  bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2717  err = brcmf_inform_single_bss(cfg, bi);
2718  if (err)
2719  goto update_bss_info_out;
2720 
2721  ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2722  ie_len = le32_to_cpu(bi->ie_length);
2723  beacon_interval = le16_to_cpu(bi->beacon_period);
2724 
2725  tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2726  if (tim)
2727  dtim_period = tim->data[1];
2728  else {
2729  /*
2730  * active scan was done so we could not get dtim
2731  * information out of probe response.
2732  * so we speficially query dtim information to dongle.
2733  */
2734  u32 var;
2735  err = brcmf_dev_intvar_get(cfg_to_ndev(cfg),
2736  "dtim_assoc", &var);
2737  if (err) {
2738  WL_ERR("wl dtim_assoc failed (%d)\n", err);
2739  goto update_bss_info_out;
2740  }
2741  dtim_period = (u8)var;
2742  }
2743 
2744  profile->beacon_interval = beacon_interval;
2745  profile->dtim_period = dtim_period;
2746 
2747 update_bss_info_out:
2748  WL_TRACE("Exit");
2749  return err;
2750 }
2751 
2752 static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2753 {
2754  struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2755  struct escan_info *escan = &cfg->escan_info;
2756  struct brcmf_ssid ssid;
2757 
2759  if (cfg->iscan_on) {
2760  iscan->state = WL_ISCAN_STATE_IDLE;
2761 
2762  if (iscan->timer_on) {
2763  del_timer_sync(&iscan->timer);
2764  iscan->timer_on = 0;
2765  }
2766 
2767  cancel_work_sync(&iscan->work);
2768 
2769  /* Abort iscan running in FW */
2770  memset(&ssid, 0, sizeof(ssid));
2771  brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2772 
2773  if (cfg->scan_request) {
2774  /* Indidate scan abort to cfg80211 layer */
2775  WL_INFO("Terminating scan in progress\n");
2776  cfg80211_scan_done(cfg->scan_request, true);
2777  cfg->scan_request = NULL;
2778  }
2779  }
2780  if (cfg->escan_on && cfg->scan_request) {
2782  brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2783  }
2786 }
2787 
2788 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2789  bool aborted)
2790 {
2791  struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2792  struct net_device *ndev = cfg_to_ndev(cfg);
2793 
2795  WL_ERR("Scan complete while device not scanning\n");
2796  return;
2797  }
2798  if (cfg->scan_request) {
2799  WL_SCAN("ISCAN Completed scan: %s\n",
2800  aborted ? "Aborted" : "Done");
2801  cfg80211_scan_done(cfg->scan_request, aborted);
2802  brcmf_set_mpc(ndev, 1);
2803  cfg->scan_request = NULL;
2804  }
2805  cfg->iscan_kickstart = false;
2806 }
2807 
2808 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2809 {
2810  if (iscan->state != WL_ISCAN_STATE_IDLE) {
2811  WL_SCAN("wake up iscan\n");
2812  schedule_work(&iscan->work);
2813  return 0;
2814  }
2815 
2816  return -EIO;
2817 }
2818 
2819 static s32
2820 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2821  struct brcmf_scan_results **bss_list)
2822 {
2823  struct brcmf_iscan_results list;
2824  struct brcmf_scan_results *results;
2825  struct brcmf_scan_results_le *results_le;
2826  struct brcmf_iscan_results *list_buf;
2827  s32 err = 0;
2828 
2829  memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2830  list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2831  results = &list_buf->results;
2832  results_le = &list_buf->results_le;
2834  results->version = 0;
2835  results->count = 0;
2836 
2837  memset(&list, 0, sizeof(list));
2838  list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2839  err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2841  iscan->scan_buf, WL_ISCAN_BUF_MAX);
2842  if (err) {
2843  WL_ERR("error (%d)\n", err);
2844  return err;
2845  }
2846  results->buflen = le32_to_cpu(results_le->buflen);
2847  results->version = le32_to_cpu(results_le->version);
2848  results->count = le32_to_cpu(results_le->count);
2849  WL_SCAN("results->count = %d\n", results_le->count);
2850  WL_SCAN("results->buflen = %d\n", results_le->buflen);
2851  *status = le32_to_cpu(list_buf->status_le);
2852  WL_SCAN("status = %d\n", *status);
2853  *bss_list = results;
2854 
2855  return err;
2856 }
2857 
2858 static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg)
2859 {
2860  struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2861  s32 err = 0;
2862 
2863  iscan->state = WL_ISCAN_STATE_IDLE;
2864  brcmf_inform_bss(cfg);
2865  brcmf_notify_iscan_complete(iscan, false);
2866 
2867  return err;
2868 }
2869 
2870 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg)
2871 {
2872  struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2873  s32 err = 0;
2874 
2875  /* Reschedule the timer */
2876  mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2877  iscan->timer_on = 1;
2878 
2879  return err;
2880 }
2881 
2882 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg)
2883 {
2884  struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2885  s32 err = 0;
2886 
2887  brcmf_inform_bss(cfg);
2888  brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2889  /* Reschedule the timer */
2890  mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2891  iscan->timer_on = 1;
2892 
2893  return err;
2894 }
2895 
2896 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg)
2897 {
2898  struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2899  s32 err = 0;
2900 
2901  iscan->state = WL_ISCAN_STATE_IDLE;
2902  brcmf_notify_iscan_complete(iscan, true);
2903 
2904  return err;
2905 }
2906 
2907 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2908 {
2909  struct brcmf_cfg80211_iscan_ctrl *iscan =
2911  work);
2912  struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2913  struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2915 
2916  if (iscan->timer_on) {
2917  del_timer_sync(&iscan->timer);
2918  iscan->timer_on = 0;
2919  }
2920 
2921  if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) {
2922  status = BRCMF_SCAN_RESULTS_ABORTED;
2923  WL_ERR("Abort iscan\n");
2924  }
2925 
2926  el->handler[status](cfg);
2927 }
2928 
2929 static void brcmf_iscan_timer(unsigned long data)
2930 {
2931  struct brcmf_cfg80211_iscan_ctrl *iscan =
2932  (struct brcmf_cfg80211_iscan_ctrl *)data;
2933 
2934  if (iscan) {
2935  iscan->timer_on = 0;
2936  WL_SCAN("timer expired\n");
2937  brcmf_wakeup_iscan(iscan);
2938  }
2939 }
2940 
2941 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg)
2942 {
2943  struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2944 
2945  if (cfg->iscan_on) {
2946  iscan->state = WL_ISCAN_STATE_IDLE;
2947  INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2948  }
2949 
2950  return 0;
2951 }
2952 
2953 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2954 {
2955  memset(el, 0, sizeof(*el));
2956  el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2957  el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2958  el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2959  el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2960  el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2961 }
2962 
2963 static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg)
2964 {
2965  struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2966  int err = 0;
2967 
2968  if (cfg->iscan_on) {
2969  iscan->ndev = cfg_to_ndev(cfg);
2970  brcmf_init_iscan_eloop(&iscan->el);
2972  init_timer(&iscan->timer);
2973  iscan->timer.data = (unsigned long) iscan;
2974  iscan->timer.function = brcmf_iscan_timer;
2975  err = brcmf_invoke_iscan(cfg);
2976  if (!err)
2977  iscan->data = cfg;
2978  }
2979 
2980  return err;
2981 }
2982 
2983 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2984 {
2985  struct brcmf_cfg80211_info *cfg =
2986  container_of(work, struct brcmf_cfg80211_info,
2988 
2989  brcmf_notify_escan_complete(cfg,
2990  cfg->escan_info.ndev, true, true);
2991 }
2992 
2993 static void brcmf_escan_timeout(unsigned long data)
2994 {
2995  struct brcmf_cfg80211_info *cfg =
2996  (struct brcmf_cfg80211_info *)data;
2997 
2998  if (cfg->scan_request) {
2999  WL_ERR("timer expired\n");
3000  if (cfg->escan_on)
3002  }
3003 }
3004 
3005 static s32
3006 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
3007  struct brcmf_bss_info_le *bss_info_le)
3008 {
3009  if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3010  (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
3011  CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
3012  bss_info_le->SSID_len == bss->SSID_len &&
3013  !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3014  if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
3015  (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
3016  s16 bss_rssi = le16_to_cpu(bss->RSSI);
3017  s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3018 
3019  /* preserve max RSSI if the measurements are
3020  * both on-channel or both off-channel
3021  */
3022  if (bss_info_rssi > bss_rssi)
3023  bss->RSSI = bss_info_le->RSSI;
3024  } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
3025  (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
3026  /* preserve the on-channel rssi measurement
3027  * if the new measurement is off channel
3028  */
3029  bss->RSSI = bss_info_le->RSSI;
3031  }
3032  return 1;
3033  }
3034  return 0;
3035 }
3036 
3037 static s32
3038 brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
3039  struct net_device *ndev,
3040  const struct brcmf_event_msg *e, void *data)
3041 {
3042  s32 status;
3043  s32 err = 0;
3044  struct brcmf_escan_result_le *escan_result_le;
3045  struct brcmf_bss_info_le *bss_info_le;
3046  struct brcmf_bss_info_le *bss = NULL;
3047  u32 bi_length;
3048  struct brcmf_scan_results *list;
3049  u32 i;
3050  bool aborted;
3051 
3052  status = be32_to_cpu(e->status);
3053 
3054  if (!ndev || !cfg->escan_on ||
3055  !test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3056  WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
3057  ndev, cfg->escan_on,
3059  return -EPERM;
3060  }
3061 
3062  if (status == BRCMF_E_STATUS_PARTIAL) {
3063  WL_SCAN("ESCAN Partial result\n");
3064  escan_result_le = (struct brcmf_escan_result_le *) data;
3065  if (!escan_result_le) {
3066  WL_ERR("Invalid escan result (NULL pointer)\n");
3067  goto exit;
3068  }
3069  if (!cfg->scan_request) {
3070  WL_SCAN("result without cfg80211 request\n");
3071  goto exit;
3072  }
3073 
3074  if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3075  WL_ERR("Invalid bss_count %d: ignoring\n",
3076  escan_result_le->bss_count);
3077  goto exit;
3078  }
3079  bss_info_le = &escan_result_le->bss_info_le;
3080 
3081  bi_length = le32_to_cpu(bss_info_le->length);
3082  if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
3084  WL_ERR("Invalid bss_info length %d: ignoring\n",
3085  bi_length);
3086  goto exit;
3087  }
3088 
3089  if (!(cfg_to_wiphy(cfg)->interface_modes &
3091  if (le16_to_cpu(bss_info_le->capability) &
3093  WL_ERR("Ignoring IBSS result\n");
3094  goto exit;
3095  }
3096  }
3097 
3098  list = (struct brcmf_scan_results *)
3099  cfg->escan_info.escan_buf;
3100  if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
3101  WL_ERR("Buffer is too small: ignoring\n");
3102  goto exit;
3103  }
3104 
3105  for (i = 0; i < list->count; i++) {
3106  bss = bss ? (struct brcmf_bss_info_le *)
3107  ((unsigned char *)bss +
3108  le32_to_cpu(bss->length)) : list->bss_info_le;
3109  if (brcmf_compare_update_same_bss(bss, bss_info_le))
3110  goto exit;
3111  }
3112  memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
3113  bss_info_le, bi_length);
3114  list->version = le32_to_cpu(bss_info_le->version);
3115  list->buflen += bi_length;
3116  list->count++;
3117  } else {
3118  cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3119  if (cfg->scan_request) {
3120  cfg->bss_list = (struct brcmf_scan_results *)
3121  cfg->escan_info.escan_buf;
3122  brcmf_inform_bss(cfg);
3123  aborted = status != BRCMF_E_STATUS_SUCCESS;
3124  brcmf_notify_escan_complete(cfg, ndev, aborted,
3125  false);
3126  } else
3127  WL_ERR("Unexpected scan result 0x%x\n", status);
3128  }
3129 exit:
3130  return err;
3131 }
3132 
3133 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3134 {
3135 
3136  if (cfg->escan_on) {
3137  cfg->el.handler[BRCMF_E_ESCAN_RESULT] =
3138  brcmf_cfg80211_escan_handler;
3139  cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3140  /* Init scan_timeout timer */
3141  init_timer(&cfg->escan_timeout);
3142  cfg->escan_timeout.data = (unsigned long) cfg;
3143  cfg->escan_timeout.function = brcmf_escan_timeout;
3145  brcmf_cfg80211_escan_timeout_worker);
3146  }
3147 }
3148 
3149 static __always_inline void brcmf_delay(u32 ms)
3150 {
3151  if (ms < 1000 / HZ) {
3152  cond_resched();
3153  mdelay(ms);
3154  } else {
3155  msleep(ms);
3156  }
3157 }
3158 
3159 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3160 {
3161  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3162 
3163  /*
3164  * Check for WL_STATUS_READY before any function call which
3165  * could result is bus access. Don't block the resume for
3166  * any driver error conditions
3167  */
3168  WL_TRACE("Enter\n");
3169 
3170  if (test_bit(WL_STATUS_READY, &cfg->status))
3171  brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
3172 
3173  WL_TRACE("Exit\n");
3174  return 0;
3175 }
3176 
3177 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3178  struct cfg80211_wowlan *wow)
3179 {
3180  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3181  struct net_device *ndev = cfg_to_ndev(cfg);
3182 
3183  WL_TRACE("Enter\n");
3184 
3185  /*
3186  * Check for WL_STATUS_READY before any function call which
3187  * could result is bus access. Don't block the suspend for
3188  * any driver error conditions
3189  */
3190 
3191  /*
3192  * While going to suspend if associated with AP disassociate
3193  * from AP to save power while system is in suspended state
3194  */
3195  if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
3197  test_bit(WL_STATUS_READY, &cfg->status)) {
3198  WL_INFO("Disassociating from AP"
3199  " while entering suspend state\n");
3200  brcmf_link_down(cfg);
3201 
3202  /*
3203  * Make sure WPA_Supplicant receives all the event
3204  * generated due to DISASSOC call to the fw to keep
3205  * the state fw and WPA_Supplicant state consistent
3206  */
3207  brcmf_delay(500);
3208  }
3209 
3210  if (test_bit(WL_STATUS_READY, &cfg->status))
3211  brcmf_abort_scanning(cfg);
3212  else
3214 
3215  /* Turn off watchdog timer */
3216  if (test_bit(WL_STATUS_READY, &cfg->status))
3217  brcmf_set_mpc(ndev, 1);
3218 
3219  WL_TRACE("Exit\n");
3220 
3221  return 0;
3222 }
3223 
3224 static __used s32
3225 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
3226 {
3227  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
3228  u32 buflen;
3229 
3230  buflen = brcmf_c_mkiovar(name, buf, len, cfg->dcmd_buf,
3231  WL_DCMD_LEN_MAX);
3232  BUG_ON(!buflen);
3233 
3234  return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg->dcmd_buf,
3235  buflen);
3236 }
3237 
3238 static s32
3239 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
3240  s32 buf_len)
3241 {
3242  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
3243  u32 len;
3244  s32 err = 0;
3245 
3246  len = brcmf_c_mkiovar(name, NULL, 0, cfg->dcmd_buf,
3247  WL_DCMD_LEN_MAX);
3248  BUG_ON(!len);
3249  err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg->dcmd_buf,
3250  WL_DCMD_LEN_MAX);
3251  if (err) {
3252  WL_ERR("error (%d)\n", err);
3253  return err;
3254  }
3255  memcpy(buf, cfg->dcmd_buf, buf_len);
3256 
3257  return err;
3258 }
3259 
3260 static __used s32
3261 brcmf_update_pmklist(struct net_device *ndev,
3262  struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
3263 {
3264  int i, j;
3265  int pmkid_len;
3266 
3267  pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
3268 
3269  WL_CONN("No of elements %d\n", pmkid_len);
3270  for (i = 0; i < pmkid_len; i++) {
3271  WL_CONN("PMKID[%d]: %pM =\n", i,
3272  &pmk_list->pmkids.pmkid[i].BSSID);
3273  for (j = 0; j < WLAN_PMKID_LEN; j++)
3274  WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
3275  }
3276 
3277  if (!err)
3278  brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
3279  sizeof(*pmk_list));
3280 
3281  return err;
3282 }
3283 
3284 static s32
3285 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3286  struct cfg80211_pmksa *pmksa)
3287 {
3288  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3289  struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
3290  s32 err = 0;
3291  int i;
3292  int pmkid_len;
3293 
3294  WL_TRACE("Enter\n");
3295  if (!check_sys_up(wiphy))
3296  return -EIO;
3297 
3298  pmkid_len = le32_to_cpu(pmkids->npmkid);
3299  for (i = 0; i < pmkid_len; i++)
3300  if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
3301  break;
3302  if (i < WL_NUM_PMKIDS_MAX) {
3303  memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
3304  memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3305  if (i == pmkid_len) {
3306  pmkid_len++;
3307  pmkids->npmkid = cpu_to_le32(pmkid_len);
3308  }
3309  } else
3310  err = -EINVAL;
3311 
3312  WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3313  pmkids->pmkid[pmkid_len].BSSID);
3314  for (i = 0; i < WLAN_PMKID_LEN; i++)
3315  WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3316 
3317  err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3318 
3319  WL_TRACE("Exit\n");
3320  return err;
3321 }
3322 
3323 static s32
3324 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3325  struct cfg80211_pmksa *pmksa)
3326 {
3327  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3328  struct pmkid_list pmkid;
3329  s32 err = 0;
3330  int i, pmkid_len;
3331 
3332  WL_TRACE("Enter\n");
3333  if (!check_sys_up(wiphy))
3334  return -EIO;
3335 
3336  memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
3337  memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3338 
3339  WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3340  &pmkid.pmkid[0].BSSID);
3341  for (i = 0; i < WLAN_PMKID_LEN; i++)
3342  WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
3343 
3344  pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
3345  for (i = 0; i < pmkid_len; i++)
3346  if (!memcmp
3347  (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
3348  ETH_ALEN))
3349  break;
3350 
3351  if ((pmkid_len > 0)
3352  && (i < pmkid_len)) {
3353  memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
3354  sizeof(struct pmkid));
3355  for (; i < (pmkid_len - 1); i++) {
3356  memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
3357  &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
3358  ETH_ALEN);
3359  memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
3360  &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
3361  WLAN_PMKID_LEN);
3362  }
3363  cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3364  } else
3365  err = -EINVAL;
3366 
3367  err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3368 
3369  WL_TRACE("Exit\n");
3370  return err;
3371 
3372 }
3373 
3374 static s32
3375 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3376 {
3377  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3378  s32 err = 0;
3379 
3380  WL_TRACE("Enter\n");
3381  if (!check_sys_up(wiphy))
3382  return -EIO;
3383 
3384  memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
3385  err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3386 
3387  WL_TRACE("Exit\n");
3388  return err;
3389 
3390 }
3391 
3392 /*
3393  * PFN result doesn't have all the info which are
3394  * required by the supplicant
3395  * (For e.g IEs) Do a target Escan so that sched scan results are reported
3396  * via wl_inform_single_bss in the required format. Escan does require the
3397  * scan request in the form of cfg80211_scan_request. For timebeing, create
3398  * cfg80211_scan_request one out of the received PNO event.
3399  */
3400 static s32
3401 brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
3402  struct net_device *ndev,
3403  const struct brcmf_event_msg *e, void *data)
3404 {
3405  struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3406  struct cfg80211_scan_request *request = NULL;
3407  struct cfg80211_ssid *ssid = NULL;
3408  struct ieee80211_channel *channel = NULL;
3409  struct wiphy *wiphy = cfg_to_wiphy(cfg);
3410  int err = 0;
3411  int channel_req = 0;
3412  int band = 0;
3413  struct brcmf_pno_scanresults_le *pfn_result;
3414  u32 result_count;
3415  u32 status;
3416 
3417  WL_SCAN("Enter\n");
3418 
3420  WL_SCAN("PFN NET LOST event. Do Nothing\n");
3421  return 0;
3422  }
3423 
3424  pfn_result = (struct brcmf_pno_scanresults_le *)data;
3425  result_count = le32_to_cpu(pfn_result->count);
3426  status = le32_to_cpu(pfn_result->status);
3427 
3428  /*
3429  * PFN event is limited to fit 512 bytes so we may get
3430  * multiple NET_FOUND events. For now place a warning here.
3431  */
3432  WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3433  WL_SCAN("PFN NET FOUND event. count: %d\n", result_count);
3434  if (result_count > 0) {
3435  int i;
3436 
3437  request = kzalloc(sizeof(*request), GFP_KERNEL);
3438  ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3439  channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3440  if (!request || !ssid || !channel) {
3441  err = -ENOMEM;
3442  goto out_err;
3443  }
3444 
3445  request->wiphy = wiphy;
3446  data += sizeof(struct brcmf_pno_scanresults_le);
3447  netinfo_start = (struct brcmf_pno_net_info_le *)data;
3448 
3449  for (i = 0; i < result_count; i++) {
3450  netinfo = &netinfo_start[i];
3451  if (!netinfo) {
3452  WL_ERR("Invalid netinfo ptr. index: %d\n", i);
3453  err = -EINVAL;
3454  goto out_err;
3455  }
3456 
3457  WL_SCAN("SSID:%s Channel:%d\n",
3458  netinfo->SSID, netinfo->channel);
3459  memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3460  ssid[i].ssid_len = netinfo->SSID_len;
3461  request->n_ssids++;
3462 
3463  channel_req = netinfo->channel;
3464  if (channel_req <= CH_MAX_2G_CHANNEL)
3465  band = NL80211_BAND_2GHZ;
3466  else
3467  band = NL80211_BAND_5GHZ;
3468  channel[i].center_freq =
3469  ieee80211_channel_to_frequency(channel_req,
3470  band);
3471  channel[i].band = band;
3472  channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3473  request->channels[i] = &channel[i];
3474  request->n_channels++;
3475  }
3476 
3477  /* assign parsed ssid array */
3478  if (request->n_ssids)
3479  request->ssids = &ssid[0];
3480 
3481  if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3482  /* Abort any on-going scan */
3483  brcmf_abort_scanning(cfg);
3484  }
3485 
3487  err = brcmf_do_escan(cfg, wiphy, ndev, request);
3488  if (err) {
3490  goto out_err;
3491  }
3492  cfg->sched_escan = true;
3493  cfg->scan_request = request;
3494  } else {
3495  WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
3496  goto out_err;
3497  }
3498 
3499  kfree(ssid);
3500  kfree(channel);
3501  kfree(request);
3502  return 0;
3503 
3504 out_err:
3505  kfree(ssid);
3506  kfree(channel);
3507  kfree(request);
3509  return err;
3510 }
3511 
3512 #ifndef CONFIG_BRCMISCAN
3513 static int brcmf_dev_pno_clean(struct net_device *ndev)
3514 {
3515  char iovbuf[128];
3516  int ret;
3517 
3518  /* Disable pfn */
3519  ret = brcmf_dev_intvar_set(ndev, "pfn", 0);
3520  if (ret == 0) {
3521  /* clear pfn */
3522  ret = brcmf_dev_iovar_setbuf(ndev, "pfnclear", NULL, 0,
3523  iovbuf, sizeof(iovbuf));
3524  }
3525  if (ret < 0)
3526  WL_ERR("failed code %d\n", ret);
3527 
3528  return ret;
3529 }
3530 
3531 static int brcmf_dev_pno_config(struct net_device *ndev)
3532 {
3533  struct brcmf_pno_param_le pfn_param;
3534  char iovbuf[128];
3535 
3536  memset(&pfn_param, 0, sizeof(pfn_param));
3537  pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3538 
3539  /* set extra pno params */
3540  pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3541  pfn_param.repeat = BRCMF_PNO_REPEAT;
3542  pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3543 
3544  /* set up pno scan fr */
3545  pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3546 
3547  return brcmf_dev_iovar_setbuf(ndev, "pfn_set",
3548  &pfn_param, sizeof(pfn_param),
3549  iovbuf, sizeof(iovbuf));
3550 }
3551 
3552 static int
3553 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3554  struct net_device *ndev,
3555  struct cfg80211_sched_scan_request *request)
3556 {
3557  char iovbuf[128];
3558  struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3559  struct brcmf_pno_net_param_le pfn;
3560  int i;
3561  int ret = 0;
3562 
3563  WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
3564  request->n_match_sets, request->n_ssids);
3565  if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3566  WL_ERR("Scanning already : status (%lu)\n", cfg->status);
3567  return -EAGAIN;
3568  }
3569 
3570  if (!request || !request->n_ssids || !request->n_match_sets) {
3571  WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
3572  request ? request->n_ssids : 0);
3573  return -EINVAL;
3574  }
3575 
3576  if (request->n_ssids > 0) {
3577  for (i = 0; i < request->n_ssids; i++) {
3578  /* Active scan req for ssids */
3579  WL_SCAN(">>> Active scan req for ssid (%s)\n",
3580  request->ssids[i].ssid);
3581 
3582  /*
3583  * match_set ssids is a supert set of n_ssid list,
3584  * so we need not add these set seperately.
3585  */
3586  }
3587  }
3588 
3589  if (request->n_match_sets > 0) {
3590  /* clean up everything */
3591  ret = brcmf_dev_pno_clean(ndev);
3592  if (ret < 0) {
3593  WL_ERR("failed error=%d\n", ret);
3594  return ret;
3595  }
3596 
3597  /* configure pno */
3598  ret = brcmf_dev_pno_config(ndev);
3599  if (ret < 0) {
3600  WL_ERR("PNO setup failed!! ret=%d\n", ret);
3601  return -EINVAL;
3602  }
3603 
3604  /* configure each match set */
3605  for (i = 0; i < request->n_match_sets; i++) {
3606  struct cfg80211_ssid *ssid;
3607  u32 ssid_len;
3608 
3609  ssid = &request->match_sets[i].ssid;
3610  ssid_len = ssid->ssid_len;
3611 
3612  if (!ssid_len) {
3613  WL_ERR("skip broadcast ssid\n");
3614  continue;
3615  }
3616  pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3617  pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3618  pfn.wsec = cpu_to_le32(0);
3619  pfn.infra = cpu_to_le32(1);
3620  pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3621  pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3622  memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3623  ret = brcmf_dev_iovar_setbuf(ndev, "pfn_add",
3624  &pfn, sizeof(pfn),
3625  iovbuf, sizeof(iovbuf));
3626  WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
3627  ret == 0 ? "set" : "failed",
3628  ssid->ssid);
3629  }
3630  /* Enable the PNO */
3631  if (brcmf_dev_intvar_set(ndev, "pfn", 1) < 0) {
3632  WL_ERR("PNO enable failed!! ret=%d\n", ret);
3633  return -EINVAL;
3634  }
3635  } else {
3636  return -EINVAL;
3637  }
3638 
3639  return 0;
3640 }
3641 
3642 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3643  struct net_device *ndev)
3644 {
3645  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3646 
3647  WL_SCAN("enter\n");
3648  brcmf_dev_pno_clean(ndev);
3649  if (cfg->sched_escan)
3650  brcmf_notify_escan_complete(cfg, ndev, true, true);
3651  return 0;
3652 }
3653 #endif /* CONFIG_BRCMISCAN */
3654 
3655 #ifdef CONFIG_NL80211_TESTMODE
3656 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3657 {
3658  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3659  struct net_device *ndev = cfg->wdev->netdev;
3660  struct brcmf_dcmd *dcmd = data;
3661  struct sk_buff *reply;
3662  int ret;
3663 
3664  ret = brcmf_netlink_dcmd(ndev, dcmd);
3665  if (ret == 0) {
3666  reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3667  nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3668  ret = cfg80211_testmode_reply(reply);
3669  }
3670  return ret;
3671 }
3672 #endif
3673 
3674 static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3675 {
3676  s32 err;
3677 
3678  /* set auth */
3679  err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", 0, bssidx);
3680  if (err < 0) {
3681  WL_ERR("auth error %d\n", err);
3682  return err;
3683  }
3684  /* set wsec */
3685  err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", 0, bssidx);
3686  if (err < 0) {
3687  WL_ERR("wsec error %d\n", err);
3688  return err;
3689  }
3690  /* set upper-layer auth */
3691  err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth",
3692  WPA_AUTH_NONE, bssidx);
3693  if (err < 0) {
3694  WL_ERR("wpa_auth error %d\n", err);
3695  return err;
3696  }
3697 
3698  return 0;
3699 }
3700 
3701 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3702 {
3703  if (is_rsn_ie)
3704  return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3705 
3706  return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3707 }
3708 
3709 static s32
3710 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3711  bool is_rsn_ie, s32 bssidx)
3712 {
3713  u32 auth = 0; /* d11 open authentication */
3714  u16 count;
3715  s32 err = 0;
3716  s32 len = 0;
3717  u32 i;
3718  u32 wsec;
3719  u32 pval = 0;
3720  u32 gval = 0;
3721  u32 wpa_auth = 0;
3722  u32 offset;
3723  u8 *data;
3724  u16 rsn_cap;
3725  u32 wme_bss_disable;
3726 
3727  WL_TRACE("Enter\n");
3728  if (wpa_ie == NULL)
3729  goto exit;
3730 
3731  len = wpa_ie->len + TLV_HDR_LEN;
3732  data = (u8 *)wpa_ie;
3733  offset = 0;
3734  if (!is_rsn_ie)
3735  offset += VS_IE_FIXED_HDR_LEN;
3736  offset += WPA_IE_VERSION_LEN;
3737 
3738  /* check for multicast cipher suite */
3739  if (offset + WPA_IE_MIN_OUI_LEN > len) {
3740  err = -EINVAL;
3741  WL_ERR("no multicast cipher suite\n");
3742  goto exit;
3743  }
3744 
3745  if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3746  err = -EINVAL;
3747  WL_ERR("ivalid OUI\n");
3748  goto exit;
3749  }
3750  offset += TLV_OUI_LEN;
3751 
3752  /* pick up multicast cipher */
3753  switch (data[offset]) {
3754  case WPA_CIPHER_NONE:
3755  gval = 0;
3756  break;
3757  case WPA_CIPHER_WEP_40:
3758  case WPA_CIPHER_WEP_104:
3759  gval = WEP_ENABLED;
3760  break;
3761  case WPA_CIPHER_TKIP:
3762  gval = TKIP_ENABLED;
3763  break;
3764  case WPA_CIPHER_AES_CCM:
3765  gval = AES_ENABLED;
3766  break;
3767  default:
3768  err = -EINVAL;
3769  WL_ERR("Invalid multi cast cipher info\n");
3770  goto exit;
3771  }
3772 
3773  offset++;
3774  /* walk thru unicast cipher list and pick up what we recognize */
3775  count = data[offset] + (data[offset + 1] << 8);
3776  offset += WPA_IE_SUITE_COUNT_LEN;
3777  /* Check for unicast suite(s) */
3778  if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3779  err = -EINVAL;
3780  WL_ERR("no unicast cipher suite\n");
3781  goto exit;
3782  }
3783  for (i = 0; i < count; i++) {
3784  if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3785  err = -EINVAL;
3786  WL_ERR("ivalid OUI\n");
3787  goto exit;
3788  }
3789  offset += TLV_OUI_LEN;
3790  switch (data[offset]) {
3791  case WPA_CIPHER_NONE:
3792  break;
3793  case WPA_CIPHER_WEP_40:
3794  case WPA_CIPHER_WEP_104:
3795  pval |= WEP_ENABLED;
3796  break;
3797  case WPA_CIPHER_TKIP:
3798  pval |= TKIP_ENABLED;
3799  break;
3800  case WPA_CIPHER_AES_CCM:
3801  pval |= AES_ENABLED;
3802  break;
3803  default:
3804  WL_ERR("Ivalid unicast security info\n");
3805  }
3806  offset++;
3807  }
3808  /* walk thru auth management suite list and pick up what we recognize */
3809  count = data[offset] + (data[offset + 1] << 8);
3810  offset += WPA_IE_SUITE_COUNT_LEN;
3811  /* Check for auth key management suite(s) */
3812  if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3813  err = -EINVAL;
3814  WL_ERR("no auth key mgmt suite\n");
3815  goto exit;
3816  }
3817  for (i = 0; i < count; i++) {
3818  if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3819  err = -EINVAL;
3820  WL_ERR("ivalid OUI\n");
3821  goto exit;
3822  }
3823  offset += TLV_OUI_LEN;
3824  switch (data[offset]) {
3825  case RSN_AKM_NONE:
3826  WL_TRACE("RSN_AKM_NONE\n");
3827  wpa_auth |= WPA_AUTH_NONE;
3828  break;
3829  case RSN_AKM_UNSPECIFIED:
3830  WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3831  is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3832  (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3833  break;
3834  case RSN_AKM_PSK:
3835  WL_TRACE("RSN_AKM_PSK\n");
3836  is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3837  (wpa_auth |= WPA_AUTH_PSK);
3838  break;
3839  default:
3840  WL_ERR("Ivalid key mgmt info\n");
3841  }
3842  offset++;
3843  }
3844 
3845  if (is_rsn_ie) {
3846  wme_bss_disable = 1;
3847  if ((offset + RSN_CAP_LEN) <= len) {
3848  rsn_cap = data[offset] + (data[offset + 1] << 8);
3849  if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3850  wme_bss_disable = 0;
3851  }
3852  /* set wme_bss_disable to sync RSN Capabilities */
3853  err = brcmf_dev_intvar_set_bsscfg(ndev, "wme_bss_disable",
3854  wme_bss_disable, bssidx);
3855  if (err < 0) {
3856  WL_ERR("wme_bss_disable error %d\n", err);
3857  goto exit;
3858  }
3859  }
3860  /* FOR WPS , set SES_OW_ENABLED */
3861  wsec = (pval | gval | SES_OW_ENABLED);
3862 
3863  /* set auth */
3864  err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", auth, bssidx);
3865  if (err < 0) {
3866  WL_ERR("auth error %d\n", err);
3867  goto exit;
3868  }
3869  /* set wsec */
3870  err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
3871  if (err < 0) {
3872  WL_ERR("wsec error %d\n", err);
3873  goto exit;
3874  }
3875  /* set upper-layer auth */
3876  err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", wpa_auth, bssidx);
3877  if (err < 0) {
3878  WL_ERR("wpa_auth error %d\n", err);
3879  goto exit;
3880  }
3881 
3882 exit:
3883  return err;
3884 }
3885 
3886 static s32
3887 brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len,
3888  struct parsed_vndr_ies *vndr_ies)
3889 {
3890  s32 err = 0;
3891  struct brcmf_vs_tlv *vndrie;
3892  struct brcmf_tlv *ie;
3893  struct parsed_vndr_ie_info *parsed_info;
3894  s32 remaining_len;
3895 
3896  remaining_len = (s32)vndr_ie_len;
3897  memset(vndr_ies, 0, sizeof(*vndr_ies));
3898 
3899  ie = (struct brcmf_tlv *)vndr_ie_buf;
3900  while (ie) {
3901  if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3902  goto next;
3903  vndrie = (struct brcmf_vs_tlv *)ie;
3904  /* len should be bigger than OUI length + one */
3905  if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3906  WL_ERR("invalid vndr ie. length is too small %d\n",
3907  vndrie->len);
3908  goto next;
3909  }
3910  /* if wpa or wme ie, do not add ie */
3911  if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3912  ((vndrie->oui_type == WPA_OUI_TYPE) ||
3913  (vndrie->oui_type == WME_OUI_TYPE))) {
3914  WL_TRACE("Found WPA/WME oui. Do not add it\n");
3915  goto next;
3916  }
3917 
3918  parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3919 
3920  /* save vndr ie information */
3921  parsed_info->ie_ptr = (char *)vndrie;
3922  parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3923  memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3924 
3925  vndr_ies->count++;
3926 
3927  WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3928  parsed_info->vndrie.oui[0],
3929  parsed_info->vndrie.oui[1],
3930  parsed_info->vndrie.oui[2],
3931  parsed_info->vndrie.oui_type);
3932 
3933  if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3934  break;
3935 next:
3936  remaining_len -= ie->len;
3937  if (remaining_len <= 2)
3938  ie = NULL;
3939  else
3940  ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len);
3941  }
3942  return err;
3943 }
3944 
3945 static u32
3946 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3947 {
3948 
3949  __le32 iecount_le;
3950  __le32 pktflag_le;
3951 
3952  strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3953  iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3954 
3955  iecount_le = cpu_to_le32(1);
3956  memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3957 
3958  pktflag_le = cpu_to_le32(pktflag);
3959  memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3960 
3961  memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3962 
3963  return ie_len + VNDR_IE_HDR_SIZE;
3964 }
3966 s32
3968  struct net_device *ndev, s32 bssidx, s32 pktflag,
3969  u8 *vndr_ie_buf, u32 vndr_ie_len)
3970 {
3971  s32 err = 0;
3972  u8 *iovar_ie_buf;
3973  u8 *curr_ie_buf;
3974  u8 *mgmt_ie_buf = NULL;
3975  int mgmt_ie_buf_len;
3976  u32 *mgmt_ie_len = 0;
3977  u32 del_add_ie_buf_len = 0;
3978  u32 total_ie_buf_len = 0;
3979  u32 parsed_ie_buf_len = 0;
3980  struct parsed_vndr_ies old_vndr_ies;
3981  struct parsed_vndr_ies new_vndr_ies;
3982  struct parsed_vndr_ie_info *vndrie_info;
3983  s32 i;
3984  u8 *ptr;
3985  int remained_buf_len;
3986 
3987  WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag);
3988  iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3989  if (!iovar_ie_buf)
3990  return -ENOMEM;
3991  curr_ie_buf = iovar_ie_buf;
3992  if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) ||
3994  switch (pktflag) {
3995  case VNDR_IE_PRBRSP_FLAG:
3996  mgmt_ie_buf = cfg->ap_info->probe_res_ie;
3997  mgmt_ie_len = &cfg->ap_info->probe_res_ie_len;
3998  mgmt_ie_buf_len =
3999  sizeof(cfg->ap_info->probe_res_ie);
4000  break;
4001  case VNDR_IE_BEACON_FLAG:
4002  mgmt_ie_buf = cfg->ap_info->beacon_ie;
4003  mgmt_ie_len = &cfg->ap_info->beacon_ie_len;
4004  mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie);
4005  break;
4006  default:
4007  err = -EPERM;
4008  WL_ERR("not suitable type\n");
4009  goto exit;
4010  }
4011  bssidx = 0;
4012  } else {
4013  err = -EPERM;
4014  WL_ERR("not suitable type\n");
4015  goto exit;
4016  }
4017 
4018  if (vndr_ie_len > mgmt_ie_buf_len) {
4019  err = -ENOMEM;
4020  WL_ERR("extra IE size too big\n");
4021  goto exit;
4022  }
4023 
4024  /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4025  if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4026  ptr = curr_ie_buf;
4027  brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4028  for (i = 0; i < new_vndr_ies.count; i++) {
4029  vndrie_info = &new_vndr_ies.ie_info[i];
4030  memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4031  vndrie_info->ie_len);
4032  parsed_ie_buf_len += vndrie_info->ie_len;
4033  }
4034  }
4035 
4036  if (mgmt_ie_buf != NULL) {
4037  if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4038  (memcmp(mgmt_ie_buf, curr_ie_buf,
4039  parsed_ie_buf_len) == 0)) {
4040  WL_TRACE("Previous mgmt IE is equals to current IE");
4041  goto exit;
4042  }
4043 
4044  /* parse old vndr_ie */
4045  brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4046 
4047  /* make a command to delete old ie */
4048  for (i = 0; i < old_vndr_ies.count; i++) {
4049  vndrie_info = &old_vndr_ies.ie_info[i];
4050 
4051  WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4052  vndrie_info->vndrie.id,
4053  vndrie_info->vndrie.len,
4054  vndrie_info->vndrie.oui[0],
4055  vndrie_info->vndrie.oui[1],
4056  vndrie_info->vndrie.oui[2]);
4057 
4058  del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4059  vndrie_info->ie_ptr,
4060  vndrie_info->ie_len,
4061  "del");
4062  curr_ie_buf += del_add_ie_buf_len;
4063  total_ie_buf_len += del_add_ie_buf_len;
4064  }
4065  }
4066 
4067  *mgmt_ie_len = 0;
4068  /* Add if there is any extra IE */
4069  if (mgmt_ie_buf && parsed_ie_buf_len) {
4070  ptr = mgmt_ie_buf;
4071 
4072  remained_buf_len = mgmt_ie_buf_len;
4073 
4074  /* make a command to add new ie */
4075  for (i = 0; i < new_vndr_ies.count; i++) {
4076  vndrie_info = &new_vndr_ies.ie_info[i];
4077 
4078  WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4079  vndrie_info->vndrie.id,
4080  vndrie_info->vndrie.len,
4081  vndrie_info->vndrie.oui[0],
4082  vndrie_info->vndrie.oui[1],
4083  vndrie_info->vndrie.oui[2]);
4084 
4085  del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4086  vndrie_info->ie_ptr,
4087  vndrie_info->ie_len,
4088  "add");
4089  /* verify remained buf size before copy data */
4090  remained_buf_len -= vndrie_info->ie_len;
4091  if (remained_buf_len < 0) {
4092  WL_ERR("no space in mgmt_ie_buf: len left %d",
4093  remained_buf_len);
4094  break;
4095  }
4096 
4097  /* save the parsed IE in wl struct */
4098  memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4099  vndrie_info->ie_len);
4100  *mgmt_ie_len += vndrie_info->ie_len;
4101 
4102  curr_ie_buf += del_add_ie_buf_len;
4103  total_ie_buf_len += del_add_ie_buf_len;
4104  }
4105  }
4106  if (total_ie_buf_len) {
4107  err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "vndr_ie",
4108  iovar_ie_buf,
4109  total_ie_buf_len,
4110  cfg->extra_buf,
4111  WL_EXTRA_BUF_MAX, bssidx);
4112  if (err)
4113  WL_ERR("vndr ie set error : %d\n", err);
4114  }
4115 
4116 exit:
4117  kfree(iovar_ie_buf);
4118  return err;
4119 }
4120 
4121 static s32
4122 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4123  struct cfg80211_ap_settings *settings)
4124 {
4125  s32 ie_offset;
4126  struct brcmf_tlv *ssid_ie;
4127  struct brcmf_ssid_le ssid_le;
4128  s32 ioctl_value;
4129  s32 err = -EPERM;
4130  struct brcmf_tlv *rsn_ie;
4131  struct brcmf_vs_tlv *wpa_ie;
4132  struct brcmf_join_params join_params;
4133  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4134  s32 bssidx = 0;
4135 
4136  WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
4137  settings->channel_type, settings->beacon_interval,
4138  settings->dtim_period);
4139  WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
4140  settings->ssid, settings->ssid_len, settings->auth_type,
4141  settings->inactivity_timeout);
4142 
4143  if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) {
4144  WL_ERR("Not in AP creation mode\n");
4145  return -EPERM;
4146  }
4147 
4148  memset(&ssid_le, 0, sizeof(ssid_le));
4149  if (settings->ssid == NULL || settings->ssid_len == 0) {
4151  ssid_ie = brcmf_parse_tlvs(
4152  (u8 *)&settings->beacon.head[ie_offset],
4153  settings->beacon.head_len - ie_offset,
4154  WLAN_EID_SSID);
4155  if (!ssid_ie)
4156  return -EINVAL;
4157 
4158  memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4159  ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4160  WL_TRACE("SSID is (%s) in Head\n", ssid_le.SSID);
4161  } else {
4162  memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4163  ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4164  }
4165 
4166  brcmf_set_mpc(ndev, 0);
4167  ioctl_value = 1;
4168  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_DOWN, &ioctl_value);
4169  if (err < 0) {
4170  WL_ERR("BRCMF_C_DOWN error %d\n", err);
4171  goto exit;
4172  }
4173  ioctl_value = 1;
4174  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &ioctl_value);
4175  if (err < 0) {
4176  WL_ERR("SET INFRA error %d\n", err);
4177  goto exit;
4178  }
4179  ioctl_value = 1;
4180  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4181  if (err < 0) {
4182  WL_ERR("setting AP mode failed %d\n", err);
4183  goto exit;
4184  }
4185 
4186  /* find the RSN_IE */
4187  rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4188  settings->beacon.tail_len, WLAN_EID_RSN);
4189 
4190  /* find the WPA_IE */
4191  wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4192  settings->beacon.tail_len);
4193 
4194  kfree(cfg->ap_info->rsn_ie);
4195  cfg->ap_info->rsn_ie = NULL;
4196  kfree(cfg->ap_info->wpa_ie);
4197  cfg->ap_info->wpa_ie = NULL;
4198 
4199  if ((wpa_ie != NULL || rsn_ie != NULL)) {
4200  WL_TRACE("WPA(2) IE is found\n");
4201  if (wpa_ie != NULL) {
4202  /* WPA IE */
4203  err = brcmf_configure_wpaie(ndev, wpa_ie, false,
4204  bssidx);
4205  if (err < 0)
4206  goto exit;
4207  cfg->ap_info->wpa_ie = kmemdup(wpa_ie,
4208  wpa_ie->len +
4209  TLV_HDR_LEN,
4210  GFP_KERNEL);
4211  } else {
4212  /* RSN IE */
4213  err = brcmf_configure_wpaie(ndev,
4214  (struct brcmf_vs_tlv *)rsn_ie, true, bssidx);
4215  if (err < 0)
4216  goto exit;
4217  cfg->ap_info->rsn_ie = kmemdup(rsn_ie,
4218  rsn_ie->len +
4219  TLV_HDR_LEN,
4220  GFP_KERNEL);
4221  }
4222  cfg->ap_info->security_mode = true;
4223  } else {
4224  WL_TRACE("No WPA(2) IEs found\n");
4225  brcmf_configure_opensecurity(ndev, bssidx);
4226  cfg->ap_info->security_mode = false;
4227  }
4228  /* Set Beacon IEs to FW */
4229  err = brcmf_set_management_ie(cfg, ndev, bssidx,
4231  (u8 *)settings->beacon.tail,
4232  settings->beacon.tail_len);
4233  if (err)
4234  WL_ERR("Set Beacon IE Failed\n");
4235  else
4236  WL_TRACE("Applied Vndr IEs for Beacon\n");
4237 
4238  /* Set Probe Response IEs to FW */
4239  err = brcmf_set_management_ie(cfg, ndev, bssidx,
4241  (u8 *)settings->beacon.proberesp_ies,
4242  settings->beacon.proberesp_ies_len);
4243  if (err)
4244  WL_ERR("Set Probe Resp IE Failed\n");
4245  else
4246  WL_TRACE("Applied Vndr IEs for Probe Resp\n");
4247 
4248  if (settings->beacon_interval) {
4249  ioctl_value = settings->beacon_interval;
4250  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_BCNPRD,
4251  &ioctl_value);
4252  if (err < 0) {
4253  WL_ERR("Beacon Interval Set Error, %d\n", err);
4254  goto exit;
4255  }
4256  }
4257  if (settings->dtim_period) {
4258  ioctl_value = settings->dtim_period;
4259  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_DTIMPRD,
4260  &ioctl_value);
4261  if (err < 0) {
4262  WL_ERR("DTIM Interval Set Error, %d\n", err);
4263  goto exit;
4264  }
4265  }
4266  ioctl_value = 1;
4267  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4268  if (err < 0) {
4269  WL_ERR("BRCMF_C_UP error (%d)\n", err);
4270  goto exit;
4271  }
4272 
4273  memset(&join_params, 0, sizeof(join_params));
4274  /* join parameters starts with ssid */
4275  memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4276  /* create softap */
4277  err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, &join_params,
4278  sizeof(join_params));
4279  if (err < 0) {
4280  WL_ERR("SET SSID error (%d)\n", err);
4281  goto exit;
4282  }
4285 
4286 exit:
4287  if (err)
4288  brcmf_set_mpc(ndev, 1);
4289  return err;
4290 }
4291 
4292 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4293 {
4294  struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4295  s32 ioctl_value;
4296  s32 err = -EPERM;
4297 
4298  WL_TRACE("Enter\n");
4299 
4300  if (cfg->conf->mode == WL_MODE_AP) {
4301  /* Due to most likely deauths outstanding we sleep */
4302  /* first to make sure they get processed by fw. */
4303  msleep(400);
4304  ioctl_value = 0;
4305  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4306  if (err < 0) {
4307  WL_ERR("setting AP mode failed %d\n", err);
4308  goto exit;
4309  }
4310  ioctl_value = 0;
4311  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4312  if (err < 0) {
4313  WL_ERR("BRCMF_C_UP error %d\n", err);
4314  goto exit;
4315  }
4316  brcmf_set_mpc(ndev, 1);
4319  }
4320 exit:
4321  return err;
4322 }
4323 
4324 static int
4325 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4326  u8 *mac)
4327 {
4328  struct brcmf_scb_val_le scbval;
4329  s32 err;
4330 
4331  if (!mac)
4332  return -EFAULT;
4333 
4334  WL_TRACE("Enter %pM\n", mac);
4335 
4336  if (!check_sys_up(wiphy))
4337  return -EIO;
4338 
4339  memcpy(&scbval.ea, mac, ETH_ALEN);
4342  &scbval, sizeof(scbval));
4343  if (err)
4344  WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4345 
4346  WL_TRACE("Exit\n");
4347  return err;
4348 }
4349 
4350 static struct cfg80211_ops wl_cfg80211_ops = {
4351  .change_virtual_intf = brcmf_cfg80211_change_iface,
4352  .scan = brcmf_cfg80211_scan,
4353  .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4354  .join_ibss = brcmf_cfg80211_join_ibss,
4355  .leave_ibss = brcmf_cfg80211_leave_ibss,
4356  .get_station = brcmf_cfg80211_get_station,
4357  .set_tx_power = brcmf_cfg80211_set_tx_power,
4358  .get_tx_power = brcmf_cfg80211_get_tx_power,
4359  .add_key = brcmf_cfg80211_add_key,
4360  .del_key = brcmf_cfg80211_del_key,
4361  .get_key = brcmf_cfg80211_get_key,
4362  .set_default_key = brcmf_cfg80211_config_default_key,
4363  .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4364  .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4365  .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
4366  .connect = brcmf_cfg80211_connect,
4367  .disconnect = brcmf_cfg80211_disconnect,
4368  .suspend = brcmf_cfg80211_suspend,
4369  .resume = brcmf_cfg80211_resume,
4370  .set_pmksa = brcmf_cfg80211_set_pmksa,
4371  .del_pmksa = brcmf_cfg80211_del_pmksa,
4372  .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4373  .start_ap = brcmf_cfg80211_start_ap,
4374  .stop_ap = brcmf_cfg80211_stop_ap,
4375  .del_station = brcmf_cfg80211_del_station,
4376 #ifndef CONFIG_BRCMISCAN
4377  /* scheduled scan need e-scan, which is mutual exclusive with i-scan */
4378  .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4379  .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4380 #endif
4381 #ifdef CONFIG_NL80211_TESTMODE
4382  .testmode_cmd = brcmf_cfg80211_testmode
4383 #endif
4384 };
4385 
4386 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
4387 {
4388  s32 err = 0;
4389 
4390  switch (mode) {
4391  case WL_MODE_BSS:
4392  return NL80211_IFTYPE_STATION;
4393  case WL_MODE_IBSS:
4394  return NL80211_IFTYPE_ADHOC;
4395  default:
4397  }
4398 
4399  return err;
4400 }
4401 
4402 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4403 {
4404 #ifndef CONFIG_BRCMISCAN
4405  /* scheduled scan settings */
4410 #endif
4411 }
4412 
4413 static struct wireless_dev *brcmf_alloc_wdev(struct device *ndev)
4414 {
4415  struct wireless_dev *wdev;
4416  s32 err = 0;
4417 
4418  wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
4419  if (!wdev)
4420  return ERR_PTR(-ENOMEM);
4421 
4422  wdev->wiphy = wiphy_new(&wl_cfg80211_ops,
4423  sizeof(struct brcmf_cfg80211_info));
4424  if (!wdev->wiphy) {
4425  WL_ERR("Could not allocate wiphy device\n");
4426  err = -ENOMEM;
4427  goto wiphy_new_out;
4428  }
4429  set_wiphy_dev(wdev->wiphy, ndev);
4430  wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4431  wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4432  wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4435  wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4436  wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
4437  * it as 11a by default.
4438  * This will be updated with
4439  * 11n phy tables in
4440  * "ifconfig up"
4441  * if phy has 11n capability
4442  */
4443  wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4444  wdev->wiphy->cipher_suites = __wl_cipher_suites;
4445  wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4446  wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
4447  * save mode
4448  * by default
4449  */
4450  brcmf_wiphy_pno_params(wdev->wiphy);
4451  err = wiphy_register(wdev->wiphy);
4452  if (err < 0) {
4453  WL_ERR("Could not register wiphy device (%d)\n", err);
4454  goto wiphy_register_out;
4455  }
4456  return wdev;
4457 
4458 wiphy_register_out:
4459  wiphy_free(wdev->wiphy);
4460 
4461 wiphy_new_out:
4462  kfree(wdev);
4463 
4464  return ERR_PTR(err);
4465 }
4466 
4467 static void brcmf_free_wdev(struct brcmf_cfg80211_info *cfg)
4468 {
4469  struct wireless_dev *wdev = cfg->wdev;
4470 
4471  if (!wdev) {
4472  WL_ERR("wdev is invalid\n");
4473  return;
4474  }
4475  wiphy_unregister(wdev->wiphy);
4476  wiphy_free(wdev->wiphy);
4477  kfree(wdev);
4478  cfg->wdev = NULL;
4479 }
4480 
4481 static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg,
4482  const struct brcmf_event_msg *e)
4483 {
4484  u32 event = be32_to_cpu(e->event_type);
4485  u32 status = be32_to_cpu(e->status);
4486 
4487  if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4488  WL_CONN("Processing set ssid\n");
4489  cfg->link_up = true;
4490  return true;
4491  }
4492 
4493  return false;
4494 }
4495 
4496 static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg,
4497  const struct brcmf_event_msg *e)
4498 {
4499  u32 event = be32_to_cpu(e->event_type);
4500  u16 flags = be16_to_cpu(e->flags);
4501 
4502  if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4503  WL_CONN("Processing link down\n");
4504  return true;
4505  }
4506  return false;
4507 }
4508 
4509 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4510  const struct brcmf_event_msg *e)
4511 {
4512  u32 event = be32_to_cpu(e->event_type);
4513  u32 status = be32_to_cpu(e->status);
4514 
4515  if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4516  WL_CONN("Processing Link %s & no network found\n",
4518  "up" : "down");
4519  return true;
4520  }
4521 
4522  if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4523  WL_CONN("Processing connecting & no network found\n");
4524  return true;
4525  }
4526 
4527  return false;
4528 }
4529 
4530 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4531 {
4532  struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4533 
4534  kfree(conn_info->req_ie);
4535  conn_info->req_ie = NULL;
4536  conn_info->req_ie_len = 0;
4537  kfree(conn_info->resp_ie);
4538  conn_info->resp_ie = NULL;
4539  conn_info->resp_ie_len = 0;
4540 }
4541 
4542 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
4543 {
4544  struct net_device *ndev = cfg_to_ndev(cfg);
4545  struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4546  struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4547  u32 req_len;
4548  u32 resp_len;
4549  s32 err = 0;
4550 
4551  brcmf_clear_assoc_ies(cfg);
4552 
4553  err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg->extra_buf,
4555  if (err) {
4556  WL_ERR("could not get assoc info (%d)\n", err);
4557  return err;
4558  }
4559  assoc_info =
4561  req_len = le32_to_cpu(assoc_info->req_len);
4562  resp_len = le32_to_cpu(assoc_info->resp_len);
4563  if (req_len) {
4564  err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
4565  cfg->extra_buf,
4567  if (err) {
4568  WL_ERR("could not get assoc req (%d)\n", err);
4569  return err;
4570  }
4571  conn_info->req_ie_len = req_len;
4572  conn_info->req_ie =
4573  kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4574  GFP_KERNEL);
4575  } else {
4576  conn_info->req_ie_len = 0;
4577  conn_info->req_ie = NULL;
4578  }
4579  if (resp_len) {
4580  err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
4581  cfg->extra_buf,
4583  if (err) {
4584  WL_ERR("could not get assoc resp (%d)\n", err);
4585  return err;
4586  }
4587  conn_info->resp_ie_len = resp_len;
4588  conn_info->resp_ie =
4589  kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4590  GFP_KERNEL);
4591  } else {
4592  conn_info->resp_ie_len = 0;
4593  conn_info->resp_ie = NULL;
4594  }
4595  WL_CONN("req len (%d) resp len (%d)\n",
4596  conn_info->req_ie_len, conn_info->resp_ie_len);
4597 
4598  return err;
4599 }
4600 
4601 static s32
4602 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4603  struct net_device *ndev,
4604  const struct brcmf_event_msg *e)
4605 {
4606  struct brcmf_cfg80211_profile *profile = cfg->profile;
4607  struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4608  struct wiphy *wiphy = cfg_to_wiphy(cfg);
4609  struct ieee80211_channel *notify_channel = NULL;
4611  struct brcmf_bss_info_le *bi;
4612  u32 freq;
4613  s32 err = 0;
4614  u32 target_channel;
4615  u8 *buf;
4616 
4617  WL_TRACE("Enter\n");
4618 
4619  brcmf_get_assoc_ies(cfg);
4620  memcpy(profile->bssid, e->addr, ETH_ALEN);
4621  brcmf_update_bss_info(cfg);
4622 
4623  buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4624  if (buf == NULL) {
4625  err = -ENOMEM;
4626  goto done;
4627  }
4628 
4629  /* data sent to dongle has to be little endian */
4630  *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4632 
4633  if (err)
4634  goto done;
4635 
4636  bi = (struct brcmf_bss_info_le *)(buf + 4);
4637  target_channel = bi->ctl_ch ? bi->ctl_ch :
4639 
4640  if (target_channel <= CH_MAX_2G_CHANNEL)
4641  band = wiphy->bands[IEEE80211_BAND_2GHZ];
4642  else
4643  band = wiphy->bands[IEEE80211_BAND_5GHZ];
4644 
4645  freq = ieee80211_channel_to_frequency(target_channel, band->band);
4646  notify_channel = ieee80211_get_channel(wiphy, freq);
4647 
4648 done:
4649  kfree(buf);
4650  cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4651  conn_info->req_ie, conn_info->req_ie_len,
4652  conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4653  WL_CONN("Report roaming result\n");
4654 
4656  WL_TRACE("Exit\n");
4657  return err;
4658 }
4659 
4660 static s32
4661 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4662  struct net_device *ndev, const struct brcmf_event_msg *e,
4663  bool completed)
4664 {
4665  struct brcmf_cfg80211_profile *profile = cfg->profile;
4666  struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4667  s32 err = 0;
4668 
4669  WL_TRACE("Enter\n");
4670 
4672  if (completed) {
4673  brcmf_get_assoc_ies(cfg);
4674  memcpy(profile->bssid, e->addr, ETH_ALEN);
4675  brcmf_update_bss_info(cfg);
4676  }
4678  (u8 *)profile->bssid,
4679  conn_info->req_ie,
4680  conn_info->req_ie_len,
4681  conn_info->resp_ie,
4682  conn_info->resp_ie_len,
4683  completed ? WLAN_STATUS_SUCCESS :
4685  GFP_KERNEL);
4686  if (completed)
4688  WL_CONN("Report connect result - connection %s\n",
4689  completed ? "succeeded" : "failed");
4690  }
4691  WL_TRACE("Exit\n");
4692  return err;
4693 }
4694 
4695 static s32
4696 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4697  struct net_device *ndev,
4698  const struct brcmf_event_msg *e, void *data)
4699 {
4700  s32 err = 0;
4701  u32 event = be32_to_cpu(e->event_type);
4702  u32 reason = be32_to_cpu(e->reason);
4703  u32 len = be32_to_cpu(e->datalen);
4704  static int generation;
4705 
4706  struct station_info sinfo;
4707 
4708  WL_CONN("event %d, reason %d\n", event, reason);
4709  memset(&sinfo, 0, sizeof(sinfo));
4710 
4711  sinfo.filled = 0;
4712  if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4713  reason == BRCMF_E_STATUS_SUCCESS) {
4715  if (!data) {
4716  WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4717  return -EINVAL;
4718  }
4719  sinfo.assoc_req_ies = data;
4720  sinfo.assoc_req_ies_len = len;
4721  generation++;
4722  sinfo.generation = generation;
4723  cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4724  } else if ((event == BRCMF_E_DISASSOC_IND) ||
4725  (event == BRCMF_E_DEAUTH_IND) ||
4726  (event == BRCMF_E_DEAUTH)) {
4727  generation++;
4728  sinfo.generation = generation;
4729  cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4730  }
4731  return err;
4732 }
4733 
4734 static s32
4735 brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
4736  struct net_device *ndev,
4737  const struct brcmf_event_msg *e, void *data)
4738 {
4739  struct brcmf_cfg80211_profile *profile = cfg->profile;
4740  s32 err = 0;
4741 
4742  if (cfg->conf->mode == WL_MODE_AP) {
4743  err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4744  } else if (brcmf_is_linkup(cfg, e)) {
4745  WL_CONN("Linkup\n");
4746  if (brcmf_is_ibssmode(cfg)) {
4747  memcpy(profile->bssid, e->addr, ETH_ALEN);
4748  wl_inform_ibss(cfg, ndev, e->addr);
4752  } else
4753  brcmf_bss_connect_done(cfg, ndev, e, true);
4754  } else if (brcmf_is_linkdown(cfg, e)) {
4755  WL_CONN("Linkdown\n");
4756  if (brcmf_is_ibssmode(cfg)) {
4759  &cfg->status))
4760  brcmf_link_down(cfg);
4761  } else {
4762  brcmf_bss_connect_done(cfg, ndev, e, false);
4764  &cfg->status)) {
4765  cfg80211_disconnected(ndev, 0, NULL, 0,
4766  GFP_KERNEL);
4767  brcmf_link_down(cfg);
4768  }
4769  }
4770  brcmf_init_prof(cfg->profile);
4771  } else if (brcmf_is_nonetwork(cfg, e)) {
4772  if (brcmf_is_ibssmode(cfg))
4774  else
4775  brcmf_bss_connect_done(cfg, ndev, e, false);
4776  }
4777 
4778  return err;
4779 }
4780 
4781 static s32
4782 brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg,
4783  struct net_device *ndev,
4784  const struct brcmf_event_msg *e, void *data)
4785 {
4786  s32 err = 0;
4787  u32 event = be32_to_cpu(e->event_type);
4788  u32 status = be32_to_cpu(e->status);
4789 
4790  if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4791  if (test_bit(WL_STATUS_CONNECTED, &cfg->status))
4792  brcmf_bss_roaming_done(cfg, ndev, e);
4793  else
4794  brcmf_bss_connect_done(cfg, ndev, e, true);
4795  }
4796 
4797  return err;
4798 }
4799 
4800 static s32
4801 brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
4802  struct net_device *ndev,
4803  const struct brcmf_event_msg *e, void *data)
4804 {
4805  u16 flags = be16_to_cpu(e->flags);
4806  enum nl80211_key_type key_type;
4807 
4808  if (flags & BRCMF_EVENT_MSG_GROUP)
4809  key_type = NL80211_KEYTYPE_GROUP;
4810  else
4811  key_type = NL80211_KEYTYPE_PAIRWISE;
4812 
4813  cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
4814  NULL, GFP_KERNEL);
4815 
4816  return 0;
4817 }
4818 
4819 static s32
4820 brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
4821  struct net_device *ndev,
4822  const struct brcmf_event_msg *e, void *data)
4823 {
4824  struct brcmf_channel_info_le channel_inform_le;
4825  struct brcmf_scan_results_le *bss_list_le;
4826  u32 len = WL_SCAN_BUF_MAX;
4827  s32 err = 0;
4828  bool scan_abort = false;
4829  u32 scan_channel;
4830 
4831  WL_TRACE("Enter\n");
4832 
4833  if (cfg->iscan_on && cfg->iscan_kickstart) {
4834  WL_TRACE("Exit\n");
4835  return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
4836  }
4837 
4839  WL_ERR("Scan complete while device not scanning\n");
4840  scan_abort = true;
4841  err = -EINVAL;
4842  goto scan_done_out;
4843  }
4844 
4845  err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
4846  sizeof(channel_inform_le));
4847  if (err) {
4848  WL_ERR("scan busy (%d)\n", err);
4849  scan_abort = true;
4850  goto scan_done_out;
4851  }
4852  scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
4853  if (scan_channel)
4854  WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
4855  cfg->bss_list = cfg->scan_results;
4856  bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list;
4857 
4858  memset(cfg->scan_results, 0, len);
4859  bss_list_le->buflen = cpu_to_le32(len);
4861  cfg->scan_results, len);
4862  if (err) {
4863  WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
4864  err = -EINVAL;
4865  scan_abort = true;
4866  goto scan_done_out;
4867  }
4868  cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
4869  cfg->scan_results->version = le32_to_cpu(bss_list_le->version);
4870  cfg->scan_results->count = le32_to_cpu(bss_list_le->count);
4871 
4872  err = brcmf_inform_bss(cfg);
4873  if (err)
4874  scan_abort = true;
4875 
4876 scan_done_out:
4877  if (cfg->scan_request) {
4878  WL_SCAN("calling cfg80211_scan_done\n");
4879  cfg80211_scan_done(cfg->scan_request, scan_abort);
4880  brcmf_set_mpc(ndev, 1);
4881  cfg->scan_request = NULL;
4882  }
4883 
4884  WL_TRACE("Exit\n");
4885 
4886  return err;
4887 }
4888 
4889 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4890 {
4891  conf->mode = (u32)-1;
4892  conf->frag_threshold = (u32)-1;
4893  conf->rts_threshold = (u32)-1;
4894  conf->retry_short = (u32)-1;
4895  conf->retry_long = (u32)-1;
4896  conf->tx_power = -1;
4897 }
4898 
4899 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
4900 {
4901  memset(el, 0, sizeof(*el));
4902  el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
4903  el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
4904  el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status;
4905  el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status;
4906  el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status;
4907  el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status;
4908  el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status;
4909  el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
4910  el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
4911  el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
4912  el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results;
4913 }
4914 
4915 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4916 {
4917  kfree(cfg->scan_results);
4918  cfg->scan_results = NULL;
4919  kfree(cfg->bss_info);
4920  cfg->bss_info = NULL;
4921  kfree(cfg->conf);
4922  cfg->conf = NULL;
4923  kfree(cfg->profile);
4924  cfg->profile = NULL;
4925  kfree(cfg->scan_req_int);
4926  cfg->scan_req_int = NULL;
4927  kfree(cfg->escan_ioctl_buf);
4928  cfg->escan_ioctl_buf = NULL;
4929  kfree(cfg->dcmd_buf);
4930  cfg->dcmd_buf = NULL;
4931  kfree(cfg->extra_buf);
4932  cfg->extra_buf = NULL;
4933  kfree(cfg->iscan);
4934  cfg->iscan = NULL;
4935  kfree(cfg->pmk_list);
4936  cfg->pmk_list = NULL;
4937  if (cfg->ap_info) {
4938  kfree(cfg->ap_info->wpa_ie);
4939  kfree(cfg->ap_info->rsn_ie);
4940  kfree(cfg->ap_info);
4941  cfg->ap_info = NULL;
4942  }
4943 }
4944 
4945 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4946 {
4947  cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
4948  if (!cfg->scan_results)
4949  goto init_priv_mem_out;
4950  cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4951  if (!cfg->conf)
4952  goto init_priv_mem_out;
4953  cfg->profile = kzalloc(sizeof(*cfg->profile), GFP_KERNEL);
4954  if (!cfg->profile)
4955  goto init_priv_mem_out;
4956  cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4957  if (!cfg->bss_info)
4958  goto init_priv_mem_out;
4959  cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int),
4960  GFP_KERNEL);
4961  if (!cfg->scan_req_int)
4962  goto init_priv_mem_out;
4963  cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4964  if (!cfg->escan_ioctl_buf)
4965  goto init_priv_mem_out;
4966  cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
4967  if (!cfg->dcmd_buf)
4968  goto init_priv_mem_out;
4969  cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4970  if (!cfg->extra_buf)
4971  goto init_priv_mem_out;
4972  cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL);
4973  if (!cfg->iscan)
4974  goto init_priv_mem_out;
4975  cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4976  if (!cfg->pmk_list)
4977  goto init_priv_mem_out;
4978 
4979  return 0;
4980 
4981 init_priv_mem_out:
4982  brcmf_deinit_priv_mem(cfg);
4983 
4984  return -ENOMEM;
4985 }
4986 
4987 /*
4988 * retrieve first queued event from head
4989 */
4990 
4991 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
4992  struct brcmf_cfg80211_info *cfg)
4993 {
4994  struct brcmf_cfg80211_event_q *e = NULL;
4995 
4996  spin_lock_irq(&cfg->evt_q_lock);
4997  if (!list_empty(&cfg->evt_q_list)) {
4998  e = list_first_entry(&cfg->evt_q_list,
5000  list_del(&e->evt_q_list);
5001  }
5002  spin_unlock_irq(&cfg->evt_q_lock);
5003 
5004  return e;
5005 }
5006 
5007 /*
5008 * push event to tail of the queue
5009 *
5010 * remark: this function may not sleep as it is called in atomic context.
5011 */
5012 
5013 static s32
5014 brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event,
5015  const struct brcmf_event_msg *msg, void *data)
5016 {
5017  struct brcmf_cfg80211_event_q *e;
5018  s32 err = 0;
5019  ulong flags;
5020  u32 data_len;
5021  u32 total_len;
5022 
5023  total_len = sizeof(struct brcmf_cfg80211_event_q);
5024  if (data)
5025  data_len = be32_to_cpu(msg->datalen);
5026  else
5027  data_len = 0;
5028  total_len += data_len;
5029  e = kzalloc(total_len, GFP_ATOMIC);
5030  if (!e)
5031  return -ENOMEM;
5032 
5033  e->etype = event;
5034  memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
5035  if (data)
5036  memcpy(&e->edata, data, data_len);
5037 
5038  spin_lock_irqsave(&cfg->evt_q_lock, flags);
5039  list_add_tail(&e->evt_q_list, &cfg->evt_q_list);
5040  spin_unlock_irqrestore(&cfg->evt_q_lock, flags);
5041 
5042  return err;
5043 }
5044 
5045 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
5046 {
5047  kfree(e);
5048 }
5049 
5050 static void brcmf_cfg80211_event_handler(struct work_struct *work)
5051 {
5052  struct brcmf_cfg80211_info *cfg =
5053  container_of(work, struct brcmf_cfg80211_info,
5054  event_work);
5055  struct brcmf_cfg80211_event_q *e;
5056 
5057  e = brcmf_deq_event(cfg);
5058  if (unlikely(!e)) {
5059  WL_ERR("event queue empty...\n");
5060  return;
5061  }
5062 
5063  do {
5064  WL_INFO("event type (%d)\n", e->etype);
5065  if (cfg->el.handler[e->etype])
5066  cfg->el.handler[e->etype](cfg,
5067  cfg_to_ndev(cfg),
5068  &e->emsg, e->edata);
5069  else
5070  WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
5071  brcmf_put_event(e);
5072  } while ((e = brcmf_deq_event(cfg)));
5073 
5074 }
5075 
5076 static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg)
5077 {
5078  spin_lock_init(&cfg->evt_q_lock);
5079  INIT_LIST_HEAD(&cfg->evt_q_list);
5080 }
5081 
5082 static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg)
5083 {
5084  struct brcmf_cfg80211_event_q *e;
5085 
5086  spin_lock_irq(&cfg->evt_q_lock);
5087  while (!list_empty(&cfg->evt_q_list)) {
5088  e = list_first_entry(&cfg->evt_q_list,
5090  list_del(&e->evt_q_list);
5091  kfree(e);
5092  }
5093  spin_unlock_irq(&cfg->evt_q_lock);
5094 }
5095 
5096 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5097 {
5098  s32 err = 0;
5099 
5100  cfg->scan_request = NULL;
5101  cfg->pwr_save = true;
5102 #ifdef CONFIG_BRCMISCAN
5103  cfg->iscan_on = true; /* iscan on & off switch.
5104  we enable iscan per default */
5105  cfg->escan_on = false; /* escan on & off switch.
5106  we disable escan per default */
5107 #else
5108  cfg->iscan_on = false; /* iscan on & off switch.
5109  we disable iscan per default */
5110  cfg->escan_on = true; /* escan on & off switch.
5111  we enable escan per default */
5112 #endif
5113  cfg->roam_on = true; /* roam on & off switch.
5114  we enable roam per default */
5115 
5116  cfg->iscan_kickstart = false;
5117  cfg->active_scan = true; /* we do active scan for
5118  specific scan per default */
5119  cfg->dongle_up = false; /* dongle is not up yet */
5120  brcmf_init_eq(cfg);
5121  err = brcmf_init_priv_mem(cfg);
5122  if (err)
5123  return err;
5124  INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler);
5125  brcmf_init_eloop_handler(&cfg->el);
5126  mutex_init(&cfg->usr_sync);
5127  err = brcmf_init_iscan(cfg);
5128  if (err)
5129  return err;
5130  brcmf_init_escan(cfg);
5131  brcmf_init_conf(cfg->conf);
5132  brcmf_init_prof(cfg->profile);
5133  brcmf_link_down(cfg);
5134 
5135  return err;
5136 }
5137 
5138 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5139 {
5141  cfg->dongle_up = false; /* dongle down */
5142  brcmf_flush_eq(cfg);
5143  brcmf_link_down(cfg);
5144  brcmf_abort_scanning(cfg);
5145  brcmf_deinit_priv_mem(cfg);
5147 
5149  struct device *busdev,
5150  struct brcmf_pub *drvr)
5151 {
5152  struct wireless_dev *wdev;
5153  struct brcmf_cfg80211_info *cfg;
5154  s32 err = 0;
5155 
5156  if (!ndev) {
5157  WL_ERR("ndev is invalid\n");
5158  return NULL;
5159  }
5160 
5161  wdev = brcmf_alloc_wdev(busdev);
5162  if (IS_ERR(wdev)) {
5163  return NULL;
5164  }
5165 
5166  wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
5167  cfg = wdev_to_cfg(wdev);
5168  cfg->wdev = wdev;
5169  cfg->pub = drvr;
5170  ndev->ieee80211_ptr = wdev;
5171  SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
5172  wdev->netdev = ndev;
5173  err = wl_init_priv(cfg);
5174  if (err) {
5175  WL_ERR("Failed to init iwm_priv (%d)\n", err);
5176  goto cfg80211_attach_out;
5177  }
5178 
5179  return cfg;
5180 
5181 cfg80211_attach_out:
5182  brcmf_free_wdev(cfg);
5183  return NULL;
5185 
5187 {
5188  wl_deinit_priv(cfg);
5189  brcmf_free_wdev(cfg);
5190 }
5192 void
5193 brcmf_cfg80211_event(struct net_device *ndev,
5194  const struct brcmf_event_msg *e, void *data)
5195 {
5197  struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
5198 
5199  if (!brcmf_enq_event(cfg, event_type, e, data))
5200  schedule_work(&cfg->event_work);
5201 }
5202 
5203 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
5204 {
5205  /* Room for "event_msgs" + '\0' + bitvec */
5206  s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
5207  s8 eventmask[BRCMF_EVENTING_MASK_LEN];
5208  s32 err = 0;
5209 
5210  WL_TRACE("Enter\n");
5211 
5212  /* Setup event_msgs */
5213  brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
5214  iovbuf, sizeof(iovbuf));
5215  err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
5216  if (err) {
5217  WL_ERR("Get event_msgs error (%d)\n", err);
5218  goto dongle_eventmsg_out;
5219  }
5220  memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
5221 
5222  setbit(eventmask, BRCMF_E_SET_SSID);
5223  setbit(eventmask, BRCMF_E_ROAM);
5224  setbit(eventmask, BRCMF_E_PRUNE);
5225  setbit(eventmask, BRCMF_E_AUTH);
5226  setbit(eventmask, BRCMF_E_REASSOC);
5227  setbit(eventmask, BRCMF_E_REASSOC_IND);
5228  setbit(eventmask, BRCMF_E_DEAUTH_IND);
5229  setbit(eventmask, BRCMF_E_DISASSOC_IND);
5230  setbit(eventmask, BRCMF_E_DISASSOC);
5231  setbit(eventmask, BRCMF_E_JOIN);
5232  setbit(eventmask, BRCMF_E_ASSOC_IND);
5233  setbit(eventmask, BRCMF_E_PSK_SUP);
5234  setbit(eventmask, BRCMF_E_LINK);
5235  setbit(eventmask, BRCMF_E_NDIS_LINK);
5236  setbit(eventmask, BRCMF_E_MIC_ERROR);
5237  setbit(eventmask, BRCMF_E_PMKID_CACHE);
5238  setbit(eventmask, BRCMF_E_TXFAIL);
5239  setbit(eventmask, BRCMF_E_JOIN_START);
5240  setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
5241  setbit(eventmask, BRCMF_E_ESCAN_RESULT);
5242  setbit(eventmask, BRCMF_E_PFN_NET_FOUND);
5243 
5244  brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
5245  iovbuf, sizeof(iovbuf));
5246  err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
5247  if (err) {
5248  WL_ERR("Set event_msgs error (%d)\n", err);
5249  goto dongle_eventmsg_out;
5250  }
5251 
5252 dongle_eventmsg_out:
5253  WL_TRACE("Exit\n");
5254  return err;
5255 }
5256 
5257 static s32
5258 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
5259 {
5260  s8 iovbuf[32];
5261  s32 err = 0;
5262  __le32 roamtrigger[2];
5263  __le32 roam_delta[2];
5264  __le32 bcn_to_le;
5265  __le32 roamvar_le;
5266 
5267  /*
5268  * Setup timeout if Beacons are lost and roam is
5269  * off to report link down
5270  */
5271  if (roamvar) {
5272  bcn_to_le = cpu_to_le32(bcn_timeout);
5273  brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
5274  sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
5275  err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
5276  iovbuf, sizeof(iovbuf));
5277  if (err) {
5278  WL_ERR("bcn_timeout error (%d)\n", err);
5279  goto dongle_rom_out;
5280  }
5281  }
5282 
5283  /*
5284  * Enable/Disable built-in roaming to allow supplicant
5285  * to take care of roaming
5286  */
5287  WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
5288  roamvar_le = cpu_to_le32(roamvar);
5289  brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
5290  sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
5291  err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
5292  if (err) {
5293  WL_ERR("roam_off error (%d)\n", err);
5294  goto dongle_rom_out;
5295  }
5296 
5297  roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5298  roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5300  (void *)roamtrigger, sizeof(roamtrigger));
5301  if (err) {
5302  WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5303  goto dongle_rom_out;
5304  }
5305 
5306  roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5307  roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5309  (void *)roam_delta, sizeof(roam_delta));
5310  if (err) {
5311  WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
5312  goto dongle_rom_out;
5313  }
5314 
5315 dongle_rom_out:
5316  return err;
5317 }
5318 
5319 static s32
5320 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
5321  s32 scan_unassoc_time, s32 scan_passive_time)
5322 {
5323  s32 err = 0;
5324  __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
5325  __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
5326  __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
5327 
5329  &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
5330  if (err) {
5331  if (err == -EOPNOTSUPP)
5332  WL_INFO("Scan assoc time is not supported\n");
5333  else
5334  WL_ERR("Scan assoc time error (%d)\n", err);
5335  goto dongle_scantime_out;
5336  }
5338  &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
5339  if (err) {
5340  if (err == -EOPNOTSUPP)
5341  WL_INFO("Scan unassoc time is not supported\n");
5342  else
5343  WL_ERR("Scan unassoc time error (%d)\n", err);
5344  goto dongle_scantime_out;
5345  }
5346 
5348  &scan_passive_tm_le, sizeof(scan_passive_tm_le));
5349  if (err) {
5350  if (err == -EOPNOTSUPP)
5351  WL_INFO("Scan passive time is not supported\n");
5352  else
5353  WL_ERR("Scan passive time error (%d)\n", err);
5354  goto dongle_scantime_out;
5355  }
5356 
5357 dongle_scantime_out:
5358  return err;
5359 }
5360 
5361 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5362 {
5363  struct wiphy *wiphy;
5364  s32 phy_list;
5365  s8 phy;
5366  s32 err = 0;
5367 
5368  err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCM_GET_PHYLIST,
5369  &phy_list, sizeof(phy_list));
5370  if (err) {
5371  WL_ERR("error (%d)\n", err);
5372  return err;
5373  }
5374 
5375  phy = ((char *)&phy_list)[0];
5376  WL_INFO("%c phy\n", phy);
5377  if (phy == 'n' || phy == 'a') {
5378  wiphy = cfg_to_wiphy(cfg);
5379  wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
5380  }
5381 
5382  return err;
5383 }
5384 
5385 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5386 {
5387  return wl_update_wiphybands(cfg);
5388 }
5389 
5390 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5391 {
5392  struct net_device *ndev;
5393  struct wireless_dev *wdev;
5394  s32 power_mode;
5395  s32 err = 0;
5396 
5397  if (cfg->dongle_up)
5398  return err;
5399 
5400  ndev = cfg_to_ndev(cfg);
5401  wdev = ndev->ieee80211_ptr;
5402 
5403  brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
5405 
5406  err = brcmf_dongle_eventmsg(ndev);
5407  if (err)
5408  goto default_conf_out;
5409 
5410  power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5411  err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
5412  if (err)
5413  goto default_conf_out;
5414  WL_INFO("power save set to %s\n",
5415  (power_mode ? "enabled" : "disabled"));
5416 
5417  err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
5419  if (err)
5420  goto default_conf_out;
5421  err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5422  NULL, NULL);
5423  if (err && err != -EINPROGRESS)
5424  goto default_conf_out;
5425  err = brcmf_dongle_probecap(cfg);
5426  if (err)
5427  goto default_conf_out;
5428 
5429  /* -EINPROGRESS: Call commit handler */
5430 
5431 default_conf_out:
5432 
5433  cfg->dongle_up = true;
5434 
5435  return err;
5436 
5437 }
5438 
5439 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info *cfg)
5440 {
5441  char buf[10+IFNAMSIZ];
5442  struct dentry *fd;
5443  s32 err = 0;
5444 
5445  sprintf(buf, "netdev:%s", cfg_to_ndev(cfg)->name);
5446  cfg->debugfsdir = debugfs_create_dir(buf,
5447  cfg_to_wiphy(cfg)->debugfsdir);
5448 
5449  fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg->debugfsdir,
5450  (u16 *)&cfg->profile->beacon_interval);
5451  if (!fd) {
5452  err = -ENOMEM;
5453  goto err_out;
5454  }
5455 
5456  fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg->debugfsdir,
5457  (u8 *)&cfg->profile->dtim_period);
5458  if (!fd) {
5459  err = -ENOMEM;
5460  goto err_out;
5461  }
5462 
5463 err_out:
5464  return err;
5465 }
5466 
5467 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg)
5468 {
5470  cfg->debugfsdir = NULL;
5471 }
5472 
5473 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
5474 {
5475  s32 err = 0;
5476 
5477  set_bit(WL_STATUS_READY, &cfg->status);
5478 
5479  brcmf_debugfs_add_netdev_params(cfg);
5480 
5481  err = brcmf_config_dongle(cfg);
5482  if (err)
5483  return err;
5484 
5485  brcmf_invoke_iscan(cfg);
5486 
5487  return err;
5488 }
5489 
5490 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
5491 {
5492  /*
5493  * While going down, if associated with AP disassociate
5494  * from AP to save power
5495  */
5496  if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
5498  test_bit(WL_STATUS_READY, &cfg->status)) {
5499  WL_INFO("Disassociating from AP");
5500  brcmf_link_down(cfg);
5501 
5502  /* Make sure WPA_Supplicant receives all the event
5503  generated due to DISASSOC call to the fw to keep
5504  the state fw and WPA_Supplicant state consistent
5505  */
5506  brcmf_delay(500);
5507  }
5508 
5509  brcmf_abort_scanning(cfg);
5511 
5512  brcmf_debugfs_remove_netdev(cfg);
5513 
5514  return 0;
5516 
5518 {
5519  s32 err = 0;
5520 
5521  mutex_lock(&cfg->usr_sync);
5522  err = __brcmf_cfg80211_up(cfg);
5523  mutex_unlock(&cfg->usr_sync);
5524 
5525  return err;
5527 
5529 {
5530  s32 err = 0;
5531 
5532  mutex_lock(&cfg->usr_sync);
5533  err = __brcmf_cfg80211_down(cfg);
5534  mutex_unlock(&cfg->usr_sync);
5535 
5536  return err;
5537 }
5538