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