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