]> git.karo-electronics.de Git - linux-beck.git/blob - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
[SCSI] libfc: remove redundant timer init for fcp
[linux-beck.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 mbm)
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         s32 dbm = MBM_TO_DBM(mbm);
1441
1442         WL_TRACE("Enter\n");
1443         if (!check_sys_up(wiphy))
1444                 return -EIO;
1445
1446         switch (type) {
1447         case NL80211_TX_POWER_AUTOMATIC:
1448                 break;
1449         case NL80211_TX_POWER_LIMITED:
1450         case NL80211_TX_POWER_FIXED:
1451                 if (dbm < 0) {
1452                         WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1453                         err = -EINVAL;
1454                         goto done;
1455                 }
1456                 break;
1457         }
1458         /* Make sure radio is off or on as far as software is concerned */
1459         disable = WL_RADIO_SW_DISABLE << 16;
1460         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1461         if (err)
1462                 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1463
1464         if (dbm > 0xffff)
1465                 txpwrmw = 0xffff;
1466         else
1467                 txpwrmw = (u16) dbm;
1468         err = brcmf_dev_intvar_set(ndev, "qtxpower",
1469                         (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1470         if (err)
1471                 WL_ERR("qtxpower error (%d)\n", err);
1472         cfg_priv->conf->tx_power = dbm;
1473
1474 done:
1475         WL_TRACE("Exit\n");
1476         return err;
1477 }
1478
1479 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1480 {
1481         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1482         struct net_device *ndev = cfg_to_ndev(cfg_priv);
1483         s32 txpwrdbm;
1484         u8 result;
1485         s32 err = 0;
1486
1487         WL_TRACE("Enter\n");
1488         if (!check_sys_up(wiphy))
1489                 return -EIO;
1490
1491         err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1492         if (err) {
1493                 WL_ERR("error (%d)\n", err);
1494                 goto done;
1495         }
1496
1497         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1498         *dbm = (s32) brcmf_qdbm_to_mw(result);
1499
1500 done:
1501         WL_TRACE("Exit\n");
1502         return err;
1503 }
1504
1505 static s32
1506 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1507                                u8 key_idx, bool unicast, bool multicast)
1508 {
1509         u32 index;
1510         u32 wsec;
1511         s32 err = 0;
1512
1513         WL_TRACE("Enter\n");
1514         WL_CONN("key index (%d)\n", key_idx);
1515         if (!check_sys_up(wiphy))
1516                 return -EIO;
1517
1518         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1519         if (err) {
1520                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1521                 goto done;
1522         }
1523
1524         if (wsec & WEP_ENABLED) {
1525                 /* Just select a new current key */
1526                 index = key_idx;
1527                 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1528                                           &index);
1529                 if (err)
1530                         WL_ERR("error (%d)\n", err);
1531         }
1532 done:
1533         WL_TRACE("Exit\n");
1534         return err;
1535 }
1536
1537 static s32
1538 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1539               u8 key_idx, const u8 *mac_addr, struct key_params *params)
1540 {
1541         struct brcmf_wsec_key key;
1542         struct brcmf_wsec_key_le key_le;
1543         s32 err = 0;
1544
1545         memset(&key, 0, sizeof(key));
1546         key.index = (u32) key_idx;
1547         /* Instead of bcast for ea address for default wep keys,
1548                  driver needs it to be Null */
1549         if (!is_multicast_ether_addr(mac_addr))
1550                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1551         key.len = (u32) params->key_len;
1552         /* check for key index change */
1553         if (key.len == 0) {
1554                 /* key delete */
1555                 err = send_key_to_dongle(ndev, &key);
1556                 if (err)
1557                         return err;
1558         } else {
1559                 if (key.len > sizeof(key.data)) {
1560                         WL_ERR("Invalid key length (%d)\n", key.len);
1561                         return -EINVAL;
1562                 }
1563
1564                 WL_CONN("Setting the key index %d\n", key.index);
1565                 memcpy(key.data, params->key, key.len);
1566
1567                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1568                         u8 keybuf[8];
1569                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1570                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1571                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1572                 }
1573
1574                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1575                 if (params->seq && params->seq_len == 6) {
1576                         /* rx iv */
1577                         u8 *ivptr;
1578                         ivptr = (u8 *) params->seq;
1579                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1580                             (ivptr[3] << 8) | ivptr[2];
1581                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1582                         key.iv_initialized = true;
1583                 }
1584
1585                 switch (params->cipher) {
1586                 case WLAN_CIPHER_SUITE_WEP40:
1587                         key.algo = CRYPTO_ALGO_WEP1;
1588                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1589                         break;
1590                 case WLAN_CIPHER_SUITE_WEP104:
1591                         key.algo = CRYPTO_ALGO_WEP128;
1592                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1593                         break;
1594                 case WLAN_CIPHER_SUITE_TKIP:
1595                         key.algo = CRYPTO_ALGO_TKIP;
1596                         WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1597                         break;
1598                 case WLAN_CIPHER_SUITE_AES_CMAC:
1599                         key.algo = CRYPTO_ALGO_AES_CCM;
1600                         WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1601                         break;
1602                 case WLAN_CIPHER_SUITE_CCMP:
1603                         key.algo = CRYPTO_ALGO_AES_CCM;
1604                         WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1605                         break;
1606                 default:
1607                         WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1608                         return -EINVAL;
1609                 }
1610                 convert_key_from_CPU(&key, &key_le);
1611
1612                 brcmf_netdev_wait_pend8021x(ndev);
1613                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1614                                       sizeof(key_le));
1615                 if (err) {
1616                         WL_ERR("WLC_SET_KEY error (%d)\n", err);
1617                         return err;
1618                 }
1619         }
1620         return err;
1621 }
1622
1623 static s32
1624 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1625                     u8 key_idx, bool pairwise, const u8 *mac_addr,
1626                     struct key_params *params)
1627 {
1628         struct brcmf_wsec_key key;
1629         s32 val;
1630         s32 wsec;
1631         s32 err = 0;
1632         u8 keybuf[8];
1633
1634         WL_TRACE("Enter\n");
1635         WL_CONN("key index (%d)\n", key_idx);
1636         if (!check_sys_up(wiphy))
1637                 return -EIO;
1638
1639         if (mac_addr) {
1640                 WL_TRACE("Exit");
1641                 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1642         }
1643         memset(&key, 0, sizeof(key));
1644
1645         key.len = (u32) params->key_len;
1646         key.index = (u32) key_idx;
1647
1648         if (key.len > sizeof(key.data)) {
1649                 WL_ERR("Too long key length (%u)\n", key.len);
1650                 err = -EINVAL;
1651                 goto done;
1652         }
1653         memcpy(key.data, params->key, key.len);
1654
1655         key.flags = BRCMF_PRIMARY_KEY;
1656         switch (params->cipher) {
1657         case WLAN_CIPHER_SUITE_WEP40:
1658                 key.algo = CRYPTO_ALGO_WEP1;
1659                 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1660                 break;
1661         case WLAN_CIPHER_SUITE_WEP104:
1662                 key.algo = CRYPTO_ALGO_WEP128;
1663                 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1664                 break;
1665         case WLAN_CIPHER_SUITE_TKIP:
1666                 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1667                 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1668                 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1669                 key.algo = CRYPTO_ALGO_TKIP;
1670                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1671                 break;
1672         case WLAN_CIPHER_SUITE_AES_CMAC:
1673                 key.algo = CRYPTO_ALGO_AES_CCM;
1674                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1675                 break;
1676         case WLAN_CIPHER_SUITE_CCMP:
1677                 key.algo = CRYPTO_ALGO_AES_CCM;
1678                 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1679                 break;
1680         default:
1681                 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1682                 err = -EINVAL;
1683                 goto done;
1684         }
1685
1686         err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1687         if (err)
1688                 goto done;
1689
1690         val = WEP_ENABLED;
1691         err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1692         if (err) {
1693                 WL_ERR("get wsec error (%d)\n", err);
1694                 goto done;
1695         }
1696         wsec &= ~(WEP_ENABLED);
1697         wsec |= val;
1698         err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1699         if (err) {
1700                 WL_ERR("set wsec error (%d)\n", err);
1701                 goto done;
1702         }
1703
1704         val = 1;                /* assume shared key. otherwise 0 */
1705         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1706         if (err)
1707                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1708 done:
1709         WL_TRACE("Exit\n");
1710         return err;
1711 }
1712
1713 static s32
1714 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1715                     u8 key_idx, bool pairwise, const u8 *mac_addr)
1716 {
1717         struct brcmf_wsec_key key;
1718         s32 err = 0;
1719         s32 val;
1720         s32 wsec;
1721
1722         WL_TRACE("Enter\n");
1723         if (!check_sys_up(wiphy))
1724                 return -EIO;
1725
1726         memset(&key, 0, sizeof(key));
1727
1728         key.index = (u32) key_idx;
1729         key.flags = BRCMF_PRIMARY_KEY;
1730         key.algo = CRYPTO_ALGO_OFF;
1731
1732         WL_CONN("key index (%d)\n", key_idx);
1733
1734         /* Set the new key/index */
1735         err = send_key_to_dongle(ndev, &key);
1736         if (err) {
1737                 if (err == -EINVAL) {
1738                         if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1739                                 /* we ignore this key index in this case */
1740                                 WL_ERR("invalid key index (%d)\n", key_idx);
1741                 }
1742                 /* Ignore this error, may happen during DISASSOC */
1743                 err = -EAGAIN;
1744                 goto done;
1745         }
1746
1747         val = 0;
1748         err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1749         if (err) {
1750                 WL_ERR("get wsec error (%d)\n", err);
1751                 /* Ignore this error, may happen during DISASSOC */
1752                 err = -EAGAIN;
1753                 goto done;
1754         }
1755         wsec &= ~(WEP_ENABLED);
1756         wsec |= val;
1757         err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1758         if (err) {
1759                 WL_ERR("set wsec error (%d)\n", err);
1760                 /* Ignore this error, may happen during DISASSOC */
1761                 err = -EAGAIN;
1762                 goto done;
1763         }
1764
1765         val = 0;                /* assume open key. otherwise 1 */
1766         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1767         if (err) {
1768                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1769                 /* Ignore this error, may happen during DISASSOC */
1770                 err = -EAGAIN;
1771         }
1772 done:
1773         WL_TRACE("Exit\n");
1774         return err;
1775 }
1776
1777 static s32
1778 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1779                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1780                     void (*callback) (void *cookie, struct key_params * params))
1781 {
1782         struct key_params params;
1783         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1784         struct brcmf_cfg80211_security *sec;
1785         s32 wsec;
1786         s32 err = 0;
1787
1788         WL_TRACE("Enter\n");
1789         WL_CONN("key index (%d)\n", key_idx);
1790         if (!check_sys_up(wiphy))
1791                 return -EIO;
1792
1793         memset(&params, 0, sizeof(params));
1794
1795         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1796         if (err) {
1797                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1798                 /* Ignore this error, may happen during DISASSOC */
1799                 err = -EAGAIN;
1800                 goto done;
1801         }
1802         switch (wsec) {
1803         case WEP_ENABLED:
1804                 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1805                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1806                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
1807                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1808                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1809                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
1810                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1811                 }
1812                 break;
1813         case TKIP_ENABLED:
1814                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1815                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1816                 break;
1817         case AES_ENABLED:
1818                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1819                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1820                 break;
1821         default:
1822                 WL_ERR("Invalid algo (0x%x)\n", wsec);
1823                 err = -EINVAL;
1824                 goto done;
1825         }
1826         callback(cookie, &params);
1827
1828 done:
1829         WL_TRACE("Exit\n");
1830         return err;
1831 }
1832
1833 static s32
1834 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1835                                     struct net_device *ndev, u8 key_idx)
1836 {
1837         WL_INFO("Not supported\n");
1838
1839         return -EOPNOTSUPP;
1840 }
1841
1842 static s32
1843 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1844                         u8 *mac, struct station_info *sinfo)
1845 {
1846         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1847         struct brcmf_scb_val_le scb_val;
1848         int rssi;
1849         s32 rate;
1850         s32 err = 0;
1851         u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1852
1853         WL_TRACE("Enter\n");
1854         if (!check_sys_up(wiphy))
1855                 return -EIO;
1856
1857         if (memcmp(mac, bssid, ETH_ALEN)) {
1858                 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1859                         "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1860                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1861                         bssid[0], bssid[1], bssid[2], bssid[3],
1862                         bssid[4], bssid[5]);
1863                 err = -ENOENT;
1864                 goto done;
1865         }
1866
1867         /* Report the current tx rate */
1868         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1869         if (err) {
1870                 WL_ERR("Could not get rate (%d)\n", err);
1871         } else {
1872                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1873                 sinfo->txrate.legacy = rate * 5;
1874                 WL_CONN("Rate %d Mbps\n", rate / 2);
1875         }
1876
1877         if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1878                 scb_val.val = cpu_to_le32(0);
1879                 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1880                                       sizeof(struct brcmf_scb_val_le));
1881                 if (err)
1882                         WL_ERR("Could not get rssi (%d)\n", err);
1883
1884                 rssi = le32_to_cpu(scb_val.val);
1885                 sinfo->filled |= STATION_INFO_SIGNAL;
1886                 sinfo->signal = rssi;
1887                 WL_CONN("RSSI %d dBm\n", rssi);
1888         }
1889
1890 done:
1891         WL_TRACE("Exit\n");
1892         return err;
1893 }
1894
1895 static s32
1896 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1897                            bool enabled, s32 timeout)
1898 {
1899         s32 pm;
1900         s32 err = 0;
1901         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1902
1903         WL_TRACE("Enter\n");
1904
1905         /*
1906          * Powersave enable/disable request is coming from the
1907          * cfg80211 even before the interface is up. In that
1908          * scenario, driver will be storing the power save
1909          * preference in cfg_priv struct to apply this to
1910          * FW later while initializing the dongle
1911          */
1912         cfg_priv->pwr_save = enabled;
1913         if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1914
1915                 WL_INFO("Device is not ready,"
1916                         "storing the value in cfg_priv struct\n");
1917                 goto done;
1918         }
1919
1920         pm = enabled ? PM_FAST : PM_OFF;
1921         WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1922
1923         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1924         if (err) {
1925                 if (err == -ENODEV)
1926                         WL_ERR("net_device is not ready yet\n");
1927                 else
1928                         WL_ERR("error (%d)\n", err);
1929         }
1930 done:
1931         WL_TRACE("Exit\n");
1932         return err;
1933 }
1934
1935 static s32
1936 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1937                              const u8 *addr,
1938                              const struct cfg80211_bitrate_mask *mask)
1939 {
1940         struct brcm_rateset_le rateset_le;
1941         s32 rate;
1942         s32 val;
1943         s32 err_bg;
1944         s32 err_a;
1945         u32 legacy;
1946         s32 err = 0;
1947
1948         WL_TRACE("Enter\n");
1949         if (!check_sys_up(wiphy))
1950                 return -EIO;
1951
1952         /* addr param is always NULL. ignore it */
1953         /* Get current rateset */
1954         err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1955                               sizeof(rateset_le));
1956         if (err) {
1957                 WL_ERR("could not get current rateset (%d)\n", err);
1958                 goto done;
1959         }
1960
1961         legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1962         if (!legacy)
1963                 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1964                              0xFFFF);
1965
1966         val = wl_g_rates[legacy - 1].bitrate * 100000;
1967
1968         if (val < le32_to_cpu(rateset_le.count))
1969                 /* Select rate by rateset index */
1970                 rate = rateset_le.rates[val] & 0x7f;
1971         else
1972                 /* Specified rate in bps */
1973                 rate = val / 500000;
1974
1975         WL_CONN("rate %d mbps\n", rate / 2);
1976
1977         /*
1978          *
1979          *      Set rate override,
1980          *      Since the is a/b/g-blind, both a/bg_rate are enforced.
1981          */
1982         err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1983         err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1984         if (err_bg && err_a) {
1985                 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1986                 err = err_bg | err_a;
1987         }
1988
1989 done:
1990         WL_TRACE("Exit\n");
1991         return err;
1992 }
1993
1994 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1995                                    struct brcmf_bss_info_le *bi)
1996 {
1997         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
1998         struct ieee80211_channel *notify_channel;
1999         struct cfg80211_bss *bss;
2000         struct ieee80211_supported_band *band;
2001         s32 err = 0;
2002         u16 channel;
2003         u32 freq;
2004         u64 notify_timestamp;
2005         u16 notify_capability;
2006         u16 notify_interval;
2007         u8 *notify_ie;
2008         size_t notify_ielen;
2009         s32 notify_signal;
2010
2011         if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2012                 WL_ERR("Bss info is larger than buffer. Discarding\n");
2013                 return 0;
2014         }
2015
2016         channel = bi->ctl_ch ? bi->ctl_ch :
2017                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2018
2019         if (channel <= CH_MAX_2G_CHANNEL)
2020                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2021         else
2022                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2023
2024         freq = ieee80211_channel_to_frequency(channel, band->band);
2025         notify_channel = ieee80211_get_channel(wiphy, freq);
2026
2027         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2028         notify_capability = le16_to_cpu(bi->capability);
2029         notify_interval = le16_to_cpu(bi->beacon_period);
2030         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2031         notify_ielen = le32_to_cpu(bi->ie_length);
2032         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2033
2034         WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2035                         bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2036                         bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2037         WL_CONN("Channel: %d(%d)\n", channel, freq);
2038         WL_CONN("Capability: %X\n", notify_capability);
2039         WL_CONN("Beacon interval: %d\n", notify_interval);
2040         WL_CONN("Signal: %d\n", notify_signal);
2041         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2042
2043         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2044                 notify_timestamp, notify_capability, notify_interval, notify_ie,
2045                 notify_ielen, notify_signal, GFP_KERNEL);
2046
2047         if (!bss)
2048                 return -ENOMEM;
2049
2050         cfg80211_put_bss(bss);
2051
2052         return err;
2053 }
2054
2055 static struct brcmf_bss_info_le *
2056 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2057 {
2058         if (bss == NULL)
2059                 return list->bss_info_le;
2060         return (struct brcmf_bss_info_le *)((unsigned long)bss +
2061                                             le32_to_cpu(bss->length));
2062 }
2063
2064 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2065 {
2066         struct brcmf_scan_results *bss_list;
2067         struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2068         s32 err = 0;
2069         int i;
2070
2071         bss_list = cfg_priv->bss_list;
2072         if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2073                 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2074                        bss_list->version);
2075                 return -EOPNOTSUPP;
2076         }
2077         WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2078         for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2079                 bi = next_bss_le(bss_list, bi);
2080                 err = brcmf_inform_single_bss(cfg_priv, bi);
2081                 if (err)
2082                         break;
2083         }
2084         return err;
2085 }
2086
2087 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2088                           struct net_device *ndev, const u8 *bssid)
2089 {
2090         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2091         struct ieee80211_channel *notify_channel;
2092         struct brcmf_bss_info_le *bi = NULL;
2093         struct ieee80211_supported_band *band;
2094         struct cfg80211_bss *bss;
2095         u8 *buf = NULL;
2096         s32 err = 0;
2097         u16 channel;
2098         u32 freq;
2099         u64 notify_timestamp;
2100         u16 notify_capability;
2101         u16 notify_interval;
2102         u8 *notify_ie;
2103         size_t notify_ielen;
2104         s32 notify_signal;
2105
2106         WL_TRACE("Enter\n");
2107
2108         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2109         if (buf == NULL) {
2110                 err = -ENOMEM;
2111                 goto CleanUp;
2112         }
2113
2114         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2115
2116         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2117         if (err) {
2118                 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2119                 goto CleanUp;
2120         }
2121
2122         bi = (struct brcmf_bss_info_le *)(buf + 4);
2123
2124         channel = bi->ctl_ch ? bi->ctl_ch :
2125                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2126
2127         if (channel <= CH_MAX_2G_CHANNEL)
2128                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2129         else
2130                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2131
2132         freq = ieee80211_channel_to_frequency(channel, band->band);
2133         notify_channel = ieee80211_get_channel(wiphy, freq);
2134
2135         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2136         notify_capability = le16_to_cpu(bi->capability);
2137         notify_interval = le16_to_cpu(bi->beacon_period);
2138         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2139         notify_ielen = le32_to_cpu(bi->ie_length);
2140         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2141
2142         WL_CONN("channel: %d(%d)\n", channel, freq);
2143         WL_CONN("capability: %X\n", notify_capability);
2144         WL_CONN("beacon interval: %d\n", notify_interval);
2145         WL_CONN("signal: %d\n", notify_signal);
2146         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2147
2148         bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2149                 notify_timestamp, notify_capability, notify_interval,
2150                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2151
2152         if (!bss) {
2153                 err = -ENOMEM;
2154                 goto CleanUp;
2155         }
2156
2157         cfg80211_put_bss(bss);
2158
2159 CleanUp:
2160
2161         kfree(buf);
2162
2163         WL_TRACE("Exit\n");
2164
2165         return err;
2166 }
2167
2168 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2169 {
2170         return cfg_priv->conf->mode == WL_MODE_IBSS;
2171 }
2172
2173 /*
2174  * Traverse a string of 1-byte tag/1-byte length/variable-length value
2175  * triples, returning a pointer to the substring whose first element
2176  * matches tag
2177  */
2178 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2179 {
2180         struct brcmf_tlv *elt;
2181         int totlen;
2182
2183         elt = (struct brcmf_tlv *) buf;
2184         totlen = buflen;
2185
2186         /* find tagged parameter */
2187         while (totlen >= 2) {
2188                 int len = elt->len;
2189
2190                 /* validate remaining totlen */
2191                 if ((elt->id == key) && (totlen >= (len + 2)))
2192                         return elt;
2193
2194                 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2195                 totlen -= (len + 2);
2196         }
2197
2198         return NULL;
2199 }
2200
2201 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2202 {
2203         struct brcmf_bss_info_le *bi;
2204         struct brcmf_ssid *ssid;
2205         struct brcmf_tlv *tim;
2206         u16 beacon_interval;
2207         u8 dtim_period;
2208         size_t ie_len;
2209         u8 *ie;
2210         s32 err = 0;
2211
2212         WL_TRACE("Enter\n");
2213         if (brcmf_is_ibssmode(cfg_priv))
2214                 return err;
2215
2216         ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2217
2218         *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2219         err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2220                         cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2221         if (err) {
2222                 WL_ERR("Could not get bss info %d\n", err);
2223                 goto update_bss_info_out;
2224         }
2225
2226         bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
2227         err = brcmf_inform_single_bss(cfg_priv, bi);
2228         if (err)
2229                 goto update_bss_info_out;
2230
2231         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2232         ie_len = le32_to_cpu(bi->ie_length);
2233         beacon_interval = le16_to_cpu(bi->beacon_period);
2234
2235         tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2236         if (tim)
2237                 dtim_period = tim->data[1];
2238         else {
2239                 /*
2240                 * active scan was done so we could not get dtim
2241                 * information out of probe response.
2242                 * so we speficially query dtim information to dongle.
2243                 */
2244                 u32 var;
2245                 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2246                                            "dtim_assoc", &var);
2247                 if (err) {
2248                         WL_ERR("wl dtim_assoc failed (%d)\n", err);
2249                         goto update_bss_info_out;
2250                 }
2251                 dtim_period = (u8)var;
2252         }
2253
2254         brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2255         brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2256
2257 update_bss_info_out:
2258         WL_TRACE("Exit");
2259         return err;
2260 }
2261
2262 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2263 {
2264         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2265         struct brcmf_ssid ssid;
2266
2267         if (cfg_priv->iscan_on) {
2268                 iscan->state = WL_ISCAN_STATE_IDLE;
2269
2270                 if (iscan->timer_on) {
2271                         del_timer_sync(&iscan->timer);
2272                         iscan->timer_on = 0;
2273                 }
2274
2275                 cancel_work_sync(&iscan->work);
2276
2277                 /* Abort iscan running in FW */
2278                 memset(&ssid, 0, sizeof(ssid));
2279                 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2280         }
2281 }
2282
2283 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2284                                         bool aborted)
2285 {
2286         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2287         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2288
2289         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2290                 WL_ERR("Scan complete while device not scanning\n");
2291                 return;
2292         }
2293         if (cfg_priv->scan_request) {
2294                 WL_SCAN("ISCAN Completed scan: %s\n",
2295                                 aborted ? "Aborted" : "Done");
2296                 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2297                 brcmf_set_mpc(ndev, 1);
2298                 cfg_priv->scan_request = NULL;
2299         }
2300         cfg_priv->iscan_kickstart = false;
2301 }
2302
2303 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2304 {
2305         if (iscan->state != WL_ISCAN_STATE_IDLE) {
2306                 WL_SCAN("wake up iscan\n");
2307                 schedule_work(&iscan->work);
2308                 return 0;
2309         }
2310
2311         return -EIO;
2312 }
2313
2314 static s32
2315 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2316                      struct brcmf_scan_results **bss_list)
2317 {
2318         struct brcmf_iscan_results list;
2319         struct brcmf_scan_results *results;
2320         struct brcmf_scan_results_le *results_le;
2321         struct brcmf_iscan_results *list_buf;
2322         s32 err = 0;
2323
2324         memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2325         list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2326         results = &list_buf->results;
2327         results_le = &list_buf->results_le;
2328         results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2329         results->version = 0;
2330         results->count = 0;
2331
2332         memset(&list, 0, sizeof(list));
2333         list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2334         err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2335                                      BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2336                                      iscan->scan_buf, WL_ISCAN_BUF_MAX);
2337         if (err) {
2338                 WL_ERR("error (%d)\n", err);
2339                 return err;
2340         }
2341         results->buflen = le32_to_cpu(results_le->buflen);
2342         results->version = le32_to_cpu(results_le->version);
2343         results->count = le32_to_cpu(results_le->count);
2344         WL_SCAN("results->count = %d\n", results_le->count);
2345         WL_SCAN("results->buflen = %d\n", results_le->buflen);
2346         *status = le32_to_cpu(list_buf->status_le);
2347         WL_SCAN("status = %d\n", *status);
2348         *bss_list = results;
2349
2350         return err;
2351 }
2352
2353 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2354 {
2355         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2356         s32 err = 0;
2357
2358         iscan->state = WL_ISCAN_STATE_IDLE;
2359         brcmf_inform_bss(cfg_priv);
2360         brcmf_notify_iscan_complete(iscan, false);
2361
2362         return err;
2363 }
2364
2365 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2366 {
2367         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2368         s32 err = 0;
2369
2370         /* Reschedule the timer */
2371         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2372         iscan->timer_on = 1;
2373
2374         return err;
2375 }
2376
2377 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2378 {
2379         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2380         s32 err = 0;
2381
2382         brcmf_inform_bss(cfg_priv);
2383         brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2384         /* Reschedule the timer */
2385         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2386         iscan->timer_on = 1;
2387
2388         return err;
2389 }
2390
2391 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2392 {
2393         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2394         s32 err = 0;
2395
2396         iscan->state = WL_ISCAN_STATE_IDLE;
2397         brcmf_notify_iscan_complete(iscan, true);
2398
2399         return err;
2400 }
2401
2402 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2403 {
2404         struct brcmf_cfg80211_iscan_ctrl *iscan =
2405                         container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2406                                      work);
2407         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2408         struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2409         u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2410
2411         if (iscan->timer_on) {
2412                 del_timer_sync(&iscan->timer);
2413                 iscan->timer_on = 0;
2414         }
2415
2416         if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2417                 status = BRCMF_SCAN_RESULTS_ABORTED;
2418                 WL_ERR("Abort iscan\n");
2419         }
2420
2421         el->handler[status](cfg_priv);
2422 }
2423
2424 static void brcmf_iscan_timer(unsigned long data)
2425 {
2426         struct brcmf_cfg80211_iscan_ctrl *iscan =
2427                         (struct brcmf_cfg80211_iscan_ctrl *)data;
2428
2429         if (iscan) {
2430                 iscan->timer_on = 0;
2431                 WL_SCAN("timer expired\n");
2432                 brcmf_wakeup_iscan(iscan);
2433         }
2434 }
2435
2436 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2437 {
2438         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2439
2440         if (cfg_priv->iscan_on) {
2441                 iscan->state = WL_ISCAN_STATE_IDLE;
2442                 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2443         }
2444
2445         return 0;
2446 }
2447
2448 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2449 {
2450         memset(el, 0, sizeof(*el));
2451         el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2452         el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2453         el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2454         el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2455         el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2456 }
2457
2458 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2459 {
2460         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2461         int err = 0;
2462
2463         if (cfg_priv->iscan_on) {
2464                 iscan->ndev = cfg_to_ndev(cfg_priv);
2465                 brcmf_init_iscan_eloop(&iscan->el);
2466                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2467                 init_timer(&iscan->timer);
2468                 iscan->timer.data = (unsigned long) iscan;
2469                 iscan->timer.function = brcmf_iscan_timer;
2470                 err = brcmf_invoke_iscan(cfg_priv);
2471                 if (!err)
2472                         iscan->data = cfg_priv;
2473         }
2474
2475         return err;
2476 }
2477
2478 static void brcmf_delay(u32 ms)
2479 {
2480         if (ms < 1000 / HZ) {
2481                 cond_resched();
2482                 mdelay(ms);
2483         } else {
2484                 msleep(ms);
2485         }
2486 }
2487
2488 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2489 {
2490         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2491
2492         /*
2493          * Check for WL_STATUS_READY before any function call which
2494          * could result is bus access. Don't block the resume for
2495          * any driver error conditions
2496          */
2497         WL_TRACE("Enter\n");
2498
2499         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2500                 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2501
2502         WL_TRACE("Exit\n");
2503         return 0;
2504 }
2505
2506 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2507                                   struct cfg80211_wowlan *wow)
2508 {
2509         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2510         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2511
2512         WL_TRACE("Enter\n");
2513
2514         /*
2515          * Check for WL_STATUS_READY before any function call which
2516          * could result is bus access. Don't block the suspend for
2517          * any driver error conditions
2518          */
2519
2520         /*
2521          * While going to suspend if associated with AP disassociate
2522          * from AP to save power while system is in suspended state
2523          */
2524         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2525              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2526              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2527                 WL_INFO("Disassociating from AP"
2528                         " while entering suspend state\n");
2529                 brcmf_link_down(cfg_priv);
2530
2531                 /*
2532                  * Make sure WPA_Supplicant receives all the event
2533                  * generated due to DISASSOC call to the fw to keep
2534                  * the state fw and WPA_Supplicant state consistent
2535                  */
2536                 brcmf_delay(500);
2537         }
2538
2539         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2540         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2541                 brcmf_term_iscan(cfg_priv);
2542
2543         if (cfg_priv->scan_request) {
2544                 /* Indidate scan abort to cfg80211 layer */
2545                 WL_INFO("Terminating scan in progress\n");
2546                 cfg80211_scan_done(cfg_priv->scan_request, true);
2547                 cfg_priv->scan_request = NULL;
2548         }
2549         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2550         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2551
2552         /* Turn off watchdog timer */
2553         if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2554                 WL_INFO("Enable MPC\n");
2555                 brcmf_set_mpc(ndev, 1);
2556         }
2557
2558         WL_TRACE("Exit\n");
2559
2560         return 0;
2561 }
2562
2563 static __used s32
2564 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2565 {
2566         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2567         u32 buflen;
2568
2569         buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2570                                WL_DCMD_LEN_MAX);
2571         BUG_ON(!buflen);
2572
2573         return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2574                                buflen);
2575 }
2576
2577 static s32
2578 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2579                   s32 buf_len)
2580 {
2581         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2582         u32 len;
2583         s32 err = 0;
2584
2585         len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2586                             WL_DCMD_LEN_MAX);
2587         BUG_ON(!len);
2588         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2589                               WL_DCMD_LEN_MAX);
2590         if (err) {
2591                 WL_ERR("error (%d)\n", err);
2592                 return err;
2593         }
2594         memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2595
2596         return err;
2597 }
2598
2599 static __used s32
2600 brcmf_update_pmklist(struct net_device *ndev,
2601                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2602 {
2603         int i, j;
2604         int pmkid_len;
2605
2606         pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2607
2608         WL_CONN("No of elements %d\n", pmkid_len);
2609         for (i = 0; i < pmkid_len; i++) {
2610                 WL_CONN("PMKID[%d]: %pM =\n", i,
2611                         &pmk_list->pmkids.pmkid[i].BSSID);
2612                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2613                         WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2614         }
2615
2616         if (!err)
2617                 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2618                                         sizeof(*pmk_list));
2619
2620         return err;
2621 }
2622
2623 static s32
2624 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2625                          struct cfg80211_pmksa *pmksa)
2626 {
2627         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2628         struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2629         s32 err = 0;
2630         int i;
2631         int pmkid_len;
2632
2633         WL_TRACE("Enter\n");
2634         if (!check_sys_up(wiphy))
2635                 return -EIO;
2636
2637         pmkid_len = le32_to_cpu(pmkids->npmkid);
2638         for (i = 0; i < pmkid_len; i++)
2639                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2640                         break;
2641         if (i < WL_NUM_PMKIDS_MAX) {
2642                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2643                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2644                 if (i == pmkid_len) {
2645                         pmkid_len++;
2646                         pmkids->npmkid = cpu_to_le32(pmkid_len);
2647                 }
2648         } else
2649                 err = -EINVAL;
2650
2651         WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2652                 pmkids->pmkid[pmkid_len].BSSID);
2653         for (i = 0; i < WLAN_PMKID_LEN; i++)
2654                 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2655
2656         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2657
2658         WL_TRACE("Exit\n");
2659         return err;
2660 }
2661
2662 static s32
2663 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2664                       struct cfg80211_pmksa *pmksa)
2665 {
2666         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2667         struct pmkid_list pmkid;
2668         s32 err = 0;
2669         int i, pmkid_len;
2670
2671         WL_TRACE("Enter\n");
2672         if (!check_sys_up(wiphy))
2673                 return -EIO;
2674
2675         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2676         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2677
2678         WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2679                &pmkid.pmkid[0].BSSID);
2680         for (i = 0; i < WLAN_PMKID_LEN; i++)
2681                 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2682
2683         pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2684         for (i = 0; i < pmkid_len; i++)
2685                 if (!memcmp
2686                     (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2687                      ETH_ALEN))
2688                         break;
2689
2690         if ((pmkid_len > 0)
2691             && (i < pmkid_len)) {
2692                 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2693                        sizeof(struct pmkid));
2694                 for (; i < (pmkid_len - 1); i++) {
2695                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2696                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2697                                ETH_ALEN);
2698                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2699                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2700                                WLAN_PMKID_LEN);
2701                 }
2702                 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2703         } else
2704                 err = -EINVAL;
2705
2706         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2707
2708         WL_TRACE("Exit\n");
2709         return err;
2710
2711 }
2712
2713 static s32
2714 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2715 {
2716         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2717         s32 err = 0;
2718
2719         WL_TRACE("Enter\n");
2720         if (!check_sys_up(wiphy))
2721                 return -EIO;
2722
2723         memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2724         err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2725
2726         WL_TRACE("Exit\n");
2727         return err;
2728
2729 }
2730
2731 static struct cfg80211_ops wl_cfg80211_ops = {
2732         .change_virtual_intf = brcmf_cfg80211_change_iface,
2733         .scan = brcmf_cfg80211_scan,
2734         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2735         .join_ibss = brcmf_cfg80211_join_ibss,
2736         .leave_ibss = brcmf_cfg80211_leave_ibss,
2737         .get_station = brcmf_cfg80211_get_station,
2738         .set_tx_power = brcmf_cfg80211_set_tx_power,
2739         .get_tx_power = brcmf_cfg80211_get_tx_power,
2740         .add_key = brcmf_cfg80211_add_key,
2741         .del_key = brcmf_cfg80211_del_key,
2742         .get_key = brcmf_cfg80211_get_key,
2743         .set_default_key = brcmf_cfg80211_config_default_key,
2744         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2745         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2746         .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2747         .connect = brcmf_cfg80211_connect,
2748         .disconnect = brcmf_cfg80211_disconnect,
2749         .suspend = brcmf_cfg80211_suspend,
2750         .resume = brcmf_cfg80211_resume,
2751         .set_pmksa = brcmf_cfg80211_set_pmksa,
2752         .del_pmksa = brcmf_cfg80211_del_pmksa,
2753         .flush_pmksa = brcmf_cfg80211_flush_pmksa
2754 };
2755
2756 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2757 {
2758         s32 err = 0;
2759
2760         switch (mode) {
2761         case WL_MODE_BSS:
2762                 return NL80211_IFTYPE_STATION;
2763         case WL_MODE_IBSS:
2764                 return NL80211_IFTYPE_ADHOC;
2765         default:
2766                 return NL80211_IFTYPE_UNSPECIFIED;
2767         }
2768
2769         return err;
2770 }
2771
2772 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2773                                           struct device *ndev)
2774 {
2775         struct wireless_dev *wdev;
2776         s32 err = 0;
2777
2778         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2779         if (!wdev)
2780                 return ERR_PTR(-ENOMEM);
2781
2782         wdev->wiphy =
2783             wiphy_new(&wl_cfg80211_ops,
2784                       sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2785         if (!wdev->wiphy) {
2786                 WL_ERR("Couldn not allocate wiphy device\n");
2787                 err = -ENOMEM;
2788                 goto wiphy_new_out;
2789         }
2790         set_wiphy_dev(wdev->wiphy, ndev);
2791         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2792         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2793         wdev->wiphy->interface_modes =
2794             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2795         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2796         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;    /* Set
2797                                                 * it as 11a by default.
2798                                                 * This will be updated with
2799                                                 * 11n phy tables in
2800                                                 * "ifconfig up"
2801                                                 * if phy has 11n capability
2802                                                 */
2803         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2804         wdev->wiphy->cipher_suites = __wl_cipher_suites;
2805         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2806         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;      /* enable power
2807                                                                  * save mode
2808                                                                  * by default
2809                                                                  */
2810         err = wiphy_register(wdev->wiphy);
2811         if (err < 0) {
2812                 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2813                 goto wiphy_register_out;
2814         }
2815         return wdev;
2816
2817 wiphy_register_out:
2818         wiphy_free(wdev->wiphy);
2819
2820 wiphy_new_out:
2821         kfree(wdev);
2822
2823         return ERR_PTR(err);
2824 }
2825
2826 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2827 {
2828         struct wireless_dev *wdev = cfg_priv->wdev;
2829
2830         if (!wdev) {
2831                 WL_ERR("wdev is invalid\n");
2832                 return;
2833         }
2834         wiphy_unregister(wdev->wiphy);
2835         wiphy_free(wdev->wiphy);
2836         kfree(wdev);
2837         cfg_priv->wdev = NULL;
2838 }
2839
2840 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2841                             const struct brcmf_event_msg *e)
2842 {
2843         u32 event = be32_to_cpu(e->event_type);
2844         u32 status = be32_to_cpu(e->status);
2845
2846         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2847                 WL_CONN("Processing set ssid\n");
2848                 cfg_priv->link_up = true;
2849                 return true;
2850         }
2851
2852         return false;
2853 }
2854
2855 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2856                               const struct brcmf_event_msg *e)
2857 {
2858         u32 event = be32_to_cpu(e->event_type);
2859         u16 flags = be16_to_cpu(e->flags);
2860
2861         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2862                 WL_CONN("Processing link down\n");
2863                 return true;
2864         }
2865         return false;
2866 }
2867
2868 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2869                                const struct brcmf_event_msg *e)
2870 {
2871         u32 event = be32_to_cpu(e->event_type);
2872         u32 status = be32_to_cpu(e->status);
2873
2874         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2875                 WL_CONN("Processing Link %s & no network found\n",
2876                                 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2877                                 "up" : "down");
2878                 return true;
2879         }
2880
2881         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2882                 WL_CONN("Processing connecting & no network found\n");
2883                 return true;
2884         }
2885
2886         return false;
2887 }
2888
2889 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2890 {
2891         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2892
2893         kfree(conn_info->req_ie);
2894         conn_info->req_ie = NULL;
2895         conn_info->req_ie_len = 0;
2896         kfree(conn_info->resp_ie);
2897         conn_info->resp_ie = NULL;
2898         conn_info->resp_ie_len = 0;
2899 }
2900
2901 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2902 {
2903         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2904         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2905         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2906         u32 req_len;
2907         u32 resp_len;
2908         s32 err = 0;
2909
2910         brcmf_clear_assoc_ies(cfg_priv);
2911
2912         err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2913                                 WL_ASSOC_INFO_MAX);
2914         if (err) {
2915                 WL_ERR("could not get assoc info (%d)\n", err);
2916                 return err;
2917         }
2918         assoc_info =
2919                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2920         req_len = le32_to_cpu(assoc_info->req_len);
2921         resp_len = le32_to_cpu(assoc_info->resp_len);
2922         if (req_len) {
2923                 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2924                                            cfg_priv->extra_buf,
2925                                            WL_ASSOC_INFO_MAX);
2926                 if (err) {
2927                         WL_ERR("could not get assoc req (%d)\n", err);
2928                         return err;
2929                 }
2930                 conn_info->req_ie_len = req_len;
2931                 conn_info->req_ie =
2932                     kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2933                             GFP_KERNEL);
2934         } else {
2935                 conn_info->req_ie_len = 0;
2936                 conn_info->req_ie = NULL;
2937         }
2938         if (resp_len) {
2939                 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2940                                            cfg_priv->extra_buf,
2941                                            WL_ASSOC_INFO_MAX);
2942                 if (err) {
2943                         WL_ERR("could not get assoc resp (%d)\n", err);
2944                         return err;
2945                 }
2946                 conn_info->resp_ie_len = resp_len;
2947                 conn_info->resp_ie =
2948                     kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2949                             GFP_KERNEL);
2950         } else {
2951                 conn_info->resp_ie_len = 0;
2952                 conn_info->resp_ie = NULL;
2953         }
2954         WL_CONN("req len (%d) resp len (%d)\n",
2955                conn_info->req_ie_len, conn_info->resp_ie_len);
2956
2957         return err;
2958 }
2959
2960 static s32
2961 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2962                        struct net_device *ndev,
2963                        const struct brcmf_event_msg *e)
2964 {
2965         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2966         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2967         struct brcmf_channel_info_le channel_le;
2968         struct ieee80211_channel *notify_channel;
2969         struct ieee80211_supported_band *band;
2970         u32 freq;
2971         s32 err = 0;
2972         u32 target_channel;
2973
2974         WL_TRACE("Enter\n");
2975
2976         brcmf_get_assoc_ies(cfg_priv);
2977         brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2978         brcmf_update_bss_info(cfg_priv);
2979
2980         brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2981                         sizeof(channel_le));
2982
2983         target_channel = le32_to_cpu(channel_le.target_channel);
2984         WL_CONN("Roamed to channel %d\n", target_channel);
2985
2986         if (target_channel <= CH_MAX_2G_CHANNEL)
2987                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2988         else
2989                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2990
2991         freq = ieee80211_channel_to_frequency(target_channel, band->band);
2992         notify_channel = ieee80211_get_channel(wiphy, freq);
2993
2994         cfg80211_roamed(ndev, notify_channel,
2995                         (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2996                         conn_info->req_ie, conn_info->req_ie_len,
2997                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2998         WL_CONN("Report roaming result\n");
2999
3000         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3001         WL_TRACE("Exit\n");
3002         return err;
3003 }
3004
3005 static s32
3006 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3007                        struct net_device *ndev, const struct brcmf_event_msg *e,
3008                        bool completed)
3009 {
3010         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3011         s32 err = 0;
3012
3013         WL_TRACE("Enter\n");
3014
3015         if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3016                 if (completed) {
3017                         brcmf_get_assoc_ies(cfg_priv);
3018                         brcmf_update_prof(cfg_priv, NULL, &e->addr,
3019                                           WL_PROF_BSSID);
3020                         brcmf_update_bss_info(cfg_priv);
3021                 }
3022                 cfg80211_connect_result(ndev,
3023                                         (u8 *)brcmf_read_prof(cfg_priv,
3024                                                               WL_PROF_BSSID),
3025                                         conn_info->req_ie,
3026                                         conn_info->req_ie_len,
3027                                         conn_info->resp_ie,
3028                                         conn_info->resp_ie_len,
3029                                         completed ? WLAN_STATUS_SUCCESS :
3030                                                     WLAN_STATUS_AUTH_TIMEOUT,
3031                                         GFP_KERNEL);
3032                 if (completed)
3033                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3034                 WL_CONN("Report connect result - connection %s\n",
3035                                 completed ? "succeeded" : "failed");
3036         }
3037         WL_TRACE("Exit\n");
3038         return err;
3039 }
3040
3041 static s32
3042 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3043                             struct net_device *ndev,
3044                             const struct brcmf_event_msg *e, void *data)
3045 {
3046         s32 err = 0;
3047
3048         if (brcmf_is_linkup(cfg_priv, e)) {
3049                 WL_CONN("Linkup\n");
3050                 if (brcmf_is_ibssmode(cfg_priv)) {
3051                         brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3052                                 WL_PROF_BSSID);
3053                         wl_inform_ibss(cfg_priv, ndev, e->addr);
3054                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3055                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3056                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3057                 } else
3058                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3059         } else if (brcmf_is_linkdown(cfg_priv, e)) {
3060                 WL_CONN("Linkdown\n");
3061                 if (brcmf_is_ibssmode(cfg_priv)) {
3062                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3063                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
3064                                 &cfg_priv->status))
3065                                 brcmf_link_down(cfg_priv);
3066                 } else {
3067                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3068                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
3069                                 &cfg_priv->status)) {
3070                                 cfg80211_disconnected(ndev, 0, NULL, 0,
3071                                         GFP_KERNEL);
3072                                 brcmf_link_down(cfg_priv);
3073                         }
3074                 }
3075                 brcmf_init_prof(cfg_priv->profile);
3076         } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3077                 if (brcmf_is_ibssmode(cfg_priv))
3078                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3079                 else
3080                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3081         }
3082
3083         return err;
3084 }
3085
3086 static s32
3087 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3088                             struct net_device *ndev,
3089                             const struct brcmf_event_msg *e, void *data)
3090 {
3091         s32 err = 0;
3092         u32 event = be32_to_cpu(e->event_type);
3093         u32 status = be32_to_cpu(e->status);
3094
3095         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3096                 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3097                         brcmf_bss_roaming_done(cfg_priv, ndev, e);
3098                 else
3099                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3100         }
3101
3102         return err;
3103 }
3104
3105 static s32
3106 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3107                         struct net_device *ndev,
3108                         const struct brcmf_event_msg *e, void *data)
3109 {
3110         u16 flags = be16_to_cpu(e->flags);
3111         enum nl80211_key_type key_type;
3112
3113         if (flags & BRCMF_EVENT_MSG_GROUP)
3114                 key_type = NL80211_KEYTYPE_GROUP;
3115         else
3116                 key_type = NL80211_KEYTYPE_PAIRWISE;
3117
3118         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3119                                      NULL, GFP_KERNEL);
3120
3121         return 0;
3122 }
3123
3124 static s32
3125 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3126                          struct net_device *ndev,
3127                          const struct brcmf_event_msg *e, void *data)
3128 {
3129         struct brcmf_channel_info_le channel_inform_le;
3130         struct brcmf_scan_results_le *bss_list_le;
3131         u32 len = WL_SCAN_BUF_MAX;
3132         s32 err = 0;
3133         bool scan_abort = false;
3134         u32 scan_channel;
3135
3136         WL_TRACE("Enter\n");
3137
3138         if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3139                 WL_TRACE("Exit\n");
3140                 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3141         }
3142
3143         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3144                 WL_ERR("Scan complete while device not scanning\n");
3145                 scan_abort = true;
3146                 err = -EINVAL;
3147                 goto scan_done_out;
3148         }
3149
3150         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3151                               sizeof(channel_inform_le));
3152         if (err) {
3153                 WL_ERR("scan busy (%d)\n", err);
3154                 scan_abort = true;
3155                 goto scan_done_out;
3156         }
3157         scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3158         if (scan_channel)
3159                 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3160         cfg_priv->bss_list = cfg_priv->scan_results;
3161         bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3162
3163         memset(cfg_priv->scan_results, 0, len);
3164         bss_list_le->buflen = cpu_to_le32(len);
3165         err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3166                               cfg_priv->scan_results, len);
3167         if (err) {
3168                 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3169                 err = -EINVAL;
3170                 scan_abort = true;
3171                 goto scan_done_out;
3172         }
3173         cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3174         cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3175         cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3176
3177         err = brcmf_inform_bss(cfg_priv);
3178         if (err) {
3179                 scan_abort = true;
3180                 goto scan_done_out;
3181         }
3182
3183 scan_done_out:
3184         if (cfg_priv->scan_request) {
3185                 WL_SCAN("calling cfg80211_scan_done\n");
3186                 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3187                 brcmf_set_mpc(ndev, 1);
3188                 cfg_priv->scan_request = NULL;
3189         }
3190
3191         WL_TRACE("Exit\n");
3192
3193         return err;
3194 }
3195
3196 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3197 {
3198         conf->mode = (u32)-1;
3199         conf->frag_threshold = (u32)-1;
3200         conf->rts_threshold = (u32)-1;
3201         conf->retry_short = (u32)-1;
3202         conf->retry_long = (u32)-1;
3203         conf->tx_power = -1;
3204 }
3205
3206 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3207 {
3208         memset(el, 0, sizeof(*el));
3209         el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3210         el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3211         el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3212         el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3213         el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3214 }
3215
3216 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3217 {
3218         kfree(cfg_priv->scan_results);
3219         cfg_priv->scan_results = NULL;
3220         kfree(cfg_priv->bss_info);
3221         cfg_priv->bss_info = NULL;
3222         kfree(cfg_priv->conf);
3223         cfg_priv->conf = NULL;
3224         kfree(cfg_priv->profile);
3225         cfg_priv->profile = NULL;
3226         kfree(cfg_priv->scan_req_int);
3227         cfg_priv->scan_req_int = NULL;
3228         kfree(cfg_priv->dcmd_buf);
3229         cfg_priv->dcmd_buf = NULL;
3230         kfree(cfg_priv->extra_buf);
3231         cfg_priv->extra_buf = NULL;
3232         kfree(cfg_priv->iscan);
3233         cfg_priv->iscan = NULL;
3234         kfree(cfg_priv->pmk_list);
3235         cfg_priv->pmk_list = NULL;
3236 }
3237
3238 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3239 {
3240         cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3241         if (!cfg_priv->scan_results)
3242                 goto init_priv_mem_out;
3243         cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3244         if (!cfg_priv->conf)
3245                 goto init_priv_mem_out;
3246         cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3247         if (!cfg_priv->profile)
3248                 goto init_priv_mem_out;
3249         cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3250         if (!cfg_priv->bss_info)
3251                 goto init_priv_mem_out;
3252         cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3253                                          GFP_KERNEL);
3254         if (!cfg_priv->scan_req_int)
3255                 goto init_priv_mem_out;
3256         cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3257         if (!cfg_priv->dcmd_buf)
3258                 goto init_priv_mem_out;
3259         cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3260         if (!cfg_priv->extra_buf)
3261                 goto init_priv_mem_out;
3262         cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3263         if (!cfg_priv->iscan)
3264                 goto init_priv_mem_out;
3265         cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3266         if (!cfg_priv->pmk_list)
3267                 goto init_priv_mem_out;
3268
3269         return 0;
3270
3271 init_priv_mem_out:
3272         brcmf_deinit_priv_mem(cfg_priv);
3273
3274         return -ENOMEM;
3275 }
3276
3277 /*
3278 * retrieve first queued event from head
3279 */
3280
3281 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3282         struct brcmf_cfg80211_priv *cfg_priv)
3283 {
3284         struct brcmf_cfg80211_event_q *e = NULL;
3285
3286         spin_lock_irq(&cfg_priv->evt_q_lock);
3287         if (!list_empty(&cfg_priv->evt_q_list)) {
3288                 e = list_first_entry(&cfg_priv->evt_q_list,
3289                                      struct brcmf_cfg80211_event_q, evt_q_list);
3290                 list_del(&e->evt_q_list);
3291         }
3292         spin_unlock_irq(&cfg_priv->evt_q_lock);
3293
3294         return e;
3295 }
3296
3297 /*
3298 ** push event to tail of the queue
3299 */
3300
3301 static s32
3302 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3303                 const struct brcmf_event_msg *msg)
3304 {
3305         struct brcmf_cfg80211_event_q *e;
3306         s32 err = 0;
3307
3308         e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3309         if (!e)
3310                 return -ENOMEM;
3311
3312         e->etype = event;
3313         memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3314
3315         spin_lock_irq(&cfg_priv->evt_q_lock);
3316         list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3317         spin_unlock_irq(&cfg_priv->evt_q_lock);
3318
3319         return err;
3320 }
3321
3322 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3323 {
3324         kfree(e);
3325 }
3326
3327 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3328 {
3329         struct brcmf_cfg80211_priv *cfg_priv =
3330                         container_of(work, struct brcmf_cfg80211_priv,
3331                                      event_work);
3332         struct brcmf_cfg80211_event_q *e;
3333
3334         e = brcmf_deq_event(cfg_priv);
3335         if (unlikely(!e)) {
3336                 WL_ERR("event queue empty...\n");
3337                 return;
3338         }
3339
3340         do {
3341                 WL_INFO("event type (%d)\n", e->etype);
3342                 if (cfg_priv->el.handler[e->etype])
3343                         cfg_priv->el.handler[e->etype](cfg_priv,
3344                                                        cfg_to_ndev(cfg_priv),
3345                                                        &e->emsg, e->edata);
3346                 else
3347                         WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3348                 brcmf_put_event(e);
3349         } while ((e = brcmf_deq_event(cfg_priv)));
3350
3351 }
3352
3353 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3354 {
3355         spin_lock_init(&cfg_priv->evt_q_lock);
3356         INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3357 }
3358
3359 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3360 {
3361         struct brcmf_cfg80211_event_q *e;
3362
3363         spin_lock_irq(&cfg_priv->evt_q_lock);
3364         while (!list_empty(&cfg_priv->evt_q_list)) {
3365                 e = list_first_entry(&cfg_priv->evt_q_list,
3366                                      struct brcmf_cfg80211_event_q, evt_q_list);
3367                 list_del(&e->evt_q_list);
3368                 kfree(e);
3369         }
3370         spin_unlock_irq(&cfg_priv->evt_q_lock);
3371 }
3372
3373 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3374 {
3375         s32 err = 0;
3376
3377         cfg_priv->scan_request = NULL;
3378         cfg_priv->pwr_save = true;
3379         cfg_priv->iscan_on = true;      /* iscan on & off switch.
3380                                  we enable iscan per default */
3381         cfg_priv->roam_on = true;       /* roam on & off switch.
3382                                  we enable roam per default */
3383
3384         cfg_priv->iscan_kickstart = false;
3385         cfg_priv->active_scan = true;   /* we do active scan for
3386                                  specific scan per default */
3387         cfg_priv->dongle_up = false;    /* dongle is not up yet */
3388         brcmf_init_eq(cfg_priv);
3389         err = brcmf_init_priv_mem(cfg_priv);
3390         if (err)
3391                 return err;
3392         INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3393         brcmf_init_eloop_handler(&cfg_priv->el);
3394         mutex_init(&cfg_priv->usr_sync);
3395         err = brcmf_init_iscan(cfg_priv);
3396         if (err)
3397                 return err;
3398         brcmf_init_conf(cfg_priv->conf);
3399         brcmf_init_prof(cfg_priv->profile);
3400         brcmf_link_down(cfg_priv);
3401
3402         return err;
3403 }
3404
3405 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3406 {
3407         cancel_work_sync(&cfg_priv->event_work);
3408         cfg_priv->dongle_up = false;    /* dongle down */
3409         brcmf_flush_eq(cfg_priv);
3410         brcmf_link_down(cfg_priv);
3411         brcmf_term_iscan(cfg_priv);
3412         brcmf_deinit_priv_mem(cfg_priv);
3413 }
3414
3415 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3416                                                  struct device *busdev,
3417                                                  void *data)
3418 {
3419         struct wireless_dev *wdev;
3420         struct brcmf_cfg80211_priv *cfg_priv;
3421         struct brcmf_cfg80211_iface *ci;
3422         struct brcmf_cfg80211_dev *cfg_dev;
3423         s32 err = 0;
3424
3425         if (!ndev) {
3426                 WL_ERR("ndev is invalid\n");
3427                 return NULL;
3428         }
3429         cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3430         if (!cfg_dev)
3431                 return NULL;
3432
3433         wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3434         if (IS_ERR(wdev)) {
3435                 kfree(cfg_dev);
3436                 return NULL;
3437         }
3438
3439         wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3440         cfg_priv = wdev_to_cfg(wdev);
3441         cfg_priv->wdev = wdev;
3442         cfg_priv->pub = data;
3443         ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3444         ci->cfg_priv = cfg_priv;
3445         ndev->ieee80211_ptr = wdev;
3446         SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3447         wdev->netdev = ndev;
3448         err = wl_init_priv(cfg_priv);
3449         if (err) {
3450                 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3451                 goto cfg80211_attach_out;
3452         }
3453         brcmf_set_drvdata(cfg_dev, ci);
3454
3455         return cfg_dev;
3456
3457 cfg80211_attach_out:
3458         brcmf_free_wdev(cfg_priv);
3459         kfree(cfg_dev);
3460         return NULL;
3461 }
3462
3463 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3464 {
3465         struct brcmf_cfg80211_priv *cfg_priv;
3466
3467         cfg_priv = brcmf_priv_get(cfg_dev);
3468
3469         wl_deinit_priv(cfg_priv);
3470         brcmf_free_wdev(cfg_priv);
3471         brcmf_set_drvdata(cfg_dev, NULL);
3472         kfree(cfg_dev);
3473 }
3474
3475 void
3476 brcmf_cfg80211_event(struct net_device *ndev,
3477                   const struct brcmf_event_msg *e, void *data)
3478 {
3479         u32 event_type = be32_to_cpu(e->event_type);
3480         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3481
3482         if (!brcmf_enq_event(cfg_priv, event_type, e))
3483                 schedule_work(&cfg_priv->event_work);
3484 }
3485
3486 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3487 {
3488         s32 infra = 0;
3489         s32 err = 0;
3490
3491         switch (iftype) {
3492         case NL80211_IFTYPE_MONITOR:
3493         case NL80211_IFTYPE_WDS:
3494                 WL_ERR("type (%d) : currently we do not support this mode\n",
3495                        iftype);
3496                 err = -EINVAL;
3497                 return err;
3498         case NL80211_IFTYPE_ADHOC:
3499                 infra = 0;
3500                 break;
3501         case NL80211_IFTYPE_STATION:
3502                 infra = 1;
3503                 break;
3504         default:
3505                 err = -EINVAL;
3506                 WL_ERR("invalid type (%d)\n", iftype);
3507                 return err;
3508         }
3509         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3510         if (err) {
3511                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3512                 return err;
3513         }
3514
3515         return 0;
3516 }
3517
3518 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3519 {
3520         /* Room for "event_msgs" + '\0' + bitvec */
3521         s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3522         s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3523         s32 err = 0;
3524
3525         WL_TRACE("Enter\n");
3526
3527         /* Setup event_msgs */
3528         brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3529                         iovbuf, sizeof(iovbuf));
3530         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3531         if (err) {
3532                 WL_ERR("Get event_msgs error (%d)\n", err);
3533                 goto dongle_eventmsg_out;
3534         }
3535         memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3536
3537         setbit(eventmask, BRCMF_E_SET_SSID);
3538         setbit(eventmask, BRCMF_E_ROAM);
3539         setbit(eventmask, BRCMF_E_PRUNE);
3540         setbit(eventmask, BRCMF_E_AUTH);
3541         setbit(eventmask, BRCMF_E_REASSOC);
3542         setbit(eventmask, BRCMF_E_REASSOC_IND);
3543         setbit(eventmask, BRCMF_E_DEAUTH_IND);
3544         setbit(eventmask, BRCMF_E_DISASSOC_IND);
3545         setbit(eventmask, BRCMF_E_DISASSOC);
3546         setbit(eventmask, BRCMF_E_JOIN);
3547         setbit(eventmask, BRCMF_E_ASSOC_IND);
3548         setbit(eventmask, BRCMF_E_PSK_SUP);
3549         setbit(eventmask, BRCMF_E_LINK);
3550         setbit(eventmask, BRCMF_E_NDIS_LINK);
3551         setbit(eventmask, BRCMF_E_MIC_ERROR);
3552         setbit(eventmask, BRCMF_E_PMKID_CACHE);
3553         setbit(eventmask, BRCMF_E_TXFAIL);
3554         setbit(eventmask, BRCMF_E_JOIN_START);
3555         setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3556
3557         brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3558                         iovbuf, sizeof(iovbuf));
3559         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3560         if (err) {
3561                 WL_ERR("Set event_msgs error (%d)\n", err);
3562                 goto dongle_eventmsg_out;
3563         }
3564
3565 dongle_eventmsg_out:
3566         WL_TRACE("Exit\n");
3567         return err;
3568 }
3569
3570 static s32
3571 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3572 {
3573         s8 iovbuf[32];
3574         s32 err = 0;
3575         __le32 roamtrigger[2];
3576         __le32 roam_delta[2];
3577         __le32 bcn_to_le;
3578         __le32 roamvar_le;
3579
3580         /*
3581          * Setup timeout if Beacons are lost and roam is
3582          * off to report link down
3583          */
3584         if (roamvar) {
3585                 bcn_to_le = cpu_to_le32(bcn_timeout);
3586                 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3587                         sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3588                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3589                                    iovbuf, sizeof(iovbuf));
3590                 if (err) {
3591                         WL_ERR("bcn_timeout error (%d)\n", err);
3592                         goto dongle_rom_out;
3593                 }
3594         }
3595
3596         /*
3597          * Enable/Disable built-in roaming to allow supplicant
3598          * to take care of roaming
3599          */
3600         WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3601         roamvar_le = cpu_to_le32(roamvar);
3602         brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3603                                 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3604         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3605         if (err) {
3606                 WL_ERR("roam_off error (%d)\n", err);
3607                 goto dongle_rom_out;
3608         }
3609
3610         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3611         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3612         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3613                         (void *)roamtrigger, sizeof(roamtrigger));
3614         if (err) {
3615                 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3616                 goto dongle_rom_out;
3617         }
3618
3619         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3620         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3621         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3622                                 (void *)roam_delta, sizeof(roam_delta));
3623         if (err) {
3624                 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3625                 goto dongle_rom_out;
3626         }
3627
3628 dongle_rom_out:
3629         return err;
3630 }
3631
3632 static s32
3633 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3634                       s32 scan_unassoc_time, s32 scan_passive_time)
3635 {
3636         s32 err = 0;
3637         __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3638         __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3639         __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3640
3641         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3642                            &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3643         if (err) {
3644                 if (err == -EOPNOTSUPP)
3645                         WL_INFO("Scan assoc time is not supported\n");
3646                 else
3647                         WL_ERR("Scan assoc time error (%d)\n", err);
3648                 goto dongle_scantime_out;
3649         }
3650         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3651                            &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3652         if (err) {
3653                 if (err == -EOPNOTSUPP)
3654                         WL_INFO("Scan unassoc time is not supported\n");
3655                 else
3656                         WL_ERR("Scan unassoc time error (%d)\n", err);
3657                 goto dongle_scantime_out;
3658         }
3659
3660         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3661                            &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3662         if (err) {
3663                 if (err == -EOPNOTSUPP)
3664                         WL_INFO("Scan passive time is not supported\n");
3665                 else
3666                         WL_ERR("Scan passive time error (%d)\n", err);
3667                 goto dongle_scantime_out;
3668         }
3669
3670 dongle_scantime_out:
3671         return err;
3672 }
3673
3674 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3675 {
3676         struct wiphy *wiphy;
3677         s32 phy_list;
3678         s8 phy;
3679         s32 err = 0;
3680
3681         err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3682                               &phy_list, sizeof(phy_list));
3683         if (err) {
3684                 WL_ERR("error (%d)\n", err);
3685                 return err;
3686         }
3687
3688         phy = ((char *)&phy_list)[1];
3689         WL_INFO("%c phy\n", phy);
3690         if (phy == 'n' || phy == 'a') {
3691                 wiphy = cfg_to_wiphy(cfg_priv);
3692                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3693         }
3694
3695         return err;
3696 }
3697
3698 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3699 {
3700         return wl_update_wiphybands(cfg_priv);
3701 }
3702
3703 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3704 {
3705         struct net_device *ndev;
3706         struct wireless_dev *wdev;
3707         s32 power_mode;
3708         s32 err = 0;
3709
3710         if (cfg_priv->dongle_up)
3711                 return err;
3712
3713         ndev = cfg_to_ndev(cfg_priv);
3714         wdev = ndev->ieee80211_ptr;
3715
3716         brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3717                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3718
3719         err = brcmf_dongle_eventmsg(ndev);
3720         if (err)
3721                 goto default_conf_out;
3722
3723         power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3724         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3725         if (err)
3726                 goto default_conf_out;
3727         WL_INFO("power save set to %s\n",
3728                 (power_mode ? "enabled" : "disabled"));
3729
3730         err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3731                                 WL_BEACON_TIMEOUT);
3732         if (err)
3733                 goto default_conf_out;
3734         err = brcmf_dongle_mode(ndev, wdev->iftype);
3735         if (err && err != -EINPROGRESS)
3736                 goto default_conf_out;
3737         err = brcmf_dongle_probecap(cfg_priv);
3738         if (err)
3739                 goto default_conf_out;
3740
3741         /* -EINPROGRESS: Call commit handler */
3742
3743 default_conf_out:
3744
3745         cfg_priv->dongle_up = true;
3746
3747         return err;
3748
3749 }
3750
3751 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3752 {
3753         char buf[10+IFNAMSIZ];
3754         struct dentry *fd;
3755         s32 err = 0;
3756
3757         sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3758         cfg_priv->debugfsdir = debugfs_create_dir(buf,
3759                                         cfg_to_wiphy(cfg_priv)->debugfsdir);
3760
3761         fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3762                 (u16 *)&cfg_priv->profile->beacon_interval);
3763         if (!fd) {
3764                 err = -ENOMEM;
3765                 goto err_out;
3766         }
3767
3768         fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3769                 (u8 *)&cfg_priv->profile->dtim_period);
3770         if (!fd) {
3771                 err = -ENOMEM;
3772                 goto err_out;
3773         }
3774
3775 err_out:
3776         return err;
3777 }
3778
3779 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3780 {
3781         debugfs_remove_recursive(cfg_priv->debugfsdir);
3782         cfg_priv->debugfsdir = NULL;
3783 }
3784
3785 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3786 {
3787         s32 err = 0;
3788
3789         set_bit(WL_STATUS_READY, &cfg_priv->status);
3790
3791         brcmf_debugfs_add_netdev_params(cfg_priv);
3792
3793         err = brcmf_config_dongle(cfg_priv);
3794         if (err)
3795                 return err;
3796
3797         brcmf_invoke_iscan(cfg_priv);
3798
3799         return err;
3800 }
3801
3802 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3803 {
3804         /*
3805          * While going down, if associated with AP disassociate
3806          * from AP to save power
3807          */
3808         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3809              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3810              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3811                 WL_INFO("Disassociating from AP");
3812                 brcmf_link_down(cfg_priv);
3813
3814                 /* Make sure WPA_Supplicant receives all the event
3815                    generated due to DISASSOC call to the fw to keep
3816                    the state fw and WPA_Supplicant state consistent
3817                  */
3818                 brcmf_delay(500);
3819         }
3820
3821         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3822         brcmf_term_iscan(cfg_priv);
3823         if (cfg_priv->scan_request) {
3824                 cfg80211_scan_done(cfg_priv->scan_request, true);
3825                 /* May need to perform this to cover rmmod */
3826                 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3827                 cfg_priv->scan_request = NULL;
3828         }
3829         clear_bit(WL_STATUS_READY, &cfg_priv->status);
3830         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3831         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3832
3833         brcmf_debugfs_remove_netdev(cfg_priv);
3834
3835         return 0;
3836 }
3837
3838 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3839 {
3840         struct brcmf_cfg80211_priv *cfg_priv;
3841         s32 err = 0;
3842
3843         cfg_priv = brcmf_priv_get(cfg_dev);
3844         mutex_lock(&cfg_priv->usr_sync);
3845         err = __brcmf_cfg80211_up(cfg_priv);
3846         mutex_unlock(&cfg_priv->usr_sync);
3847
3848         return err;
3849 }
3850
3851 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3852 {
3853         struct brcmf_cfg80211_priv *cfg_priv;
3854         s32 err = 0;
3855
3856         cfg_priv = brcmf_priv_get(cfg_dev);
3857         mutex_lock(&cfg_priv->usr_sync);
3858         err = __brcmf_cfg80211_down(cfg_priv);
3859         mutex_unlock(&cfg_priv->usr_sync);
3860
3861         return err;
3862 }
3863
3864 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3865                                u8 t, u8 l, u8 *v)
3866 {
3867         struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3868         s32 err = 0;
3869
3870         if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3871                 WL_ERR("ei crosses buffer boundary\n");
3872                 return -ENOSPC;
3873         }
3874         ie->buf[ie->offset] = t;
3875         ie->buf[ie->offset + 1] = l;
3876         memcpy(&ie->buf[ie->offset + 2], v, l);
3877         ie->offset += l + 2;
3878
3879         return err;
3880 }