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