]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/blob - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
Merge tag 'for-linus-20121212' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowe...
[can-eth-gw-linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / wl_cfg80211.c
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 }
126
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[] = {
136         RATETAB_ENT(BRCM_RATE_1M, 0),
137         RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
138         RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
139         RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
140         RATETAB_ENT(BRCM_RATE_6M, 0),
141         RATETAB_ENT(BRCM_RATE_9M, 0),
142         RATETAB_ENT(BRCM_RATE_12M, 0),
143         RATETAB_ENT(BRCM_RATE_18M, 0),
144         RATETAB_ENT(BRCM_RATE_24M, 0),
145         RATETAB_ENT(BRCM_RATE_36M, 0),
146         RATETAB_ENT(BRCM_RATE_48M, 0),
147         RATETAB_ENT(BRCM_RATE_54M, 0),
148 };
149
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[] = {
277         WLAN_CIPHER_SUITE_WEP40,
278         WLAN_CIPHER_SUITE_WEP104,
279         WLAN_CIPHER_SUITE_TKIP,
280         WLAN_CIPHER_SUITE_CCMP,
281         WLAN_CIPHER_SUITE_AES_CMAC,
282 };
283
284 /* tag_ID/length/value_buffer tuple */
285 struct brcmf_tlv {
286         u8 id;
287         u8 len;
288         u8 data[1];
289 };
290
291 /* Vendor specific ie. id = 221, oui and type defines exact ie */
292 struct brcmf_vs_tlv {
293         u8 id;
294         u8 len;
295         u8 oui[3];
296         u8 oui_type;
297 };
298
299 struct parsed_vndr_ie_info {
300         u8 *ie_ptr;
301         u32 ie_len;     /* total length including id & length field */
302         struct brcmf_vs_tlv vndrie;
303 };
304
305 struct parsed_vndr_ies {
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  */
315
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) {
491         case NL80211_IFTYPE_MONITOR:
492         case NL80211_IFTYPE_WDS:
493                 WL_ERR("type (%d) : currently we do not support this type\n",
494                        type);
495                 return -EOPNOTSUPP;
496         case NL80211_IFTYPE_ADHOC:
497                 cfg->conf->mode = WL_MODE_IBSS;
498                 infra = 0;
499                 break;
500         case NL80211_IFTYPE_STATION:
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) {
514                 set_bit(WL_STATUS_AP_CREATING, &cfg->status);
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);
690         struct brcmf_iscan_params_le *params;
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
702         params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
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,
754                      struct cfg80211_scan_request *request,
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         }
770         if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
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;
795         set_bit(WL_STATUS_SCANNING, &cfg->status);
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);
817                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
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:
841         clear_bit(WL_STATUS_SCANNING, &cfg->status);
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];
881                         channel = ieee80211_frequency_to_channel(
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 &
894                                                 IEEE80211_CHAN_NO_HT40PLUS)
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 =
942                 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
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))
963                 del_timer_sync(&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         }
1001         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
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);
1035         params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
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,
1040                         cfg->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
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);
1066         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
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;
1076         results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
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;
1131         set_bit(WL_STATUS_SCANNING, &cfg->status);
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);
1153                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
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:
1177         clear_bit(WL_STATUS_SCANNING, &cfg->status);
1178         if (timer_pending(&cfg->escan_timeout))
1179                 del_timer_sync(&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
1361         set_bit(WL_STATUS_CONNECTING, &cfg->status);
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) +
1434                                    BRCMF_ASSOC_PARAMS_FIXED_SIZE;
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 =
1446                         ieee80211_frequency_to_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)
1477                 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
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)
1509                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1510         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1511                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
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) {
1535         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1536                 val = 0;
1537                 WL_CONN("open system\n");
1538                 break;
1539         case NL80211_AUTHTYPE_SHARED_KEY:
1540                 val = 1;
1541                 WL_CONN("shared key\n");
1542                 break;
1543         case NL80211_AUTHTYPE_AUTOMATIC:
1544                 val = 2;
1545                 WL_CONN("automatic\n");
1546                 break;
1547         case NL80211_AUTHTYPE_NETWORK_EAP:
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]) {
1578                 case WLAN_CIPHER_SUITE_WEP40:
1579                 case WLAN_CIPHER_SUITE_WEP104:
1580                         pval = WEP_ENABLED;
1581                         break;
1582                 case WLAN_CIPHER_SUITE_TKIP:
1583                         pval = TKIP_ENABLED;
1584                         break;
1585                 case WLAN_CIPHER_SUITE_CCMP:
1586                         pval = AES_ENABLED;
1587                         break;
1588                 case WLAN_CIPHER_SUITE_AES_CMAC:
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) {
1599                 case WLAN_CIPHER_SUITE_WEP40:
1600                 case WLAN_CIPHER_SUITE_WEP104:
1601                         gval = WEP_ENABLED;
1602                         break;
1603                 case WLAN_CIPHER_SUITE_TKIP:
1604                         gval = TKIP_ENABLED;
1605                         break;
1606                 case WLAN_CIPHER_SUITE_CCMP:
1607                         gval = AES_ENABLED;
1608                         break;
1609                 case WLAN_CIPHER_SUITE_AES_CMAC:
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
1710         if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1711                 return 0;
1712
1713         if (!(sec->cipher_pairwise &
1714             (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
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) {
1727         case WLAN_CIPHER_SUITE_WEP40:
1728                 key.algo = CRYPTO_ALGO_WEP1;
1729                 break;
1730         case WLAN_CIPHER_SUITE_WEP104:
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
1779         set_bit(WL_STATUS_CONNECTING, &cfg->status);
1780
1781         if (chan) {
1782                 cfg->channel =
1783                         ieee80211_frequency_to_channel(chan->center_freq);
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)
1845                 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
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
1863         clear_bit(WL_STATUS_CONNECTED, &cfg->status);
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) {
1895         case NL80211_TX_POWER_AUTOMATIC:
1896                 break;
1897         case NL80211_TX_POWER_LIMITED:
1898         case NL80211_TX_POWER_FIXED:
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) {
2040                 case WLAN_CIPHER_SUITE_WEP40:
2041                         key.algo = CRYPTO_ALGO_WEP1;
2042                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2043                         break;
2044                 case WLAN_CIPHER_SUITE_WEP104:
2045                         key.algo = CRYPTO_ALGO_WEP128;
2046                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2047                         break;
2048                 case WLAN_CIPHER_SUITE_TKIP:
2049                         key.algo = CRYPTO_ALGO_TKIP;
2050                         WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2051                         break;
2052                 case WLAN_CIPHER_SUITE_AES_CMAC:
2053                         key.algo = CRYPTO_ALGO_AES_CCM;
2054                         WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2055                         break;
2056                 case WLAN_CIPHER_SUITE_CCMP:
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
2066                 brcmf_netdev_wait_pend8021x(ndev);
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) {
2113         case WLAN_CIPHER_SUITE_WEP40:
2114                 key.algo = CRYPTO_ALGO_WEP1;
2115                 val = WEP_ENABLED;
2116                 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2117                 break;
2118         case WLAN_CIPHER_SUITE_WEP104:
2119                 key.algo = CRYPTO_ALGO_WEP128;
2120                 val = WEP_ENABLED;
2121                 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2122                 break;
2123         case WLAN_CIPHER_SUITE_TKIP:
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;
2134         case WLAN_CIPHER_SUITE_AES_CMAC:
2135                 key.algo = CRYPTO_ALGO_AES_CCM;
2136                 val = AES_ENABLED;
2137                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2138                 break;
2139         case WLAN_CIPHER_SUITE_CCMP:
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;
2241                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2242                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
2243                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2244                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2245                         params.cipher = 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:
2254                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
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
2305                 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2306                 sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000;
2307                 if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) {
2308                         sinfo->filled |= STATION_INFO_CONNECTED_TIME;
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;
2456         struct ieee80211_supported_band *band;
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 :
2472                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
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;
2546         struct ieee80211_supported_band *band;
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
2568         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
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 :
2577                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
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 }
2676
2677 struct brcmf_vs_tlv *
2678 brcmf_find_wpaie(u8 *parse, u32 len)
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,
2684                                      WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
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;
2696         u16 beacon_interval;
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
2708         *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
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
2758         set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
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) {
2781                 escan->escan_state = WL_ESCAN_STATE_IDLE;
2782                 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2783         }
2784         clear_bit(WL_STATUS_SCANNING, &cfg->status);
2785         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
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
2794         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
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;
2833         results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
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,
2840                                      BRCMF_ISCAN_RESULTS_FIXED_SIZE,
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 =
2910                         container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2911                                      work);
2912         struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2913         struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2914         u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
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);
2971                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
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,
2987                                      escan_timeout_work);
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)
3001                         schedule_work(&cfg->escan_timeout_work);
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;
3030                         bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
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,
3058                         !test_bit(WL_STATUS_SCANNING, &cfg->status));
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) -
3083                                         WL_ESCAN_RESULTS_FIXED_SIZE)) {
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 &
3090                                         BIT(NL80211_IFTYPE_ADHOC))) {
3091                         if (le16_to_cpu(bss_info_le->capability) &
3092                                                 WLAN_CAPABILITY_IBSS) {
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;
3144                 INIT_WORK(&cfg->escan_timeout_work,
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) ||
3196              test_bit(WL_STATUS_CONNECTING, &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
3213                 clear_bit(WL_STATUS_SCANNING, &cfg->status);
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
3419         if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) {
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
3486                 set_bit(WL_STATUS_SCANNING, &cfg->status);
3487                 err = brcmf_do_escan(cfg, wiphy, ndev, request);
3488                 if (err) {
3489                         clear_bit(WL_STATUS_SCANNING, &cfg->status);
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);
3508         cfg80211_sched_scan_stopped(wiphy);
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 }
3965
3966 s32
3967 brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
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) ||
3993             test_bit(WL_STATUS_AP_CREATED, &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) {
4150                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
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,
4230                                       VNDR_IE_BEACON_FLAG,
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,
4240                                       VNDR_IE_PRBRSP_FLAG,
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         }
4283         clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4284         set_bit(WL_STATUS_AP_CREATED, &cfg->status);
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);
4317                 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4318                 clear_bit(WL_STATUS_AP_CREATED, &cfg->status);
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);
4340         scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4341         err = brcmf_exec_dcmd(ndev, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
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:
4396                 return NL80211_IFTYPE_UNSPECIFIED;
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 */
4406         wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4407         wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4408         wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4409         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
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) |
4433                                        BIT(NL80211_IFTYPE_ADHOC) |
4434                                        BIT(NL80211_IFTYPE_AP);
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",
4517                                 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
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,
4554                                 WL_ASSOC_INFO_MAX);
4555         if (err) {
4556                 WL_ERR("could not get assoc info (%d)\n", err);
4557                 return err;
4558         }
4559         assoc_info =
4560                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
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,
4566                                            WL_ASSOC_INFO_MAX);
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,
4582                                            WL_ASSOC_INFO_MAX);
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;
4610         struct ieee80211_supported_band *band;
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);
4631         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, 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 :
4638                                       CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
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
4655         set_bit(WL_STATUS_CONNECTED, &cfg->status);
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
4671         if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) {
4672                 if (completed) {
4673                         brcmf_get_assoc_ies(cfg);
4674                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4675                         brcmf_update_bss_info(cfg);
4676                 }
4677                 cfg80211_connect_result(ndev,
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 :
4684                                                     WLAN_STATUS_AUTH_TIMEOUT,
4685                                         GFP_KERNEL);
4686                 if (completed)
4687                         set_bit(WL_STATUS_CONNECTED, &cfg->status);
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) {
4714                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
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);
4749                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4750                         clear_bit(WL_STATUS_CONNECTING, &cfg->status);
4751                         set_bit(WL_STATUS_CONNECTED, &cfg->status);
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)) {
4757                         clear_bit(WL_STATUS_CONNECTING, &cfg->status);
4758                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
4759                                 &cfg->status))
4760                                 brcmf_link_down(cfg);
4761                 } else {
4762                         brcmf_bss_connect_done(cfg, ndev, e, false);
4763                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
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))
4773                         clear_bit(WL_STATUS_CONNECTING, &cfg->status);
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
4838         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
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);
4860         err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
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,
4999                                      struct brcmf_cfg80211_event_q, 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,
5089                                      struct brcmf_cfg80211_event_q, 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 {
5140         cancel_work_sync(&cfg->event_work);
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);
5146 }
5147
5148 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
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;
5184 }
5185
5186 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5187 {
5188         wl_deinit_priv(cfg);
5189         brcmf_free_wdev(cfg);
5190 }
5191
5192 void
5193 brcmf_cfg80211_event(struct net_device *ndev,
5194                   const struct brcmf_event_msg *e, void *data)
5195 {
5196         u32 event_type = be32_to_cpu(e->event_type);
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);
5299         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
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);
5308         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
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
5328         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
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         }
5337         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
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
5347         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
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,
5404                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_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),
5418                                 WL_BEACON_TIMEOUT);
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 {
5469         debugfs_remove_recursive(cfg->debugfsdir);
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) ||
5497              test_bit(WL_STATUS_CONNECTING, &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);
5510         clear_bit(WL_STATUS_READY, &cfg->status);
5511
5512         brcmf_debugfs_remove_netdev(cfg);
5513
5514         return 0;
5515 }
5516
5517 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
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;
5526 }
5527
5528 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
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