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