]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
brcm80211: moved power conversion functions
[mv-sheeva.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 #include <linux/kernel.h>
20 #include <linux/if_arp.h>
21 #include <linux/sched.h>
22 #include <linux/kthread.h>
23 #include <linux/netdevice.h>
24 #include <linux/bitops.h>
25 #include <linux/etherdevice.h>
26 #include <linux/ieee80211.h>
27 #include <linux/uaccess.h>
28 #include <net/cfg80211.h>
29
30 #include <brcmu_utils.h>
31 #include <defs.h>
32 #include <brcmu_wifi.h>
33 #include "dhd.h"
34 #include "wl_cfg80211.h"
35
36 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
37         (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
38
39 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
40
41 static u32 brcmf_dbg_level = WL_DBG_ERR;
42
43 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
44 {
45         dev->driver_data = data;
46 }
47
48 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
49 {
50         void *data = NULL;
51
52         if (dev)
53                 data = dev->driver_data;
54         return data;
55 }
56
57 static
58 struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
59 {
60         struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
61         return ci->cfg_priv;
62 }
63
64 static bool check_sys_up(struct wiphy *wiphy)
65 {
66         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
67         if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
68                 WL_INFO("device is not ready : status (%d)\n",
69                         (int)cfg_priv->status);
70                 return false;
71         }
72         return true;
73 }
74
75 #define CHAN2G(_channel, _freq, _flags) {                       \
76         .band                   = IEEE80211_BAND_2GHZ,          \
77         .center_freq            = (_freq),                      \
78         .hw_value               = (_channel),                   \
79         .flags                  = (_flags),                     \
80         .max_antenna_gain       = 0,                            \
81         .max_power              = 30,                           \
82 }
83
84 #define CHAN5G(_channel, _flags) {                              \
85         .band                   = IEEE80211_BAND_5GHZ,          \
86         .center_freq            = 5000 + (5 * (_channel)),      \
87         .hw_value               = (_channel),                   \
88         .flags                  = (_flags),                     \
89         .max_antenna_gain       = 0,                            \
90         .max_power              = 30,                           \
91 }
92
93 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
94 #define RATETAB_ENT(_rateid, _flags) \
95         {                                                               \
96                 .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
97                 .hw_value       = (_rateid),                            \
98                 .flags          = (_flags),                             \
99         }
100
101 static struct ieee80211_rate __wl_rates[] = {
102         RATETAB_ENT(BRCM_RATE_1M, 0),
103         RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
104         RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
105         RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
106         RATETAB_ENT(BRCM_RATE_6M, 0),
107         RATETAB_ENT(BRCM_RATE_9M, 0),
108         RATETAB_ENT(BRCM_RATE_12M, 0),
109         RATETAB_ENT(BRCM_RATE_18M, 0),
110         RATETAB_ENT(BRCM_RATE_24M, 0),
111         RATETAB_ENT(BRCM_RATE_36M, 0),
112         RATETAB_ENT(BRCM_RATE_48M, 0),
113         RATETAB_ENT(BRCM_RATE_54M, 0),
114 };
115
116 #define wl_a_rates              (__wl_rates + 4)
117 #define wl_a_rates_size 8
118 #define wl_g_rates              (__wl_rates + 0)
119 #define wl_g_rates_size 12
120
121 static struct ieee80211_channel __wl_2ghz_channels[] = {
122         CHAN2G(1, 2412, 0),
123         CHAN2G(2, 2417, 0),
124         CHAN2G(3, 2422, 0),
125         CHAN2G(4, 2427, 0),
126         CHAN2G(5, 2432, 0),
127         CHAN2G(6, 2437, 0),
128         CHAN2G(7, 2442, 0),
129         CHAN2G(8, 2447, 0),
130         CHAN2G(9, 2452, 0),
131         CHAN2G(10, 2457, 0),
132         CHAN2G(11, 2462, 0),
133         CHAN2G(12, 2467, 0),
134         CHAN2G(13, 2472, 0),
135         CHAN2G(14, 2484, 0),
136 };
137
138 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
139         CHAN5G(34, 0), CHAN5G(36, 0),
140         CHAN5G(38, 0), CHAN5G(40, 0),
141         CHAN5G(42, 0), CHAN5G(44, 0),
142         CHAN5G(46, 0), CHAN5G(48, 0),
143         CHAN5G(52, 0), CHAN5G(56, 0),
144         CHAN5G(60, 0), CHAN5G(64, 0),
145         CHAN5G(100, 0), CHAN5G(104, 0),
146         CHAN5G(108, 0), CHAN5G(112, 0),
147         CHAN5G(116, 0), CHAN5G(120, 0),
148         CHAN5G(124, 0), CHAN5G(128, 0),
149         CHAN5G(132, 0), CHAN5G(136, 0),
150         CHAN5G(140, 0), CHAN5G(149, 0),
151         CHAN5G(153, 0), CHAN5G(157, 0),
152         CHAN5G(161, 0), CHAN5G(165, 0),
153         CHAN5G(184, 0), CHAN5G(188, 0),
154         CHAN5G(192, 0), CHAN5G(196, 0),
155         CHAN5G(200, 0), CHAN5G(204, 0),
156         CHAN5G(208, 0), CHAN5G(212, 0),
157         CHAN5G(216, 0),
158 };
159
160 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
161         CHAN5G(32, 0), CHAN5G(34, 0),
162         CHAN5G(36, 0), CHAN5G(38, 0),
163         CHAN5G(40, 0), CHAN5G(42, 0),
164         CHAN5G(44, 0), CHAN5G(46, 0),
165         CHAN5G(48, 0), CHAN5G(50, 0),
166         CHAN5G(52, 0), CHAN5G(54, 0),
167         CHAN5G(56, 0), CHAN5G(58, 0),
168         CHAN5G(60, 0), CHAN5G(62, 0),
169         CHAN5G(64, 0), CHAN5G(66, 0),
170         CHAN5G(68, 0), CHAN5G(70, 0),
171         CHAN5G(72, 0), CHAN5G(74, 0),
172         CHAN5G(76, 0), CHAN5G(78, 0),
173         CHAN5G(80, 0), CHAN5G(82, 0),
174         CHAN5G(84, 0), CHAN5G(86, 0),
175         CHAN5G(88, 0), CHAN5G(90, 0),
176         CHAN5G(92, 0), CHAN5G(94, 0),
177         CHAN5G(96, 0), CHAN5G(98, 0),
178         CHAN5G(100, 0), CHAN5G(102, 0),
179         CHAN5G(104, 0), CHAN5G(106, 0),
180         CHAN5G(108, 0), CHAN5G(110, 0),
181         CHAN5G(112, 0), CHAN5G(114, 0),
182         CHAN5G(116, 0), CHAN5G(118, 0),
183         CHAN5G(120, 0), CHAN5G(122, 0),
184         CHAN5G(124, 0), CHAN5G(126, 0),
185         CHAN5G(128, 0), CHAN5G(130, 0),
186         CHAN5G(132, 0), CHAN5G(134, 0),
187         CHAN5G(136, 0), CHAN5G(138, 0),
188         CHAN5G(140, 0), CHAN5G(142, 0),
189         CHAN5G(144, 0), CHAN5G(145, 0),
190         CHAN5G(146, 0), CHAN5G(147, 0),
191         CHAN5G(148, 0), CHAN5G(149, 0),
192         CHAN5G(150, 0), CHAN5G(151, 0),
193         CHAN5G(152, 0), CHAN5G(153, 0),
194         CHAN5G(154, 0), CHAN5G(155, 0),
195         CHAN5G(156, 0), CHAN5G(157, 0),
196         CHAN5G(158, 0), CHAN5G(159, 0),
197         CHAN5G(160, 0), CHAN5G(161, 0),
198         CHAN5G(162, 0), CHAN5G(163, 0),
199         CHAN5G(164, 0), CHAN5G(165, 0),
200         CHAN5G(166, 0), CHAN5G(168, 0),
201         CHAN5G(170, 0), CHAN5G(172, 0),
202         CHAN5G(174, 0), CHAN5G(176, 0),
203         CHAN5G(178, 0), CHAN5G(180, 0),
204         CHAN5G(182, 0), CHAN5G(184, 0),
205         CHAN5G(186, 0), CHAN5G(188, 0),
206         CHAN5G(190, 0), CHAN5G(192, 0),
207         CHAN5G(194, 0), CHAN5G(196, 0),
208         CHAN5G(198, 0), CHAN5G(200, 0),
209         CHAN5G(202, 0), CHAN5G(204, 0),
210         CHAN5G(206, 0), CHAN5G(208, 0),
211         CHAN5G(210, 0), CHAN5G(212, 0),
212         CHAN5G(214, 0), CHAN5G(216, 0),
213         CHAN5G(218, 0), CHAN5G(220, 0),
214         CHAN5G(222, 0), CHAN5G(224, 0),
215         CHAN5G(226, 0), CHAN5G(228, 0),
216 };
217
218 static struct ieee80211_supported_band __wl_band_2ghz = {
219         .band = IEEE80211_BAND_2GHZ,
220         .channels = __wl_2ghz_channels,
221         .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
222         .bitrates = wl_g_rates,
223         .n_bitrates = wl_g_rates_size,
224 };
225
226 static struct ieee80211_supported_band __wl_band_5ghz_a = {
227         .band = IEEE80211_BAND_5GHZ,
228         .channels = __wl_5ghz_a_channels,
229         .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
230         .bitrates = wl_a_rates,
231         .n_bitrates = wl_a_rates_size,
232 };
233
234 static struct ieee80211_supported_band __wl_band_5ghz_n = {
235         .band = IEEE80211_BAND_5GHZ,
236         .channels = __wl_5ghz_n_channels,
237         .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
238         .bitrates = wl_a_rates,
239         .n_bitrates = wl_a_rates_size,
240 };
241
242 static const u32 __wl_cipher_suites[] = {
243         WLAN_CIPHER_SUITE_WEP40,
244         WLAN_CIPHER_SUITE_WEP104,
245         WLAN_CIPHER_SUITE_TKIP,
246         WLAN_CIPHER_SUITE_CCMP,
247         WLAN_CIPHER_SUITE_AES_CMAC,
248 };
249
250 /* Quarter dBm units to mW
251  * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
252  * Table is offset so the last entry is largest mW value that fits in
253  * a u16.
254  */
255
256 #define QDBM_OFFSET 153         /* Offset for first entry */
257 #define QDBM_TABLE_LEN 40       /* Table size */
258
259 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
260  * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
261  */
262 #define QDBM_TABLE_LOW_BOUND 6493       /* Low bound */
263
264 /* Largest mW value that will round down to the last table entry,
265  * QDBM_OFFSET + QDBM_TABLE_LEN-1.
266  * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
267  * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
268  */
269 #define QDBM_TABLE_HIGH_BOUND 64938     /* High bound */
270
271 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
272 /* qdBm:        +0      +1      +2      +3      +4      +5      +6      +7 */
273 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
274 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
275 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
276 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
277 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
278 };
279
280 static u16 brcmf_qdbm_to_mw(u8 qdbm)
281 {
282         uint factor = 1;
283         int idx = qdbm - QDBM_OFFSET;
284
285         if (idx >= QDBM_TABLE_LEN)
286                 /* clamp to max u16 mW value */
287                 return 0xFFFF;
288
289         /* scale the qdBm index up to the range of the table 0-40
290          * where an offset of 40 qdBm equals a factor of 10 mW.
291          */
292         while (idx < 0) {
293                 idx += 40;
294                 factor *= 10;
295         }
296
297         /* return the mW value scaled down to the correct factor of 10,
298          * adding in factor/2 to get proper rounding.
299          */
300         return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
301 }
302
303 static u8 brcmf_mw_to_qdbm(u16 mw)
304 {
305         u8 qdbm;
306         int offset;
307         uint mw_uint = mw;
308         uint boundary;
309
310         /* handle boundary case */
311         if (mw_uint <= 1)
312                 return 0;
313
314         offset = QDBM_OFFSET;
315
316         /* move mw into the range of the table */
317         while (mw_uint < QDBM_TABLE_LOW_BOUND) {
318                 mw_uint *= 10;
319                 offset -= 40;
320         }
321
322         for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
323                 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
324                                                     nqdBm_to_mW_map[qdbm]) / 2;
325                 if (mw_uint < boundary)
326                         break;
327         }
328
329         qdbm += (u8) offset;
330
331         return qdbm;
332 }
333
334 /* function for reading/writing a single u32 from/to the dongle */
335 static int
336 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
337 {
338         int err;
339         __le32 par_le = cpu_to_le32(*par);
340
341         err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
342         *par = le32_to_cpu(par_le);
343
344         return err;
345 }
346
347 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
348                                  struct brcmf_wsec_key_le *key_le)
349 {
350         key_le->index = cpu_to_le32(key->index);
351         key_le->len = cpu_to_le32(key->len);
352         key_le->algo = cpu_to_le32(key->algo);
353         key_le->flags = cpu_to_le32(key->flags);
354         key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
355         key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
356         key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
357         memcpy(key_le->data, key->data, sizeof(key->data));
358         memcpy(key_le->ea, key->ea, sizeof(key->ea));
359 }
360
361 static int send_key_to_dongle(struct net_device *ndev,
362                               struct brcmf_wsec_key *key)
363 {
364         int err;
365         struct brcmf_wsec_key_le key_le;
366
367         convert_key_from_CPU(key, &key_le);
368         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
369         if (err)
370                 WL_ERR("WLC_SET_KEY error (%d)\n", err);
371         return err;
372 }
373
374 static s32
375 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
376                          enum nl80211_iftype type, u32 *flags,
377                          struct vif_params *params)
378 {
379         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
380         struct wireless_dev *wdev;
381         s32 infra = 0;
382         s32 err = 0;
383
384         WL_TRACE("Enter\n");
385         if (!check_sys_up(wiphy))
386                 return -EIO;
387
388         switch (type) {
389         case NL80211_IFTYPE_MONITOR:
390         case NL80211_IFTYPE_WDS:
391                 WL_ERR("type (%d) : currently we do not support this type\n",
392                        type);
393                 return -EOPNOTSUPP;
394         case NL80211_IFTYPE_ADHOC:
395                 cfg_priv->conf->mode = WL_MODE_IBSS;
396                 infra = 0;
397                 break;
398         case NL80211_IFTYPE_STATION:
399                 cfg_priv->conf->mode = WL_MODE_BSS;
400                 infra = 1;
401                 break;
402         default:
403                 err = -EINVAL;
404                 goto done;
405         }
406
407         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
408         if (err) {
409                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
410                 err = -EAGAIN;
411         } else {
412                 wdev = ndev->ieee80211_ptr;
413                 wdev->iftype = type;
414         }
415
416         WL_INFO("IF Type = %s\n",
417                 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
418
419 done:
420         WL_TRACE("Exit\n");
421
422         return err;
423 }
424
425 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
426 {
427         s8 buf[BRCMF_DCMD_SMLEN];
428         u32 len;
429         s32 err = 0;
430         __le32 val_le;
431
432         val_le = cpu_to_le32(val);
433         len = brcmu_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
434                             sizeof(buf));
435         BUG_ON(!len);
436
437         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
438         if (err)
439                 WL_ERR("error (%d)\n", err);
440
441         return err;
442 }
443
444 static s32
445 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
446 {
447         union {
448                 s8 buf[BRCMF_DCMD_SMLEN];
449                 __le32 val;
450         } var;
451         u32 len;
452         u32 data_null;
453         s32 err = 0;
454
455         len =
456             brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
457                         sizeof(var.buf));
458         BUG_ON(!len);
459         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
460         if (err)
461                 WL_ERR("error (%d)\n", err);
462
463         *retval = le32_to_cpu(var.val);
464
465         return err;
466 }
467
468 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
469 {
470         s32 err = 0;
471         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
472
473         if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
474                 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
475                 if (err) {
476                         WL_ERR("fail to set mpc\n");
477                         return;
478                 }
479                 WL_INFO("MPC : %d\n", mpc);
480         }
481 }
482
483 static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
484                           struct brcmf_ssid *ssid)
485 {
486         memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
487         params_le->bss_type = DOT11_BSSTYPE_ANY;
488         params_le->scan_type = 0;
489         params_le->channel_num = 0;
490         params_le->nprobes = cpu_to_le32(-1);
491         params_le->active_time = cpu_to_le32(-1);
492         params_le->passive_time = cpu_to_le32(-1);
493         params_le->home_time = cpu_to_le32(-1);
494         if (ssid && ssid->SSID_len)
495                 memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
496 }
497
498 static s32
499 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
500                     s32 paramlen, void *bufptr, s32 buflen)
501 {
502         s32 iolen;
503
504         iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
505         BUG_ON(!iolen);
506
507         return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
508 }
509
510 static s32
511 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
512                     s32 paramlen, void *bufptr, s32 buflen)
513 {
514         s32 iolen;
515
516         iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
517         BUG_ON(!iolen);
518
519         return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
520 }
521
522 static s32
523 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
524                 struct brcmf_ssid *ssid, u16 action)
525 {
526         s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
527                           offsetof(struct brcmf_iscan_params_le, params_le);
528         struct brcmf_iscan_params_le *params;
529         s32 err = 0;
530
531         if (ssid && ssid->SSID_len)
532                 params_size += sizeof(struct brcmf_ssid);
533         params = kzalloc(params_size, GFP_KERNEL);
534         if (!params)
535                 return -ENOMEM;
536         BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
537
538         wl_iscan_prep(&params->params_le, ssid);
539
540         params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
541         params->action = cpu_to_le16(action);
542         params->scan_duration = cpu_to_le16(0);
543
544         err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
545                                      iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
546         if (err) {
547                 if (err == -EBUSY)
548                         WL_INFO("system busy : iscan canceled\n");
549                 else
550                         WL_ERR("error (%d)\n", err);
551         }
552
553         kfree(params);
554         return err;
555 }
556
557 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
558 {
559         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
560         struct net_device *ndev = cfg_to_ndev(cfg_priv);
561         struct brcmf_ssid ssid;
562         __le32 passive_scan;
563         s32 err = 0;
564
565         /* Broadcast scan by default */
566         memset(&ssid, 0, sizeof(ssid));
567
568         iscan->state = WL_ISCAN_STATE_SCANING;
569
570         passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
571         err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
572                         &passive_scan, sizeof(passive_scan));
573         if (err) {
574                 WL_ERR("error (%d)\n", err);
575                 return err;
576         }
577         brcmf_set_mpc(ndev, 0);
578         cfg_priv->iscan_kickstart = true;
579         err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
580         if (err) {
581                 brcmf_set_mpc(ndev, 1);
582                 cfg_priv->iscan_kickstart = false;
583                 return err;
584         }
585         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
586         iscan->timer_on = 1;
587         return err;
588 }
589
590 static s32
591 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
592                    struct cfg80211_scan_request *request,
593                    struct cfg80211_ssid *this_ssid)
594 {
595         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
596         struct cfg80211_ssid *ssids;
597         struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
598         __le32 passive_scan;
599         bool iscan_req;
600         bool spec_scan;
601         s32 err = 0;
602         u32 SSID_len;
603
604         if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
605                 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
606                 return -EAGAIN;
607         }
608         if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
609                 WL_ERR("Scanning being aborted : status (%lu)\n",
610                        cfg_priv->status);
611                 return -EAGAIN;
612         }
613         if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
614                 WL_ERR("Connecting : status (%lu)\n",
615                        cfg_priv->status);
616                 return -EAGAIN;
617         }
618
619         iscan_req = false;
620         spec_scan = false;
621         if (request) {
622                 /* scan bss */
623                 ssids = request->ssids;
624                 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
625                         iscan_req = true;
626         } else {
627                 /* scan in ibss */
628                 /* we don't do iscan in ibss */
629                 ssids = this_ssid;
630         }
631
632         cfg_priv->scan_request = request;
633         set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
634         if (iscan_req) {
635                 err = brcmf_do_iscan(cfg_priv);
636                 if (!err)
637                         return err;
638                 else
639                         goto scan_out;
640         } else {
641                 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
642                        ssids->ssid, ssids->ssid_len);
643                 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
644                 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
645                 sr->ssid_le.SSID_len = cpu_to_le32(0);
646                 if (SSID_len) {
647                         memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
648                         sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
649                         spec_scan = true;
650                 } else {
651                         WL_SCAN("Broadcast scan\n");
652                 }
653
654                 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
655                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
656                                 &passive_scan, sizeof(passive_scan));
657                 if (err) {
658                         WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
659                         goto scan_out;
660                 }
661                 brcmf_set_mpc(ndev, 0);
662                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
663                                       sizeof(sr->ssid_le));
664                 if (err) {
665                         if (err == -EBUSY)
666                                 WL_INFO("system busy : scan for \"%s\" "
667                                         "canceled\n", sr->ssid_le.SSID);
668                         else
669                                 WL_ERR("WLC_SCAN error (%d)\n", err);
670
671                         brcmf_set_mpc(ndev, 1);
672                         goto scan_out;
673                 }
674         }
675
676         return 0;
677
678 scan_out:
679         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
680         cfg_priv->scan_request = NULL;
681         return err;
682 }
683
684 static s32
685 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
686                  struct cfg80211_scan_request *request)
687 {
688         s32 err = 0;
689
690         WL_TRACE("Enter\n");
691
692         if (!check_sys_up(wiphy))
693                 return -EIO;
694
695         err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
696         if (err)
697                 WL_ERR("scan error (%d)\n", err);
698
699         WL_TRACE("Exit\n");
700         return err;
701 }
702
703 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
704 {
705         s32 err = 0;
706
707         err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
708         if (err)
709                 WL_ERR("Error (%d)\n", err);
710
711         return err;
712 }
713
714 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
715 {
716         s32 err = 0;
717
718         err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
719         if (err)
720                 WL_ERR("Error (%d)\n", err);
721
722         return err;
723 }
724
725 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
726 {
727         s32 err = 0;
728         u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
729
730         err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
731         if (err) {
732                 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
733                 return err;
734         }
735         return err;
736 }
737
738 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
739 {
740         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
741         struct net_device *ndev = cfg_to_ndev(cfg_priv);
742         s32 err = 0;
743
744         WL_TRACE("Enter\n");
745         if (!check_sys_up(wiphy))
746                 return -EIO;
747
748         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
749             (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
750                 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
751                 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
752                 if (!err)
753                         goto done;
754         }
755         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
756             (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
757                 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
758                 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
759                 if (!err)
760                         goto done;
761         }
762         if (changed & WIPHY_PARAM_RETRY_LONG
763             && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
764                 cfg_priv->conf->retry_long = wiphy->retry_long;
765                 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
766                 if (!err)
767                         goto done;
768         }
769         if (changed & WIPHY_PARAM_RETRY_SHORT
770             && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
771                 cfg_priv->conf->retry_short = wiphy->retry_short;
772                 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
773                 if (!err)
774                         goto done;
775         }
776
777 done:
778         WL_TRACE("Exit\n");
779         return err;
780 }
781
782 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
783 {
784         switch (item) {
785         case WL_PROF_SEC:
786                 return &cfg_priv->profile->sec;
787         case WL_PROF_BSSID:
788                 return &cfg_priv->profile->bssid;
789         case WL_PROF_SSID:
790                 return &cfg_priv->profile->ssid;
791         }
792         WL_ERR("invalid item (%d)\n", item);
793         return NULL;
794 }
795
796 static s32
797 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
798                   const struct brcmf_event_msg *e, void *data, s32 item)
799 {
800         s32 err = 0;
801         struct brcmf_ssid *ssid;
802
803         switch (item) {
804         case WL_PROF_SSID:
805                 ssid = (struct brcmf_ssid *) data;
806                 memset(cfg_priv->profile->ssid.SSID, 0,
807                        sizeof(cfg_priv->profile->ssid.SSID));
808                 memcpy(cfg_priv->profile->ssid.SSID,
809                        ssid->SSID, ssid->SSID_len);
810                 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
811                 break;
812         case WL_PROF_BSSID:
813                 if (data)
814                         memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
815                 else
816                         memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
817                 break;
818         case WL_PROF_SEC:
819                 memcpy(&cfg_priv->profile->sec, data,
820                        sizeof(cfg_priv->profile->sec));
821                 break;
822         case WL_PROF_BEACONINT:
823                 cfg_priv->profile->beacon_interval = *(u16 *)data;
824                 break;
825         case WL_PROF_DTIMPERIOD:
826                 cfg_priv->profile->dtim_period = *(u8 *)data;
827                 break;
828         default:
829                 WL_ERR("unsupported item (%d)\n", item);
830                 err = -EOPNOTSUPP;
831                 break;
832         }
833
834         return err;
835 }
836
837 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
838 {
839         memset(prof, 0, sizeof(*prof));
840 }
841
842 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
843         size_t *join_params_size)
844 {
845         u16 chanspec = 0;
846
847         if (ch != 0) {
848                 if (ch <= CH_MAX_2G_CHANNEL)
849                         chanspec |= WL_CHANSPEC_BAND_2G;
850                 else
851                         chanspec |= WL_CHANSPEC_BAND_5G;
852
853                 chanspec |= WL_CHANSPEC_BW_20;
854                 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
855
856                 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
857                                      sizeof(u16);
858
859                 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
860                 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
861                 join_params->params_le.chanspec_num = cpu_to_le32(1);
862
863                 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
864                         "channel %d, chanspec %#X\n",
865                         chanspec, ch, chanspec);
866         }
867 }
868
869 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
870 {
871         struct net_device *ndev = NULL;
872         s32 err = 0;
873
874         WL_TRACE("Enter\n");
875
876         if (cfg_priv->link_up) {
877                 ndev = cfg_to_ndev(cfg_priv);
878                 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
879                 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
880                 if (err)
881                         WL_ERR("WLC_DISASSOC failed (%d)\n", err);
882                 cfg_priv->link_up = false;
883         }
884         WL_TRACE("Exit\n");
885 }
886
887 static s32
888 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
889                       struct cfg80211_ibss_params *params)
890 {
891         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
892         struct brcmf_join_params join_params;
893         size_t join_params_size = 0;
894         s32 err = 0;
895         s32 wsec = 0;
896         s32 bcnprd;
897         struct brcmf_ssid ssid;
898
899         WL_TRACE("Enter\n");
900         if (!check_sys_up(wiphy))
901                 return -EIO;
902
903         if (params->ssid)
904                 WL_CONN("SSID: %s\n", params->ssid);
905         else {
906                 WL_CONN("SSID: NULL, Not supported\n");
907                 return -EOPNOTSUPP;
908         }
909
910         set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
911
912         if (params->bssid)
913                 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
914                 params->bssid[0], params->bssid[1], params->bssid[2],
915                 params->bssid[3], params->bssid[4], params->bssid[5]);
916         else
917                 WL_CONN("No BSSID specified\n");
918
919         if (params->channel)
920                 WL_CONN("channel: %d\n", params->channel->center_freq);
921         else
922                 WL_CONN("no channel specified\n");
923
924         if (params->channel_fixed)
925                 WL_CONN("fixed channel required\n");
926         else
927                 WL_CONN("no fixed channel required\n");
928
929         if (params->ie && params->ie_len)
930                 WL_CONN("ie len: %d\n", params->ie_len);
931         else
932                 WL_CONN("no ie specified\n");
933
934         if (params->beacon_interval)
935                 WL_CONN("beacon interval: %d\n", params->beacon_interval);
936         else
937                 WL_CONN("no beacon interval specified\n");
938
939         if (params->basic_rates)
940                 WL_CONN("basic rates: %08X\n", params->basic_rates);
941         else
942                 WL_CONN("no basic rates specified\n");
943
944         if (params->privacy)
945                 WL_CONN("privacy required\n");
946         else
947                 WL_CONN("no privacy required\n");
948
949         /* Configure Privacy for starter */
950         if (params->privacy)
951                 wsec |= WEP_ENABLED;
952
953         err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
954         if (err) {
955                 WL_ERR("wsec failed (%d)\n", err);
956                 goto done;
957         }
958
959         /* Configure Beacon Interval for starter */
960         if (params->beacon_interval)
961                 bcnprd = params->beacon_interval;
962         else
963                 bcnprd = 100;
964
965         err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
966         if (err) {
967                 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
968                 goto done;
969         }
970
971         /* Configure required join parameter */
972         memset(&join_params, 0, sizeof(struct brcmf_join_params));
973
974         /* SSID */
975         ssid.SSID_len = min_t(u32, params->ssid_len, 32);
976         memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
977         memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
978         join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
979         join_params_size = sizeof(join_params.ssid_le);
980         brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
981
982         /* BSSID */
983         if (params->bssid) {
984                 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
985                 join_params_size = sizeof(join_params.ssid_le) +
986                                    BRCMF_ASSOC_PARAMS_FIXED_SIZE;
987         } else {
988                 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
989         }
990
991         brcmf_update_prof(cfg_priv, NULL,
992                           &join_params.params_le.bssid, WL_PROF_BSSID);
993
994         /* Channel */
995         if (params->channel) {
996                 u32 target_channel;
997
998                 cfg_priv->channel =
999                         ieee80211_frequency_to_channel(
1000                                 params->channel->center_freq);
1001                 if (params->channel_fixed) {
1002                         /* adding chanspec */
1003                         brcmf_ch_to_chanspec(cfg_priv->channel,
1004                                 &join_params, &join_params_size);
1005                 }
1006
1007                 /* set channel for starter */
1008                 target_channel = cfg_priv->channel;
1009                 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1010                                           &target_channel);
1011                 if (err) {
1012                         WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1013                         goto done;
1014                 }
1015         } else
1016                 cfg_priv->channel = 0;
1017
1018         cfg_priv->ibss_starter = false;
1019
1020
1021         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1022                            &join_params, join_params_size);
1023         if (err) {
1024                 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1025                 goto done;
1026         }
1027
1028 done:
1029         if (err)
1030                 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1031         WL_TRACE("Exit\n");
1032         return err;
1033 }
1034
1035 static s32
1036 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1037 {
1038         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1039         s32 err = 0;
1040
1041         WL_TRACE("Enter\n");
1042         if (!check_sys_up(wiphy))
1043                 return -EIO;
1044
1045         brcmf_link_down(cfg_priv);
1046
1047         WL_TRACE("Exit\n");
1048
1049         return err;
1050 }
1051
1052 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1053                                  struct cfg80211_connect_params *sme)
1054 {
1055         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1056         struct brcmf_cfg80211_security *sec;
1057         s32 val = 0;
1058         s32 err = 0;
1059
1060         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1061                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1062         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1063                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1064         else
1065                 val = WPA_AUTH_DISABLED;
1066         WL_CONN("setting wpa_auth to 0x%0x\n", val);
1067         err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1068         if (err) {
1069                 WL_ERR("set wpa_auth failed (%d)\n", err);
1070                 return err;
1071         }
1072         sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1073         sec->wpa_versions = sme->crypto.wpa_versions;
1074         return err;
1075 }
1076
1077 static s32 brcmf_set_auth_type(struct net_device *ndev,
1078                                struct cfg80211_connect_params *sme)
1079 {
1080         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1081         struct brcmf_cfg80211_security *sec;
1082         s32 val = 0;
1083         s32 err = 0;
1084
1085         switch (sme->auth_type) {
1086         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1087                 val = 0;
1088                 WL_CONN("open system\n");
1089                 break;
1090         case NL80211_AUTHTYPE_SHARED_KEY:
1091                 val = 1;
1092                 WL_CONN("shared key\n");
1093                 break;
1094         case NL80211_AUTHTYPE_AUTOMATIC:
1095                 val = 2;
1096                 WL_CONN("automatic\n");
1097                 break;
1098         case NL80211_AUTHTYPE_NETWORK_EAP:
1099                 WL_CONN("network eap\n");
1100         default:
1101                 val = 2;
1102                 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1103                 break;
1104         }
1105
1106         err = brcmf_dev_intvar_set(ndev, "auth", val);
1107         if (err) {
1108                 WL_ERR("set auth failed (%d)\n", err);
1109                 return err;
1110         }
1111         sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1112         sec->auth_type = sme->auth_type;
1113         return err;
1114 }
1115
1116 static s32
1117 brcmf_set_set_cipher(struct net_device *ndev,
1118                      struct cfg80211_connect_params *sme)
1119 {
1120         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1121         struct brcmf_cfg80211_security *sec;
1122         s32 pval = 0;
1123         s32 gval = 0;
1124         s32 err = 0;
1125
1126         if (sme->crypto.n_ciphers_pairwise) {
1127                 switch (sme->crypto.ciphers_pairwise[0]) {
1128                 case WLAN_CIPHER_SUITE_WEP40:
1129                 case WLAN_CIPHER_SUITE_WEP104:
1130                         pval = WEP_ENABLED;
1131                         break;
1132                 case WLAN_CIPHER_SUITE_TKIP:
1133                         pval = TKIP_ENABLED;
1134                         break;
1135                 case WLAN_CIPHER_SUITE_CCMP:
1136                         pval = AES_ENABLED;
1137                         break;
1138                 case WLAN_CIPHER_SUITE_AES_CMAC:
1139                         pval = AES_ENABLED;
1140                         break;
1141                 default:
1142                         WL_ERR("invalid cipher pairwise (%d)\n",
1143                                sme->crypto.ciphers_pairwise[0]);
1144                         return -EINVAL;
1145                 }
1146         }
1147         if (sme->crypto.cipher_group) {
1148                 switch (sme->crypto.cipher_group) {
1149                 case WLAN_CIPHER_SUITE_WEP40:
1150                 case WLAN_CIPHER_SUITE_WEP104:
1151                         gval = WEP_ENABLED;
1152                         break;
1153                 case WLAN_CIPHER_SUITE_TKIP:
1154                         gval = TKIP_ENABLED;
1155                         break;
1156                 case WLAN_CIPHER_SUITE_CCMP:
1157                         gval = AES_ENABLED;
1158                         break;
1159                 case WLAN_CIPHER_SUITE_AES_CMAC:
1160                         gval = AES_ENABLED;
1161                         break;
1162                 default:
1163                         WL_ERR("invalid cipher group (%d)\n",
1164                                sme->crypto.cipher_group);
1165                         return -EINVAL;
1166                 }
1167         }
1168
1169         WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1170         err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1171         if (err) {
1172                 WL_ERR("error (%d)\n", err);
1173                 return err;
1174         }
1175
1176         sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1177         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1178         sec->cipher_group = sme->crypto.cipher_group;
1179
1180         return err;
1181 }
1182
1183 static s32
1184 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1185 {
1186         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1187         struct brcmf_cfg80211_security *sec;
1188         s32 val = 0;
1189         s32 err = 0;
1190
1191         if (sme->crypto.n_akm_suites) {
1192                 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1193                 if (err) {
1194                         WL_ERR("could not get wpa_auth (%d)\n", err);
1195                         return err;
1196                 }
1197                 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1198                         switch (sme->crypto.akm_suites[0]) {
1199                         case WLAN_AKM_SUITE_8021X:
1200                                 val = WPA_AUTH_UNSPECIFIED;
1201                                 break;
1202                         case WLAN_AKM_SUITE_PSK:
1203                                 val = WPA_AUTH_PSK;
1204                                 break;
1205                         default:
1206                                 WL_ERR("invalid cipher group (%d)\n",
1207                                        sme->crypto.cipher_group);
1208                                 return -EINVAL;
1209                         }
1210                 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1211                         switch (sme->crypto.akm_suites[0]) {
1212                         case WLAN_AKM_SUITE_8021X:
1213                                 val = WPA2_AUTH_UNSPECIFIED;
1214                                 break;
1215                         case WLAN_AKM_SUITE_PSK:
1216                                 val = WPA2_AUTH_PSK;
1217                                 break;
1218                         default:
1219                                 WL_ERR("invalid cipher group (%d)\n",
1220                                        sme->crypto.cipher_group);
1221                                 return -EINVAL;
1222                         }
1223                 }
1224
1225                 WL_CONN("setting wpa_auth to %d\n", val);
1226                 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1227                 if (err) {
1228                         WL_ERR("could not set wpa_auth (%d)\n", err);
1229                         return err;
1230                 }
1231         }
1232         sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1233         sec->wpa_auth = sme->crypto.akm_suites[0];
1234
1235         return err;
1236 }
1237
1238 static s32
1239 brcmf_set_wep_sharedkey(struct net_device *ndev,
1240                      struct cfg80211_connect_params *sme)
1241 {
1242         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1243         struct brcmf_cfg80211_security *sec;
1244         struct brcmf_wsec_key key;
1245         s32 val;
1246         s32 err = 0;
1247
1248         WL_CONN("key len (%d)\n", sme->key_len);
1249
1250         if (sme->key_len == 0)
1251                 return 0;
1252
1253         sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1254         WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1255                 sec->wpa_versions, sec->cipher_pairwise);
1256
1257         if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1258                 return 0;
1259
1260         if (sec->cipher_pairwise &
1261             (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1262                 memset(&key, 0, sizeof(key));
1263                 key.len = (u32) sme->key_len;
1264                 key.index = (u32) sme->key_idx;
1265                 if (key.len > sizeof(key.data)) {
1266                         WL_ERR("Too long key length (%u)\n", key.len);
1267                         return -EINVAL;
1268                 }
1269                 memcpy(key.data, sme->key, key.len);
1270                 key.flags = BRCMF_PRIMARY_KEY;
1271                 switch (sec->cipher_pairwise) {
1272                 case WLAN_CIPHER_SUITE_WEP40:
1273                         key.algo = CRYPTO_ALGO_WEP1;
1274                         break;
1275                 case WLAN_CIPHER_SUITE_WEP104:
1276                         key.algo = CRYPTO_ALGO_WEP128;
1277                         break;
1278                 default:
1279                         WL_ERR("Invalid algorithm (%d)\n",
1280                                sme->crypto.ciphers_pairwise[0]);
1281                         return -EINVAL;
1282                 }
1283                 /* Set the new key/index */
1284                 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1285                         key.len, key.index, key.algo);
1286                 WL_CONN("key \"%s\"\n", key.data);
1287                 err = send_key_to_dongle(ndev, &key);
1288                 if (err)
1289                         return err;
1290
1291                 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1292                         WL_CONN("set auth_type to shared key\n");
1293                         val = 1;        /* shared key */
1294                         err = brcmf_dev_intvar_set(ndev, "auth", val);
1295                         if (err) {
1296                                 WL_ERR("set auth failed (%d)\n", err);
1297                                 return err;
1298                         }
1299                 }
1300         }
1301         return err;
1302 }
1303
1304 static s32
1305 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1306                     struct cfg80211_connect_params *sme)
1307 {
1308         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1309         struct ieee80211_channel *chan = sme->channel;
1310         struct brcmf_join_params join_params;
1311         size_t join_params_size;
1312         struct brcmf_ssid ssid;
1313
1314         s32 err = 0;
1315
1316         WL_TRACE("Enter\n");
1317         if (!check_sys_up(wiphy))
1318                 return -EIO;
1319
1320         if (!sme->ssid) {
1321                 WL_ERR("Invalid ssid\n");
1322                 return -EOPNOTSUPP;
1323         }
1324
1325         set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1326
1327         if (chan) {
1328                 cfg_priv->channel =
1329                         ieee80211_frequency_to_channel(chan->center_freq);
1330                 WL_CONN("channel (%d), center_req (%d)\n",
1331                                 cfg_priv->channel, chan->center_freq);
1332         } else
1333                 cfg_priv->channel = 0;
1334
1335         WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1336
1337         err = brcmf_set_wpa_version(ndev, sme);
1338         if (err) {
1339                 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1340                 goto done;
1341         }
1342
1343         err = brcmf_set_auth_type(ndev, sme);
1344         if (err) {
1345                 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1346                 goto done;
1347         }
1348
1349         err = brcmf_set_set_cipher(ndev, sme);
1350         if (err) {
1351                 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1352                 goto done;
1353         }
1354
1355         err = brcmf_set_key_mgmt(ndev, sme);
1356         if (err) {
1357                 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1358                 goto done;
1359         }
1360
1361         err = brcmf_set_wep_sharedkey(ndev, sme);
1362         if (err) {
1363                 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1364                 goto done;
1365         }
1366
1367         memset(&join_params, 0, sizeof(join_params));
1368         join_params_size = sizeof(join_params.ssid_le);
1369
1370         ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len);
1371         memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1372         memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1373         join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1374         brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1375
1376         memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1377
1378         if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1379                 WL_CONN("ssid \"%s\", len (%d)\n",
1380                        ssid.SSID, ssid.SSID_len);
1381
1382         brcmf_ch_to_chanspec(cfg_priv->channel,
1383                              &join_params, &join_params_size);
1384         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1385                            &join_params, join_params_size);
1386         if (err)
1387                 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1388
1389 done:
1390         if (err)
1391                 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1392         WL_TRACE("Exit\n");
1393         return err;
1394 }
1395
1396 static s32
1397 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1398                        u16 reason_code)
1399 {
1400         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1401         struct brcmf_scb_val_le scbval;
1402         s32 err = 0;
1403
1404         WL_TRACE("Enter. Reason code = %d\n", reason_code);
1405         if (!check_sys_up(wiphy))
1406                 return -EIO;
1407
1408         clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1409
1410         memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1411         scbval.val = cpu_to_le32(reason_code);
1412         err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1413                               sizeof(struct brcmf_scb_val_le));
1414         if (err)
1415                 WL_ERR("error (%d)\n", err);
1416
1417         cfg_priv->link_up = false;
1418
1419         WL_TRACE("Exit\n");
1420         return err;
1421 }
1422
1423 static s32
1424 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1425                          enum nl80211_tx_power_setting type, s32 dbm)
1426 {
1427
1428         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1429         struct net_device *ndev = cfg_to_ndev(cfg_priv);
1430         u16 txpwrmw;
1431         s32 err = 0;
1432         s32 disable = 0;
1433
1434         WL_TRACE("Enter\n");
1435         if (!check_sys_up(wiphy))
1436                 return -EIO;
1437
1438         switch (type) {
1439         case NL80211_TX_POWER_AUTOMATIC:
1440                 break;
1441         case NL80211_TX_POWER_LIMITED:
1442                 if (dbm < 0) {
1443                         WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1444                         err = -EINVAL;
1445                         goto done;
1446                 }
1447                 break;
1448         case NL80211_TX_POWER_FIXED:
1449                 if (dbm < 0) {
1450                         WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1451                         err = -EINVAL;
1452                         goto done;
1453                 }
1454                 break;
1455         }
1456         /* Make sure radio is off or on as far as software is concerned */
1457         disable = WL_RADIO_SW_DISABLE << 16;
1458         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1459         if (err)
1460                 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1461
1462         if (dbm > 0xffff)
1463                 txpwrmw = 0xffff;
1464         else
1465                 txpwrmw = (u16) dbm;
1466         err = brcmf_dev_intvar_set(ndev, "qtxpower",
1467                         (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1468         if (err)
1469                 WL_ERR("qtxpower error (%d)\n", err);
1470         cfg_priv->conf->tx_power = dbm;
1471
1472 done:
1473         WL_TRACE("Exit\n");
1474         return err;
1475 }
1476
1477 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1478 {
1479         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1480         struct net_device *ndev = cfg_to_ndev(cfg_priv);
1481         s32 txpwrdbm;
1482         u8 result;
1483         s32 err = 0;
1484
1485         WL_TRACE("Enter\n");
1486         if (!check_sys_up(wiphy))
1487                 return -EIO;
1488
1489         err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1490         if (err) {
1491                 WL_ERR("error (%d)\n", err);
1492                 goto done;
1493         }
1494
1495         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1496         *dbm = (s32) brcmf_qdbm_to_mw(result);
1497
1498 done:
1499         WL_TRACE("Exit\n");
1500         return err;
1501 }
1502
1503 static s32
1504 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1505                                u8 key_idx, bool unicast, bool multicast)
1506 {
1507         u32 index;
1508         u32 wsec;
1509         s32 err = 0;
1510
1511         WL_TRACE("Enter\n");
1512         WL_CONN("key index (%d)\n", key_idx);
1513         if (!check_sys_up(wiphy))
1514                 return -EIO;
1515
1516         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1517         if (err) {
1518                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1519                 goto done;
1520         }
1521
1522         if (wsec & WEP_ENABLED) {
1523                 /* Just select a new current key */
1524                 index = key_idx;
1525                 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1526                                           &index);
1527                 if (err)
1528                         WL_ERR("error (%d)\n", err);
1529         }
1530 done:
1531         WL_TRACE("Exit\n");
1532         return err;
1533 }
1534
1535 static s32
1536 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1537               u8 key_idx, const u8 *mac_addr, struct key_params *params)
1538 {
1539         struct brcmf_wsec_key key;
1540         struct brcmf_wsec_key_le key_le;
1541         s32 err = 0;
1542
1543         memset(&key, 0, sizeof(key));
1544         key.index = (u32) key_idx;
1545         /* Instead of bcast for ea address for default wep keys,
1546                  driver needs it to be Null */
1547         if (!is_multicast_ether_addr(mac_addr))
1548                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1549         key.len = (u32) params->key_len;
1550         /* check for key index change */
1551         if (key.len == 0) {
1552                 /* key delete */
1553                 err = send_key_to_dongle(ndev, &key);
1554                 if (err)
1555                         return err;
1556         } else {
1557                 if (key.len > sizeof(key.data)) {
1558                         WL_ERR("Invalid key length (%d)\n", key.len);
1559                         return -EINVAL;
1560                 }
1561
1562                 WL_CONN("Setting the key index %d\n", key.index);
1563                 memcpy(key.data, params->key, key.len);
1564
1565                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1566                         u8 keybuf[8];
1567                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1568                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1569                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1570                 }
1571
1572                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1573                 if (params->seq && params->seq_len == 6) {
1574                         /* rx iv */
1575                         u8 *ivptr;
1576                         ivptr = (u8 *) params->seq;
1577                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1578                             (ivptr[3] << 8) | ivptr[2];
1579                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1580                         key.iv_initialized = true;
1581                 }
1582
1583                 switch (params->cipher) {
1584                 case WLAN_CIPHER_SUITE_WEP40:
1585                         key.algo = CRYPTO_ALGO_WEP1;
1586                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1587                         break;
1588                 case WLAN_CIPHER_SUITE_WEP104:
1589                         key.algo = CRYPTO_ALGO_WEP128;
1590                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1591                         break;
1592                 case WLAN_CIPHER_SUITE_TKIP:
1593                         key.algo = CRYPTO_ALGO_TKIP;
1594                         WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1595                         break;
1596                 case WLAN_CIPHER_SUITE_AES_CMAC:
1597                         key.algo = CRYPTO_ALGO_AES_CCM;
1598                         WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1599                         break;
1600                 case WLAN_CIPHER_SUITE_CCMP:
1601                         key.algo = CRYPTO_ALGO_AES_CCM;
1602                         WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1603                         break;
1604                 default:
1605                         WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1606                         return -EINVAL;
1607                 }
1608                 convert_key_from_CPU(&key, &key_le);
1609
1610                 brcmf_netdev_wait_pend8021x(ndev);
1611                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1612                                       sizeof(key_le));
1613                 if (err) {
1614                         WL_ERR("WLC_SET_KEY error (%d)\n", err);
1615                         return err;
1616                 }
1617         }
1618         return err;
1619 }
1620
1621 static s32
1622 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1623                     u8 key_idx, bool pairwise, const u8 *mac_addr,
1624                     struct key_params *params)
1625 {
1626         struct brcmf_wsec_key key;
1627         s32 val;
1628         s32 wsec;
1629         s32 err = 0;
1630         u8 keybuf[8];
1631
1632         WL_TRACE("Enter\n");
1633         WL_CONN("key index (%d)\n", key_idx);
1634         if (!check_sys_up(wiphy))
1635                 return -EIO;
1636
1637         if (mac_addr) {
1638                 WL_TRACE("Exit");
1639                 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1640         }
1641         memset(&key, 0, sizeof(key));
1642
1643         key.len = (u32) params->key_len;
1644         key.index = (u32) key_idx;
1645
1646         if (key.len > sizeof(key.data)) {
1647                 WL_ERR("Too long key length (%u)\n", key.len);
1648                 err = -EINVAL;
1649                 goto done;
1650         }
1651         memcpy(key.data, params->key, key.len);
1652
1653         key.flags = BRCMF_PRIMARY_KEY;
1654         switch (params->cipher) {
1655         case WLAN_CIPHER_SUITE_WEP40:
1656                 key.algo = CRYPTO_ALGO_WEP1;
1657                 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1658                 break;
1659         case WLAN_CIPHER_SUITE_WEP104:
1660                 key.algo = CRYPTO_ALGO_WEP128;
1661                 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1662                 break;
1663         case WLAN_CIPHER_SUITE_TKIP:
1664                 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1665                 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1666                 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1667                 key.algo = CRYPTO_ALGO_TKIP;
1668                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1669                 break;
1670         case WLAN_CIPHER_SUITE_AES_CMAC:
1671                 key.algo = CRYPTO_ALGO_AES_CCM;
1672                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1673                 break;
1674         case WLAN_CIPHER_SUITE_CCMP:
1675                 key.algo = CRYPTO_ALGO_AES_CCM;
1676                 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1677                 break;
1678         default:
1679                 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1680                 err = -EINVAL;
1681                 goto done;
1682         }
1683
1684         err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1685         if (err)
1686                 goto done;
1687
1688         val = WEP_ENABLED;
1689         err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1690         if (err) {
1691                 WL_ERR("get wsec error (%d)\n", err);
1692                 goto done;
1693         }
1694         wsec &= ~(WEP_ENABLED);
1695         wsec |= val;
1696         err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1697         if (err) {
1698                 WL_ERR("set wsec error (%d)\n", err);
1699                 goto done;
1700         }
1701
1702         val = 1;                /* assume shared key. otherwise 0 */
1703         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1704         if (err)
1705                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1706 done:
1707         WL_TRACE("Exit\n");
1708         return err;
1709 }
1710
1711 static s32
1712 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1713                     u8 key_idx, bool pairwise, const u8 *mac_addr)
1714 {
1715         struct brcmf_wsec_key key;
1716         s32 err = 0;
1717         s32 val;
1718         s32 wsec;
1719
1720         WL_TRACE("Enter\n");
1721         if (!check_sys_up(wiphy))
1722                 return -EIO;
1723
1724         memset(&key, 0, sizeof(key));
1725
1726         key.index = (u32) key_idx;
1727         key.flags = BRCMF_PRIMARY_KEY;
1728         key.algo = CRYPTO_ALGO_OFF;
1729
1730         WL_CONN("key index (%d)\n", key_idx);
1731
1732         /* Set the new key/index */
1733         err = send_key_to_dongle(ndev, &key);
1734         if (err) {
1735                 if (err == -EINVAL) {
1736                         if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1737                                 /* we ignore this key index in this case */
1738                                 WL_ERR("invalid key index (%d)\n", key_idx);
1739                 }
1740                 /* Ignore this error, may happen during DISASSOC */
1741                 err = -EAGAIN;
1742                 goto done;
1743         }
1744
1745         val = 0;
1746         err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1747         if (err) {
1748                 WL_ERR("get wsec error (%d)\n", err);
1749                 /* Ignore this error, may happen during DISASSOC */
1750                 err = -EAGAIN;
1751                 goto done;
1752         }
1753         wsec &= ~(WEP_ENABLED);
1754         wsec |= val;
1755         err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1756         if (err) {
1757                 WL_ERR("set wsec error (%d)\n", err);
1758                 /* Ignore this error, may happen during DISASSOC */
1759                 err = -EAGAIN;
1760                 goto done;
1761         }
1762
1763         val = 0;                /* assume open key. otherwise 1 */
1764         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1765         if (err) {
1766                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1767                 /* Ignore this error, may happen during DISASSOC */
1768                 err = -EAGAIN;
1769         }
1770 done:
1771         WL_TRACE("Exit\n");
1772         return err;
1773 }
1774
1775 static s32
1776 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1777                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1778                     void (*callback) (void *cookie, struct key_params * params))
1779 {
1780         struct key_params params;
1781         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1782         struct brcmf_cfg80211_security *sec;
1783         s32 wsec;
1784         s32 err = 0;
1785
1786         WL_TRACE("Enter\n");
1787         WL_CONN("key index (%d)\n", key_idx);
1788         if (!check_sys_up(wiphy))
1789                 return -EIO;
1790
1791         memset(&params, 0, sizeof(params));
1792
1793         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1794         if (err) {
1795                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1796                 /* Ignore this error, may happen during DISASSOC */
1797                 err = -EAGAIN;
1798                 goto done;
1799         }
1800         switch (wsec) {
1801         case WEP_ENABLED:
1802                 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1803                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1804                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
1805                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1806                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1807                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
1808                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1809                 }
1810                 break;
1811         case TKIP_ENABLED:
1812                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1813                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1814                 break;
1815         case AES_ENABLED:
1816                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1817                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1818                 break;
1819         default:
1820                 WL_ERR("Invalid algo (0x%x)\n", wsec);
1821                 err = -EINVAL;
1822                 goto done;
1823         }
1824         callback(cookie, &params);
1825
1826 done:
1827         WL_TRACE("Exit\n");
1828         return err;
1829 }
1830
1831 static s32
1832 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1833                                     struct net_device *ndev, u8 key_idx)
1834 {
1835         WL_INFO("Not supported\n");
1836
1837         return -EOPNOTSUPP;
1838 }
1839
1840 static s32
1841 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1842                         u8 *mac, struct station_info *sinfo)
1843 {
1844         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1845         struct brcmf_scb_val_le scb_val;
1846         int rssi;
1847         s32 rate;
1848         s32 err = 0;
1849         u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1850
1851         WL_TRACE("Enter\n");
1852         if (!check_sys_up(wiphy))
1853                 return -EIO;
1854
1855         if (memcmp(mac, bssid, ETH_ALEN)) {
1856                 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1857                         "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1858                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1859                         bssid[0], bssid[1], bssid[2], bssid[3],
1860                         bssid[4], bssid[5]);
1861                 err = -ENOENT;
1862                 goto done;
1863         }
1864
1865         /* Report the current tx rate */
1866         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1867         if (err) {
1868                 WL_ERR("Could not get rate (%d)\n", err);
1869         } else {
1870                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1871                 sinfo->txrate.legacy = rate * 5;
1872                 WL_CONN("Rate %d Mbps\n", rate / 2);
1873         }
1874
1875         if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1876                 scb_val.val = cpu_to_le32(0);
1877                 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1878                                       sizeof(struct brcmf_scb_val_le));
1879                 if (err)
1880                         WL_ERR("Could not get rssi (%d)\n", err);
1881
1882                 rssi = le32_to_cpu(scb_val.val);
1883                 sinfo->filled |= STATION_INFO_SIGNAL;
1884                 sinfo->signal = rssi;
1885                 WL_CONN("RSSI %d dBm\n", rssi);
1886         }
1887
1888 done:
1889         WL_TRACE("Exit\n");
1890         return err;
1891 }
1892
1893 static s32
1894 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1895                            bool enabled, s32 timeout)
1896 {
1897         s32 pm;
1898         s32 err = 0;
1899         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1900
1901         WL_TRACE("Enter\n");
1902
1903         /*
1904          * Powersave enable/disable request is coming from the
1905          * cfg80211 even before the interface is up. In that
1906          * scenario, driver will be storing the power save
1907          * preference in cfg_priv struct to apply this to
1908          * FW later while initializing the dongle
1909          */
1910         cfg_priv->pwr_save = enabled;
1911         if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1912
1913                 WL_INFO("Device is not ready,"
1914                         "storing the value in cfg_priv struct\n");
1915                 goto done;
1916         }
1917
1918         pm = enabled ? PM_FAST : PM_OFF;
1919         WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1920
1921         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1922         if (err) {
1923                 if (err == -ENODEV)
1924                         WL_ERR("net_device is not ready yet\n");
1925                 else
1926                         WL_ERR("error (%d)\n", err);
1927         }
1928 done:
1929         WL_TRACE("Exit\n");
1930         return err;
1931 }
1932
1933 static s32
1934 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1935                              const u8 *addr,
1936                              const struct cfg80211_bitrate_mask *mask)
1937 {
1938         struct brcm_rateset_le rateset_le;
1939         s32 rate;
1940         s32 val;
1941         s32 err_bg;
1942         s32 err_a;
1943         u32 legacy;
1944         s32 err = 0;
1945
1946         WL_TRACE("Enter\n");
1947         if (!check_sys_up(wiphy))
1948                 return -EIO;
1949
1950         /* addr param is always NULL. ignore it */
1951         /* Get current rateset */
1952         err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1953                               sizeof(rateset_le));
1954         if (err) {
1955                 WL_ERR("could not get current rateset (%d)\n", err);
1956                 goto done;
1957         }
1958
1959         legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1960         if (!legacy)
1961                 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1962                              0xFFFF);
1963
1964         val = wl_g_rates[legacy - 1].bitrate * 100000;
1965
1966         if (val < le32_to_cpu(rateset_le.count))
1967                 /* Select rate by rateset index */
1968                 rate = rateset_le.rates[val] & 0x7f;
1969         else
1970                 /* Specified rate in bps */
1971                 rate = val / 500000;
1972
1973         WL_CONN("rate %d mbps\n", rate / 2);
1974
1975         /*
1976          *
1977          *      Set rate override,
1978          *      Since the is a/b/g-blind, both a/bg_rate are enforced.
1979          */
1980         err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1981         err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1982         if (err_bg && err_a) {
1983                 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1984                 err = err_bg | err_a;
1985         }
1986
1987 done:
1988         WL_TRACE("Exit\n");
1989         return err;
1990 }
1991
1992 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1993                                    struct brcmf_bss_info *bi)
1994 {
1995         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
1996         struct ieee80211_channel *notify_channel;
1997         struct cfg80211_bss *bss;
1998         struct ieee80211_supported_band *band;
1999         s32 err = 0;
2000         u16 channel;
2001         u32 freq;
2002         u64 notify_timestamp;
2003         u16 notify_capability;
2004         u16 notify_interval;
2005         u8 *notify_ie;
2006         size_t notify_ielen;
2007         s32 notify_signal;
2008
2009         if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2010                 WL_ERR("Bss info is larger than buffer. Discarding\n");
2011                 return 0;
2012         }
2013
2014         channel = bi->ctl_ch ? bi->ctl_ch :
2015                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2016
2017         if (channel <= CH_MAX_2G_CHANNEL)
2018                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2019         else
2020                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2021
2022         freq = ieee80211_channel_to_frequency(channel, band->band);
2023         notify_channel = ieee80211_get_channel(wiphy, freq);
2024
2025         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2026         notify_capability = le16_to_cpu(bi->capability);
2027         notify_interval = le16_to_cpu(bi->beacon_period);
2028         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2029         notify_ielen = le32_to_cpu(bi->ie_length);
2030         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2031
2032         WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2033                         bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2034                         bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2035         WL_CONN("Channel: %d(%d)\n", channel, freq);
2036         WL_CONN("Capability: %X\n", notify_capability);
2037         WL_CONN("Beacon interval: %d\n", notify_interval);
2038         WL_CONN("Signal: %d\n", notify_signal);
2039         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2040
2041         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2042                 notify_timestamp, notify_capability, notify_interval, notify_ie,
2043                 notify_ielen, notify_signal, GFP_KERNEL);
2044
2045         if (!bss) {
2046                 WL_ERR("cfg80211_inform_bss_frame error\n");
2047                 return -EINVAL;
2048         }
2049
2050         return err;
2051 }
2052
2053 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2054 {
2055         struct brcmf_scan_results *bss_list;
2056         struct brcmf_bss_info *bi = NULL;       /* must be initialized */
2057         s32 err = 0;
2058         int i;
2059
2060         bss_list = cfg_priv->bss_list;
2061         if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2062                 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2063                        bss_list->version);
2064                 return -EOPNOTSUPP;
2065         }
2066         WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2067         for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2068                 bi = next_bss(bss_list, bi);
2069                 err = brcmf_inform_single_bss(cfg_priv, bi);
2070                 if (err)
2071                         break;
2072         }
2073         return err;
2074 }
2075
2076 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2077                           struct net_device *ndev, const u8 *bssid)
2078 {
2079         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2080         struct ieee80211_channel *notify_channel;
2081         struct brcmf_bss_info *bi = NULL;
2082         struct ieee80211_supported_band *band;
2083         u8 *buf = NULL;
2084         s32 err = 0;
2085         u16 channel;
2086         u32 freq;
2087         u64 notify_timestamp;
2088         u16 notify_capability;
2089         u16 notify_interval;
2090         u8 *notify_ie;
2091         size_t notify_ielen;
2092         s32 notify_signal;
2093
2094         WL_TRACE("Enter\n");
2095
2096         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2097         if (buf == NULL) {
2098                 err = -ENOMEM;
2099                 goto CleanUp;
2100         }
2101
2102         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2103
2104         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2105         if (err) {
2106                 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2107                 goto CleanUp;
2108         }
2109
2110         bi = (struct brcmf_bss_info *)(buf + 4);
2111
2112         channel = bi->ctl_ch ? bi->ctl_ch :
2113                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2114
2115         if (channel <= CH_MAX_2G_CHANNEL)
2116                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2117         else
2118                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2119
2120         freq = ieee80211_channel_to_frequency(channel, band->band);
2121         notify_channel = ieee80211_get_channel(wiphy, freq);
2122
2123         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2124         notify_capability = le16_to_cpu(bi->capability);
2125         notify_interval = le16_to_cpu(bi->beacon_period);
2126         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2127         notify_ielen = le32_to_cpu(bi->ie_length);
2128         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2129
2130         WL_CONN("channel: %d(%d)\n", channel, freq);
2131         WL_CONN("capability: %X\n", notify_capability);
2132         WL_CONN("beacon interval: %d\n", notify_interval);
2133         WL_CONN("signal: %d\n", notify_signal);
2134         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2135
2136         cfg80211_inform_bss(wiphy, notify_channel, bssid,
2137                 notify_timestamp, notify_capability, notify_interval,
2138                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2139
2140 CleanUp:
2141
2142         kfree(buf);
2143
2144         WL_TRACE("Exit\n");
2145
2146         return err;
2147 }
2148
2149 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2150 {
2151         return cfg_priv->conf->mode == WL_MODE_IBSS;
2152 }
2153
2154 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2155 {
2156         struct brcmf_bss_info *bi;
2157         struct brcmf_ssid *ssid;
2158         struct brcmu_tlv *tim;
2159         u16 beacon_interval;
2160         u8 dtim_period;
2161         size_t ie_len;
2162         u8 *ie;
2163         s32 err = 0;
2164
2165         WL_TRACE("Enter\n");
2166         if (brcmf_is_ibssmode(cfg_priv))
2167                 return err;
2168
2169         ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2170
2171         *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2172         err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2173                         cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2174         if (err) {
2175                 WL_ERR("Could not get bss info %d\n", err);
2176                 goto update_bss_info_out;
2177         }
2178
2179         bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2180         err = brcmf_inform_single_bss(cfg_priv, bi);
2181         if (err)
2182                 goto update_bss_info_out;
2183
2184         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2185         ie_len = le32_to_cpu(bi->ie_length);
2186         beacon_interval = le16_to_cpu(bi->beacon_period);
2187
2188         tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2189         if (tim)
2190                 dtim_period = tim->data[1];
2191         else {
2192                 /*
2193                 * active scan was done so we could not get dtim
2194                 * information out of probe response.
2195                 * so we speficially query dtim information to dongle.
2196                 */
2197                 u32 var;
2198                 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2199                                            "dtim_assoc", &var);
2200                 if (err) {
2201                         WL_ERR("wl dtim_assoc failed (%d)\n", err);
2202                         goto update_bss_info_out;
2203                 }
2204                 dtim_period = (u8)var;
2205         }
2206
2207         brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2208         brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2209
2210 update_bss_info_out:
2211         WL_TRACE("Exit");
2212         return err;
2213 }
2214
2215 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2216 {
2217         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2218         struct brcmf_ssid ssid;
2219
2220         if (cfg_priv->iscan_on) {
2221                 iscan->state = WL_ISCAN_STATE_IDLE;
2222
2223                 if (iscan->timer_on) {
2224                         del_timer_sync(&iscan->timer);
2225                         iscan->timer_on = 0;
2226                 }
2227
2228                 cancel_work_sync(&iscan->work);
2229
2230                 /* Abort iscan running in FW */
2231                 memset(&ssid, 0, sizeof(ssid));
2232                 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2233         }
2234 }
2235
2236 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2237                                         bool aborted)
2238 {
2239         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2240         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2241
2242         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2243                 WL_ERR("Scan complete while device not scanning\n");
2244                 return;
2245         }
2246         if (cfg_priv->scan_request) {
2247                 WL_SCAN("ISCAN Completed scan: %s\n",
2248                                 aborted ? "Aborted" : "Done");
2249                 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2250                 brcmf_set_mpc(ndev, 1);
2251                 cfg_priv->scan_request = NULL;
2252         }
2253         cfg_priv->iscan_kickstart = false;
2254 }
2255
2256 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2257 {
2258         if (iscan->state != WL_ISCAN_STATE_IDLE) {
2259                 WL_SCAN("wake up iscan\n");
2260                 schedule_work(&iscan->work);
2261                 return 0;
2262         }
2263
2264         return -EIO;
2265 }
2266
2267 static s32
2268 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2269                      struct brcmf_scan_results **bss_list)
2270 {
2271         struct brcmf_iscan_results list;
2272         struct brcmf_scan_results *results;
2273         struct brcmf_scan_results_le *results_le;
2274         struct brcmf_iscan_results *list_buf;
2275         s32 err = 0;
2276
2277         memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2278         list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2279         results = &list_buf->results;
2280         results_le = &list_buf->results_le;
2281         results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2282         results->version = 0;
2283         results->count = 0;
2284
2285         memset(&list, 0, sizeof(list));
2286         list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2287         err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2288                                      BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2289                                      iscan->scan_buf, WL_ISCAN_BUF_MAX);
2290         if (err) {
2291                 WL_ERR("error (%d)\n", err);
2292                 return err;
2293         }
2294         results->buflen = le32_to_cpu(results_le->buflen);
2295         results->version = le32_to_cpu(results_le->version);
2296         results->count = le32_to_cpu(results_le->count);
2297         WL_SCAN("results->count = %d\n", results_le->count);
2298         WL_SCAN("results->buflen = %d\n", results_le->buflen);
2299         *status = le32_to_cpu(list_buf->status_le);
2300         WL_SCAN("status = %d\n", *status);
2301         *bss_list = results;
2302
2303         return err;
2304 }
2305
2306 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2307 {
2308         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2309         s32 err = 0;
2310
2311         iscan->state = WL_ISCAN_STATE_IDLE;
2312         brcmf_inform_bss(cfg_priv);
2313         brcmf_notify_iscan_complete(iscan, false);
2314
2315         return err;
2316 }
2317
2318 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2319 {
2320         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2321         s32 err = 0;
2322
2323         /* Reschedule the timer */
2324         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2325         iscan->timer_on = 1;
2326
2327         return err;
2328 }
2329
2330 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2331 {
2332         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2333         s32 err = 0;
2334
2335         brcmf_inform_bss(cfg_priv);
2336         brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2337         /* Reschedule the timer */
2338         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2339         iscan->timer_on = 1;
2340
2341         return err;
2342 }
2343
2344 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2345 {
2346         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2347         s32 err = 0;
2348
2349         iscan->state = WL_ISCAN_STATE_IDLE;
2350         brcmf_notify_iscan_complete(iscan, true);
2351
2352         return err;
2353 }
2354
2355 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2356 {
2357         struct brcmf_cfg80211_iscan_ctrl *iscan =
2358                         container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2359                                      work);
2360         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2361         struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2362         u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2363
2364         if (iscan->timer_on) {
2365                 del_timer_sync(&iscan->timer);
2366                 iscan->timer_on = 0;
2367         }
2368
2369         if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2370                 status = BRCMF_SCAN_RESULTS_ABORTED;
2371                 WL_ERR("Abort iscan\n");
2372         }
2373
2374         el->handler[status](cfg_priv);
2375 }
2376
2377 static void brcmf_iscan_timer(unsigned long data)
2378 {
2379         struct brcmf_cfg80211_iscan_ctrl *iscan =
2380                         (struct brcmf_cfg80211_iscan_ctrl *)data;
2381
2382         if (iscan) {
2383                 iscan->timer_on = 0;
2384                 WL_SCAN("timer expired\n");
2385                 brcmf_wakeup_iscan(iscan);
2386         }
2387 }
2388
2389 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2390 {
2391         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2392
2393         if (cfg_priv->iscan_on) {
2394                 iscan->state = WL_ISCAN_STATE_IDLE;
2395                 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2396         }
2397
2398         return 0;
2399 }
2400
2401 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2402 {
2403         memset(el, 0, sizeof(*el));
2404         el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2405         el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2406         el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2407         el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2408         el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2409 }
2410
2411 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2412 {
2413         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2414         int err = 0;
2415
2416         if (cfg_priv->iscan_on) {
2417                 iscan->ndev = cfg_to_ndev(cfg_priv);
2418                 brcmf_init_iscan_eloop(&iscan->el);
2419                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2420                 init_timer(&iscan->timer);
2421                 iscan->timer.data = (unsigned long) iscan;
2422                 iscan->timer.function = brcmf_iscan_timer;
2423                 err = brcmf_invoke_iscan(cfg_priv);
2424                 if (!err)
2425                         iscan->data = cfg_priv;
2426         }
2427
2428         return err;
2429 }
2430
2431 static void brcmf_delay(u32 ms)
2432 {
2433         if (ms < 1000 / HZ) {
2434                 cond_resched();
2435                 mdelay(ms);
2436         } else {
2437                 msleep(ms);
2438         }
2439 }
2440
2441 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2442 {
2443         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2444
2445         /*
2446          * Check for WL_STATUS_READY before any function call which
2447          * could result is bus access. Don't block the resume for
2448          * any driver error conditions
2449          */
2450         WL_TRACE("Enter\n");
2451
2452         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2453                 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2454
2455         WL_TRACE("Exit\n");
2456         return 0;
2457 }
2458
2459 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2460                                   struct cfg80211_wowlan *wow)
2461 {
2462         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2463         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2464
2465         WL_TRACE("Enter\n");
2466
2467         /*
2468          * Check for WL_STATUS_READY before any function call which
2469          * could result is bus access. Don't block the suspend for
2470          * any driver error conditions
2471          */
2472
2473         /*
2474          * While going to suspend if associated with AP disassociate
2475          * from AP to save power while system is in suspended state
2476          */
2477         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2478              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2479              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2480                 WL_INFO("Disassociating from AP"
2481                         " while entering suspend state\n");
2482                 brcmf_link_down(cfg_priv);
2483
2484                 /*
2485                  * Make sure WPA_Supplicant receives all the event
2486                  * generated due to DISASSOC call to the fw to keep
2487                  * the state fw and WPA_Supplicant state consistent
2488                  */
2489                 brcmf_delay(500);
2490         }
2491
2492         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2493         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2494                 brcmf_term_iscan(cfg_priv);
2495
2496         if (cfg_priv->scan_request) {
2497                 /* Indidate scan abort to cfg80211 layer */
2498                 WL_INFO("Terminating scan in progress\n");
2499                 cfg80211_scan_done(cfg_priv->scan_request, true);
2500                 cfg_priv->scan_request = NULL;
2501         }
2502         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2503         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2504
2505         /* Turn off watchdog timer */
2506         if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2507                 WL_INFO("Enable MPC\n");
2508                 brcmf_set_mpc(ndev, 1);
2509         }
2510
2511         WL_TRACE("Exit\n");
2512
2513         return 0;
2514 }
2515
2516 static __used s32
2517 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2518 {
2519         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2520         u32 buflen;
2521
2522         buflen = brcmu_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2523                                WL_DCMD_LEN_MAX);
2524         BUG_ON(!buflen);
2525
2526         return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2527                                buflen);
2528 }
2529
2530 static s32
2531 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2532                   s32 buf_len)
2533 {
2534         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2535         u32 len;
2536         s32 err = 0;
2537
2538         len = brcmu_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2539                             WL_DCMD_LEN_MAX);
2540         BUG_ON(!len);
2541         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2542                               WL_DCMD_LEN_MAX);
2543         if (err) {
2544                 WL_ERR("error (%d)\n", err);
2545                 return err;
2546         }
2547         memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2548
2549         return err;
2550 }
2551
2552 static __used s32
2553 brcmf_update_pmklist(struct net_device *ndev,
2554                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2555 {
2556         int i, j;
2557         int pmkid_len;
2558
2559         pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2560
2561         WL_CONN("No of elements %d\n", pmkid_len);
2562         for (i = 0; i < pmkid_len; i++) {
2563                 WL_CONN("PMKID[%d]: %pM =\n", i,
2564                         &pmk_list->pmkids.pmkid[i].BSSID);
2565                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2566                         WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2567         }
2568
2569         if (!err)
2570                 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2571                                         sizeof(*pmk_list));
2572
2573         return err;
2574 }
2575
2576 static s32
2577 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2578                          struct cfg80211_pmksa *pmksa)
2579 {
2580         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2581         struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2582         s32 err = 0;
2583         int i;
2584         int pmkid_len;
2585
2586         WL_TRACE("Enter\n");
2587         if (!check_sys_up(wiphy))
2588                 return -EIO;
2589
2590         pmkid_len = le32_to_cpu(pmkids->npmkid);
2591         for (i = 0; i < pmkid_len; i++)
2592                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2593                         break;
2594         if (i < WL_NUM_PMKIDS_MAX) {
2595                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2596                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2597                 if (i == pmkid_len) {
2598                         pmkid_len++;
2599                         pmkids->npmkid = cpu_to_le32(pmkid_len);
2600                 }
2601         } else
2602                 err = -EINVAL;
2603
2604         WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2605                 pmkids->pmkid[pmkid_len].BSSID);
2606         for (i = 0; i < WLAN_PMKID_LEN; i++)
2607                 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2608
2609         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2610
2611         WL_TRACE("Exit\n");
2612         return err;
2613 }
2614
2615 static s32
2616 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2617                       struct cfg80211_pmksa *pmksa)
2618 {
2619         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2620         struct pmkid_list pmkid;
2621         s32 err = 0;
2622         int i, pmkid_len;
2623
2624         WL_TRACE("Enter\n");
2625         if (!check_sys_up(wiphy))
2626                 return -EIO;
2627
2628         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2629         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2630
2631         WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2632                &pmkid.pmkid[0].BSSID);
2633         for (i = 0; i < WLAN_PMKID_LEN; i++)
2634                 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2635
2636         pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2637         for (i = 0; i < pmkid_len; i++)
2638                 if (!memcmp
2639                     (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2640                      ETH_ALEN))
2641                         break;
2642
2643         if ((pmkid_len > 0)
2644             && (i < pmkid_len)) {
2645                 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2646                        sizeof(struct pmkid));
2647                 for (; i < (pmkid_len - 1); i++) {
2648                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2649                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2650                                ETH_ALEN);
2651                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2652                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2653                                WLAN_PMKID_LEN);
2654                 }
2655                 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2656         } else
2657                 err = -EINVAL;
2658
2659         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2660
2661         WL_TRACE("Exit\n");
2662         return err;
2663
2664 }
2665
2666 static s32
2667 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2668 {
2669         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2670         s32 err = 0;
2671
2672         WL_TRACE("Enter\n");
2673         if (!check_sys_up(wiphy))
2674                 return -EIO;
2675
2676         memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2677         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2678
2679         WL_TRACE("Exit\n");
2680         return err;
2681
2682 }
2683
2684 static struct cfg80211_ops wl_cfg80211_ops = {
2685         .change_virtual_intf = brcmf_cfg80211_change_iface,
2686         .scan = brcmf_cfg80211_scan,
2687         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2688         .join_ibss = brcmf_cfg80211_join_ibss,
2689         .leave_ibss = brcmf_cfg80211_leave_ibss,
2690         .get_station = brcmf_cfg80211_get_station,
2691         .set_tx_power = brcmf_cfg80211_set_tx_power,
2692         .get_tx_power = brcmf_cfg80211_get_tx_power,
2693         .add_key = brcmf_cfg80211_add_key,
2694         .del_key = brcmf_cfg80211_del_key,
2695         .get_key = brcmf_cfg80211_get_key,
2696         .set_default_key = brcmf_cfg80211_config_default_key,
2697         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2698         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2699         .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2700         .connect = brcmf_cfg80211_connect,
2701         .disconnect = brcmf_cfg80211_disconnect,
2702         .suspend = brcmf_cfg80211_suspend,
2703         .resume = brcmf_cfg80211_resume,
2704         .set_pmksa = brcmf_cfg80211_set_pmksa,
2705         .del_pmksa = brcmf_cfg80211_del_pmksa,
2706         .flush_pmksa = brcmf_cfg80211_flush_pmksa
2707 };
2708
2709 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2710 {
2711         s32 err = 0;
2712
2713         switch (mode) {
2714         case WL_MODE_BSS:
2715                 return NL80211_IFTYPE_STATION;
2716         case WL_MODE_IBSS:
2717                 return NL80211_IFTYPE_ADHOC;
2718         default:
2719                 return NL80211_IFTYPE_UNSPECIFIED;
2720         }
2721
2722         return err;
2723 }
2724
2725 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2726                                           struct device *ndev)
2727 {
2728         struct wireless_dev *wdev;
2729         s32 err = 0;
2730
2731         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2732         if (!wdev)
2733                 return ERR_PTR(-ENOMEM);
2734
2735         wdev->wiphy =
2736             wiphy_new(&wl_cfg80211_ops,
2737                       sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2738         if (!wdev->wiphy) {
2739                 WL_ERR("Couldn not allocate wiphy device\n");
2740                 err = -ENOMEM;
2741                 goto wiphy_new_out;
2742         }
2743         set_wiphy_dev(wdev->wiphy, ndev);
2744         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2745         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2746         wdev->wiphy->interface_modes =
2747             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2748         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2749         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;    /* Set
2750                                                 * it as 11a by default.
2751                                                 * This will be updated with
2752                                                 * 11n phy tables in
2753                                                 * "ifconfig up"
2754                                                 * if phy has 11n capability
2755                                                 */
2756         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2757         wdev->wiphy->cipher_suites = __wl_cipher_suites;
2758         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2759         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;      /* enable power
2760                                                                  * save mode
2761                                                                  * by default
2762                                                                  */
2763         err = wiphy_register(wdev->wiphy);
2764         if (err < 0) {
2765                 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2766                 goto wiphy_register_out;
2767         }
2768         return wdev;
2769
2770 wiphy_register_out:
2771         wiphy_free(wdev->wiphy);
2772
2773 wiphy_new_out:
2774         kfree(wdev);
2775
2776         return ERR_PTR(err);
2777 }
2778
2779 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2780 {
2781         struct wireless_dev *wdev = cfg_priv->wdev;
2782
2783         if (!wdev) {
2784                 WL_ERR("wdev is invalid\n");
2785                 return;
2786         }
2787         wiphy_unregister(wdev->wiphy);
2788         wiphy_free(wdev->wiphy);
2789         kfree(wdev);
2790         cfg_priv->wdev = NULL;
2791 }
2792
2793 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2794                             const struct brcmf_event_msg *e)
2795 {
2796         u32 event = be32_to_cpu(e->event_type);
2797         u32 status = be32_to_cpu(e->status);
2798
2799         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2800                 WL_CONN("Processing set ssid\n");
2801                 cfg_priv->link_up = true;
2802                 return true;
2803         }
2804
2805         return false;
2806 }
2807
2808 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2809                               const struct brcmf_event_msg *e)
2810 {
2811         u32 event = be32_to_cpu(e->event_type);
2812         u16 flags = be16_to_cpu(e->flags);
2813
2814         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2815                 WL_CONN("Processing link down\n");
2816                 return true;
2817         }
2818         return false;
2819 }
2820
2821 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2822                                const struct brcmf_event_msg *e)
2823 {
2824         u32 event = be32_to_cpu(e->event_type);
2825         u32 status = be32_to_cpu(e->status);
2826
2827         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2828                 WL_CONN("Processing Link %s & no network found\n",
2829                                 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2830                                 "up" : "down");
2831                 return true;
2832         }
2833
2834         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2835                 WL_CONN("Processing connecting & no network found\n");
2836                 return true;
2837         }
2838
2839         return false;
2840 }
2841
2842 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2843 {
2844         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2845
2846         kfree(conn_info->req_ie);
2847         conn_info->req_ie = NULL;
2848         conn_info->req_ie_len = 0;
2849         kfree(conn_info->resp_ie);
2850         conn_info->resp_ie = NULL;
2851         conn_info->resp_ie_len = 0;
2852 }
2853
2854 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2855 {
2856         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2857         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2858         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2859         u32 req_len;
2860         u32 resp_len;
2861         s32 err = 0;
2862
2863         brcmf_clear_assoc_ies(cfg_priv);
2864
2865         err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2866                                 WL_ASSOC_INFO_MAX);
2867         if (err) {
2868                 WL_ERR("could not get assoc info (%d)\n", err);
2869                 return err;
2870         }
2871         assoc_info =
2872                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2873         req_len = le32_to_cpu(assoc_info->req_len);
2874         resp_len = le32_to_cpu(assoc_info->resp_len);
2875         if (req_len) {
2876                 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2877                                            cfg_priv->extra_buf,
2878                                            WL_ASSOC_INFO_MAX);
2879                 if (err) {
2880                         WL_ERR("could not get assoc req (%d)\n", err);
2881                         return err;
2882                 }
2883                 conn_info->req_ie_len = req_len;
2884                 conn_info->req_ie =
2885                     kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2886                             GFP_KERNEL);
2887         } else {
2888                 conn_info->req_ie_len = 0;
2889                 conn_info->req_ie = NULL;
2890         }
2891         if (resp_len) {
2892                 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2893                                            cfg_priv->extra_buf,
2894                                            WL_ASSOC_INFO_MAX);
2895                 if (err) {
2896                         WL_ERR("could not get assoc resp (%d)\n", err);
2897                         return err;
2898                 }
2899                 conn_info->resp_ie_len = resp_len;
2900                 conn_info->resp_ie =
2901                     kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2902                             GFP_KERNEL);
2903         } else {
2904                 conn_info->resp_ie_len = 0;
2905                 conn_info->resp_ie = NULL;
2906         }
2907         WL_CONN("req len (%d) resp len (%d)\n",
2908                conn_info->req_ie_len, conn_info->resp_ie_len);
2909
2910         return err;
2911 }
2912
2913 static s32
2914 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2915                        struct net_device *ndev,
2916                        const struct brcmf_event_msg *e)
2917 {
2918         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2919         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2920         struct brcmf_channel_info_le channel_le;
2921         struct ieee80211_channel *notify_channel;
2922         struct ieee80211_supported_band *band;
2923         u32 freq;
2924         s32 err = 0;
2925         u32 target_channel;
2926
2927         WL_TRACE("Enter\n");
2928
2929         brcmf_get_assoc_ies(cfg_priv);
2930         brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2931         brcmf_update_bss_info(cfg_priv);
2932
2933         brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2934                         sizeof(channel_le));
2935
2936         target_channel = le32_to_cpu(channel_le.target_channel);
2937         WL_CONN("Roamed to channel %d\n", target_channel);
2938
2939         if (target_channel <= CH_MAX_2G_CHANNEL)
2940                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2941         else
2942                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2943
2944         freq = ieee80211_channel_to_frequency(target_channel, band->band);
2945         notify_channel = ieee80211_get_channel(wiphy, freq);
2946
2947         cfg80211_roamed(ndev, notify_channel,
2948                         (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2949                         conn_info->req_ie, conn_info->req_ie_len,
2950                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2951         WL_CONN("Report roaming result\n");
2952
2953         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2954         WL_TRACE("Exit\n");
2955         return err;
2956 }
2957
2958 static s32
2959 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2960                        struct net_device *ndev, const struct brcmf_event_msg *e,
2961                        bool completed)
2962 {
2963         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2964         s32 err = 0;
2965
2966         WL_TRACE("Enter\n");
2967
2968         if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2969                 if (completed) {
2970                         brcmf_get_assoc_ies(cfg_priv);
2971                         brcmf_update_prof(cfg_priv, NULL, &e->addr,
2972                                           WL_PROF_BSSID);
2973                         brcmf_update_bss_info(cfg_priv);
2974                 }
2975                 cfg80211_connect_result(ndev,
2976                                         (u8 *)brcmf_read_prof(cfg_priv,
2977                                                               WL_PROF_BSSID),
2978                                         conn_info->req_ie,
2979                                         conn_info->req_ie_len,
2980                                         conn_info->resp_ie,
2981                                         conn_info->resp_ie_len,
2982                                         completed ? WLAN_STATUS_SUCCESS :
2983                                                     WLAN_STATUS_AUTH_TIMEOUT,
2984                                         GFP_KERNEL);
2985                 if (completed)
2986                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2987                 WL_CONN("Report connect result - connection %s\n",
2988                                 completed ? "succeeded" : "failed");
2989         }
2990         WL_TRACE("Exit\n");
2991         return err;
2992 }
2993
2994 static s32
2995 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2996                             struct net_device *ndev,
2997                             const struct brcmf_event_msg *e, void *data)
2998 {
2999         s32 err = 0;
3000
3001         if (brcmf_is_linkup(cfg_priv, e)) {
3002                 WL_CONN("Linkup\n");
3003                 if (brcmf_is_ibssmode(cfg_priv)) {
3004                         brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3005                                 WL_PROF_BSSID);
3006                         wl_inform_ibss(cfg_priv, ndev, e->addr);
3007                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3008                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3009                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3010                 } else
3011                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3012         } else if (brcmf_is_linkdown(cfg_priv, e)) {
3013                 WL_CONN("Linkdown\n");
3014                 if (brcmf_is_ibssmode(cfg_priv)) {
3015                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3016                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
3017                                 &cfg_priv->status))
3018                                 brcmf_link_down(cfg_priv);
3019                 } else {
3020                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3021                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
3022                                 &cfg_priv->status)) {
3023                                 cfg80211_disconnected(ndev, 0, NULL, 0,
3024                                         GFP_KERNEL);
3025                                 brcmf_link_down(cfg_priv);
3026                         }
3027                 }
3028                 brcmf_init_prof(cfg_priv->profile);
3029         } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3030                 if (brcmf_is_ibssmode(cfg_priv))
3031                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3032                 else
3033                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3034         }
3035
3036         return err;
3037 }
3038
3039 static s32
3040 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3041                             struct net_device *ndev,
3042                             const struct brcmf_event_msg *e, void *data)
3043 {
3044         s32 err = 0;
3045         u32 event = be32_to_cpu(e->event_type);
3046         u32 status = be32_to_cpu(e->status);
3047
3048         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3049                 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3050                         brcmf_bss_roaming_done(cfg_priv, ndev, e);
3051                 else
3052                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3053         }
3054
3055         return err;
3056 }
3057
3058 static s32
3059 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3060                         struct net_device *ndev,
3061                         const struct brcmf_event_msg *e, void *data)
3062 {
3063         u16 flags = be16_to_cpu(e->flags);
3064         enum nl80211_key_type key_type;
3065
3066         if (flags & BRCMF_EVENT_MSG_GROUP)
3067                 key_type = NL80211_KEYTYPE_GROUP;
3068         else
3069                 key_type = NL80211_KEYTYPE_PAIRWISE;
3070
3071         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3072                                      NULL, GFP_KERNEL);
3073
3074         return 0;
3075 }
3076
3077 static s32
3078 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3079                          struct net_device *ndev,
3080                          const struct brcmf_event_msg *e, void *data)
3081 {
3082         struct brcmf_channel_info_le channel_inform_le;
3083         struct brcmf_scan_results_le *bss_list_le;
3084         u32 len = WL_SCAN_BUF_MAX;
3085         s32 err = 0;
3086         bool scan_abort = false;
3087         u32 scan_channel;
3088
3089         WL_TRACE("Enter\n");
3090
3091         if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3092                 WL_TRACE("Exit\n");
3093                 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3094         }
3095
3096         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3097                 WL_ERR("Scan complete while device not scanning\n");
3098                 scan_abort = true;
3099                 err = -EINVAL;
3100                 goto scan_done_out;
3101         }
3102
3103         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3104                               sizeof(channel_inform_le));
3105         if (err) {
3106                 WL_ERR("scan busy (%d)\n", err);
3107                 scan_abort = true;
3108                 goto scan_done_out;
3109         }
3110         scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3111         if (scan_channel)
3112                 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3113         cfg_priv->bss_list = cfg_priv->scan_results;
3114         bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3115
3116         memset(cfg_priv->scan_results, 0, len);
3117         bss_list_le->buflen = cpu_to_le32(len);
3118         err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3119                               cfg_priv->scan_results, len);
3120         if (err) {
3121                 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3122                 err = -EINVAL;
3123                 scan_abort = true;
3124                 goto scan_done_out;
3125         }
3126         cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3127         cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3128         cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3129
3130         err = brcmf_inform_bss(cfg_priv);
3131         if (err) {
3132                 scan_abort = true;
3133                 goto scan_done_out;
3134         }
3135
3136 scan_done_out:
3137         if (cfg_priv->scan_request) {
3138                 WL_SCAN("calling cfg80211_scan_done\n");
3139                 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3140                 brcmf_set_mpc(ndev, 1);
3141                 cfg_priv->scan_request = NULL;
3142         }
3143
3144         WL_TRACE("Exit\n");
3145
3146         return err;
3147 }
3148
3149 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3150 {
3151         conf->mode = (u32)-1;
3152         conf->frag_threshold = (u32)-1;
3153         conf->rts_threshold = (u32)-1;
3154         conf->retry_short = (u32)-1;
3155         conf->retry_long = (u32)-1;
3156         conf->tx_power = -1;
3157 }
3158
3159 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3160 {
3161         memset(el, 0, sizeof(*el));
3162         el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3163         el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3164         el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3165         el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3166         el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3167 }
3168
3169 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3170 {
3171         kfree(cfg_priv->scan_results);
3172         cfg_priv->scan_results = NULL;
3173         kfree(cfg_priv->bss_info);
3174         cfg_priv->bss_info = NULL;
3175         kfree(cfg_priv->conf);
3176         cfg_priv->conf = NULL;
3177         kfree(cfg_priv->profile);
3178         cfg_priv->profile = NULL;
3179         kfree(cfg_priv->scan_req_int);
3180         cfg_priv->scan_req_int = NULL;
3181         kfree(cfg_priv->dcmd_buf);
3182         cfg_priv->dcmd_buf = NULL;
3183         kfree(cfg_priv->extra_buf);
3184         cfg_priv->extra_buf = NULL;
3185         kfree(cfg_priv->iscan);
3186         cfg_priv->iscan = NULL;
3187         kfree(cfg_priv->pmk_list);
3188         cfg_priv->pmk_list = NULL;
3189 }
3190
3191 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3192 {
3193         cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3194         if (!cfg_priv->scan_results)
3195                 goto init_priv_mem_out;
3196         cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3197         if (!cfg_priv->conf)
3198                 goto init_priv_mem_out;
3199         cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3200         if (!cfg_priv->profile)
3201                 goto init_priv_mem_out;
3202         cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3203         if (!cfg_priv->bss_info)
3204                 goto init_priv_mem_out;
3205         cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3206                                          GFP_KERNEL);
3207         if (!cfg_priv->scan_req_int)
3208                 goto init_priv_mem_out;
3209         cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3210         if (!cfg_priv->dcmd_buf)
3211                 goto init_priv_mem_out;
3212         cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3213         if (!cfg_priv->extra_buf)
3214                 goto init_priv_mem_out;
3215         cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3216         if (!cfg_priv->iscan)
3217                 goto init_priv_mem_out;
3218         cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3219         if (!cfg_priv->pmk_list)
3220                 goto init_priv_mem_out;
3221
3222         return 0;
3223
3224 init_priv_mem_out:
3225         brcmf_deinit_priv_mem(cfg_priv);
3226
3227         return -ENOMEM;
3228 }
3229
3230 /*
3231 * retrieve first queued event from head
3232 */
3233
3234 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3235         struct brcmf_cfg80211_priv *cfg_priv)
3236 {
3237         struct brcmf_cfg80211_event_q *e = NULL;
3238
3239         spin_lock_irq(&cfg_priv->evt_q_lock);
3240         if (!list_empty(&cfg_priv->evt_q_list)) {
3241                 e = list_first_entry(&cfg_priv->evt_q_list,
3242                                      struct brcmf_cfg80211_event_q, evt_q_list);
3243                 list_del(&e->evt_q_list);
3244         }
3245         spin_unlock_irq(&cfg_priv->evt_q_lock);
3246
3247         return e;
3248 }
3249
3250 /*
3251 ** push event to tail of the queue
3252 */
3253
3254 static s32
3255 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3256                 const struct brcmf_event_msg *msg)
3257 {
3258         struct brcmf_cfg80211_event_q *e;
3259         s32 err = 0;
3260
3261         e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3262         if (!e)
3263                 return -ENOMEM;
3264
3265         e->etype = event;
3266         memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3267
3268         spin_lock_irq(&cfg_priv->evt_q_lock);
3269         list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3270         spin_unlock_irq(&cfg_priv->evt_q_lock);
3271
3272         return err;
3273 }
3274
3275 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3276 {
3277         kfree(e);
3278 }
3279
3280 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3281 {
3282         struct brcmf_cfg80211_priv *cfg_priv =
3283                         container_of(work, struct brcmf_cfg80211_priv,
3284                                      event_work);
3285         struct brcmf_cfg80211_event_q *e;
3286
3287         e = brcmf_deq_event(cfg_priv);
3288         if (unlikely(!e)) {
3289                 WL_ERR("event queue empty...\n");
3290                 return;
3291         }
3292
3293         do {
3294                 WL_INFO("event type (%d)\n", e->etype);
3295                 if (cfg_priv->el.handler[e->etype])
3296                         cfg_priv->el.handler[e->etype](cfg_priv,
3297                                                        cfg_to_ndev(cfg_priv),
3298                                                        &e->emsg, e->edata);
3299                 else
3300                         WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3301                 brcmf_put_event(e);
3302         } while ((e = brcmf_deq_event(cfg_priv)));
3303
3304 }
3305
3306 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3307 {
3308         spin_lock_init(&cfg_priv->evt_q_lock);
3309         INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3310 }
3311
3312 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3313 {
3314         struct brcmf_cfg80211_event_q *e;
3315
3316         spin_lock_irq(&cfg_priv->evt_q_lock);
3317         while (!list_empty(&cfg_priv->evt_q_list)) {
3318                 e = list_first_entry(&cfg_priv->evt_q_list,
3319                                      struct brcmf_cfg80211_event_q, evt_q_list);
3320                 list_del(&e->evt_q_list);
3321                 kfree(e);
3322         }
3323         spin_unlock_irq(&cfg_priv->evt_q_lock);
3324 }
3325
3326 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3327 {
3328         s32 err = 0;
3329
3330         cfg_priv->scan_request = NULL;
3331         cfg_priv->pwr_save = true;
3332         cfg_priv->iscan_on = true;      /* iscan on & off switch.
3333                                  we enable iscan per default */
3334         cfg_priv->roam_on = true;       /* roam on & off switch.
3335                                  we enable roam per default */
3336
3337         cfg_priv->iscan_kickstart = false;
3338         cfg_priv->active_scan = true;   /* we do active scan for
3339                                  specific scan per default */
3340         cfg_priv->dongle_up = false;    /* dongle is not up yet */
3341         brcmf_init_eq(cfg_priv);
3342         err = brcmf_init_priv_mem(cfg_priv);
3343         if (err)
3344                 return err;
3345         INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3346         brcmf_init_eloop_handler(&cfg_priv->el);
3347         mutex_init(&cfg_priv->usr_sync);
3348         err = brcmf_init_iscan(cfg_priv);
3349         if (err)
3350                 return err;
3351         brcmf_init_conf(cfg_priv->conf);
3352         brcmf_init_prof(cfg_priv->profile);
3353         brcmf_link_down(cfg_priv);
3354
3355         return err;
3356 }
3357
3358 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3359 {
3360         cancel_work_sync(&cfg_priv->event_work);
3361         cfg_priv->dongle_up = false;    /* dongle down */
3362         brcmf_flush_eq(cfg_priv);
3363         brcmf_link_down(cfg_priv);
3364         brcmf_term_iscan(cfg_priv);
3365         brcmf_deinit_priv_mem(cfg_priv);
3366 }
3367
3368 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3369                                                  struct device *busdev,
3370                                                  void *data)
3371 {
3372         struct wireless_dev *wdev;
3373         struct brcmf_cfg80211_priv *cfg_priv;
3374         struct brcmf_cfg80211_iface *ci;
3375         struct brcmf_cfg80211_dev *cfg_dev;
3376         s32 err = 0;
3377
3378         if (!ndev) {
3379                 WL_ERR("ndev is invalid\n");
3380                 return NULL;
3381         }
3382         cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3383         if (!cfg_dev)
3384                 return NULL;
3385
3386         wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3387         if (IS_ERR(wdev)) {
3388                 kfree(cfg_dev);
3389                 return NULL;
3390         }
3391
3392         wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3393         cfg_priv = wdev_to_cfg(wdev);
3394         cfg_priv->wdev = wdev;
3395         cfg_priv->pub = data;
3396         ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3397         ci->cfg_priv = cfg_priv;
3398         ndev->ieee80211_ptr = wdev;
3399         SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3400         wdev->netdev = ndev;
3401         err = wl_init_priv(cfg_priv);
3402         if (err) {
3403                 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3404                 goto cfg80211_attach_out;
3405         }
3406         brcmf_set_drvdata(cfg_dev, ci);
3407
3408         return cfg_dev;
3409
3410 cfg80211_attach_out:
3411         brcmf_free_wdev(cfg_priv);
3412         kfree(cfg_dev);
3413         return NULL;
3414 }
3415
3416 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3417 {
3418         struct brcmf_cfg80211_priv *cfg_priv;
3419
3420         cfg_priv = brcmf_priv_get(cfg_dev);
3421
3422         wl_deinit_priv(cfg_priv);
3423         brcmf_free_wdev(cfg_priv);
3424         brcmf_set_drvdata(cfg_dev, NULL);
3425         kfree(cfg_dev);
3426 }
3427
3428 void
3429 brcmf_cfg80211_event(struct net_device *ndev,
3430                   const struct brcmf_event_msg *e, void *data)
3431 {
3432         u32 event_type = be32_to_cpu(e->event_type);
3433         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3434
3435         if (!brcmf_enq_event(cfg_priv, event_type, e))
3436                 schedule_work(&cfg_priv->event_work);
3437 }
3438
3439 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3440 {
3441         s32 infra = 0;
3442         s32 err = 0;
3443
3444         switch (iftype) {
3445         case NL80211_IFTYPE_MONITOR:
3446         case NL80211_IFTYPE_WDS:
3447                 WL_ERR("type (%d) : currently we do not support this mode\n",
3448                        iftype);
3449                 err = -EINVAL;
3450                 return err;
3451         case NL80211_IFTYPE_ADHOC:
3452                 infra = 0;
3453                 break;
3454         case NL80211_IFTYPE_STATION:
3455                 infra = 1;
3456                 break;
3457         default:
3458                 err = -EINVAL;
3459                 WL_ERR("invalid type (%d)\n", iftype);
3460                 return err;
3461         }
3462         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3463         if (err) {
3464                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3465                 return err;
3466         }
3467
3468         return 0;
3469 }
3470
3471 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3472 {
3473         /* Room for "event_msgs" + '\0' + bitvec */
3474         s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3475         s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3476         s32 err = 0;
3477
3478         WL_TRACE("Enter\n");
3479
3480         /* Setup event_msgs */
3481         brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3482                     sizeof(iovbuf));
3483         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3484         if (err) {
3485                 WL_ERR("Get event_msgs error (%d)\n", err);
3486                 goto dongle_eventmsg_out;
3487         }
3488         memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3489
3490         setbit(eventmask, BRCMF_E_SET_SSID);
3491         setbit(eventmask, BRCMF_E_ROAM);
3492         setbit(eventmask, BRCMF_E_PRUNE);
3493         setbit(eventmask, BRCMF_E_AUTH);
3494         setbit(eventmask, BRCMF_E_REASSOC);
3495         setbit(eventmask, BRCMF_E_REASSOC_IND);
3496         setbit(eventmask, BRCMF_E_DEAUTH_IND);
3497         setbit(eventmask, BRCMF_E_DISASSOC_IND);
3498         setbit(eventmask, BRCMF_E_DISASSOC);
3499         setbit(eventmask, BRCMF_E_JOIN);
3500         setbit(eventmask, BRCMF_E_ASSOC_IND);
3501         setbit(eventmask, BRCMF_E_PSK_SUP);
3502         setbit(eventmask, BRCMF_E_LINK);
3503         setbit(eventmask, BRCMF_E_NDIS_LINK);
3504         setbit(eventmask, BRCMF_E_MIC_ERROR);
3505         setbit(eventmask, BRCMF_E_PMKID_CACHE);
3506         setbit(eventmask, BRCMF_E_TXFAIL);
3507         setbit(eventmask, BRCMF_E_JOIN_START);
3508         setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3509
3510         brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3511                     sizeof(iovbuf));
3512         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3513         if (err) {
3514                 WL_ERR("Set event_msgs error (%d)\n", err);
3515                 goto dongle_eventmsg_out;
3516         }
3517
3518 dongle_eventmsg_out:
3519         WL_TRACE("Exit\n");
3520         return err;
3521 }
3522
3523 static s32
3524 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3525 {
3526         s8 iovbuf[32];
3527         s32 err = 0;
3528         __le32 roamtrigger[2];
3529         __le32 roam_delta[2];
3530         __le32 bcn_to_le;
3531         __le32 roamvar_le;
3532
3533         /*
3534          * Setup timeout if Beacons are lost and roam is
3535          * off to report link down
3536          */
3537         if (roamvar) {
3538                 bcn_to_le = cpu_to_le32(bcn_timeout);
3539                 brcmu_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3540                         sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3541                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3542                                    iovbuf, sizeof(iovbuf));
3543                 if (err) {
3544                         WL_ERR("bcn_timeout error (%d)\n", err);
3545                         goto dongle_rom_out;
3546                 }
3547         }
3548
3549         /*
3550          * Enable/Disable built-in roaming to allow supplicant
3551          * to take care of roaming
3552          */
3553         WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3554         roamvar_le = cpu_to_le32(roamvar);
3555         brcmu_mkiovar("roam_off", (char *)&roamvar_le,
3556                                 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3557         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3558         if (err) {
3559                 WL_ERR("roam_off error (%d)\n", err);
3560                 goto dongle_rom_out;
3561         }
3562
3563         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3564         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3565         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3566                         (void *)roamtrigger, sizeof(roamtrigger));
3567         if (err) {
3568                 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3569                 goto dongle_rom_out;
3570         }
3571
3572         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3573         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3574         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3575                                 (void *)roam_delta, sizeof(roam_delta));
3576         if (err) {
3577                 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3578                 goto dongle_rom_out;
3579         }
3580
3581 dongle_rom_out:
3582         return err;
3583 }
3584
3585 static s32
3586 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3587                       s32 scan_unassoc_time, s32 scan_passive_time)
3588 {
3589         s32 err = 0;
3590         __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3591         __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3592         __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3593
3594         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3595                            &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3596         if (err) {
3597                 if (err == -EOPNOTSUPP)
3598                         WL_INFO("Scan assoc time is not supported\n");
3599                 else
3600                         WL_ERR("Scan assoc time error (%d)\n", err);
3601                 goto dongle_scantime_out;
3602         }
3603         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3604                            &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3605         if (err) {
3606                 if (err == -EOPNOTSUPP)
3607                         WL_INFO("Scan unassoc time is not supported\n");
3608                 else
3609                         WL_ERR("Scan unassoc time error (%d)\n", err);
3610                 goto dongle_scantime_out;
3611         }
3612
3613         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3614                            &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3615         if (err) {
3616                 if (err == -EOPNOTSUPP)
3617                         WL_INFO("Scan passive time is not supported\n");
3618                 else
3619                         WL_ERR("Scan passive time error (%d)\n", err);
3620                 goto dongle_scantime_out;
3621         }
3622
3623 dongle_scantime_out:
3624         return err;
3625 }
3626
3627 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3628 {
3629         struct wiphy *wiphy;
3630         s32 phy_list;
3631         s8 phy;
3632         s32 err = 0;
3633
3634         err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3635                               &phy_list, sizeof(phy_list));
3636         if (err) {
3637                 WL_ERR("error (%d)\n", err);
3638                 return err;
3639         }
3640
3641         phy = ((char *)&phy_list)[1];
3642         WL_INFO("%c phy\n", phy);
3643         if (phy == 'n' || phy == 'a') {
3644                 wiphy = cfg_to_wiphy(cfg_priv);
3645                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3646         }
3647
3648         return err;
3649 }
3650
3651 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3652 {
3653         return wl_update_wiphybands(cfg_priv);
3654 }
3655
3656 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3657 {
3658         struct net_device *ndev;
3659         struct wireless_dev *wdev;
3660         s32 power_mode;
3661         s32 err = 0;
3662
3663         if (cfg_priv->dongle_up)
3664                 return err;
3665
3666         ndev = cfg_to_ndev(cfg_priv);
3667         wdev = ndev->ieee80211_ptr;
3668
3669         brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3670                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3671
3672         err = brcmf_dongle_eventmsg(ndev);
3673         if (err)
3674                 goto default_conf_out;
3675
3676         power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3677         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3678         if (err)
3679                 goto default_conf_out;
3680         WL_INFO("power save set to %s\n",
3681                 (power_mode ? "enabled" : "disabled"));
3682
3683         err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3684                                 WL_BEACON_TIMEOUT);
3685         if (err)
3686                 goto default_conf_out;
3687         err = brcmf_dongle_mode(ndev, wdev->iftype);
3688         if (err && err != -EINPROGRESS)
3689                 goto default_conf_out;
3690         err = brcmf_dongle_probecap(cfg_priv);
3691         if (err)
3692                 goto default_conf_out;
3693
3694         /* -EINPROGRESS: Call commit handler */
3695
3696 default_conf_out:
3697
3698         cfg_priv->dongle_up = true;
3699
3700         return err;
3701
3702 }
3703
3704 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3705 {
3706         char buf[10+IFNAMSIZ];
3707         struct dentry *fd;
3708         s32 err = 0;
3709
3710         sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3711         cfg_priv->debugfsdir = debugfs_create_dir(buf,
3712                                         cfg_to_wiphy(cfg_priv)->debugfsdir);
3713
3714         fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3715                 (u16 *)&cfg_priv->profile->beacon_interval);
3716         if (!fd) {
3717                 err = -ENOMEM;
3718                 goto err_out;
3719         }
3720
3721         fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3722                 (u8 *)&cfg_priv->profile->dtim_period);
3723         if (!fd) {
3724                 err = -ENOMEM;
3725                 goto err_out;
3726         }
3727
3728 err_out:
3729         return err;
3730 }
3731
3732 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3733 {
3734         debugfs_remove_recursive(cfg_priv->debugfsdir);
3735         cfg_priv->debugfsdir = NULL;
3736 }
3737
3738 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3739 {
3740         s32 err = 0;
3741
3742         set_bit(WL_STATUS_READY, &cfg_priv->status);
3743
3744         brcmf_debugfs_add_netdev_params(cfg_priv);
3745
3746         err = brcmf_config_dongle(cfg_priv);
3747         if (err)
3748                 return err;
3749
3750         brcmf_invoke_iscan(cfg_priv);
3751
3752         return err;
3753 }
3754
3755 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3756 {
3757         /*
3758          * While going down, if associated with AP disassociate
3759          * from AP to save power
3760          */
3761         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3762              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3763              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3764                 WL_INFO("Disassociating from AP");
3765                 brcmf_link_down(cfg_priv);
3766
3767                 /* Make sure WPA_Supplicant receives all the event
3768                    generated due to DISASSOC call to the fw to keep
3769                    the state fw and WPA_Supplicant state consistent
3770                  */
3771                 brcmf_delay(500);
3772         }
3773
3774         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3775         brcmf_term_iscan(cfg_priv);
3776         if (cfg_priv->scan_request) {
3777                 cfg80211_scan_done(cfg_priv->scan_request, true);
3778                 /* May need to perform this to cover rmmod */
3779                 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3780                 cfg_priv->scan_request = NULL;
3781         }
3782         clear_bit(WL_STATUS_READY, &cfg_priv->status);
3783         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3784         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3785
3786         brcmf_debugfs_remove_netdev(cfg_priv);
3787
3788         return 0;
3789 }
3790
3791 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3792 {
3793         struct brcmf_cfg80211_priv *cfg_priv;
3794         s32 err = 0;
3795
3796         cfg_priv = brcmf_priv_get(cfg_dev);
3797         mutex_lock(&cfg_priv->usr_sync);
3798         err = __brcmf_cfg80211_up(cfg_priv);
3799         mutex_unlock(&cfg_priv->usr_sync);
3800
3801         return err;
3802 }
3803
3804 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3805 {
3806         struct brcmf_cfg80211_priv *cfg_priv;
3807         s32 err = 0;
3808
3809         cfg_priv = brcmf_priv_get(cfg_dev);
3810         mutex_lock(&cfg_priv->usr_sync);
3811         err = __brcmf_cfg80211_down(cfg_priv);
3812         mutex_unlock(&cfg_priv->usr_sync);
3813
3814         return err;
3815 }
3816
3817 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3818                                u8 t, u8 l, u8 *v)
3819 {
3820         struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3821         s32 err = 0;
3822
3823         if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3824                 WL_ERR("ei crosses buffer boundary\n");
3825                 return -ENOSPC;
3826         }
3827         ie->buf[ie->offset] = t;
3828         ie->buf[ie->offset + 1] = l;
3829         memcpy(&ie->buf[ie->offset + 2], v, l);
3830         ie->offset += l + 2;
3831
3832         return err;
3833 }