0bda00c07e2f0d090d173975676b3c6fe180ce84
[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                 __le32 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 = params->beacon_interval;
894         else
895                 bcnprd = 100;
896
897         err = brcmf_dev_ioctl_u32(dev, BRCM_SET_BCNPRD, &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 = le32_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         *(__le32 *)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 = le32_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         *(__le32 *)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) + le16_to_cpu(bi->ie_offset);
2115         ie_len = le32_to_cpu(bi->ie_length);
2116         beacon_interval = le16_to_cpu(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_scan_results_le *results_le;
2205         struct brcmf_iscan_results *list_buf;
2206         s32 err = 0;
2207
2208         memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2209         list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2210         results = &list_buf->results;
2211         results_le = &list_buf->results_le;
2212         results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2213         results->version = 0;
2214         results->count = 0;
2215
2216         memset(&list, 0, sizeof(list));
2217         list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2218         err = brcmf_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2219                                 BRCMF_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2220                                 WL_ISCAN_BUF_MAX);
2221         if (unlikely(err)) {
2222                 WL_ERR("error (%d)\n", err);
2223                 return err;
2224         }
2225         results->buflen = le32_to_cpu(results_le->buflen);
2226         results->version = le32_to_cpu(results_le->version);
2227         results->count = le32_to_cpu(results_le->count);
2228         WL_SCAN("results->count = %d\n", results_le->count);
2229         WL_SCAN("results->buflen = %d\n", results_le->buflen);
2230         *status = le32_to_cpu(list_buf->status_le);
2231         WL_SCAN("status = %d\n", *status);
2232         *bss_list = results;
2233
2234         return err;
2235 }
2236
2237 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2238 {
2239         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2240         s32 err = 0;
2241
2242         iscan->state = WL_ISCAN_STATE_IDLE;
2243         rtnl_lock();
2244         brcmf_inform_bss(cfg_priv);
2245         brcmf_notify_iscan_complete(iscan, false);
2246         rtnl_unlock();
2247
2248         return err;
2249 }
2250
2251 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2252 {
2253         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2254         s32 err = 0;
2255
2256         /* Reschedule the timer */
2257         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2258         iscan->timer_on = 1;
2259
2260         return err;
2261 }
2262
2263 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2264 {
2265         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2266         s32 err = 0;
2267
2268         rtnl_lock();
2269         brcmf_inform_bss(cfg_priv);
2270         brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2271         rtnl_unlock();
2272         /* Reschedule the timer */
2273         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2274         iscan->timer_on = 1;
2275
2276         return err;
2277 }
2278
2279 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2280 {
2281         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2282         s32 err = 0;
2283
2284         iscan->state = WL_ISCAN_STATE_IDLE;
2285         rtnl_lock();
2286         brcmf_notify_iscan_complete(iscan, true);
2287         rtnl_unlock();
2288
2289         return err;
2290 }
2291
2292 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2293 {
2294         struct brcmf_cfg80211_iscan_ctrl *iscan =
2295                         container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2296                                      work);
2297         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2298         struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2299         u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2300
2301         if (iscan->timer_on) {
2302                 del_timer_sync(&iscan->timer);
2303                 iscan->timer_on = 0;
2304         }
2305
2306         rtnl_lock();
2307         if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2308                 status = BRCMF_SCAN_RESULTS_ABORTED;
2309                 WL_ERR("Abort iscan\n");
2310         }
2311         rtnl_unlock();
2312
2313         el->handler[status](cfg_priv);
2314 }
2315
2316 static void brcmf_iscan_timer(unsigned long data)
2317 {
2318         struct brcmf_cfg80211_iscan_ctrl *iscan =
2319                         (struct brcmf_cfg80211_iscan_ctrl *)data;
2320
2321         if (iscan) {
2322                 iscan->timer_on = 0;
2323                 WL_SCAN("timer expired\n");
2324                 brcmf_wakeup_iscan(iscan);
2325         }
2326 }
2327
2328 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2329 {
2330         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2331
2332         if (cfg_priv->iscan_on) {
2333                 iscan->state = WL_ISCAN_STATE_IDLE;
2334                 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2335         }
2336
2337         return 0;
2338 }
2339
2340 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2341 {
2342         memset(el, 0, sizeof(*el));
2343         el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2344         el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2345         el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2346         el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2347         el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2348 }
2349
2350 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2351 {
2352         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2353         int err = 0;
2354
2355         if (cfg_priv->iscan_on) {
2356                 iscan->dev = cfg_to_ndev(cfg_priv);
2357                 brcmf_init_iscan_eloop(&iscan->el);
2358                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2359                 init_timer(&iscan->timer);
2360                 iscan->timer.data = (unsigned long) iscan;
2361                 iscan->timer.function = brcmf_iscan_timer;
2362                 err = brcmf_invoke_iscan(cfg_priv);
2363                 if (!err)
2364                         iscan->data = cfg_priv;
2365         }
2366
2367         return err;
2368 }
2369
2370 static void brcmf_delay(u32 ms)
2371 {
2372         if (ms < 1000 / HZ) {
2373                 cond_resched();
2374                 mdelay(ms);
2375         } else {
2376                 msleep(ms);
2377         }
2378 }
2379
2380 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2381 {
2382         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2383
2384         /*
2385          * Check for WL_STATUS_READY before any function call which
2386          * could result is bus access. Don't block the resume for
2387          * any driver error conditions
2388          */
2389         WL_TRACE("Enter\n");
2390
2391         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2392                 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2393
2394         WL_TRACE("Exit\n");
2395         return 0;
2396 }
2397
2398 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2399                                   struct cfg80211_wowlan *wow)
2400 {
2401         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2402         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2403
2404         WL_TRACE("Enter\n");
2405
2406         /*
2407          * Check for WL_STATUS_READY before any function call which
2408          * could result is bus access. Don't block the suspend for
2409          * any driver error conditions
2410          */
2411
2412         /*
2413          * While going to suspend if associated with AP disassociate
2414          * from AP to save power while system is in suspended state
2415          */
2416         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2417              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2418              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2419                 WL_INFO("Disassociating from AP"
2420                         " while entering suspend state\n");
2421                 brcmf_link_down(cfg_priv);
2422
2423                 /*
2424                  * Make sure WPA_Supplicant receives all the event
2425                  * generated due to DISASSOC call to the fw to keep
2426                  * the state fw and WPA_Supplicant state consistent
2427                  */
2428                 rtnl_unlock();
2429                 brcmf_delay(500);
2430                 rtnl_lock();
2431         }
2432
2433         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2434         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2435                 brcmf_term_iscan(cfg_priv);
2436
2437         if (cfg_priv->scan_request) {
2438                 /* Indidate scan abort to cfg80211 layer */
2439                 WL_INFO("Terminating scan in progress\n");
2440                 cfg80211_scan_done(cfg_priv->scan_request, true);
2441                 cfg_priv->scan_request = NULL;
2442         }
2443         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2444         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2445
2446         /* Turn off watchdog timer */
2447         if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2448                 WL_INFO("Enable MPC\n");
2449                 brcmf_set_mpc(ndev, 1);
2450         }
2451
2452         WL_TRACE("Exit\n");
2453
2454         return 0;
2455 }
2456
2457 static __used s32
2458 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2459 {
2460         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2461         u32 buflen;
2462
2463         buflen = brcmu_mkiovar(name, buf, len, cfg_priv->ioctl_buf,
2464                                WL_IOCTL_LEN_MAX);
2465         BUG_ON(!buflen);
2466
2467         return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, cfg_priv->ioctl_buf,
2468                                buflen);
2469 }
2470
2471 static s32
2472 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2473                   s32 buf_len)
2474 {
2475         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2476         u32 len;
2477         s32 err = 0;
2478
2479         len = brcmu_mkiovar(name, NULL, 0, cfg_priv->ioctl_buf,
2480                             WL_IOCTL_LEN_MAX);
2481         BUG_ON(!len);
2482         err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, (void *)cfg_priv->ioctl_buf,
2483                         WL_IOCTL_LEN_MAX);
2484         if (unlikely(err)) {
2485                 WL_ERR("error (%d)\n", err);
2486                 return err;
2487         }
2488         memcpy(buf, cfg_priv->ioctl_buf, buf_len);
2489
2490         return err;
2491 }
2492
2493 static __used s32
2494 brcmf_update_pmklist(struct net_device *dev,
2495                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2496 {
2497         int i, j;
2498
2499         WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2500         for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2501                 WL_CONN("PMKID[%d]: %pM =\n", i,
2502                         &pmk_list->pmkids.pmkid[i].BSSID);
2503                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2504                         WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2505         }
2506
2507         if (likely(!err))
2508                 brcmf_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2509                                         sizeof(*pmk_list));
2510
2511         return err;
2512 }
2513
2514 static s32
2515 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2516                          struct cfg80211_pmksa *pmksa)
2517 {
2518         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2519         struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2520         s32 err = 0;
2521         int i;
2522
2523         WL_TRACE("Enter\n");
2524         if (!check_sys_up(wiphy))
2525                 return -EIO;
2526
2527         for (i = 0; i < pmkids->npmkid; i++)
2528                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2529                         break;
2530         if (i < WL_NUM_PMKIDS_MAX) {
2531                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2532                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2533                 if (i == pmkids->npmkid)
2534                         pmkids->npmkid++;
2535         } else
2536                 err = -EINVAL;
2537
2538         WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2539                 pmkids->pmkid[pmkids->npmkid].BSSID);
2540         for (i = 0; i < WLAN_PMKID_LEN; i++)
2541                 WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
2542
2543         err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2544
2545         WL_TRACE("Exit\n");
2546         return err;
2547 }
2548
2549 static s32
2550 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2551                       struct cfg80211_pmksa *pmksa)
2552 {
2553         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2554         struct pmkid_list pmkid;
2555         s32 err = 0;
2556         int i;
2557
2558         WL_TRACE("Enter\n");
2559         if (!check_sys_up(wiphy))
2560                 return -EIO;
2561
2562         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2563         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2564
2565         WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2566                &pmkid.pmkid[0].BSSID);
2567         for (i = 0; i < WLAN_PMKID_LEN; i++)
2568                 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2569
2570         for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
2571                 if (!memcmp
2572                     (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2573                      ETH_ALEN))
2574                         break;
2575
2576         if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
2577             && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
2578                 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2579                        sizeof(struct pmkid));
2580                 for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
2581                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2582                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2583                                ETH_ALEN);
2584                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2585                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2586                                WLAN_PMKID_LEN);
2587                 }
2588                 cfg_priv->pmk_list->pmkids.npmkid--;
2589         } else
2590                 err = -EINVAL;
2591
2592         err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2593
2594         WL_TRACE("Exit\n");
2595         return err;
2596
2597 }
2598
2599 static s32
2600 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2601 {
2602         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2603         s32 err = 0;
2604
2605         WL_TRACE("Enter\n");
2606         if (!check_sys_up(wiphy))
2607                 return -EIO;
2608
2609         memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2610         err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2611
2612         WL_TRACE("Exit\n");
2613         return err;
2614
2615 }
2616
2617 static struct cfg80211_ops wl_cfg80211_ops = {
2618         .change_virtual_intf = brcmf_cfg80211_change_iface,
2619         .scan = brcmf_cfg80211_scan,
2620         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2621         .join_ibss = brcmf_cfg80211_join_ibss,
2622         .leave_ibss = brcmf_cfg80211_leave_ibss,
2623         .get_station = brcmf_cfg80211_get_station,
2624         .set_tx_power = brcmf_cfg80211_set_tx_power,
2625         .get_tx_power = brcmf_cfg80211_get_tx_power,
2626         .add_key = brcmf_cfg80211_add_key,
2627         .del_key = brcmf_cfg80211_del_key,
2628         .get_key = brcmf_cfg80211_get_key,
2629         .set_default_key = brcmf_cfg80211_config_default_key,
2630         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2631         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2632         .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2633         .connect = brcmf_cfg80211_connect,
2634         .disconnect = brcmf_cfg80211_disconnect,
2635         .suspend = brcmf_cfg80211_suspend,
2636         .resume = brcmf_cfg80211_resume,
2637         .set_pmksa = brcmf_cfg80211_set_pmksa,
2638         .del_pmksa = brcmf_cfg80211_del_pmksa,
2639         .flush_pmksa = brcmf_cfg80211_flush_pmksa
2640 };
2641
2642 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2643 {
2644         s32 err = 0;
2645
2646         switch (mode) {
2647         case WL_MODE_BSS:
2648                 return NL80211_IFTYPE_STATION;
2649         case WL_MODE_IBSS:
2650                 return NL80211_IFTYPE_ADHOC;
2651         default:
2652                 return NL80211_IFTYPE_UNSPECIFIED;
2653         }
2654
2655         return err;
2656 }
2657
2658 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2659                                           struct device *dev)
2660 {
2661         struct wireless_dev *wdev;
2662         s32 err = 0;
2663
2664         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2665         if (unlikely(!wdev)) {
2666                 WL_ERR("Could not allocate wireless device\n");
2667                 return ERR_PTR(-ENOMEM);
2668         }
2669         wdev->wiphy =
2670             wiphy_new(&wl_cfg80211_ops,
2671                       sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2672         if (unlikely(!wdev->wiphy)) {
2673                 WL_ERR("Couldn not allocate wiphy device\n");
2674                 err = -ENOMEM;
2675                 goto wiphy_new_out;
2676         }
2677         set_wiphy_dev(wdev->wiphy, dev);
2678         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2679         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2680         wdev->wiphy->interface_modes =
2681             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2682         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2683         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;    /* Set
2684                                                 * it as 11a by default.
2685                                                 * This will be updated with
2686                                                 * 11n phy tables in
2687                                                 * "ifconfig up"
2688                                                 * if phy has 11n capability
2689                                                 */
2690         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2691         wdev->wiphy->cipher_suites = __wl_cipher_suites;
2692         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2693         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;      /* enable power
2694                                                                  * save mode
2695                                                                  * by default
2696                                                                  */
2697         err = wiphy_register(wdev->wiphy);
2698         if (unlikely(err < 0)) {
2699                 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2700                 goto wiphy_register_out;
2701         }
2702         return wdev;
2703
2704 wiphy_register_out:
2705         wiphy_free(wdev->wiphy);
2706
2707 wiphy_new_out:
2708         kfree(wdev);
2709
2710         return ERR_PTR(err);
2711 }
2712
2713 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2714 {
2715         struct wireless_dev *wdev = cfg_priv->wdev;
2716
2717         if (unlikely(!wdev)) {
2718                 WL_ERR("wdev is invalid\n");
2719                 return;
2720         }
2721         wiphy_unregister(wdev->wiphy);
2722         wiphy_free(wdev->wiphy);
2723         kfree(wdev);
2724         cfg_priv->wdev = NULL;
2725 }
2726
2727 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2728                             const struct brcmf_event_msg *e)
2729 {
2730         u32 event = be32_to_cpu(e->event_type);
2731         u32 status = be32_to_cpu(e->status);
2732
2733         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2734                 WL_CONN("Processing set ssid\n");
2735                 cfg_priv->link_up = true;
2736                 return true;
2737         }
2738
2739         return false;
2740 }
2741
2742 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2743                               const struct brcmf_event_msg *e)
2744 {
2745         u32 event = be32_to_cpu(e->event_type);
2746         u16 flags = be16_to_cpu(e->flags);
2747
2748         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2749                 WL_CONN("Processing link down\n");
2750                 return true;
2751         }
2752         return false;
2753 }
2754
2755 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2756                                const struct brcmf_event_msg *e)
2757 {
2758         u32 event = be32_to_cpu(e->event_type);
2759         u32 status = be32_to_cpu(e->status);
2760
2761         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2762                 WL_CONN("Processing Link %s & no network found\n",
2763                                 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2764                                 "up" : "down");
2765                 return true;
2766         }
2767
2768         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2769                 WL_CONN("Processing connecting & no network found\n");
2770                 return true;
2771         }
2772
2773         return false;
2774 }
2775
2776 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2777 {
2778         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2779
2780         kfree(conn_info->req_ie);
2781         conn_info->req_ie = NULL;
2782         conn_info->req_ie_len = 0;
2783         kfree(conn_info->resp_ie);
2784         conn_info->resp_ie = NULL;
2785         conn_info->resp_ie_len = 0;
2786 }
2787
2788 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2789 {
2790         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2791         struct brcmf_cfg80211_assoc_ielen *assoc_info;
2792         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2793         u32 req_len;
2794         u32 resp_len;
2795         s32 err = 0;
2796
2797         brcmf_clear_assoc_ies(cfg_priv);
2798
2799         err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2800                                 WL_ASSOC_INFO_MAX);
2801         if (unlikely(err)) {
2802                 WL_ERR("could not get assoc info (%d)\n", err);
2803                 return err;
2804         }
2805         assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2806         req_len = assoc_info->req_len;
2807         resp_len = assoc_info->resp_len;
2808         if (req_len) {
2809                 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2810                                            cfg_priv->extra_buf,
2811                                            WL_ASSOC_INFO_MAX);
2812                 if (unlikely(err)) {
2813                         WL_ERR("could not get assoc req (%d)\n", err);
2814                         return err;
2815                 }
2816                 conn_info->req_ie_len = req_len;
2817                 conn_info->req_ie =
2818                     kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2819                             GFP_KERNEL);
2820         } else {
2821                 conn_info->req_ie_len = 0;
2822                 conn_info->req_ie = NULL;
2823         }
2824         if (resp_len) {
2825                 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2826                                            cfg_priv->extra_buf,
2827                                            WL_ASSOC_INFO_MAX);
2828                 if (unlikely(err)) {
2829                         WL_ERR("could not get assoc resp (%d)\n", err);
2830                         return err;
2831                 }
2832                 conn_info->resp_ie_len = resp_len;
2833                 conn_info->resp_ie =
2834                     kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2835                             GFP_KERNEL);
2836         } else {
2837                 conn_info->resp_ie_len = 0;
2838                 conn_info->resp_ie = NULL;
2839         }
2840         WL_CONN("req len (%d) resp len (%d)\n",
2841                conn_info->req_ie_len, conn_info->resp_ie_len);
2842
2843         return err;
2844 }
2845
2846 static s32
2847 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2848                        struct net_device *ndev,
2849                        const struct brcmf_event_msg *e)
2850 {
2851         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2852         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2853         struct brcmf_channel_info_le channel_le;
2854         struct ieee80211_channel *notify_channel;
2855         struct ieee80211_supported_band *band;
2856         u32 freq;
2857         s32 err = 0;
2858         u32 target_channel;
2859
2860         WL_TRACE("Enter\n");
2861
2862         brcmf_get_assoc_ies(cfg_priv);
2863         brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2864         brcmf_update_bss_info(cfg_priv);
2865
2866         brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2867                         sizeof(channel_le));
2868
2869         target_channel = le32_to_cpu(channel_le.target_channel);
2870         WL_CONN("Roamed to channel %d\n", target_channel);
2871
2872         if (target_channel <= CH_MAX_2G_CHANNEL)
2873                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2874         else
2875                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2876
2877         freq = ieee80211_channel_to_frequency(target_channel, band->band);
2878         notify_channel = ieee80211_get_channel(wiphy, freq);
2879
2880         cfg80211_roamed(ndev, notify_channel,
2881                         (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2882                         conn_info->req_ie, conn_info->req_ie_len,
2883                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2884         WL_CONN("Report roaming result\n");
2885
2886         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2887         WL_TRACE("Exit\n");
2888         return err;
2889 }
2890
2891 static s32
2892 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2893                        struct net_device *ndev, const struct brcmf_event_msg *e,
2894                        bool completed)
2895 {
2896         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2897         s32 err = 0;
2898
2899         WL_TRACE("Enter\n");
2900
2901         if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2902                 if (completed) {
2903                         brcmf_get_assoc_ies(cfg_priv);
2904                         brcmf_update_prof(cfg_priv, NULL, &e->addr,
2905                                           WL_PROF_BSSID);
2906                         brcmf_update_bss_info(cfg_priv);
2907                 }
2908                 cfg80211_connect_result(ndev,
2909                                         (u8 *)brcmf_read_prof(cfg_priv,
2910                                                               WL_PROF_BSSID),
2911                                         conn_info->req_ie,
2912                                         conn_info->req_ie_len,
2913                                         conn_info->resp_ie,
2914                                         conn_info->resp_ie_len,
2915                                         completed ? WLAN_STATUS_SUCCESS :
2916                                                     WLAN_STATUS_AUTH_TIMEOUT,
2917                                         GFP_KERNEL);
2918                 if (completed)
2919                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2920                 WL_CONN("Report connect result - connection %s\n",
2921                                 completed ? "succeeded" : "failed");
2922         }
2923         WL_TRACE("Exit\n");
2924         return err;
2925 }
2926
2927 static s32
2928 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2929                             struct net_device *ndev,
2930                             const struct brcmf_event_msg *e, void *data)
2931 {
2932         s32 err = 0;
2933
2934         if (brcmf_is_linkup(cfg_priv, e)) {
2935                 WL_CONN("Linkup\n");
2936                 if (brcmf_is_ibssmode(cfg_priv)) {
2937                         brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2938                                 WL_PROF_BSSID);
2939                         wl_inform_ibss(cfg_priv, ndev, e->addr);
2940                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2941                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2942                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2943                 } else
2944                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2945         } else if (brcmf_is_linkdown(cfg_priv, e)) {
2946                 WL_CONN("Linkdown\n");
2947                 if (brcmf_is_ibssmode(cfg_priv)) {
2948                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2949                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2950                                 &cfg_priv->status))
2951                                 brcmf_link_down(cfg_priv);
2952                 } else {
2953                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2954                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2955                                 &cfg_priv->status)) {
2956                                 cfg80211_disconnected(ndev, 0, NULL, 0,
2957                                         GFP_KERNEL);
2958                                 brcmf_link_down(cfg_priv);
2959                         }
2960                 }
2961                 brcmf_init_prof(cfg_priv->profile);
2962         } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2963                 if (brcmf_is_ibssmode(cfg_priv))
2964                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2965                 else
2966                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2967         }
2968
2969         return err;
2970 }
2971
2972 static s32
2973 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2974                             struct net_device *ndev,
2975                             const struct brcmf_event_msg *e, void *data)
2976 {
2977         s32 err = 0;
2978         u32 event = be32_to_cpu(e->event_type);
2979         u32 status = be32_to_cpu(e->status);
2980
2981         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2982                 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2983                         brcmf_bss_roaming_done(cfg_priv, ndev, e);
2984                 else
2985                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2986         }
2987
2988         return err;
2989 }
2990
2991 static s32
2992 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2993                         struct net_device *ndev,
2994                         const struct brcmf_event_msg *e, void *data)
2995 {
2996         u16 flags = be16_to_cpu(e->flags);
2997         enum nl80211_key_type key_type;
2998
2999         rtnl_lock();
3000         if (flags & BRCMF_EVENT_MSG_GROUP)
3001                 key_type = NL80211_KEYTYPE_GROUP;
3002         else
3003                 key_type = NL80211_KEYTYPE_PAIRWISE;
3004
3005         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3006                                      NULL, GFP_KERNEL);
3007         rtnl_unlock();
3008
3009         return 0;
3010 }
3011
3012 static s32
3013 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3014                          struct net_device *ndev,
3015                          const struct brcmf_event_msg *e, void *data)
3016 {
3017         struct brcmf_channel_info_le channel_inform_le;
3018         struct brcmf_scan_results_le *bss_list_le;
3019         u32 len = WL_SCAN_BUF_MAX;
3020         s32 err = 0;
3021         bool scan_abort = false;
3022         u32 scan_channel;
3023
3024         WL_TRACE("Enter\n");
3025
3026         if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3027                 WL_TRACE("Exit\n");
3028                 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3029         }
3030
3031         if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
3032                                          &cfg_priv->status))) {
3033                 WL_ERR("Scan complete while device not scanning\n");
3034                 scan_abort = true;
3035                 err = -EINVAL;
3036                 goto scan_done_out;
3037         }
3038
3039         err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3040                               sizeof(channel_inform_le));
3041         if (unlikely(err)) {
3042                 WL_ERR("scan busy (%d)\n", err);
3043                 scan_abort = true;
3044                 goto scan_done_out;
3045         }
3046         scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3047         if (unlikely(scan_channel))
3048                 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3049         cfg_priv->bss_list = cfg_priv->scan_results;
3050         bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3051
3052         memset(cfg_priv->scan_results, 0, len);
3053         bss_list_le->buflen = cpu_to_le32(len);
3054         err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN_RESULTS,
3055                               cfg_priv->scan_results, len);
3056         if (unlikely(err)) {
3057                 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3058                 err = -EINVAL;
3059                 scan_abort = true;
3060                 goto scan_done_out;
3061         }
3062         cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3063         cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3064         cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3065
3066         err = brcmf_inform_bss(cfg_priv);
3067         if (err) {
3068                 scan_abort = true;
3069                 goto scan_done_out;
3070         }
3071
3072 scan_done_out:
3073         if (cfg_priv->scan_request) {
3074                 WL_SCAN("calling cfg80211_scan_done\n");
3075                 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3076                 brcmf_set_mpc(ndev, 1);
3077                 cfg_priv->scan_request = NULL;
3078         }
3079
3080         WL_TRACE("Exit\n");
3081
3082         return err;
3083 }
3084
3085 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3086 {
3087         conf->mode = (u32)-1;
3088         conf->frag_threshold = (u32)-1;
3089         conf->rts_threshold = (u32)-1;
3090         conf->retry_short = (u32)-1;
3091         conf->retry_long = (u32)-1;
3092         conf->tx_power = -1;
3093 }
3094
3095 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3096 {
3097         memset(el, 0, sizeof(*el));
3098         el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3099         el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3100         el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3101         el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3102         el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3103 }
3104
3105 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3106 {
3107         kfree(cfg_priv->scan_results);
3108         cfg_priv->scan_results = NULL;
3109         kfree(cfg_priv->bss_info);
3110         cfg_priv->bss_info = NULL;
3111         kfree(cfg_priv->conf);
3112         cfg_priv->conf = NULL;
3113         kfree(cfg_priv->profile);
3114         cfg_priv->profile = NULL;
3115         kfree(cfg_priv->scan_req_int);
3116         cfg_priv->scan_req_int = NULL;
3117         kfree(cfg_priv->ioctl_buf);
3118         cfg_priv->ioctl_buf = NULL;
3119         kfree(cfg_priv->extra_buf);
3120         cfg_priv->extra_buf = NULL;
3121         kfree(cfg_priv->iscan);
3122         cfg_priv->iscan = NULL;
3123         kfree(cfg_priv->pmk_list);
3124         cfg_priv->pmk_list = NULL;
3125 }
3126
3127 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3128 {
3129         cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3130         if (unlikely(!cfg_priv->scan_results)) {
3131                 WL_ERR("Scan results alloc failed\n");
3132                 goto init_priv_mem_out;
3133         }
3134         cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3135         if (unlikely(!cfg_priv->conf)) {
3136                 WL_ERR("wl_conf alloc failed\n");
3137                 goto init_priv_mem_out;
3138         }
3139         cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3140         if (unlikely(!cfg_priv->profile)) {
3141                 WL_ERR("wl_profile alloc failed\n");
3142                 goto init_priv_mem_out;
3143         }
3144         cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3145         if (unlikely(!cfg_priv->bss_info)) {
3146                 WL_ERR("Bss information alloc failed\n");
3147                 goto init_priv_mem_out;
3148         }
3149         cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3150                                          GFP_KERNEL);
3151         if (unlikely(!cfg_priv->scan_req_int)) {
3152                 WL_ERR("Scan req alloc failed\n");
3153                 goto init_priv_mem_out;
3154         }
3155         cfg_priv->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
3156         if (unlikely(!cfg_priv->ioctl_buf)) {
3157                 WL_ERR("Ioctl buf alloc failed\n");
3158                 goto init_priv_mem_out;
3159         }
3160         cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3161         if (unlikely(!cfg_priv->extra_buf)) {
3162                 WL_ERR("Extra buf alloc failed\n");
3163                 goto init_priv_mem_out;
3164         }
3165         cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3166         if (unlikely(!cfg_priv->iscan)) {
3167                 WL_ERR("Iscan buf alloc failed\n");
3168                 goto init_priv_mem_out;
3169         }
3170         cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3171         if (unlikely(!cfg_priv->pmk_list)) {
3172                 WL_ERR("pmk list alloc failed\n");
3173                 goto init_priv_mem_out;
3174         }
3175
3176         return 0;
3177
3178 init_priv_mem_out:
3179         brcmf_deinit_priv_mem(cfg_priv);
3180
3181         return -ENOMEM;
3182 }
3183
3184 /*
3185 * retrieve first queued event from head
3186 */
3187
3188 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3189         struct brcmf_cfg80211_priv *cfg_priv)
3190 {
3191         struct brcmf_cfg80211_event_q *e = NULL;
3192
3193         spin_lock_irq(&cfg_priv->evt_q_lock);
3194         if (likely(!list_empty(&cfg_priv->evt_q_list))) {
3195                 e = list_first_entry(&cfg_priv->evt_q_list,
3196                                      struct brcmf_cfg80211_event_q, evt_q_list);
3197                 list_del(&e->evt_q_list);
3198         }
3199         spin_unlock_irq(&cfg_priv->evt_q_lock);
3200
3201         return e;
3202 }
3203
3204 /*
3205 ** push event to tail of the queue
3206 */
3207
3208 static s32
3209 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3210                 const struct brcmf_event_msg *msg)
3211 {
3212         struct brcmf_cfg80211_event_q *e;
3213         s32 err = 0;
3214
3215         e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3216         if (unlikely(!e)) {
3217                 WL_ERR("event alloc failed\n");
3218                 return -ENOMEM;
3219         }
3220
3221         e->etype = event;
3222         memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3223
3224         spin_lock_irq(&cfg_priv->evt_q_lock);
3225         list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3226         spin_unlock_irq(&cfg_priv->evt_q_lock);
3227
3228         return err;
3229 }
3230
3231 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3232 {
3233         kfree(e);
3234 }
3235
3236 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3237 {
3238         struct brcmf_cfg80211_priv *cfg_priv =
3239                         container_of(work, struct brcmf_cfg80211_priv,
3240                                      event_work);
3241         struct brcmf_cfg80211_event_q *e;
3242
3243         e = brcmf_deq_event(cfg_priv);
3244         if (unlikely(!e)) {
3245                 WL_ERR("event queue empty...\n");
3246                 return;
3247         }
3248
3249         do {
3250                 WL_INFO("event type (%d)\n", e->etype);
3251                 if (cfg_priv->el.handler[e->etype])
3252                         cfg_priv->el.handler[e->etype](cfg_priv,
3253                                                        cfg_to_ndev(cfg_priv),
3254                                                        &e->emsg, e->edata);
3255                 else
3256                         WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3257                 brcmf_put_event(e);
3258         } while ((e = brcmf_deq_event(cfg_priv)));
3259
3260 }
3261
3262 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3263 {
3264         spin_lock_init(&cfg_priv->evt_q_lock);
3265         INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3266 }
3267
3268 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3269 {
3270         struct brcmf_cfg80211_event_q *e;
3271
3272         spin_lock_irq(&cfg_priv->evt_q_lock);
3273         while (!list_empty(&cfg_priv->evt_q_list)) {
3274                 e = list_first_entry(&cfg_priv->evt_q_list,
3275                                      struct brcmf_cfg80211_event_q, evt_q_list);
3276                 list_del(&e->evt_q_list);
3277                 kfree(e);
3278         }
3279         spin_unlock_irq(&cfg_priv->evt_q_lock);
3280 }
3281
3282 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3283 {
3284         s32 err = 0;
3285
3286         cfg_priv->scan_request = NULL;
3287         cfg_priv->pwr_save = true;
3288         cfg_priv->iscan_on = true;      /* iscan on & off switch.
3289                                  we enable iscan per default */
3290         cfg_priv->roam_on = true;       /* roam on & off switch.
3291                                  we enable roam per default */
3292
3293         cfg_priv->iscan_kickstart = false;
3294         cfg_priv->active_scan = true;   /* we do active scan for
3295                                  specific scan per default */
3296         cfg_priv->dongle_up = false;    /* dongle is not up yet */
3297         brcmf_init_eq(cfg_priv);
3298         err = brcmf_init_priv_mem(cfg_priv);
3299         if (unlikely(err))
3300                 return err;
3301         INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3302         brcmf_init_eloop_handler(&cfg_priv->el);
3303         mutex_init(&cfg_priv->usr_sync);
3304         err = brcmf_init_iscan(cfg_priv);
3305         if (unlikely(err))
3306                 return err;
3307         brcmf_init_conf(cfg_priv->conf);
3308         brcmf_init_prof(cfg_priv->profile);
3309         brcmf_link_down(cfg_priv);
3310
3311         return err;
3312 }
3313
3314 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3315 {
3316         cancel_work_sync(&cfg_priv->event_work);
3317         cfg_priv->dongle_up = false;    /* dongle down */
3318         brcmf_flush_eq(cfg_priv);
3319         brcmf_link_down(cfg_priv);
3320         brcmf_term_iscan(cfg_priv);
3321         brcmf_deinit_priv_mem(cfg_priv);
3322 }
3323
3324 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3325                                                  struct device *busdev,
3326                                                  void *data)
3327 {
3328         struct wireless_dev *wdev;
3329         struct brcmf_cfg80211_priv *cfg_priv;
3330         struct brcmf_cfg80211_iface *ci;
3331         struct brcmf_cfg80211_dev *cfg_dev;
3332         s32 err = 0;
3333
3334         if (unlikely(!ndev)) {
3335                 WL_ERR("ndev is invalid\n");
3336                 return NULL;
3337         }
3338         cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3339         if (unlikely(!cfg_dev)) {
3340                 WL_ERR("wl_cfg80211_dev is invalid\n");
3341                 return NULL;
3342         }
3343
3344         wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3345         if (IS_ERR(wdev)) {
3346                 kfree(cfg_dev);
3347                 return NULL;
3348         }
3349
3350         wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3351         cfg_priv = wdev_to_cfg(wdev);
3352         cfg_priv->wdev = wdev;
3353         cfg_priv->pub = data;
3354         ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3355         ci->cfg_priv = cfg_priv;
3356         ndev->ieee80211_ptr = wdev;
3357         SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3358         wdev->netdev = ndev;
3359         err = wl_init_priv(cfg_priv);
3360         if (unlikely(err)) {
3361                 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3362                 goto cfg80211_attach_out;
3363         }
3364         brcmf_set_drvdata(cfg_dev, ci);
3365
3366         return cfg_dev;
3367
3368 cfg80211_attach_out:
3369         brcmf_free_wdev(cfg_priv);
3370         kfree(cfg_dev);
3371         return NULL;
3372 }
3373
3374 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3375 {
3376         struct brcmf_cfg80211_priv *cfg_priv;
3377
3378         cfg_priv = brcmf_priv_get(cfg_dev);
3379
3380         wl_deinit_priv(cfg_priv);
3381         brcmf_free_wdev(cfg_priv);
3382         brcmf_set_drvdata(cfg_dev, NULL);
3383         kfree(cfg_dev);
3384 }
3385
3386 void
3387 brcmf_cfg80211_event(struct net_device *ndev,
3388                   const struct brcmf_event_msg *e, void *data)
3389 {
3390         u32 event_type = be32_to_cpu(e->event_type);
3391         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3392
3393         if (likely(!brcmf_enq_event(cfg_priv, event_type, e)))
3394                 schedule_work(&cfg_priv->event_work);
3395 }
3396
3397 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3398 {
3399         s32 infra = 0;
3400         s32 err = 0;
3401
3402         switch (iftype) {
3403         case NL80211_IFTYPE_MONITOR:
3404         case NL80211_IFTYPE_WDS:
3405                 WL_ERR("type (%d) : currently we do not support this mode\n",
3406                        iftype);
3407                 err = -EINVAL;
3408                 return err;
3409         case NL80211_IFTYPE_ADHOC:
3410                 infra = 0;
3411                 break;
3412         case NL80211_IFTYPE_STATION:
3413                 infra = 1;
3414                 break;
3415         default:
3416                 err = -EINVAL;
3417                 WL_ERR("invalid type (%d)\n", iftype);
3418                 return err;
3419         }
3420         err = brcmf_dev_ioctl_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3421         if (unlikely(err)) {
3422                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3423                 return err;
3424         }
3425
3426         return 0;
3427 }
3428
3429 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3430 {
3431         /* Room for "event_msgs" + '\0' + bitvec */
3432         s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3433         s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3434         s32 err = 0;
3435
3436         WL_TRACE("Enter\n");
3437
3438         /* Setup event_msgs */
3439         brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3440                     sizeof(iovbuf));
3441         err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3442         if (unlikely(err)) {
3443                 WL_ERR("Get event_msgs error (%d)\n", err);
3444                 goto dongle_eventmsg_out;
3445         }
3446         memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3447
3448         setbit(eventmask, BRCMF_E_SET_SSID);
3449         setbit(eventmask, BRCMF_E_ROAM);
3450         setbit(eventmask, BRCMF_E_PRUNE);
3451         setbit(eventmask, BRCMF_E_AUTH);
3452         setbit(eventmask, BRCMF_E_REASSOC);
3453         setbit(eventmask, BRCMF_E_REASSOC_IND);
3454         setbit(eventmask, BRCMF_E_DEAUTH_IND);
3455         setbit(eventmask, BRCMF_E_DISASSOC_IND);
3456         setbit(eventmask, BRCMF_E_DISASSOC);
3457         setbit(eventmask, BRCMF_E_JOIN);
3458         setbit(eventmask, BRCMF_E_ASSOC_IND);
3459         setbit(eventmask, BRCMF_E_PSK_SUP);
3460         setbit(eventmask, BRCMF_E_LINK);
3461         setbit(eventmask, BRCMF_E_NDIS_LINK);
3462         setbit(eventmask, BRCMF_E_MIC_ERROR);
3463         setbit(eventmask, BRCMF_E_PMKID_CACHE);
3464         setbit(eventmask, BRCMF_E_TXFAIL);
3465         setbit(eventmask, BRCMF_E_JOIN_START);
3466         setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3467
3468         brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3469                     sizeof(iovbuf));
3470         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3471         if (unlikely(err)) {
3472                 WL_ERR("Set event_msgs error (%d)\n", err);
3473                 goto dongle_eventmsg_out;
3474         }
3475
3476 dongle_eventmsg_out:
3477         WL_TRACE("Exit\n");
3478         return err;
3479 }
3480
3481 static s32
3482 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3483 {
3484         s8 iovbuf[32];
3485         s32 roamtrigger[2];
3486         s32 roam_delta[2];
3487         s32 err = 0;
3488
3489         /*
3490          * Setup timeout if Beacons are lost and roam is
3491          * off to report link down
3492          */
3493         if (roamvar) {
3494                 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3495                         sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3496                 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR,
3497                                    iovbuf, sizeof(iovbuf));
3498                 if (unlikely(err)) {
3499                         WL_ERR("bcn_timeout error (%d)\n", err);
3500                         goto dongle_rom_out;
3501                 }
3502         }
3503
3504         /*
3505          * Enable/Disable built-in roaming to allow supplicant
3506          * to take care of roaming
3507          */
3508         WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3509         brcmu_mkiovar("roam_off", (char *)&roamvar,
3510                                 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3511         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3512         if (unlikely(err)) {
3513                 WL_ERR("roam_off error (%d)\n", err);
3514                 goto dongle_rom_out;
3515         }
3516
3517         roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3518         roamtrigger[1] = BRCM_BAND_ALL;
3519         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3520                         (void *)roamtrigger, sizeof(roamtrigger));
3521         if (unlikely(err)) {
3522                 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3523                 goto dongle_rom_out;
3524         }
3525
3526         roam_delta[0] = WL_ROAM_DELTA;
3527         roam_delta[1] = BRCM_BAND_ALL;
3528         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_DELTA,
3529                                 (void *)roam_delta, sizeof(roam_delta));
3530         if (unlikely(err)) {
3531                 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3532                 goto dongle_rom_out;
3533         }
3534
3535 dongle_rom_out:
3536         return err;
3537 }
3538
3539 static s32
3540 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3541                 s32 scan_unassoc_time, s32 scan_passive_time)
3542 {
3543         s32 err = 0;
3544
3545         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3546                            &scan_assoc_time, sizeof(scan_assoc_time));
3547         if (err) {
3548                 if (err == -EOPNOTSUPP)
3549                         WL_INFO("Scan assoc time is not supported\n");
3550                 else
3551                         WL_ERR("Scan assoc time error (%d)\n", err);
3552                 goto dongle_scantime_out;
3553         }
3554         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3555                            &scan_unassoc_time, sizeof(scan_unassoc_time));
3556         if (err) {
3557                 if (err == -EOPNOTSUPP)
3558                         WL_INFO("Scan unassoc time is not supported\n");
3559                 else
3560                         WL_ERR("Scan unassoc time error (%d)\n", err);
3561                 goto dongle_scantime_out;
3562         }
3563
3564         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3565                            &scan_passive_time, sizeof(scan_passive_time));
3566         if (err) {
3567                 if (err == -EOPNOTSUPP)
3568                         WL_INFO("Scan passive time is not supported\n");
3569                 else
3570                         WL_ERR("Scan passive time error (%d)\n", err);
3571                 goto dongle_scantime_out;
3572         }
3573
3574 dongle_scantime_out:
3575         return err;
3576 }
3577
3578 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3579 {
3580         struct wiphy *wiphy;
3581         s32 phy_list;
3582         s8 phy;
3583         s32 err = 0;
3584
3585         err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3586                               &phy_list, sizeof(phy_list));
3587         if (unlikely(err)) {
3588                 WL_ERR("error (%d)\n", err);
3589                 return err;
3590         }
3591
3592         phy = ((char *)&phy_list)[1];
3593         WL_INFO("%c phy\n", phy);
3594         if (phy == 'n' || phy == 'a') {
3595                 wiphy = cfg_to_wiphy(cfg_priv);
3596                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3597         }
3598
3599         return err;
3600 }
3601
3602 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3603 {
3604         return wl_update_wiphybands(cfg_priv);
3605 }
3606
3607 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv,
3608                                bool need_lock)
3609 {
3610         struct net_device *ndev;
3611         struct wireless_dev *wdev;
3612         s32 power_mode;
3613         s32 err = 0;
3614
3615         if (cfg_priv->dongle_up)
3616                 return err;
3617
3618         ndev = cfg_to_ndev(cfg_priv);
3619         wdev = ndev->ieee80211_ptr;
3620         if (need_lock)
3621                 rtnl_lock();
3622
3623         brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3624                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3625
3626         err = brcmf_dongle_eventmsg(ndev);
3627         if (unlikely(err))
3628                 goto default_conf_out;
3629
3630         power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3631         err = brcmf_dev_ioctl_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3632         if (err)
3633                 goto default_conf_out;
3634         WL_INFO("power save set to %s\n",
3635                 (power_mode ? "enabled" : "disabled"));
3636
3637         err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3638                                 WL_BEACON_TIMEOUT);
3639         if (unlikely(err))
3640                 goto default_conf_out;
3641         err = brcmf_dongle_mode(ndev, wdev->iftype);
3642         if (unlikely(err && err != -EINPROGRESS))
3643                 goto default_conf_out;
3644         err = brcmf_dongle_probecap(cfg_priv);
3645         if (unlikely(err))
3646                 goto default_conf_out;
3647
3648         /* -EINPROGRESS: Call commit handler */
3649
3650 default_conf_out:
3651         if (need_lock)
3652                 rtnl_unlock();
3653
3654         cfg_priv->dongle_up = true;
3655
3656         return err;
3657
3658 }
3659
3660 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3661 {
3662         char buf[10+IFNAMSIZ];
3663         struct dentry *fd;
3664         s32 err = 0;
3665
3666         sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3667         cfg_priv->debugfsdir = debugfs_create_dir(buf,
3668                                         cfg_to_wiphy(cfg_priv)->debugfsdir);
3669
3670         fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3671                 (u16 *)&cfg_priv->profile->beacon_interval);
3672         if (!fd) {
3673                 err = -ENOMEM;
3674                 goto err_out;
3675         }
3676
3677         fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3678                 (u8 *)&cfg_priv->profile->dtim_period);
3679         if (!fd) {
3680                 err = -ENOMEM;
3681                 goto err_out;
3682         }
3683
3684 err_out:
3685         return err;
3686 }
3687
3688 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3689 {
3690         debugfs_remove_recursive(cfg_priv->debugfsdir);
3691         cfg_priv->debugfsdir = NULL;
3692 }
3693
3694 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3695 {
3696         s32 err = 0;
3697
3698         set_bit(WL_STATUS_READY, &cfg_priv->status);
3699
3700         brcmf_debugfs_add_netdev_params(cfg_priv);
3701
3702         err = brcmf_config_dongle(cfg_priv, false);
3703         if (unlikely(err))
3704                 return err;
3705
3706         brcmf_invoke_iscan(cfg_priv);
3707
3708         return err;
3709 }
3710
3711 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3712 {
3713         /*
3714          * While going down, if associated with AP disassociate
3715          * from AP to save power
3716          */
3717         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3718              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3719              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3720                 WL_INFO("Disassociating from AP");
3721                 brcmf_link_down(cfg_priv);
3722
3723                 /* Make sure WPA_Supplicant receives all the event
3724                    generated due to DISASSOC call to the fw to keep
3725                    the state fw and WPA_Supplicant state consistent
3726                  */
3727                 rtnl_unlock();
3728                 brcmf_delay(500);
3729                 rtnl_lock();
3730         }
3731
3732         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3733         brcmf_term_iscan(cfg_priv);
3734         if (cfg_priv->scan_request) {
3735                 cfg80211_scan_done(cfg_priv->scan_request, true);
3736                 /* May need to perform this to cover rmmod */
3737                 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3738                 cfg_priv->scan_request = NULL;
3739         }
3740         clear_bit(WL_STATUS_READY, &cfg_priv->status);
3741         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3742         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3743
3744         brcmf_debugfs_remove_netdev(cfg_priv);
3745
3746         return 0;
3747 }
3748
3749 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3750 {
3751         struct brcmf_cfg80211_priv *cfg_priv;
3752         s32 err = 0;
3753
3754         cfg_priv = brcmf_priv_get(cfg_dev);
3755         mutex_lock(&cfg_priv->usr_sync);
3756         err = __brcmf_cfg80211_up(cfg_priv);
3757         mutex_unlock(&cfg_priv->usr_sync);
3758
3759         return err;
3760 }
3761
3762 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3763 {
3764         struct brcmf_cfg80211_priv *cfg_priv;
3765         s32 err = 0;
3766
3767         cfg_priv = brcmf_priv_get(cfg_dev);
3768         mutex_lock(&cfg_priv->usr_sync);
3769         err = __brcmf_cfg80211_down(cfg_priv);
3770         mutex_unlock(&cfg_priv->usr_sync);
3771
3772         return err;
3773 }
3774
3775 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3776                                u8 t, u8 l, u8 *v)
3777 {
3778         struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3779         s32 err = 0;
3780
3781         if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3782                 WL_ERR("ei crosses buffer boundary\n");
3783                 return -ENOSPC;
3784         }
3785         ie->buf[ie->offset] = t;
3786         ie->buf[ie->offset + 1] = l;
3787         memcpy(&ie->buf[ie->offset + 2], v, l);
3788         ie->offset += l + 2;
3789
3790         return err;
3791 }