]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
e95a883c77daa08b91b585a5f1351a168b5dc96d
[mv-sheeva.git] / drivers / net / wireless / brcm80211 / brcmfmac / wl_cfg80211.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
18
19 #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         u64 notify_timestamp;
2007         u16 notify_capability;
2008         u16 notify_interval;
2009         u8 *notify_ie;
2010         size_t notify_ielen;
2011         s32 notify_signal;
2012
2013         if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2014                 WL_ERR("Bss info is larger than buffer. Discarding\n");
2015                 return 0;
2016         }
2017
2018         channel = bi->ctl_ch ? bi->ctl_ch :
2019                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2020
2021         if (channel <= CH_MAX_2G_CHANNEL)
2022                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2023         else
2024                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2025
2026         freq = ieee80211_channel_to_frequency(channel, band->band);
2027         notify_channel = ieee80211_get_channel(wiphy, freq);
2028
2029         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2030         notify_capability = le16_to_cpu(bi->capability);
2031         notify_interval = le16_to_cpu(bi->beacon_period);
2032         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2033         notify_ielen = le32_to_cpu(bi->ie_length);
2034         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2035
2036         WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2037                         bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2038                         bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2039         WL_CONN("Channel: %d(%d)\n", channel, freq);
2040         WL_CONN("Capability: %X\n", notify_capability);
2041         WL_CONN("Beacon interval: %d\n", notify_interval);
2042         WL_CONN("Signal: %d\n", notify_signal);
2043         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2044
2045         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2046                 notify_timestamp, notify_capability, notify_interval, notify_ie,
2047                 notify_ielen, notify_signal, GFP_KERNEL);
2048
2049         if (!bss)
2050                 return -ENOMEM;
2051
2052         cfg80211_put_bss(bss);
2053
2054         return err;
2055 }
2056
2057 static struct brcmf_bss_info_le *
2058 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2059 {
2060         if (bss == NULL)
2061                 return list->bss_info_le;
2062         return (struct brcmf_bss_info_le *)((unsigned long)bss +
2063                                             le32_to_cpu(bss->length));
2064 }
2065
2066 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2067 {
2068         struct brcmf_scan_results *bss_list;
2069         struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2070         s32 err = 0;
2071         int i;
2072
2073         bss_list = cfg_priv->bss_list;
2074         if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2075                 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2076                        bss_list->version);
2077                 return -EOPNOTSUPP;
2078         }
2079         WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2080         for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2081                 bi = next_bss_le(bss_list, bi);
2082                 err = brcmf_inform_single_bss(cfg_priv, bi);
2083                 if (err)
2084                         break;
2085         }
2086         return err;
2087 }
2088
2089 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2090                           struct net_device *ndev, const u8 *bssid)
2091 {
2092         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2093         struct ieee80211_channel *notify_channel;
2094         struct brcmf_bss_info_le *bi = NULL;
2095         struct ieee80211_supported_band *band;
2096         struct cfg80211_bss *bss;
2097         u8 *buf = NULL;
2098         s32 err = 0;
2099         u16 channel;
2100         u32 freq;
2101         u64 notify_timestamp;
2102         u16 notify_capability;
2103         u16 notify_interval;
2104         u8 *notify_ie;
2105         size_t notify_ielen;
2106         s32 notify_signal;
2107
2108         WL_TRACE("Enter\n");
2109
2110         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2111         if (buf == NULL) {
2112                 err = -ENOMEM;
2113                 goto CleanUp;
2114         }
2115
2116         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2117
2118         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2119         if (err) {
2120                 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2121                 goto CleanUp;
2122         }
2123
2124         bi = (struct brcmf_bss_info_le *)(buf + 4);
2125
2126         channel = bi->ctl_ch ? bi->ctl_ch :
2127                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2128
2129         if (channel <= CH_MAX_2G_CHANNEL)
2130                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2131         else
2132                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2133
2134         freq = ieee80211_channel_to_frequency(channel, band->band);
2135         notify_channel = ieee80211_get_channel(wiphy, freq);
2136
2137         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2138         notify_capability = le16_to_cpu(bi->capability);
2139         notify_interval = le16_to_cpu(bi->beacon_period);
2140         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2141         notify_ielen = le32_to_cpu(bi->ie_length);
2142         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2143
2144         WL_CONN("channel: %d(%d)\n", channel, freq);
2145         WL_CONN("capability: %X\n", notify_capability);
2146         WL_CONN("beacon interval: %d\n", notify_interval);
2147         WL_CONN("signal: %d\n", notify_signal);
2148         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2149
2150         bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2151                 notify_timestamp, notify_capability, notify_interval,
2152                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2153
2154         if (!bss) {
2155                 err = -ENOMEM;
2156                 goto CleanUp;
2157         }
2158
2159         cfg80211_put_bss(bss);
2160
2161 CleanUp:
2162
2163         kfree(buf);
2164
2165         WL_TRACE("Exit\n");
2166
2167         return err;
2168 }
2169
2170 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2171 {
2172         return cfg_priv->conf->mode == WL_MODE_IBSS;
2173 }
2174
2175 /*
2176  * Traverse a string of 1-byte tag/1-byte length/variable-length value
2177  * triples, returning a pointer to the substring whose first element
2178  * matches tag
2179  */
2180 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2181 {
2182         struct brcmf_tlv *elt;
2183         int totlen;
2184
2185         elt = (struct brcmf_tlv *) buf;
2186         totlen = buflen;
2187
2188         /* find tagged parameter */
2189         while (totlen >= 2) {
2190                 int len = elt->len;
2191
2192                 /* validate remaining totlen */
2193                 if ((elt->id == key) && (totlen >= (len + 2)))
2194                         return elt;
2195
2196                 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2197                 totlen -= (len + 2);
2198         }
2199
2200         return NULL;
2201 }
2202
2203 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2204 {
2205         struct brcmf_bss_info_le *bi;
2206         struct brcmf_ssid *ssid;
2207         struct brcmf_tlv *tim;
2208         u16 beacon_interval;
2209         u8 dtim_period;
2210         size_t ie_len;
2211         u8 *ie;
2212         s32 err = 0;
2213
2214         WL_TRACE("Enter\n");
2215         if (brcmf_is_ibssmode(cfg_priv))
2216                 return err;
2217
2218         ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2219
2220         *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2221         err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2222                         cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2223         if (err) {
2224                 WL_ERR("Could not get bss info %d\n", err);
2225                 goto update_bss_info_out;
2226         }
2227
2228         bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
2229         err = brcmf_inform_single_bss(cfg_priv, bi);
2230         if (err)
2231                 goto update_bss_info_out;
2232
2233         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2234         ie_len = le32_to_cpu(bi->ie_length);
2235         beacon_interval = le16_to_cpu(bi->beacon_period);
2236
2237         tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2238         if (tim)
2239                 dtim_period = tim->data[1];
2240         else {
2241                 /*
2242                 * active scan was done so we could not get dtim
2243                 * information out of probe response.
2244                 * so we speficially query dtim information to dongle.
2245                 */
2246                 u32 var;
2247                 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2248                                            "dtim_assoc", &var);
2249                 if (err) {
2250                         WL_ERR("wl dtim_assoc failed (%d)\n", err);
2251                         goto update_bss_info_out;
2252                 }
2253                 dtim_period = (u8)var;
2254         }
2255
2256         brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2257         brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2258
2259 update_bss_info_out:
2260         WL_TRACE("Exit");
2261         return err;
2262 }
2263
2264 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2265 {
2266         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2267         struct brcmf_ssid ssid;
2268
2269         if (cfg_priv->iscan_on) {
2270                 iscan->state = WL_ISCAN_STATE_IDLE;
2271
2272                 if (iscan->timer_on) {
2273                         del_timer_sync(&iscan->timer);
2274                         iscan->timer_on = 0;
2275                 }
2276
2277                 cancel_work_sync(&iscan->work);
2278
2279                 /* Abort iscan running in FW */
2280                 memset(&ssid, 0, sizeof(ssid));
2281                 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2282         }
2283 }
2284
2285 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2286                                         bool aborted)
2287 {
2288         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2289         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2290
2291         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2292                 WL_ERR("Scan complete while device not scanning\n");
2293                 return;
2294         }
2295         if (cfg_priv->scan_request) {
2296                 WL_SCAN("ISCAN Completed scan: %s\n",
2297                                 aborted ? "Aborted" : "Done");
2298                 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2299                 brcmf_set_mpc(ndev, 1);
2300                 cfg_priv->scan_request = NULL;
2301         }
2302         cfg_priv->iscan_kickstart = false;
2303 }
2304
2305 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2306 {
2307         if (iscan->state != WL_ISCAN_STATE_IDLE) {
2308                 WL_SCAN("wake up iscan\n");
2309                 schedule_work(&iscan->work);
2310                 return 0;
2311         }
2312
2313         return -EIO;
2314 }
2315
2316 static s32
2317 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2318                      struct brcmf_scan_results **bss_list)
2319 {
2320         struct brcmf_iscan_results list;
2321         struct brcmf_scan_results *results;
2322         struct brcmf_scan_results_le *results_le;
2323         struct brcmf_iscan_results *list_buf;
2324         s32 err = 0;
2325
2326         memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2327         list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2328         results = &list_buf->results;
2329         results_le = &list_buf->results_le;
2330         results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2331         results->version = 0;
2332         results->count = 0;
2333
2334         memset(&list, 0, sizeof(list));
2335         list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2336         err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2337                                      BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2338                                      iscan->scan_buf, WL_ISCAN_BUF_MAX);
2339         if (err) {
2340                 WL_ERR("error (%d)\n", err);
2341                 return err;
2342         }
2343         results->buflen = le32_to_cpu(results_le->buflen);
2344         results->version = le32_to_cpu(results_le->version);
2345         results->count = le32_to_cpu(results_le->count);
2346         WL_SCAN("results->count = %d\n", results_le->count);
2347         WL_SCAN("results->buflen = %d\n", results_le->buflen);
2348         *status = le32_to_cpu(list_buf->status_le);
2349         WL_SCAN("status = %d\n", *status);
2350         *bss_list = results;
2351
2352         return err;
2353 }
2354
2355 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2356 {
2357         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2358         s32 err = 0;
2359
2360         iscan->state = WL_ISCAN_STATE_IDLE;
2361         brcmf_inform_bss(cfg_priv);
2362         brcmf_notify_iscan_complete(iscan, false);
2363
2364         return err;
2365 }
2366
2367 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2368 {
2369         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2370         s32 err = 0;
2371
2372         /* Reschedule the timer */
2373         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2374         iscan->timer_on = 1;
2375
2376         return err;
2377 }
2378
2379 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2380 {
2381         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2382         s32 err = 0;
2383
2384         brcmf_inform_bss(cfg_priv);
2385         brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2386         /* Reschedule the timer */
2387         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2388         iscan->timer_on = 1;
2389
2390         return err;
2391 }
2392
2393 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2394 {
2395         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2396         s32 err = 0;
2397
2398         iscan->state = WL_ISCAN_STATE_IDLE;
2399         brcmf_notify_iscan_complete(iscan, true);
2400
2401         return err;
2402 }
2403
2404 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2405 {
2406         struct brcmf_cfg80211_iscan_ctrl *iscan =
2407                         container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2408                                      work);
2409         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2410         struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2411         u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2412
2413         if (iscan->timer_on) {
2414                 del_timer_sync(&iscan->timer);
2415                 iscan->timer_on = 0;
2416         }
2417
2418         if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2419                 status = BRCMF_SCAN_RESULTS_ABORTED;
2420                 WL_ERR("Abort iscan\n");
2421         }
2422
2423         el->handler[status](cfg_priv);
2424 }
2425
2426 static void brcmf_iscan_timer(unsigned long data)
2427 {
2428         struct brcmf_cfg80211_iscan_ctrl *iscan =
2429                         (struct brcmf_cfg80211_iscan_ctrl *)data;
2430
2431         if (iscan) {
2432                 iscan->timer_on = 0;
2433                 WL_SCAN("timer expired\n");
2434                 brcmf_wakeup_iscan(iscan);
2435         }
2436 }
2437
2438 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2439 {
2440         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2441
2442         if (cfg_priv->iscan_on) {
2443                 iscan->state = WL_ISCAN_STATE_IDLE;
2444                 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2445         }
2446
2447         return 0;
2448 }
2449
2450 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2451 {
2452         memset(el, 0, sizeof(*el));
2453         el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2454         el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2455         el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2456         el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2457         el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2458 }
2459
2460 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2461 {
2462         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2463         int err = 0;
2464
2465         if (cfg_priv->iscan_on) {
2466                 iscan->ndev = cfg_to_ndev(cfg_priv);
2467                 brcmf_init_iscan_eloop(&iscan->el);
2468                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2469                 init_timer(&iscan->timer);
2470                 iscan->timer.data = (unsigned long) iscan;
2471                 iscan->timer.function = brcmf_iscan_timer;
2472                 err = brcmf_invoke_iscan(cfg_priv);
2473                 if (!err)
2474                         iscan->data = cfg_priv;
2475         }
2476
2477         return err;
2478 }
2479
2480 static __always_inline void brcmf_delay(u32 ms)
2481 {
2482         if (ms < 1000 / HZ) {
2483                 cond_resched();
2484                 mdelay(ms);
2485         } else {
2486                 msleep(ms);
2487         }
2488 }
2489
2490 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2491 {
2492         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2493
2494         /*
2495          * Check for WL_STATUS_READY before any function call which
2496          * could result is bus access. Don't block the resume for
2497          * any driver error conditions
2498          */
2499         WL_TRACE("Enter\n");
2500
2501         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2502                 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2503
2504         WL_TRACE("Exit\n");
2505         return 0;
2506 }
2507
2508 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2509                                   struct cfg80211_wowlan *wow)
2510 {
2511         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2512         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2513
2514         WL_TRACE("Enter\n");
2515
2516         /*
2517          * Check for WL_STATUS_READY before any function call which
2518          * could result is bus access. Don't block the suspend for
2519          * any driver error conditions
2520          */
2521
2522         /*
2523          * While going to suspend if associated with AP disassociate
2524          * from AP to save power while system is in suspended state
2525          */
2526         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2527              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2528              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2529                 WL_INFO("Disassociating from AP"
2530                         " while entering suspend state\n");
2531                 brcmf_link_down(cfg_priv);
2532
2533                 /*
2534                  * Make sure WPA_Supplicant receives all the event
2535                  * generated due to DISASSOC call to the fw to keep
2536                  * the state fw and WPA_Supplicant state consistent
2537                  */
2538                 brcmf_delay(500);
2539         }
2540
2541         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2542         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2543                 brcmf_term_iscan(cfg_priv);
2544
2545         if (cfg_priv->scan_request) {
2546                 /* Indidate scan abort to cfg80211 layer */
2547                 WL_INFO("Terminating scan in progress\n");
2548                 cfg80211_scan_done(cfg_priv->scan_request, true);
2549                 cfg_priv->scan_request = NULL;
2550         }
2551         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2552         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2553
2554         /* Turn off watchdog timer */
2555         if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2556                 WL_INFO("Enable MPC\n");
2557                 brcmf_set_mpc(ndev, 1);
2558         }
2559
2560         WL_TRACE("Exit\n");
2561
2562         return 0;
2563 }
2564
2565 static __used s32
2566 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2567 {
2568         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2569         u32 buflen;
2570
2571         buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2572                                WL_DCMD_LEN_MAX);
2573         BUG_ON(!buflen);
2574
2575         return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2576                                buflen);
2577 }
2578
2579 static s32
2580 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2581                   s32 buf_len)
2582 {
2583         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2584         u32 len;
2585         s32 err = 0;
2586
2587         len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2588                             WL_DCMD_LEN_MAX);
2589         BUG_ON(!len);
2590         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2591                               WL_DCMD_LEN_MAX);
2592         if (err) {
2593                 WL_ERR("error (%d)\n", err);
2594                 return err;
2595         }
2596         memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2597
2598         return err;
2599 }
2600
2601 static __used s32
2602 brcmf_update_pmklist(struct net_device *ndev,
2603                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2604 {
2605         int i, j;
2606         int pmkid_len;
2607
2608         pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2609
2610         WL_CONN("No of elements %d\n", pmkid_len);
2611         for (i = 0; i < pmkid_len; i++) {
2612                 WL_CONN("PMKID[%d]: %pM =\n", i,
2613                         &pmk_list->pmkids.pmkid[i].BSSID);
2614                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2615                         WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2616         }
2617
2618         if (!err)
2619                 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2620                                         sizeof(*pmk_list));
2621
2622         return err;
2623 }
2624
2625 static s32
2626 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2627                          struct cfg80211_pmksa *pmksa)
2628 {
2629         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2630         struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2631         s32 err = 0;
2632         int i;
2633         int pmkid_len;
2634
2635         WL_TRACE("Enter\n");
2636         if (!check_sys_up(wiphy))
2637                 return -EIO;
2638
2639         pmkid_len = le32_to_cpu(pmkids->npmkid);
2640         for (i = 0; i < pmkid_len; i++)
2641                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2642                         break;
2643         if (i < WL_NUM_PMKIDS_MAX) {
2644                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2645                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2646                 if (i == pmkid_len) {
2647                         pmkid_len++;
2648                         pmkids->npmkid = cpu_to_le32(pmkid_len);
2649                 }
2650         } else
2651                 err = -EINVAL;
2652
2653         WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2654                 pmkids->pmkid[pmkid_len].BSSID);
2655         for (i = 0; i < WLAN_PMKID_LEN; i++)
2656                 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2657
2658         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2659
2660         WL_TRACE("Exit\n");
2661         return err;
2662 }
2663
2664 static s32
2665 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2666                       struct cfg80211_pmksa *pmksa)
2667 {
2668         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2669         struct pmkid_list pmkid;
2670         s32 err = 0;
2671         int i, pmkid_len;
2672
2673         WL_TRACE("Enter\n");
2674         if (!check_sys_up(wiphy))
2675                 return -EIO;
2676
2677         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2678         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2679
2680         WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2681                &pmkid.pmkid[0].BSSID);
2682         for (i = 0; i < WLAN_PMKID_LEN; i++)
2683                 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2684
2685         pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2686         for (i = 0; i < pmkid_len; i++)
2687                 if (!memcmp
2688                     (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2689                      ETH_ALEN))
2690                         break;
2691
2692         if ((pmkid_len > 0)
2693             && (i < pmkid_len)) {
2694                 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2695                        sizeof(struct pmkid));
2696                 for (; i < (pmkid_len - 1); i++) {
2697                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2698                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2699                                ETH_ALEN);
2700                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2701                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2702                                WLAN_PMKID_LEN);
2703                 }
2704                 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2705         } else
2706                 err = -EINVAL;
2707
2708         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2709
2710         WL_TRACE("Exit\n");
2711         return err;
2712
2713 }
2714
2715 static s32
2716 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2717 {
2718         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2719         s32 err = 0;
2720
2721         WL_TRACE("Enter\n");
2722         if (!check_sys_up(wiphy))
2723                 return -EIO;
2724
2725         memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2726         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2727
2728         WL_TRACE("Exit\n");
2729         return err;
2730
2731 }
2732
2733 static struct cfg80211_ops wl_cfg80211_ops = {
2734         .change_virtual_intf = brcmf_cfg80211_change_iface,
2735         .scan = brcmf_cfg80211_scan,
2736         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2737         .join_ibss = brcmf_cfg80211_join_ibss,
2738         .leave_ibss = brcmf_cfg80211_leave_ibss,
2739         .get_station = brcmf_cfg80211_get_station,
2740         .set_tx_power = brcmf_cfg80211_set_tx_power,
2741         .get_tx_power = brcmf_cfg80211_get_tx_power,
2742         .add_key = brcmf_cfg80211_add_key,
2743         .del_key = brcmf_cfg80211_del_key,
2744         .get_key = brcmf_cfg80211_get_key,
2745         .set_default_key = brcmf_cfg80211_config_default_key,
2746         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2747         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2748         .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2749         .connect = brcmf_cfg80211_connect,
2750         .disconnect = brcmf_cfg80211_disconnect,
2751         .suspend = brcmf_cfg80211_suspend,
2752         .resume = brcmf_cfg80211_resume,
2753         .set_pmksa = brcmf_cfg80211_set_pmksa,
2754         .del_pmksa = brcmf_cfg80211_del_pmksa,
2755         .flush_pmksa = brcmf_cfg80211_flush_pmksa
2756 };
2757
2758 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2759 {
2760         s32 err = 0;
2761
2762         switch (mode) {
2763         case WL_MODE_BSS:
2764                 return NL80211_IFTYPE_STATION;
2765         case WL_MODE_IBSS:
2766                 return NL80211_IFTYPE_ADHOC;
2767         default:
2768                 return NL80211_IFTYPE_UNSPECIFIED;
2769         }
2770
2771         return err;
2772 }
2773
2774 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2775                                           struct device *ndev)
2776 {
2777         struct wireless_dev *wdev;
2778         s32 err = 0;
2779
2780         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2781         if (!wdev)
2782                 return ERR_PTR(-ENOMEM);
2783
2784         wdev->wiphy =
2785             wiphy_new(&wl_cfg80211_ops,
2786                       sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2787         if (!wdev->wiphy) {
2788                 WL_ERR("Could not allocate wiphy device\n");
2789                 err = -ENOMEM;
2790                 goto wiphy_new_out;
2791         }
2792         set_wiphy_dev(wdev->wiphy, ndev);
2793         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2794         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2795         wdev->wiphy->interface_modes =
2796             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2797         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2798         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;    /* Set
2799                                                 * it as 11a by default.
2800                                                 * This will be updated with
2801                                                 * 11n phy tables in
2802                                                 * "ifconfig up"
2803                                                 * if phy has 11n capability
2804                                                 */
2805         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2806         wdev->wiphy->cipher_suites = __wl_cipher_suites;
2807         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2808         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;      /* enable power
2809                                                                  * save mode
2810                                                                  * by default
2811                                                                  */
2812         err = wiphy_register(wdev->wiphy);
2813         if (err < 0) {
2814                 WL_ERR("Could not register wiphy device (%d)\n", err);
2815                 goto wiphy_register_out;
2816         }
2817         return wdev;
2818
2819 wiphy_register_out:
2820         wiphy_free(wdev->wiphy);
2821
2822 wiphy_new_out:
2823         kfree(wdev);
2824
2825         return ERR_PTR(err);
2826 }
2827
2828 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2829 {
2830         struct wireless_dev *wdev = cfg_priv->wdev;
2831
2832         if (!wdev) {
2833                 WL_ERR("wdev is invalid\n");
2834                 return;
2835         }
2836         wiphy_unregister(wdev->wiphy);
2837         wiphy_free(wdev->wiphy);
2838         kfree(wdev);
2839         cfg_priv->wdev = NULL;
2840 }
2841
2842 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2843                             const struct brcmf_event_msg *e)
2844 {
2845         u32 event = be32_to_cpu(e->event_type);
2846         u32 status = be32_to_cpu(e->status);
2847
2848         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2849                 WL_CONN("Processing set ssid\n");
2850                 cfg_priv->link_up = true;
2851                 return true;
2852         }
2853
2854         return false;
2855 }
2856
2857 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2858                               const struct brcmf_event_msg *e)
2859 {
2860         u32 event = be32_to_cpu(e->event_type);
2861         u16 flags = be16_to_cpu(e->flags);
2862
2863         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2864                 WL_CONN("Processing link down\n");
2865                 return true;
2866         }
2867         return false;
2868 }
2869
2870 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2871                                const struct brcmf_event_msg *e)
2872 {
2873         u32 event = be32_to_cpu(e->event_type);
2874         u32 status = be32_to_cpu(e->status);
2875
2876         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2877                 WL_CONN("Processing Link %s & no network found\n",
2878                                 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2879                                 "up" : "down");
2880                 return true;
2881         }
2882
2883         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2884                 WL_CONN("Processing connecting & no network found\n");
2885                 return true;
2886         }
2887
2888         return false;
2889 }
2890
2891 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2892 {
2893         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2894
2895         kfree(conn_info->req_ie);
2896         conn_info->req_ie = NULL;
2897         conn_info->req_ie_len = 0;
2898         kfree(conn_info->resp_ie);
2899         conn_info->resp_ie = NULL;
2900         conn_info->resp_ie_len = 0;
2901 }
2902
2903 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2904 {
2905         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2906         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2907         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2908         u32 req_len;
2909         u32 resp_len;
2910         s32 err = 0;
2911
2912         brcmf_clear_assoc_ies(cfg_priv);
2913
2914         err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2915                                 WL_ASSOC_INFO_MAX);
2916         if (err) {
2917                 WL_ERR("could not get assoc info (%d)\n", err);
2918                 return err;
2919         }
2920         assoc_info =
2921                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2922         req_len = le32_to_cpu(assoc_info->req_len);
2923         resp_len = le32_to_cpu(assoc_info->resp_len);
2924         if (req_len) {
2925                 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2926                                            cfg_priv->extra_buf,
2927                                            WL_ASSOC_INFO_MAX);
2928                 if (err) {
2929                         WL_ERR("could not get assoc req (%d)\n", err);
2930                         return err;
2931                 }
2932                 conn_info->req_ie_len = req_len;
2933                 conn_info->req_ie =
2934                     kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2935                             GFP_KERNEL);
2936         } else {
2937                 conn_info->req_ie_len = 0;
2938                 conn_info->req_ie = NULL;
2939         }
2940         if (resp_len) {
2941                 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2942                                            cfg_priv->extra_buf,
2943                                            WL_ASSOC_INFO_MAX);
2944                 if (err) {
2945                         WL_ERR("could not get assoc resp (%d)\n", err);
2946                         return err;
2947                 }
2948                 conn_info->resp_ie_len = resp_len;
2949                 conn_info->resp_ie =
2950                     kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2951                             GFP_KERNEL);
2952         } else {
2953                 conn_info->resp_ie_len = 0;
2954                 conn_info->resp_ie = NULL;
2955         }
2956         WL_CONN("req len (%d) resp len (%d)\n",
2957                conn_info->req_ie_len, conn_info->resp_ie_len);
2958
2959         return err;
2960 }
2961
2962 static s32
2963 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2964                        struct net_device *ndev,
2965                        const struct brcmf_event_msg *e)
2966 {
2967         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2968         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2969         struct brcmf_channel_info_le channel_le;
2970         struct ieee80211_channel *notify_channel;
2971         struct ieee80211_supported_band *band;
2972         u32 freq;
2973         s32 err = 0;
2974         u32 target_channel;
2975
2976         WL_TRACE("Enter\n");
2977
2978         brcmf_get_assoc_ies(cfg_priv);
2979         brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2980         brcmf_update_bss_info(cfg_priv);
2981
2982         brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2983                         sizeof(channel_le));
2984
2985         target_channel = le32_to_cpu(channel_le.target_channel);
2986         WL_CONN("Roamed to channel %d\n", target_channel);
2987
2988         if (target_channel <= CH_MAX_2G_CHANNEL)
2989                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2990         else
2991                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2992
2993         freq = ieee80211_channel_to_frequency(target_channel, band->band);
2994         notify_channel = ieee80211_get_channel(wiphy, freq);
2995
2996         cfg80211_roamed(ndev, notify_channel,
2997                         (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2998                         conn_info->req_ie, conn_info->req_ie_len,
2999                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
3000         WL_CONN("Report roaming result\n");
3001
3002         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3003         WL_TRACE("Exit\n");
3004         return err;
3005 }
3006
3007 static s32
3008 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3009                        struct net_device *ndev, const struct brcmf_event_msg *e,
3010                        bool completed)
3011 {
3012         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3013         s32 err = 0;
3014
3015         WL_TRACE("Enter\n");
3016
3017         if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3018                 if (completed) {
3019                         brcmf_get_assoc_ies(cfg_priv);
3020                         brcmf_update_prof(cfg_priv, NULL, &e->addr,
3021                                           WL_PROF_BSSID);
3022                         brcmf_update_bss_info(cfg_priv);
3023                 }
3024                 cfg80211_connect_result(ndev,
3025                                         (u8 *)brcmf_read_prof(cfg_priv,
3026                                                               WL_PROF_BSSID),
3027                                         conn_info->req_ie,
3028                                         conn_info->req_ie_len,
3029                                         conn_info->resp_ie,
3030                                         conn_info->resp_ie_len,
3031                                         completed ? WLAN_STATUS_SUCCESS :
3032                                                     WLAN_STATUS_AUTH_TIMEOUT,
3033                                         GFP_KERNEL);
3034                 if (completed)
3035                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3036                 WL_CONN("Report connect result - connection %s\n",
3037                                 completed ? "succeeded" : "failed");
3038         }
3039         WL_TRACE("Exit\n");
3040         return err;
3041 }
3042
3043 static s32
3044 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3045                             struct net_device *ndev,
3046                             const struct brcmf_event_msg *e, void *data)
3047 {
3048         s32 err = 0;
3049
3050         if (brcmf_is_linkup(cfg_priv, e)) {
3051                 WL_CONN("Linkup\n");
3052                 if (brcmf_is_ibssmode(cfg_priv)) {
3053                         brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3054                                 WL_PROF_BSSID);
3055                         wl_inform_ibss(cfg_priv, ndev, e->addr);
3056                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3057                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3058                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3059                 } else
3060                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3061         } else if (brcmf_is_linkdown(cfg_priv, e)) {
3062                 WL_CONN("Linkdown\n");
3063                 if (brcmf_is_ibssmode(cfg_priv)) {
3064                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3065                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
3066                                 &cfg_priv->status))
3067                                 brcmf_link_down(cfg_priv);
3068                 } else {
3069                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3070                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
3071                                 &cfg_priv->status)) {
3072                                 cfg80211_disconnected(ndev, 0, NULL, 0,
3073                                         GFP_KERNEL);
3074                                 brcmf_link_down(cfg_priv);
3075                         }
3076                 }
3077                 brcmf_init_prof(cfg_priv->profile);
3078         } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3079                 if (brcmf_is_ibssmode(cfg_priv))
3080                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3081                 else
3082                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3083         }
3084
3085         return err;
3086 }
3087
3088 static s32
3089 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3090                             struct net_device *ndev,
3091                             const struct brcmf_event_msg *e, void *data)
3092 {
3093         s32 err = 0;
3094         u32 event = be32_to_cpu(e->event_type);
3095         u32 status = be32_to_cpu(e->status);
3096
3097         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3098                 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3099                         brcmf_bss_roaming_done(cfg_priv, ndev, e);
3100                 else
3101                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3102         }
3103
3104         return err;
3105 }
3106
3107 static s32
3108 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3109                         struct net_device *ndev,
3110                         const struct brcmf_event_msg *e, void *data)
3111 {
3112         u16 flags = be16_to_cpu(e->flags);
3113         enum nl80211_key_type key_type;
3114
3115         if (flags & BRCMF_EVENT_MSG_GROUP)
3116                 key_type = NL80211_KEYTYPE_GROUP;
3117         else
3118                 key_type = NL80211_KEYTYPE_PAIRWISE;
3119
3120         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3121                                      NULL, GFP_KERNEL);
3122
3123         return 0;
3124 }
3125
3126 static s32
3127 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3128                          struct net_device *ndev,
3129                          const struct brcmf_event_msg *e, void *data)
3130 {
3131         struct brcmf_channel_info_le channel_inform_le;
3132         struct brcmf_scan_results_le *bss_list_le;
3133         u32 len = WL_SCAN_BUF_MAX;
3134         s32 err = 0;
3135         bool scan_abort = false;
3136         u32 scan_channel;
3137
3138         WL_TRACE("Enter\n");
3139
3140         if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3141                 WL_TRACE("Exit\n");
3142                 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3143         }
3144
3145         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3146                 WL_ERR("Scan complete while device not scanning\n");
3147                 scan_abort = true;
3148                 err = -EINVAL;
3149                 goto scan_done_out;
3150         }
3151
3152         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3153                               sizeof(channel_inform_le));
3154         if (err) {
3155                 WL_ERR("scan busy (%d)\n", err);
3156                 scan_abort = true;
3157                 goto scan_done_out;
3158         }
3159         scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3160         if (scan_channel)
3161                 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3162         cfg_priv->bss_list = cfg_priv->scan_results;
3163         bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3164
3165         memset(cfg_priv->scan_results, 0, len);
3166         bss_list_le->buflen = cpu_to_le32(len);
3167         err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3168                               cfg_priv->scan_results, len);
3169         if (err) {
3170                 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3171                 err = -EINVAL;
3172                 scan_abort = true;
3173                 goto scan_done_out;
3174         }
3175         cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3176         cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3177         cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3178
3179         err = brcmf_inform_bss(cfg_priv);
3180         if (err) {
3181                 scan_abort = true;
3182                 goto scan_done_out;
3183         }
3184
3185 scan_done_out:
3186         if (cfg_priv->scan_request) {
3187                 WL_SCAN("calling cfg80211_scan_done\n");
3188                 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3189                 brcmf_set_mpc(ndev, 1);
3190                 cfg_priv->scan_request = NULL;
3191         }
3192
3193         WL_TRACE("Exit\n");
3194
3195         return err;
3196 }
3197
3198 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3199 {
3200         conf->mode = (u32)-1;
3201         conf->frag_threshold = (u32)-1;
3202         conf->rts_threshold = (u32)-1;
3203         conf->retry_short = (u32)-1;
3204         conf->retry_long = (u32)-1;
3205         conf->tx_power = -1;
3206 }
3207
3208 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3209 {
3210         memset(el, 0, sizeof(*el));
3211         el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3212         el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3213         el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3214         el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3215         el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3216 }
3217
3218 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3219 {
3220         kfree(cfg_priv->scan_results);
3221         cfg_priv->scan_results = NULL;
3222         kfree(cfg_priv->bss_info);
3223         cfg_priv->bss_info = NULL;
3224         kfree(cfg_priv->conf);
3225         cfg_priv->conf = NULL;
3226         kfree(cfg_priv->profile);
3227         cfg_priv->profile = NULL;
3228         kfree(cfg_priv->scan_req_int);
3229         cfg_priv->scan_req_int = NULL;
3230         kfree(cfg_priv->dcmd_buf);
3231         cfg_priv->dcmd_buf = NULL;
3232         kfree(cfg_priv->extra_buf);
3233         cfg_priv->extra_buf = NULL;
3234         kfree(cfg_priv->iscan);
3235         cfg_priv->iscan = NULL;
3236         kfree(cfg_priv->pmk_list);
3237         cfg_priv->pmk_list = NULL;
3238 }
3239
3240 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3241 {
3242         cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3243         if (!cfg_priv->scan_results)
3244                 goto init_priv_mem_out;
3245         cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3246         if (!cfg_priv->conf)
3247                 goto init_priv_mem_out;
3248         cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3249         if (!cfg_priv->profile)
3250                 goto init_priv_mem_out;
3251         cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3252         if (!cfg_priv->bss_info)
3253                 goto init_priv_mem_out;
3254         cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3255                                          GFP_KERNEL);
3256         if (!cfg_priv->scan_req_int)
3257                 goto init_priv_mem_out;
3258         cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3259         if (!cfg_priv->dcmd_buf)
3260                 goto init_priv_mem_out;
3261         cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3262         if (!cfg_priv->extra_buf)
3263                 goto init_priv_mem_out;
3264         cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3265         if (!cfg_priv->iscan)
3266                 goto init_priv_mem_out;
3267         cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3268         if (!cfg_priv->pmk_list)
3269                 goto init_priv_mem_out;
3270
3271         return 0;
3272
3273 init_priv_mem_out:
3274         brcmf_deinit_priv_mem(cfg_priv);
3275
3276         return -ENOMEM;
3277 }
3278
3279 /*
3280 * retrieve first queued event from head
3281 */
3282
3283 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3284         struct brcmf_cfg80211_priv *cfg_priv)
3285 {
3286         struct brcmf_cfg80211_event_q *e = NULL;
3287
3288         spin_lock_irq(&cfg_priv->evt_q_lock);
3289         if (!list_empty(&cfg_priv->evt_q_list)) {
3290                 e = list_first_entry(&cfg_priv->evt_q_list,
3291                                      struct brcmf_cfg80211_event_q, evt_q_list);
3292                 list_del(&e->evt_q_list);
3293         }
3294         spin_unlock_irq(&cfg_priv->evt_q_lock);
3295
3296         return e;
3297 }
3298
3299 /*
3300 ** push event to tail of the queue
3301 */
3302
3303 static s32
3304 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3305                 const struct brcmf_event_msg *msg)
3306 {
3307         struct brcmf_cfg80211_event_q *e;
3308         s32 err = 0;
3309
3310         e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3311         if (!e)
3312                 return -ENOMEM;
3313
3314         e->etype = event;
3315         memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3316
3317         spin_lock_irq(&cfg_priv->evt_q_lock);
3318         list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3319         spin_unlock_irq(&cfg_priv->evt_q_lock);
3320
3321         return err;
3322 }
3323
3324 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3325 {
3326         kfree(e);
3327 }
3328
3329 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3330 {
3331         struct brcmf_cfg80211_priv *cfg_priv =
3332                         container_of(work, struct brcmf_cfg80211_priv,
3333                                      event_work);
3334         struct brcmf_cfg80211_event_q *e;
3335
3336         e = brcmf_deq_event(cfg_priv);
3337         if (unlikely(!e)) {
3338                 WL_ERR("event queue empty...\n");
3339                 return;
3340         }
3341
3342         do {
3343                 WL_INFO("event type (%d)\n", e->etype);
3344                 if (cfg_priv->el.handler[e->etype])
3345                         cfg_priv->el.handler[e->etype](cfg_priv,
3346                                                        cfg_to_ndev(cfg_priv),
3347                                                        &e->emsg, e->edata);
3348                 else
3349                         WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3350                 brcmf_put_event(e);
3351         } while ((e = brcmf_deq_event(cfg_priv)));
3352
3353 }
3354
3355 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3356 {
3357         spin_lock_init(&cfg_priv->evt_q_lock);
3358         INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3359 }
3360
3361 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3362 {
3363         struct brcmf_cfg80211_event_q *e;
3364
3365         spin_lock_irq(&cfg_priv->evt_q_lock);
3366         while (!list_empty(&cfg_priv->evt_q_list)) {
3367                 e = list_first_entry(&cfg_priv->evt_q_list,
3368                                      struct brcmf_cfg80211_event_q, evt_q_list);
3369                 list_del(&e->evt_q_list);
3370                 kfree(e);
3371         }
3372         spin_unlock_irq(&cfg_priv->evt_q_lock);
3373 }
3374
3375 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3376 {
3377         s32 err = 0;
3378
3379         cfg_priv->scan_request = NULL;
3380         cfg_priv->pwr_save = true;
3381         cfg_priv->iscan_on = true;      /* iscan on & off switch.
3382                                  we enable iscan per default */
3383         cfg_priv->roam_on = true;       /* roam on & off switch.
3384                                  we enable roam per default */
3385
3386         cfg_priv->iscan_kickstart = false;
3387         cfg_priv->active_scan = true;   /* we do active scan for
3388                                  specific scan per default */
3389         cfg_priv->dongle_up = false;    /* dongle is not up yet */
3390         brcmf_init_eq(cfg_priv);
3391         err = brcmf_init_priv_mem(cfg_priv);
3392         if (err)
3393                 return err;
3394         INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3395         brcmf_init_eloop_handler(&cfg_priv->el);
3396         mutex_init(&cfg_priv->usr_sync);
3397         err = brcmf_init_iscan(cfg_priv);
3398         if (err)
3399                 return err;
3400         brcmf_init_conf(cfg_priv->conf);
3401         brcmf_init_prof(cfg_priv->profile);
3402         brcmf_link_down(cfg_priv);
3403
3404         return err;
3405 }
3406
3407 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3408 {
3409         cancel_work_sync(&cfg_priv->event_work);
3410         cfg_priv->dongle_up = false;    /* dongle down */
3411         brcmf_flush_eq(cfg_priv);
3412         brcmf_link_down(cfg_priv);
3413         brcmf_term_iscan(cfg_priv);
3414         brcmf_deinit_priv_mem(cfg_priv);
3415 }
3416
3417 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3418                                                  struct device *busdev,
3419                                                  void *data)
3420 {
3421         struct wireless_dev *wdev;
3422         struct brcmf_cfg80211_priv *cfg_priv;
3423         struct brcmf_cfg80211_iface *ci;
3424         struct brcmf_cfg80211_dev *cfg_dev;
3425         s32 err = 0;
3426
3427         if (!ndev) {
3428                 WL_ERR("ndev is invalid\n");
3429                 return NULL;
3430         }
3431         cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3432         if (!cfg_dev)
3433                 return NULL;
3434
3435         wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3436         if (IS_ERR(wdev)) {
3437                 kfree(cfg_dev);
3438                 return NULL;
3439         }
3440
3441         wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3442         cfg_priv = wdev_to_cfg(wdev);
3443         cfg_priv->wdev = wdev;
3444         cfg_priv->pub = data;
3445         ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3446         ci->cfg_priv = cfg_priv;
3447         ndev->ieee80211_ptr = wdev;
3448         SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3449         wdev->netdev = ndev;
3450         err = wl_init_priv(cfg_priv);
3451         if (err) {
3452                 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3453                 goto cfg80211_attach_out;
3454         }
3455         brcmf_set_drvdata(cfg_dev, ci);
3456
3457         return cfg_dev;
3458
3459 cfg80211_attach_out:
3460         brcmf_free_wdev(cfg_priv);
3461         kfree(cfg_dev);
3462         return NULL;
3463 }
3464
3465 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3466 {
3467         struct brcmf_cfg80211_priv *cfg_priv;
3468
3469         cfg_priv = brcmf_priv_get(cfg_dev);
3470
3471         wl_deinit_priv(cfg_priv);
3472         brcmf_free_wdev(cfg_priv);
3473         brcmf_set_drvdata(cfg_dev, NULL);
3474         kfree(cfg_dev);
3475 }
3476
3477 void
3478 brcmf_cfg80211_event(struct net_device *ndev,
3479                   const struct brcmf_event_msg *e, void *data)
3480 {
3481         u32 event_type = be32_to_cpu(e->event_type);
3482         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3483
3484         if (!brcmf_enq_event(cfg_priv, event_type, e))
3485                 schedule_work(&cfg_priv->event_work);
3486 }
3487
3488 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3489 {
3490         s32 infra = 0;
3491         s32 err = 0;
3492
3493         switch (iftype) {
3494         case NL80211_IFTYPE_MONITOR:
3495         case NL80211_IFTYPE_WDS:
3496                 WL_ERR("type (%d) : currently we do not support this mode\n",
3497                        iftype);
3498                 err = -EINVAL;
3499                 return err;
3500         case NL80211_IFTYPE_ADHOC:
3501                 infra = 0;
3502                 break;
3503         case NL80211_IFTYPE_STATION:
3504                 infra = 1;
3505                 break;
3506         default:
3507                 err = -EINVAL;
3508                 WL_ERR("invalid type (%d)\n", iftype);
3509                 return err;
3510         }
3511         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3512         if (err) {
3513                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3514                 return err;
3515         }
3516
3517         return 0;
3518 }
3519
3520 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3521 {
3522         /* Room for "event_msgs" + '\0' + bitvec */
3523         s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3524         s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3525         s32 err = 0;
3526
3527         WL_TRACE("Enter\n");
3528
3529         /* Setup event_msgs */
3530         brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3531                         iovbuf, sizeof(iovbuf));
3532         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3533         if (err) {
3534                 WL_ERR("Get event_msgs error (%d)\n", err);
3535                 goto dongle_eventmsg_out;
3536         }
3537         memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3538
3539         setbit(eventmask, BRCMF_E_SET_SSID);
3540         setbit(eventmask, BRCMF_E_ROAM);
3541         setbit(eventmask, BRCMF_E_PRUNE);
3542         setbit(eventmask, BRCMF_E_AUTH);
3543         setbit(eventmask, BRCMF_E_REASSOC);
3544         setbit(eventmask, BRCMF_E_REASSOC_IND);
3545         setbit(eventmask, BRCMF_E_DEAUTH_IND);
3546         setbit(eventmask, BRCMF_E_DISASSOC_IND);
3547         setbit(eventmask, BRCMF_E_DISASSOC);
3548         setbit(eventmask, BRCMF_E_JOIN);
3549         setbit(eventmask, BRCMF_E_ASSOC_IND);
3550         setbit(eventmask, BRCMF_E_PSK_SUP);
3551         setbit(eventmask, BRCMF_E_LINK);
3552         setbit(eventmask, BRCMF_E_NDIS_LINK);
3553         setbit(eventmask, BRCMF_E_MIC_ERROR);
3554         setbit(eventmask, BRCMF_E_PMKID_CACHE);
3555         setbit(eventmask, BRCMF_E_TXFAIL);
3556         setbit(eventmask, BRCMF_E_JOIN_START);
3557         setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3558
3559         brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3560                         iovbuf, sizeof(iovbuf));
3561         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3562         if (err) {
3563                 WL_ERR("Set event_msgs error (%d)\n", err);
3564                 goto dongle_eventmsg_out;
3565         }
3566
3567 dongle_eventmsg_out:
3568         WL_TRACE("Exit\n");
3569         return err;
3570 }
3571
3572 static s32
3573 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3574 {
3575         s8 iovbuf[32];
3576         s32 err = 0;
3577         __le32 roamtrigger[2];
3578         __le32 roam_delta[2];
3579         __le32 bcn_to_le;
3580         __le32 roamvar_le;
3581
3582         /*
3583          * Setup timeout if Beacons are lost and roam is
3584          * off to report link down
3585          */
3586         if (roamvar) {
3587                 bcn_to_le = cpu_to_le32(bcn_timeout);
3588                 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3589                         sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3590                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3591                                    iovbuf, sizeof(iovbuf));
3592                 if (err) {
3593                         WL_ERR("bcn_timeout error (%d)\n", err);
3594                         goto dongle_rom_out;
3595                 }
3596         }
3597
3598         /*
3599          * Enable/Disable built-in roaming to allow supplicant
3600          * to take care of roaming
3601          */
3602         WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3603         roamvar_le = cpu_to_le32(roamvar);
3604         brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3605                                 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3606         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3607         if (err) {
3608                 WL_ERR("roam_off error (%d)\n", err);
3609                 goto dongle_rom_out;
3610         }
3611
3612         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3613         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3614         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3615                         (void *)roamtrigger, sizeof(roamtrigger));
3616         if (err) {
3617                 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3618                 goto dongle_rom_out;
3619         }
3620
3621         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3622         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3623         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3624                                 (void *)roam_delta, sizeof(roam_delta));
3625         if (err) {
3626                 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3627                 goto dongle_rom_out;
3628         }
3629
3630 dongle_rom_out:
3631         return err;
3632 }
3633
3634 static s32
3635 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3636                       s32 scan_unassoc_time, s32 scan_passive_time)
3637 {
3638         s32 err = 0;
3639         __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3640         __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3641         __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3642
3643         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3644                            &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3645         if (err) {
3646                 if (err == -EOPNOTSUPP)
3647                         WL_INFO("Scan assoc time is not supported\n");
3648                 else
3649                         WL_ERR("Scan assoc time error (%d)\n", err);
3650                 goto dongle_scantime_out;
3651         }
3652         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3653                            &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3654         if (err) {
3655                 if (err == -EOPNOTSUPP)
3656                         WL_INFO("Scan unassoc time is not supported\n");
3657                 else
3658                         WL_ERR("Scan unassoc time error (%d)\n", err);
3659                 goto dongle_scantime_out;
3660         }
3661
3662         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3663                            &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3664         if (err) {
3665                 if (err == -EOPNOTSUPP)
3666                         WL_INFO("Scan passive time is not supported\n");
3667                 else
3668                         WL_ERR("Scan passive time error (%d)\n", err);
3669                 goto dongle_scantime_out;
3670         }
3671
3672 dongle_scantime_out:
3673         return err;
3674 }
3675
3676 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3677 {
3678         struct wiphy *wiphy;
3679         s32 phy_list;
3680         s8 phy;
3681         s32 err = 0;
3682
3683         err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3684                               &phy_list, sizeof(phy_list));
3685         if (err) {
3686                 WL_ERR("error (%d)\n", err);
3687                 return err;
3688         }
3689
3690         phy = ((char *)&phy_list)[1];
3691         WL_INFO("%c phy\n", phy);
3692         if (phy == 'n' || phy == 'a') {
3693                 wiphy = cfg_to_wiphy(cfg_priv);
3694                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3695         }
3696
3697         return err;
3698 }
3699
3700 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3701 {
3702         return wl_update_wiphybands(cfg_priv);
3703 }
3704
3705 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3706 {
3707         struct net_device *ndev;
3708         struct wireless_dev *wdev;
3709         s32 power_mode;
3710         s32 err = 0;
3711
3712         if (cfg_priv->dongle_up)
3713                 return err;
3714
3715         ndev = cfg_to_ndev(cfg_priv);
3716         wdev = ndev->ieee80211_ptr;
3717
3718         brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3719                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3720
3721         err = brcmf_dongle_eventmsg(ndev);
3722         if (err)
3723                 goto default_conf_out;
3724
3725         power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3726         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3727         if (err)
3728                 goto default_conf_out;
3729         WL_INFO("power save set to %s\n",
3730                 (power_mode ? "enabled" : "disabled"));
3731
3732         err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3733                                 WL_BEACON_TIMEOUT);
3734         if (err)
3735                 goto default_conf_out;
3736         err = brcmf_dongle_mode(ndev, wdev->iftype);
3737         if (err && err != -EINPROGRESS)
3738                 goto default_conf_out;
3739         err = brcmf_dongle_probecap(cfg_priv);
3740         if (err)
3741                 goto default_conf_out;
3742
3743         /* -EINPROGRESS: Call commit handler */
3744
3745 default_conf_out:
3746
3747         cfg_priv->dongle_up = true;
3748
3749         return err;
3750
3751 }
3752
3753 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3754 {
3755         char buf[10+IFNAMSIZ];
3756         struct dentry *fd;
3757         s32 err = 0;
3758
3759         sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3760         cfg_priv->debugfsdir = debugfs_create_dir(buf,
3761                                         cfg_to_wiphy(cfg_priv)->debugfsdir);
3762
3763         fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3764                 (u16 *)&cfg_priv->profile->beacon_interval);
3765         if (!fd) {
3766                 err = -ENOMEM;
3767                 goto err_out;
3768         }
3769
3770         fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3771                 (u8 *)&cfg_priv->profile->dtim_period);
3772         if (!fd) {
3773                 err = -ENOMEM;
3774                 goto err_out;
3775         }
3776
3777 err_out:
3778         return err;
3779 }
3780
3781 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3782 {
3783         debugfs_remove_recursive(cfg_priv->debugfsdir);
3784         cfg_priv->debugfsdir = NULL;
3785 }
3786
3787 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3788 {
3789         s32 err = 0;
3790
3791         set_bit(WL_STATUS_READY, &cfg_priv->status);
3792
3793         brcmf_debugfs_add_netdev_params(cfg_priv);
3794
3795         err = brcmf_config_dongle(cfg_priv);
3796         if (err)
3797                 return err;
3798
3799         brcmf_invoke_iscan(cfg_priv);
3800
3801         return err;
3802 }
3803
3804 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3805 {
3806         /*
3807          * While going down, if associated with AP disassociate
3808          * from AP to save power
3809          */
3810         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3811              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3812              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3813                 WL_INFO("Disassociating from AP");
3814                 brcmf_link_down(cfg_priv);
3815
3816                 /* Make sure WPA_Supplicant receives all the event
3817                    generated due to DISASSOC call to the fw to keep
3818                    the state fw and WPA_Supplicant state consistent
3819                  */
3820                 brcmf_delay(500);
3821         }
3822
3823         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3824         brcmf_term_iscan(cfg_priv);
3825         if (cfg_priv->scan_request) {
3826                 cfg80211_scan_done(cfg_priv->scan_request, true);
3827                 /* May need to perform this to cover rmmod */
3828                 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3829                 cfg_priv->scan_request = NULL;
3830         }
3831         clear_bit(WL_STATUS_READY, &cfg_priv->status);
3832         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3833         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3834
3835         brcmf_debugfs_remove_netdev(cfg_priv);
3836
3837         return 0;
3838 }
3839
3840 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3841 {
3842         struct brcmf_cfg80211_priv *cfg_priv;
3843         s32 err = 0;
3844
3845         cfg_priv = brcmf_priv_get(cfg_dev);
3846         mutex_lock(&cfg_priv->usr_sync);
3847         err = __brcmf_cfg80211_up(cfg_priv);
3848         mutex_unlock(&cfg_priv->usr_sync);
3849
3850         return err;
3851 }
3852
3853 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3854 {
3855         struct brcmf_cfg80211_priv *cfg_priv;
3856         s32 err = 0;
3857
3858         cfg_priv = brcmf_priv_get(cfg_dev);
3859         mutex_lock(&cfg_priv->usr_sync);
3860         err = __brcmf_cfg80211_down(cfg_priv);
3861         mutex_unlock(&cfg_priv->usr_sync);
3862
3863         return err;
3864 }
3865
3866 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3867                                u8 t, u8 l, u8 *v)
3868 {
3869         struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3870         s32 err = 0;
3871
3872         if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3873                 WL_ERR("ei crosses buffer boundary\n");
3874                 return -ENOSPC;
3875         }
3876         ie->buf[ie->offset] = t;
3877         ie->buf[ie->offset + 1] = l;
3878         memcpy(&ie->buf[ie->offset + 2], v, l);
3879         ie->offset += l + 2;
3880
3881         return err;
3882 }