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