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