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