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