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