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