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