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