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