]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
regulator: max8952: Add missing config.of_node setting for regulator register
[karo-tx-linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / wl_cfg80211.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
18
19 #include <linux/kernel.h>
20 #include <linux/etherdevice.h>
21 #include <net/cfg80211.h>
22 #include <net/netlink.h>
23
24 #include <brcmu_utils.h>
25 #include <defs.h>
26 #include <brcmu_wifi.h>
27 #include "dhd.h"
28 #include "dhd_dbg.h"
29 #include "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_wsec_key key;
1895         s32 err = 0;
1896
1897         memset(&key, 0, sizeof(key));
1898         key.index = (u32) key_idx;
1899         /* Instead of bcast for ea address for default wep keys,
1900                  driver needs it to be Null */
1901         if (!is_multicast_ether_addr(mac_addr))
1902                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1903         key.len = (u32) params->key_len;
1904         /* check for key index change */
1905         if (key.len == 0) {
1906                 /* key delete */
1907                 err = send_key_to_dongle(ndev, &key);
1908                 if (err)
1909                         brcmf_err("key delete error (%d)\n", err);
1910         } else {
1911                 if (key.len > sizeof(key.data)) {
1912                         brcmf_err("Invalid key length (%d)\n", key.len);
1913                         return -EINVAL;
1914                 }
1915
1916                 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1917                 memcpy(key.data, params->key, key.len);
1918
1919                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1920                         u8 keybuf[8];
1921                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1922                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1923                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1924                 }
1925
1926                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1927                 if (params->seq && params->seq_len == 6) {
1928                         /* rx iv */
1929                         u8 *ivptr;
1930                         ivptr = (u8 *) params->seq;
1931                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1932                             (ivptr[3] << 8) | ivptr[2];
1933                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1934                         key.iv_initialized = true;
1935                 }
1936
1937                 switch (params->cipher) {
1938                 case WLAN_CIPHER_SUITE_WEP40:
1939                         key.algo = CRYPTO_ALGO_WEP1;
1940                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1941                         break;
1942                 case WLAN_CIPHER_SUITE_WEP104:
1943                         key.algo = CRYPTO_ALGO_WEP128;
1944                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1945                         break;
1946                 case WLAN_CIPHER_SUITE_TKIP:
1947                         key.algo = CRYPTO_ALGO_TKIP;
1948                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1949                         break;
1950                 case WLAN_CIPHER_SUITE_AES_CMAC:
1951                         key.algo = CRYPTO_ALGO_AES_CCM;
1952                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1953                         break;
1954                 case WLAN_CIPHER_SUITE_CCMP:
1955                         key.algo = CRYPTO_ALGO_AES_CCM;
1956                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1957                         break;
1958                 default:
1959                         brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1960                         return -EINVAL;
1961                 }
1962                 err = send_key_to_dongle(ndev, &key);
1963                 if (err)
1964                         brcmf_err("wsec_key error (%d)\n", err);
1965         }
1966         return err;
1967 }
1968
1969 static s32
1970 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1971                     u8 key_idx, bool pairwise, const u8 *mac_addr,
1972                     struct key_params *params)
1973 {
1974         struct brcmf_if *ifp = netdev_priv(ndev);
1975         struct brcmf_wsec_key key;
1976         s32 val;
1977         s32 wsec;
1978         s32 err = 0;
1979         u8 keybuf[8];
1980
1981         brcmf_dbg(TRACE, "Enter\n");
1982         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1983         if (!check_vif_up(ifp->vif))
1984                 return -EIO;
1985
1986         if (mac_addr) {
1987                 brcmf_dbg(TRACE, "Exit");
1988                 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1989         }
1990         memset(&key, 0, sizeof(key));
1991
1992         key.len = (u32) params->key_len;
1993         key.index = (u32) key_idx;
1994
1995         if (key.len > sizeof(key.data)) {
1996                 brcmf_err("Too long key length (%u)\n", key.len);
1997                 err = -EINVAL;
1998                 goto done;
1999         }
2000         memcpy(key.data, params->key, key.len);
2001
2002         key.flags = BRCMF_PRIMARY_KEY;
2003         switch (params->cipher) {
2004         case WLAN_CIPHER_SUITE_WEP40:
2005                 key.algo = CRYPTO_ALGO_WEP1;
2006                 val = WEP_ENABLED;
2007                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2008                 break;
2009         case WLAN_CIPHER_SUITE_WEP104:
2010                 key.algo = CRYPTO_ALGO_WEP128;
2011                 val = WEP_ENABLED;
2012                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2013                 break;
2014         case WLAN_CIPHER_SUITE_TKIP:
2015                 if (ifp->vif->mode != WL_MODE_AP) {
2016                         brcmf_dbg(CONN, "Swapping key\n");
2017                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
2018                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2019                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
2020                 }
2021                 key.algo = CRYPTO_ALGO_TKIP;
2022                 val = TKIP_ENABLED;
2023                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2024                 break;
2025         case WLAN_CIPHER_SUITE_AES_CMAC:
2026                 key.algo = CRYPTO_ALGO_AES_CCM;
2027                 val = AES_ENABLED;
2028                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2029                 break;
2030         case WLAN_CIPHER_SUITE_CCMP:
2031                 key.algo = CRYPTO_ALGO_AES_CCM;
2032                 val = AES_ENABLED;
2033                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2034                 break;
2035         default:
2036                 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2037                 err = -EINVAL;
2038                 goto done;
2039         }
2040
2041         err = send_key_to_dongle(ndev, &key);
2042         if (err)
2043                 goto done;
2044
2045         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2046         if (err) {
2047                 brcmf_err("get wsec error (%d)\n", err);
2048                 goto done;
2049         }
2050         wsec |= val;
2051         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2052         if (err) {
2053                 brcmf_err("set wsec error (%d)\n", err);
2054                 goto done;
2055         }
2056
2057 done:
2058         brcmf_dbg(TRACE, "Exit\n");
2059         return err;
2060 }
2061
2062 static s32
2063 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2064                     u8 key_idx, bool pairwise, const u8 *mac_addr)
2065 {
2066         struct brcmf_if *ifp = netdev_priv(ndev);
2067         struct brcmf_wsec_key key;
2068         s32 err = 0;
2069
2070         brcmf_dbg(TRACE, "Enter\n");
2071         if (!check_vif_up(ifp->vif))
2072                 return -EIO;
2073
2074         if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2075                 /* we ignore this key index in this case */
2076                 brcmf_err("invalid key index (%d)\n", key_idx);
2077                 return -EINVAL;
2078         }
2079
2080         memset(&key, 0, sizeof(key));
2081
2082         key.index = (u32) key_idx;
2083         key.flags = BRCMF_PRIMARY_KEY;
2084         key.algo = CRYPTO_ALGO_OFF;
2085
2086         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2087
2088         /* Set the new key/index */
2089         err = send_key_to_dongle(ndev, &key);
2090
2091         brcmf_dbg(TRACE, "Exit\n");
2092         return err;
2093 }
2094
2095 static s32
2096 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2097                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2098                     void (*callback) (void *cookie, struct key_params * params))
2099 {
2100         struct key_params params;
2101         struct brcmf_if *ifp = netdev_priv(ndev);
2102         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2103         struct brcmf_cfg80211_security *sec;
2104         s32 wsec;
2105         s32 err = 0;
2106
2107         brcmf_dbg(TRACE, "Enter\n");
2108         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2109         if (!check_vif_up(ifp->vif))
2110                 return -EIO;
2111
2112         memset(&params, 0, sizeof(params));
2113
2114         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2115         if (err) {
2116                 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2117                 /* Ignore this error, may happen during DISASSOC */
2118                 err = -EAGAIN;
2119                 goto done;
2120         }
2121         switch (wsec & ~SES_OW_ENABLED) {
2122         case WEP_ENABLED:
2123                 sec = &profile->sec;
2124                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2125                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
2126                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2127                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2128                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
2129                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2130                 }
2131                 break;
2132         case TKIP_ENABLED:
2133                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2134                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2135                 break;
2136         case AES_ENABLED:
2137                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2138                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2139                 break;
2140         default:
2141                 brcmf_err("Invalid algo (0x%x)\n", wsec);
2142                 err = -EINVAL;
2143                 goto done;
2144         }
2145         callback(cookie, &params);
2146
2147 done:
2148         brcmf_dbg(TRACE, "Exit\n");
2149         return err;
2150 }
2151
2152 static s32
2153 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2154                                     struct net_device *ndev, u8 key_idx)
2155 {
2156         brcmf_dbg(INFO, "Not supported\n");
2157
2158         return -EOPNOTSUPP;
2159 }
2160
2161 static s32
2162 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2163                            u8 *mac, struct station_info *sinfo)
2164 {
2165         struct brcmf_if *ifp = netdev_priv(ndev);
2166         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2167         struct brcmf_scb_val_le scb_val;
2168         int rssi;
2169         s32 rate;
2170         s32 err = 0;
2171         u8 *bssid = profile->bssid;
2172         struct brcmf_sta_info_le sta_info_le;
2173
2174         brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2175         if (!check_vif_up(ifp->vif))
2176                 return -EIO;
2177
2178         if (ifp->vif->mode == WL_MODE_AP) {
2179                 memcpy(&sta_info_le, mac, ETH_ALEN);
2180                 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2181                                                &sta_info_le,
2182                                                sizeof(sta_info_le));
2183                 if (err < 0) {
2184                         brcmf_err("GET STA INFO failed, %d\n", err);
2185                         goto done;
2186                 }
2187                 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2188                 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2189                 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2190                         sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2191                         sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2192                 }
2193                 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2194                           sinfo->inactive_time, sinfo->connected_time);
2195         } else if (ifp->vif->mode == WL_MODE_BSS) {
2196                 if (memcmp(mac, bssid, ETH_ALEN)) {
2197                         brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2198                                   mac, bssid);
2199                         err = -ENOENT;
2200                         goto done;
2201                 }
2202                 /* Report the current tx rate */
2203                 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2204                 if (err) {
2205                         brcmf_err("Could not get rate (%d)\n", err);
2206                         goto done;
2207                 } else {
2208                         sinfo->filled |= STATION_INFO_TX_BITRATE;
2209                         sinfo->txrate.legacy = rate * 5;
2210                         brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2211                 }
2212
2213                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2214                              &ifp->vif->sme_state)) {
2215                         memset(&scb_val, 0, sizeof(scb_val));
2216                         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2217                                                      &scb_val, sizeof(scb_val));
2218                         if (err) {
2219                                 brcmf_err("Could not get rssi (%d)\n", err);
2220                                 goto done;
2221                         } else {
2222                                 rssi = le32_to_cpu(scb_val.val);
2223                                 sinfo->filled |= STATION_INFO_SIGNAL;
2224                                 sinfo->signal = rssi;
2225                                 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2226                         }
2227                 }
2228         } else
2229                 err = -EPERM;
2230 done:
2231         brcmf_dbg(TRACE, "Exit\n");
2232         return err;
2233 }
2234
2235 static s32
2236 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2237                            bool enabled, s32 timeout)
2238 {
2239         s32 pm;
2240         s32 err = 0;
2241         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2242         struct brcmf_if *ifp = netdev_priv(ndev);
2243
2244         brcmf_dbg(TRACE, "Enter\n");
2245
2246         /*
2247          * Powersave enable/disable request is coming from the
2248          * cfg80211 even before the interface is up. In that
2249          * scenario, driver will be storing the power save
2250          * preference in cfg struct to apply this to
2251          * FW later while initializing the dongle
2252          */
2253         cfg->pwr_save = enabled;
2254         if (!check_vif_up(ifp->vif)) {
2255
2256                 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2257                 goto done;
2258         }
2259
2260         pm = enabled ? PM_FAST : PM_OFF;
2261         brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2262
2263         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2264         if (err) {
2265                 if (err == -ENODEV)
2266                         brcmf_err("net_device is not ready yet\n");
2267                 else
2268                         brcmf_err("error (%d)\n", err);
2269         }
2270 done:
2271         brcmf_dbg(TRACE, "Exit\n");
2272         return err;
2273 }
2274
2275 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2276                                    struct brcmf_bss_info_le *bi)
2277 {
2278         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2279         struct ieee80211_channel *notify_channel;
2280         struct cfg80211_bss *bss;
2281         struct ieee80211_supported_band *band;
2282         s32 err = 0;
2283         u16 channel;
2284         u32 freq;
2285         u16 notify_capability;
2286         u16 notify_interval;
2287         u8 *notify_ie;
2288         size_t notify_ielen;
2289         s32 notify_signal;
2290
2291         if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2292                 brcmf_err("Bss info is larger than buffer. Discarding\n");
2293                 return 0;
2294         }
2295
2296         channel = bi->ctl_ch ? bi->ctl_ch :
2297                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2298
2299         if (channel <= CH_MAX_2G_CHANNEL)
2300                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2301         else
2302                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2303
2304         freq = ieee80211_channel_to_frequency(channel, band->band);
2305         notify_channel = ieee80211_get_channel(wiphy, freq);
2306
2307         notify_capability = le16_to_cpu(bi->capability);
2308         notify_interval = le16_to_cpu(bi->beacon_period);
2309         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2310         notify_ielen = le32_to_cpu(bi->ie_length);
2311         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2312
2313         brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2314         brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2315         brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2316         brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2317         brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2318
2319         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2320                 0, notify_capability, notify_interval, notify_ie,
2321                 notify_ielen, notify_signal, GFP_KERNEL);
2322
2323         if (!bss)
2324                 return -ENOMEM;
2325
2326         cfg80211_put_bss(wiphy, bss);
2327
2328         return err;
2329 }
2330
2331 static struct brcmf_bss_info_le *
2332 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2333 {
2334         if (bss == NULL)
2335                 return list->bss_info_le;
2336         return (struct brcmf_bss_info_le *)((unsigned long)bss +
2337                                             le32_to_cpu(bss->length));
2338 }
2339
2340 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2341 {
2342         struct brcmf_scan_results *bss_list;
2343         struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2344         s32 err = 0;
2345         int i;
2346
2347         bss_list = cfg->bss_list;
2348         if (bss_list->count != 0 &&
2349             bss_list->version != BRCMF_BSS_INFO_VERSION) {
2350                 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2351                           bss_list->version);
2352                 return -EOPNOTSUPP;
2353         }
2354         brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2355         for (i = 0; i < bss_list->count; i++) {
2356                 bi = next_bss_le(bss_list, bi);
2357                 err = brcmf_inform_single_bss(cfg, bi);
2358                 if (err)
2359                         break;
2360         }
2361         return err;
2362 }
2363
2364 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2365                           struct net_device *ndev, const u8 *bssid)
2366 {
2367         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2368         struct ieee80211_channel *notify_channel;
2369         struct brcmf_bss_info_le *bi = NULL;
2370         struct ieee80211_supported_band *band;
2371         struct cfg80211_bss *bss;
2372         u8 *buf = NULL;
2373         s32 err = 0;
2374         u16 channel;
2375         u32 freq;
2376         u16 notify_capability;
2377         u16 notify_interval;
2378         u8 *notify_ie;
2379         size_t notify_ielen;
2380         s32 notify_signal;
2381
2382         brcmf_dbg(TRACE, "Enter\n");
2383
2384         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2385         if (buf == NULL) {
2386                 err = -ENOMEM;
2387                 goto CleanUp;
2388         }
2389
2390         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2391
2392         err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2393                                      buf, WL_BSS_INFO_MAX);
2394         if (err) {
2395                 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2396                 goto CleanUp;
2397         }
2398
2399         bi = (struct brcmf_bss_info_le *)(buf + 4);
2400
2401         channel = bi->ctl_ch ? bi->ctl_ch :
2402                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2403
2404         if (channel <= CH_MAX_2G_CHANNEL)
2405                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2406         else
2407                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2408
2409         freq = ieee80211_channel_to_frequency(channel, band->band);
2410         notify_channel = ieee80211_get_channel(wiphy, freq);
2411
2412         notify_capability = le16_to_cpu(bi->capability);
2413         notify_interval = le16_to_cpu(bi->beacon_period);
2414         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2415         notify_ielen = le32_to_cpu(bi->ie_length);
2416         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2417
2418         brcmf_dbg(CONN, "channel: %d(%d)\n", channel, freq);
2419         brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2420         brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2421         brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2422
2423         bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2424                 0, notify_capability, notify_interval,
2425                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2426
2427         if (!bss) {
2428                 err = -ENOMEM;
2429                 goto CleanUp;
2430         }
2431
2432         cfg80211_put_bss(wiphy, bss);
2433
2434 CleanUp:
2435
2436         kfree(buf);
2437
2438         brcmf_dbg(TRACE, "Exit\n");
2439
2440         return err;
2441 }
2442
2443 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2444 {
2445         return vif->mode == WL_MODE_IBSS;
2446 }
2447
2448 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2449                                  struct brcmf_if *ifp)
2450 {
2451         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2452         struct brcmf_bss_info_le *bi;
2453         struct brcmf_ssid *ssid;
2454         struct brcmf_tlv *tim;
2455         u16 beacon_interval;
2456         u8 dtim_period;
2457         size_t ie_len;
2458         u8 *ie;
2459         s32 err = 0;
2460
2461         brcmf_dbg(TRACE, "Enter\n");
2462         if (brcmf_is_ibssmode(ifp->vif))
2463                 return err;
2464
2465         ssid = &profile->ssid;
2466
2467         *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2468         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2469                                      cfg->extra_buf, WL_EXTRA_BUF_MAX);
2470         if (err) {
2471                 brcmf_err("Could not get bss info %d\n", err);
2472                 goto update_bss_info_out;
2473         }
2474
2475         bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2476         err = brcmf_inform_single_bss(cfg, bi);
2477         if (err)
2478                 goto update_bss_info_out;
2479
2480         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2481         ie_len = le32_to_cpu(bi->ie_length);
2482         beacon_interval = le16_to_cpu(bi->beacon_period);
2483
2484         tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2485         if (tim)
2486                 dtim_period = tim->data[1];
2487         else {
2488                 /*
2489                 * active scan was done so we could not get dtim
2490                 * information out of probe response.
2491                 * so we speficially query dtim information to dongle.
2492                 */
2493                 u32 var;
2494                 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2495                 if (err) {
2496                         brcmf_err("wl dtim_assoc failed (%d)\n", err);
2497                         goto update_bss_info_out;
2498                 }
2499                 dtim_period = (u8)var;
2500         }
2501
2502 update_bss_info_out:
2503         brcmf_dbg(TRACE, "Exit");
2504         return err;
2505 }
2506
2507 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2508 {
2509         struct escan_info *escan = &cfg->escan_info;
2510
2511         set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2512         if (cfg->scan_request) {
2513                 escan->escan_state = WL_ESCAN_STATE_IDLE;
2514                 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2515         }
2516         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2517         clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2518 }
2519
2520 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2521 {
2522         struct brcmf_cfg80211_info *cfg =
2523                         container_of(work, struct brcmf_cfg80211_info,
2524                                      escan_timeout_work);
2525
2526         brcmf_notify_escan_complete(cfg, cfg->escan_info.ndev, true, true);
2527 }
2528
2529 static void brcmf_escan_timeout(unsigned long data)
2530 {
2531         struct brcmf_cfg80211_info *cfg =
2532                         (struct brcmf_cfg80211_info *)data;
2533
2534         if (cfg->scan_request) {
2535                 brcmf_err("timer expired\n");
2536                 schedule_work(&cfg->escan_timeout_work);
2537         }
2538 }
2539
2540 static s32
2541 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2542                               struct brcmf_bss_info_le *bss_info_le)
2543 {
2544         if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2545                 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2546                 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2547                 bss_info_le->SSID_len == bss->SSID_len &&
2548                 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2549                 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2550                         (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2551                         s16 bss_rssi = le16_to_cpu(bss->RSSI);
2552                         s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2553
2554                         /* preserve max RSSI if the measurements are
2555                         * both on-channel or both off-channel
2556                         */
2557                         if (bss_info_rssi > bss_rssi)
2558                                 bss->RSSI = bss_info_le->RSSI;
2559                 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2560                         (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2561                         /* preserve the on-channel rssi measurement
2562                         * if the new measurement is off channel
2563                         */
2564                         bss->RSSI = bss_info_le->RSSI;
2565                         bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2566                 }
2567                 return 1;
2568         }
2569         return 0;
2570 }
2571
2572 static s32
2573 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2574                              const struct brcmf_event_msg *e, void *data)
2575 {
2576         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2577         struct net_device *ndev = ifp->ndev;
2578         s32 status;
2579         s32 err = 0;
2580         struct brcmf_escan_result_le *escan_result_le;
2581         struct brcmf_bss_info_le *bss_info_le;
2582         struct brcmf_bss_info_le *bss = NULL;
2583         u32 bi_length;
2584         struct brcmf_scan_results *list;
2585         u32 i;
2586         bool aborted;
2587
2588         status = e->status;
2589
2590         if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2591                 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev,
2592                           !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2593                 return -EPERM;
2594         }
2595
2596         if (status == BRCMF_E_STATUS_PARTIAL) {
2597                 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2598                 escan_result_le = (struct brcmf_escan_result_le *) data;
2599                 if (!escan_result_le) {
2600                         brcmf_err("Invalid escan result (NULL pointer)\n");
2601                         goto exit;
2602                 }
2603                 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2604                         brcmf_err("Invalid bss_count %d: ignoring\n",
2605                                   escan_result_le->bss_count);
2606                         goto exit;
2607                 }
2608                 bss_info_le = &escan_result_le->bss_info_le;
2609
2610                 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2611                         goto exit;
2612
2613                 if (!cfg->scan_request) {
2614                         brcmf_dbg(SCAN, "result without cfg80211 request\n");
2615                         goto exit;
2616                 }
2617
2618                 bi_length = le32_to_cpu(bss_info_le->length);
2619                 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2620                                         WL_ESCAN_RESULTS_FIXED_SIZE)) {
2621                         brcmf_err("Invalid bss_info length %d: ignoring\n",
2622                                   bi_length);
2623                         goto exit;
2624                 }
2625
2626                 if (!(cfg_to_wiphy(cfg)->interface_modes &
2627                                         BIT(NL80211_IFTYPE_ADHOC))) {
2628                         if (le16_to_cpu(bss_info_le->capability) &
2629                                                 WLAN_CAPABILITY_IBSS) {
2630                                 brcmf_err("Ignoring IBSS result\n");
2631                                 goto exit;
2632                         }
2633                 }
2634
2635                 list = (struct brcmf_scan_results *)
2636                                 cfg->escan_info.escan_buf;
2637                 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2638                         brcmf_err("Buffer is too small: ignoring\n");
2639                         goto exit;
2640                 }
2641
2642                 for (i = 0; i < list->count; i++) {
2643                         bss = bss ? (struct brcmf_bss_info_le *)
2644                                 ((unsigned char *)bss +
2645                                 le32_to_cpu(bss->length)) : list->bss_info_le;
2646                         if (brcmf_compare_update_same_bss(bss, bss_info_le))
2647                                 goto exit;
2648                 }
2649                 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2650                         bss_info_le, bi_length);
2651                 list->version = le32_to_cpu(bss_info_le->version);
2652                 list->buflen += bi_length;
2653                 list->count++;
2654         } else {
2655                 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2656                 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2657                         goto exit;
2658                 if (cfg->scan_request) {
2659                         cfg->bss_list = (struct brcmf_scan_results *)
2660                                 cfg->escan_info.escan_buf;
2661                         brcmf_inform_bss(cfg);
2662                         aborted = status != BRCMF_E_STATUS_SUCCESS;
2663                         brcmf_notify_escan_complete(cfg, ndev, aborted,
2664                                                     false);
2665                 } else
2666                         brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2667                                   status);
2668         }
2669 exit:
2670         return err;
2671 }
2672
2673 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2674 {
2675         brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2676                             brcmf_cfg80211_escan_handler);
2677         cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2678         /* Init scan_timeout timer */
2679         init_timer(&cfg->escan_timeout);
2680         cfg->escan_timeout.data = (unsigned long) cfg;
2681         cfg->escan_timeout.function = brcmf_escan_timeout;
2682         INIT_WORK(&cfg->escan_timeout_work,
2683                   brcmf_cfg80211_escan_timeout_worker);
2684 }
2685
2686 static __always_inline void brcmf_delay(u32 ms)
2687 {
2688         if (ms < 1000 / HZ) {
2689                 cond_resched();
2690                 mdelay(ms);
2691         } else {
2692                 msleep(ms);
2693         }
2694 }
2695
2696 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2697 {
2698         brcmf_dbg(TRACE, "Enter\n");
2699
2700         return 0;
2701 }
2702
2703 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2704                                   struct cfg80211_wowlan *wow)
2705 {
2706         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2707         struct net_device *ndev = cfg_to_ndev(cfg);
2708         struct brcmf_cfg80211_vif *vif;
2709
2710         brcmf_dbg(TRACE, "Enter\n");
2711
2712         /*
2713          * if the primary net_device is not READY there is nothing
2714          * we can do but pray resume goes smoothly.
2715          */
2716         vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2717         if (!check_vif_up(vif))
2718                 goto exit;
2719
2720         list_for_each_entry(vif, &cfg->vif_list, list) {
2721                 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2722                         continue;
2723                 /*
2724                  * While going to suspend if associated with AP disassociate
2725                  * from AP to save power while system is in suspended state
2726                  */
2727                 brcmf_link_down(vif);
2728
2729                 /* Make sure WPA_Supplicant receives all the event
2730                  * generated due to DISASSOC call to the fw to keep
2731                  * the state fw and WPA_Supplicant state consistent
2732                  */
2733                 brcmf_delay(500);
2734         }
2735
2736         /* end any scanning */
2737         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2738                 brcmf_abort_scanning(cfg);
2739
2740         /* Turn off watchdog timer */
2741         brcmf_set_mpc(ndev, 1);
2742
2743 exit:
2744         brcmf_dbg(TRACE, "Exit\n");
2745         /* clear any scanning activity */
2746         cfg->scan_status = 0;
2747         return 0;
2748 }
2749
2750 static __used s32
2751 brcmf_update_pmklist(struct net_device *ndev,
2752                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2753 {
2754         int i, j;
2755         int pmkid_len;
2756
2757         pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2758
2759         brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2760         for (i = 0; i < pmkid_len; i++) {
2761                 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2762                           &pmk_list->pmkids.pmkid[i].BSSID);
2763                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2764                         brcmf_dbg(CONN, "%02x\n",
2765                                   pmk_list->pmkids.pmkid[i].PMKID[j]);
2766         }
2767
2768         if (!err)
2769                 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2770                                          (char *)pmk_list, sizeof(*pmk_list));
2771
2772         return err;
2773 }
2774
2775 static s32
2776 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2777                          struct cfg80211_pmksa *pmksa)
2778 {
2779         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2780         struct brcmf_if *ifp = netdev_priv(ndev);
2781         struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2782         s32 err = 0;
2783         int i;
2784         int pmkid_len;
2785
2786         brcmf_dbg(TRACE, "Enter\n");
2787         if (!check_vif_up(ifp->vif))
2788                 return -EIO;
2789
2790         pmkid_len = le32_to_cpu(pmkids->npmkid);
2791         for (i = 0; i < pmkid_len; i++)
2792                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2793                         break;
2794         if (i < WL_NUM_PMKIDS_MAX) {
2795                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2796                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2797                 if (i == pmkid_len) {
2798                         pmkid_len++;
2799                         pmkids->npmkid = cpu_to_le32(pmkid_len);
2800                 }
2801         } else
2802                 err = -EINVAL;
2803
2804         brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2805                   pmkids->pmkid[pmkid_len].BSSID);
2806         for (i = 0; i < WLAN_PMKID_LEN; i++)
2807                 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2808
2809         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2810
2811         brcmf_dbg(TRACE, "Exit\n");
2812         return err;
2813 }
2814
2815 static s32
2816 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2817                       struct cfg80211_pmksa *pmksa)
2818 {
2819         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2820         struct brcmf_if *ifp = netdev_priv(ndev);
2821         struct pmkid_list pmkid;
2822         s32 err = 0;
2823         int i, pmkid_len;
2824
2825         brcmf_dbg(TRACE, "Enter\n");
2826         if (!check_vif_up(ifp->vif))
2827                 return -EIO;
2828
2829         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2830         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2831
2832         brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2833                   &pmkid.pmkid[0].BSSID);
2834         for (i = 0; i < WLAN_PMKID_LEN; i++)
2835                 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2836
2837         pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2838         for (i = 0; i < pmkid_len; i++)
2839                 if (!memcmp
2840                     (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2841                      ETH_ALEN))
2842                         break;
2843
2844         if ((pmkid_len > 0)
2845             && (i < pmkid_len)) {
2846                 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2847                        sizeof(struct pmkid));
2848                 for (; i < (pmkid_len - 1); i++) {
2849                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2850                                &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2851                                ETH_ALEN);
2852                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2853                                &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2854                                WLAN_PMKID_LEN);
2855                 }
2856                 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2857         } else
2858                 err = -EINVAL;
2859
2860         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2861
2862         brcmf_dbg(TRACE, "Exit\n");
2863         return err;
2864
2865 }
2866
2867 static s32
2868 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2869 {
2870         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2871         struct brcmf_if *ifp = netdev_priv(ndev);
2872         s32 err = 0;
2873
2874         brcmf_dbg(TRACE, "Enter\n");
2875         if (!check_vif_up(ifp->vif))
2876                 return -EIO;
2877
2878         memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2879         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2880
2881         brcmf_dbg(TRACE, "Exit\n");
2882         return err;
2883
2884 }
2885
2886 /*
2887  * PFN result doesn't have all the info which are
2888  * required by the supplicant
2889  * (For e.g IEs) Do a target Escan so that sched scan results are reported
2890  * via wl_inform_single_bss in the required format. Escan does require the
2891  * scan request in the form of cfg80211_scan_request. For timebeing, create
2892  * cfg80211_scan_request one out of the received PNO event.
2893  */
2894 static s32
2895 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2896                                 const struct brcmf_event_msg *e, void *data)
2897 {
2898         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2899         struct net_device *ndev = ifp->ndev;
2900         struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2901         struct cfg80211_scan_request *request = NULL;
2902         struct cfg80211_ssid *ssid = NULL;
2903         struct ieee80211_channel *channel = NULL;
2904         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2905         int err = 0;
2906         int channel_req = 0;
2907         int band = 0;
2908         struct brcmf_pno_scanresults_le *pfn_result;
2909         u32 result_count;
2910         u32 status;
2911
2912         brcmf_dbg(SCAN, "Enter\n");
2913
2914         if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2915                 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2916                 return 0;
2917         }
2918
2919         pfn_result = (struct brcmf_pno_scanresults_le *)data;
2920         result_count = le32_to_cpu(pfn_result->count);
2921         status = le32_to_cpu(pfn_result->status);
2922
2923         /*
2924          * PFN event is limited to fit 512 bytes so we may get
2925          * multiple NET_FOUND events. For now place a warning here.
2926          */
2927         WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2928         brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2929         if (result_count > 0) {
2930                 int i;
2931
2932                 request = kzalloc(sizeof(*request), GFP_KERNEL);
2933                 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2934                 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2935                 if (!request || !ssid || !channel) {
2936                         err = -ENOMEM;
2937                         goto out_err;
2938                 }
2939
2940                 request->wiphy = wiphy;
2941                 data += sizeof(struct brcmf_pno_scanresults_le);
2942                 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2943
2944                 for (i = 0; i < result_count; i++) {
2945                         netinfo = &netinfo_start[i];
2946                         if (!netinfo) {
2947                                 brcmf_err("Invalid netinfo ptr. index: %d\n",
2948                                           i);
2949                                 err = -EINVAL;
2950                                 goto out_err;
2951                         }
2952
2953                         brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2954                                   netinfo->SSID, netinfo->channel);
2955                         memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2956                         ssid[i].ssid_len = netinfo->SSID_len;
2957                         request->n_ssids++;
2958
2959                         channel_req = netinfo->channel;
2960                         if (channel_req <= CH_MAX_2G_CHANNEL)
2961                                 band = NL80211_BAND_2GHZ;
2962                         else
2963                                 band = NL80211_BAND_5GHZ;
2964                         channel[i].center_freq =
2965                                 ieee80211_channel_to_frequency(channel_req,
2966                                                                band);
2967                         channel[i].band = band;
2968                         channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2969                         request->channels[i] = &channel[i];
2970                         request->n_channels++;
2971                 }
2972
2973                 /* assign parsed ssid array */
2974                 if (request->n_ssids)
2975                         request->ssids = &ssid[0];
2976
2977                 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2978                         /* Abort any on-going scan */
2979                         brcmf_abort_scanning(cfg);
2980                 }
2981
2982                 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2983                 err = brcmf_do_escan(cfg, wiphy, ndev, request);
2984                 if (err) {
2985                         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2986                         goto out_err;
2987                 }
2988                 cfg->sched_escan = true;
2989                 cfg->scan_request = request;
2990         } else {
2991                 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2992                 goto out_err;
2993         }
2994
2995         kfree(ssid);
2996         kfree(channel);
2997         kfree(request);
2998         return 0;
2999
3000 out_err:
3001         kfree(ssid);
3002         kfree(channel);
3003         kfree(request);
3004         cfg80211_sched_scan_stopped(wiphy);
3005         return err;
3006 }
3007
3008 static int brcmf_dev_pno_clean(struct net_device *ndev)
3009 {
3010         int ret;
3011
3012         /* Disable pfn */
3013         ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3014         if (ret == 0) {
3015                 /* clear pfn */
3016                 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3017                                                NULL, 0);
3018         }
3019         if (ret < 0)
3020                 brcmf_err("failed code %d\n", ret);
3021
3022         return ret;
3023 }
3024
3025 static int brcmf_dev_pno_config(struct net_device *ndev)
3026 {
3027         struct brcmf_pno_param_le pfn_param;
3028
3029         memset(&pfn_param, 0, sizeof(pfn_param));
3030         pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3031
3032         /* set extra pno params */
3033         pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3034         pfn_param.repeat = BRCMF_PNO_REPEAT;
3035         pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3036
3037         /* set up pno scan fr */
3038         pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3039
3040         return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3041                                         &pfn_param, sizeof(pfn_param));
3042 }
3043
3044 static int
3045 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3046                                 struct net_device *ndev,
3047                                 struct cfg80211_sched_scan_request *request)
3048 {
3049         struct brcmf_if *ifp = netdev_priv(ndev);
3050         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3051         struct brcmf_pno_net_param_le pfn;
3052         int i;
3053         int ret = 0;
3054
3055         brcmf_dbg(SCAN, "Enter n_match_sets:%d   n_ssids:%d\n",
3056                   request->n_match_sets, request->n_ssids);
3057         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3058                 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3059                 return -EAGAIN;
3060         }
3061
3062         if (!request || !request->n_ssids || !request->n_match_sets) {
3063                 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3064                           request ? request->n_ssids : 0);
3065                 return -EINVAL;
3066         }
3067
3068         if (request->n_ssids > 0) {
3069                 for (i = 0; i < request->n_ssids; i++) {
3070                         /* Active scan req for ssids */
3071                         brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3072                                   request->ssids[i].ssid);
3073
3074                         /*
3075                          * match_set ssids is a supert set of n_ssid list,
3076                          * so we need not add these set seperately.
3077                          */
3078                 }
3079         }
3080
3081         if (request->n_match_sets > 0) {
3082                 /* clean up everything */
3083                 ret = brcmf_dev_pno_clean(ndev);
3084                 if  (ret < 0) {
3085                         brcmf_err("failed error=%d\n", ret);
3086                         return ret;
3087                 }
3088
3089                 /* configure pno */
3090                 ret = brcmf_dev_pno_config(ndev);
3091                 if (ret < 0) {
3092                         brcmf_err("PNO setup failed!! ret=%d\n", ret);
3093                         return -EINVAL;
3094                 }
3095
3096                 /* configure each match set */
3097                 for (i = 0; i < request->n_match_sets; i++) {
3098                         struct cfg80211_ssid *ssid;
3099                         u32 ssid_len;
3100
3101                         ssid = &request->match_sets[i].ssid;
3102                         ssid_len = ssid->ssid_len;
3103
3104                         if (!ssid_len) {
3105                                 brcmf_err("skip broadcast ssid\n");
3106                                 continue;
3107                         }
3108                         pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3109                         pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3110                         pfn.wsec = cpu_to_le32(0);
3111                         pfn.infra = cpu_to_le32(1);
3112                         pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3113                         pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3114                         memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3115                         ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3116                                                        sizeof(pfn));
3117                         brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3118                                   ret == 0 ? "set" : "failed", ssid->ssid);
3119                 }
3120                 /* Enable the PNO */
3121                 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3122                         brcmf_err("PNO enable failed!! ret=%d\n", ret);
3123                         return -EINVAL;
3124                 }
3125         } else {
3126                 return -EINVAL;
3127         }
3128
3129         return 0;
3130 }
3131
3132 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3133                                           struct net_device *ndev)
3134 {
3135         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3136
3137         brcmf_dbg(SCAN, "enter\n");
3138         brcmf_dev_pno_clean(ndev);
3139         if (cfg->sched_escan)
3140                 brcmf_notify_escan_complete(cfg, ndev, true, true);
3141         return 0;
3142 }
3143
3144 #ifdef CONFIG_NL80211_TESTMODE
3145 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3146 {
3147         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3148         struct net_device *ndev = cfg_to_ndev(cfg);
3149         struct brcmf_dcmd *dcmd = data;
3150         struct sk_buff *reply;
3151         int ret;
3152
3153         brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3154                   dcmd->buf, dcmd->len);
3155
3156         if (dcmd->set)
3157                 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3158                                              dcmd->buf, dcmd->len);
3159         else
3160                 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3161                                              dcmd->buf, dcmd->len);
3162         if (ret == 0) {
3163                 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3164                 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3165                 ret = cfg80211_testmode_reply(reply);
3166         }
3167         return ret;
3168 }
3169 #endif
3170
3171 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3172 {
3173         s32 err;
3174
3175         /* set auth */
3176         err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3177         if (err < 0) {
3178                 brcmf_err("auth error %d\n", err);
3179                 return err;
3180         }
3181         /* set wsec */
3182         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3183         if (err < 0) {
3184                 brcmf_err("wsec error %d\n", err);
3185                 return err;
3186         }
3187         /* set upper-layer auth */
3188         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3189         if (err < 0) {
3190                 brcmf_err("wpa_auth error %d\n", err);
3191                 return err;
3192         }
3193
3194         return 0;
3195 }
3196
3197 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3198 {
3199         if (is_rsn_ie)
3200                 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3201
3202         return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3203 }
3204
3205 static s32
3206 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3207                      bool is_rsn_ie)
3208 {
3209         struct brcmf_if *ifp = netdev_priv(ndev);
3210         u32 auth = 0; /* d11 open authentication */
3211         u16 count;
3212         s32 err = 0;
3213         s32 len = 0;
3214         u32 i;
3215         u32 wsec;
3216         u32 pval = 0;
3217         u32 gval = 0;
3218         u32 wpa_auth = 0;
3219         u32 offset;
3220         u8 *data;
3221         u16 rsn_cap;
3222         u32 wme_bss_disable;
3223
3224         brcmf_dbg(TRACE, "Enter\n");
3225         if (wpa_ie == NULL)
3226                 goto exit;
3227
3228         len = wpa_ie->len + TLV_HDR_LEN;
3229         data = (u8 *)wpa_ie;
3230         offset = TLV_HDR_LEN;
3231         if (!is_rsn_ie)
3232                 offset += VS_IE_FIXED_HDR_LEN;
3233         else
3234                 offset += WPA_IE_VERSION_LEN;
3235
3236         /* check for multicast cipher suite */
3237         if (offset + WPA_IE_MIN_OUI_LEN > len) {
3238                 err = -EINVAL;
3239                 brcmf_err("no multicast cipher suite\n");
3240                 goto exit;
3241         }
3242
3243         if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3244                 err = -EINVAL;
3245                 brcmf_err("ivalid OUI\n");
3246                 goto exit;
3247         }
3248         offset += TLV_OUI_LEN;
3249
3250         /* pick up multicast cipher */
3251         switch (data[offset]) {
3252         case WPA_CIPHER_NONE:
3253                 gval = 0;
3254                 break;
3255         case WPA_CIPHER_WEP_40:
3256         case WPA_CIPHER_WEP_104:
3257                 gval = WEP_ENABLED;
3258                 break;
3259         case WPA_CIPHER_TKIP:
3260                 gval = TKIP_ENABLED;
3261                 break;
3262         case WPA_CIPHER_AES_CCM:
3263                 gval = AES_ENABLED;
3264                 break;
3265         default:
3266                 err = -EINVAL;
3267                 brcmf_err("Invalid multi cast cipher info\n");
3268                 goto exit;
3269         }
3270
3271         offset++;
3272         /* walk thru unicast cipher list and pick up what we recognize */
3273         count = data[offset] + (data[offset + 1] << 8);
3274         offset += WPA_IE_SUITE_COUNT_LEN;
3275         /* Check for unicast suite(s) */
3276         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3277                 err = -EINVAL;
3278                 brcmf_err("no unicast cipher suite\n");
3279                 goto exit;
3280         }
3281         for (i = 0; i < count; i++) {
3282                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3283                         err = -EINVAL;
3284                         brcmf_err("ivalid OUI\n");
3285                         goto exit;
3286                 }
3287                 offset += TLV_OUI_LEN;
3288                 switch (data[offset]) {
3289                 case WPA_CIPHER_NONE:
3290                         break;
3291                 case WPA_CIPHER_WEP_40:
3292                 case WPA_CIPHER_WEP_104:
3293                         pval |= WEP_ENABLED;
3294                         break;
3295                 case WPA_CIPHER_TKIP:
3296                         pval |= TKIP_ENABLED;
3297                         break;
3298                 case WPA_CIPHER_AES_CCM:
3299                         pval |= AES_ENABLED;
3300                         break;
3301                 default:
3302                         brcmf_err("Ivalid unicast security info\n");
3303                 }
3304                 offset++;
3305         }
3306         /* walk thru auth management suite list and pick up what we recognize */
3307         count = data[offset] + (data[offset + 1] << 8);
3308         offset += WPA_IE_SUITE_COUNT_LEN;
3309         /* Check for auth key management suite(s) */
3310         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3311                 err = -EINVAL;
3312                 brcmf_err("no auth key mgmt suite\n");
3313                 goto exit;
3314         }
3315         for (i = 0; i < count; i++) {
3316                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3317                         err = -EINVAL;
3318                         brcmf_err("ivalid OUI\n");
3319                         goto exit;
3320                 }
3321                 offset += TLV_OUI_LEN;
3322                 switch (data[offset]) {
3323                 case RSN_AKM_NONE:
3324                         brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3325                         wpa_auth |= WPA_AUTH_NONE;
3326                         break;
3327                 case RSN_AKM_UNSPECIFIED:
3328                         brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3329                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3330                                     (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3331                         break;
3332                 case RSN_AKM_PSK:
3333                         brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3334                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3335                                     (wpa_auth |= WPA_AUTH_PSK);
3336                         break;
3337                 default:
3338                         brcmf_err("Ivalid key mgmt info\n");
3339                 }
3340                 offset++;
3341         }
3342
3343         if (is_rsn_ie) {
3344                 wme_bss_disable = 1;
3345                 if ((offset + RSN_CAP_LEN) <= len) {
3346                         rsn_cap = data[offset] + (data[offset + 1] << 8);
3347                         if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3348                                 wme_bss_disable = 0;
3349                 }
3350                 /* set wme_bss_disable to sync RSN Capabilities */
3351                 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3352                                                wme_bss_disable);
3353                 if (err < 0) {
3354                         brcmf_err("wme_bss_disable error %d\n", err);
3355                         goto exit;
3356                 }
3357         }
3358         /* FOR WPS , set SES_OW_ENABLED */
3359         wsec = (pval | gval | SES_OW_ENABLED);
3360
3361         /* set auth */
3362         err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3363         if (err < 0) {
3364                 brcmf_err("auth error %d\n", err);
3365                 goto exit;
3366         }
3367         /* set wsec */
3368         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3369         if (err < 0) {
3370                 brcmf_err("wsec error %d\n", err);
3371                 goto exit;
3372         }
3373         /* set upper-layer auth */
3374         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3375         if (err < 0) {
3376                 brcmf_err("wpa_auth error %d\n", err);
3377                 goto exit;
3378         }
3379
3380 exit:
3381         return err;
3382 }
3383
3384 static s32
3385 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3386                      struct parsed_vndr_ies *vndr_ies)
3387 {
3388         s32 err = 0;
3389         struct brcmf_vs_tlv *vndrie;
3390         struct brcmf_tlv *ie;
3391         struct parsed_vndr_ie_info *parsed_info;
3392         s32 remaining_len;
3393
3394         remaining_len = (s32)vndr_ie_len;
3395         memset(vndr_ies, 0, sizeof(*vndr_ies));
3396
3397         ie = (struct brcmf_tlv *)vndr_ie_buf;
3398         while (ie) {
3399                 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3400                         goto next;
3401                 vndrie = (struct brcmf_vs_tlv *)ie;
3402                 /* len should be bigger than OUI length + one */
3403                 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3404                         brcmf_err("invalid vndr ie. length is too small %d\n",
3405                                   vndrie->len);
3406                         goto next;
3407                 }
3408                 /* if wpa or wme ie, do not add ie */
3409                 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3410                     ((vndrie->oui_type == WPA_OUI_TYPE) ||
3411                     (vndrie->oui_type == WME_OUI_TYPE))) {
3412                         brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3413                         goto next;
3414                 }
3415
3416                 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3417
3418                 /* save vndr ie information */
3419                 parsed_info->ie_ptr = (char *)vndrie;
3420                 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3421                 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3422
3423                 vndr_ies->count++;
3424
3425                 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3426                           parsed_info->vndrie.oui[0],
3427                           parsed_info->vndrie.oui[1],
3428                           parsed_info->vndrie.oui[2],
3429                           parsed_info->vndrie.oui_type);
3430
3431                 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3432                         break;
3433 next:
3434                 remaining_len -= (ie->len + TLV_HDR_LEN);
3435                 if (remaining_len <= TLV_HDR_LEN)
3436                         ie = NULL;
3437                 else
3438                         ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3439                                 TLV_HDR_LEN);
3440         }
3441         return err;
3442 }
3443
3444 static u32
3445 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3446 {
3447
3448         __le32 iecount_le;
3449         __le32 pktflag_le;
3450
3451         strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3452         iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3453
3454         iecount_le = cpu_to_le32(1);
3455         memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3456
3457         pktflag_le = cpu_to_le32(pktflag);
3458         memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3459
3460         memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3461
3462         return ie_len + VNDR_IE_HDR_SIZE;
3463 }
3464
3465 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3466                           const u8 *vndr_ie_buf, u32 vndr_ie_len)
3467 {
3468         struct brcmf_if *ifp;
3469         struct vif_saved_ie *saved_ie;
3470         s32 err = 0;
3471         u8  *iovar_ie_buf;
3472         u8  *curr_ie_buf;
3473         u8  *mgmt_ie_buf = NULL;
3474         int mgmt_ie_buf_len;
3475         u32 *mgmt_ie_len;
3476         u32 del_add_ie_buf_len = 0;
3477         u32 total_ie_buf_len = 0;
3478         u32 parsed_ie_buf_len = 0;
3479         struct parsed_vndr_ies old_vndr_ies;
3480         struct parsed_vndr_ies new_vndr_ies;
3481         struct parsed_vndr_ie_info *vndrie_info;
3482         s32 i;
3483         u8 *ptr;
3484         int remained_buf_len;
3485
3486         if (!vif)
3487                 return -ENODEV;
3488         ifp = vif->ifp;
3489         saved_ie = &vif->saved_ie;
3490
3491         brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3492         iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3493         if (!iovar_ie_buf)
3494                 return -ENOMEM;
3495         curr_ie_buf = iovar_ie_buf;
3496         switch (pktflag) {
3497         case BRCMF_VNDR_IE_PRBREQ_FLAG:
3498                 mgmt_ie_buf = saved_ie->probe_req_ie;
3499                 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3500                 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3501                 break;
3502         case BRCMF_VNDR_IE_PRBRSP_FLAG:
3503                 mgmt_ie_buf = saved_ie->probe_res_ie;
3504                 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3505                 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3506                 break;
3507         case BRCMF_VNDR_IE_BEACON_FLAG:
3508                 mgmt_ie_buf = saved_ie->beacon_ie;
3509                 mgmt_ie_len = &saved_ie->beacon_ie_len;
3510                 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3511                 break;
3512         case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3513                 mgmt_ie_buf = saved_ie->assoc_req_ie;
3514                 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3515                 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3516                 break;
3517         default:
3518                 err = -EPERM;
3519                 brcmf_err("not suitable type\n");
3520                 goto exit;
3521         }
3522
3523         if (vndr_ie_len > mgmt_ie_buf_len) {
3524                 err = -ENOMEM;
3525                 brcmf_err("extra IE size too big\n");
3526                 goto exit;
3527         }
3528
3529         /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3530         if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3531                 ptr = curr_ie_buf;
3532                 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3533                 for (i = 0; i < new_vndr_ies.count; i++) {
3534                         vndrie_info = &new_vndr_ies.ie_info[i];
3535                         memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3536                                vndrie_info->ie_len);
3537                         parsed_ie_buf_len += vndrie_info->ie_len;
3538                 }
3539         }
3540
3541         if (mgmt_ie_buf && *mgmt_ie_len) {
3542                 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3543                     (memcmp(mgmt_ie_buf, curr_ie_buf,
3544                             parsed_ie_buf_len) == 0)) {
3545                         brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3546                         goto exit;
3547                 }
3548
3549                 /* parse old vndr_ie */
3550                 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3551
3552                 /* make a command to delete old ie */
3553                 for (i = 0; i < old_vndr_ies.count; i++) {
3554                         vndrie_info = &old_vndr_ies.ie_info[i];
3555
3556                         brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3557                                   vndrie_info->vndrie.id,
3558                                   vndrie_info->vndrie.len,
3559                                   vndrie_info->vndrie.oui[0],
3560                                   vndrie_info->vndrie.oui[1],
3561                                   vndrie_info->vndrie.oui[2]);
3562
3563                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3564                                                            vndrie_info->ie_ptr,
3565                                                            vndrie_info->ie_len,
3566                                                            "del");
3567                         curr_ie_buf += del_add_ie_buf_len;
3568                         total_ie_buf_len += del_add_ie_buf_len;
3569                 }
3570         }
3571
3572         *mgmt_ie_len = 0;
3573         /* Add if there is any extra IE */
3574         if (mgmt_ie_buf && parsed_ie_buf_len) {
3575                 ptr = mgmt_ie_buf;
3576
3577                 remained_buf_len = mgmt_ie_buf_len;
3578
3579                 /* make a command to add new ie */
3580                 for (i = 0; i < new_vndr_ies.count; i++) {
3581                         vndrie_info = &new_vndr_ies.ie_info[i];
3582
3583                         /* verify remained buf size before copy data */
3584                         if (remained_buf_len < (vndrie_info->vndrie.len +
3585                                                         VNDR_IE_VSIE_OFFSET)) {
3586                                 brcmf_err("no space in mgmt_ie_buf: len left %d",
3587                                           remained_buf_len);
3588                                 break;
3589                         }
3590                         remained_buf_len -= (vndrie_info->ie_len +
3591                                              VNDR_IE_VSIE_OFFSET);
3592
3593                         brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3594                                   vndrie_info->vndrie.id,
3595                                   vndrie_info->vndrie.len,
3596                                   vndrie_info->vndrie.oui[0],
3597                                   vndrie_info->vndrie.oui[1],
3598                                   vndrie_info->vndrie.oui[2]);
3599
3600                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3601                                                            vndrie_info->ie_ptr,
3602                                                            vndrie_info->ie_len,
3603                                                            "add");
3604
3605                         /* save the parsed IE in wl struct */
3606                         memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3607                                vndrie_info->ie_len);
3608                         *mgmt_ie_len += vndrie_info->ie_len;
3609
3610                         curr_ie_buf += del_add_ie_buf_len;
3611                         total_ie_buf_len += del_add_ie_buf_len;
3612                 }
3613         }
3614         if (total_ie_buf_len) {
3615                 err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3616                                                  total_ie_buf_len);
3617                 if (err)
3618                         brcmf_err("vndr ie set error : %d\n", err);
3619         }
3620
3621 exit:
3622         kfree(iovar_ie_buf);
3623         return err;
3624 }
3625
3626 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3627 {
3628         s32 pktflags[] = {
3629                 BRCMF_VNDR_IE_PRBREQ_FLAG,
3630                 BRCMF_VNDR_IE_PRBRSP_FLAG,
3631                 BRCMF_VNDR_IE_BEACON_FLAG
3632         };
3633         int i;
3634
3635         for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3636                 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3637
3638         memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3639         return 0;
3640 }
3641
3642 static s32
3643 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3644                         struct cfg80211_beacon_data *beacon)
3645 {
3646         s32 err;
3647
3648         /* Set Beacon IEs to FW */
3649         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3650                                     beacon->tail, beacon->tail_len);
3651         if (err) {
3652                 brcmf_err("Set Beacon IE Failed\n");
3653                 return err;
3654         }
3655         brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3656
3657         /* Set Probe Response IEs to FW */
3658         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3659                                     beacon->proberesp_ies,
3660                                     beacon->proberesp_ies_len);
3661         if (err)
3662                 brcmf_err("Set Probe Resp IE Failed\n");
3663         else
3664                 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3665
3666         return err;
3667 }
3668
3669 static s32
3670 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3671                         struct cfg80211_ap_settings *settings)
3672 {
3673         s32 ie_offset;
3674         struct brcmf_if *ifp = netdev_priv(ndev);
3675         struct brcmf_tlv *ssid_ie;
3676         struct brcmf_ssid_le ssid_le;
3677         s32 err = -EPERM;
3678         struct brcmf_tlv *rsn_ie;
3679         struct brcmf_vs_tlv *wpa_ie;
3680         struct brcmf_join_params join_params;
3681         enum nl80211_iftype dev_role;
3682         struct brcmf_fil_bss_enable_le bss_enable;
3683
3684         brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3685                   cfg80211_get_chandef_type(&settings->chandef),
3686                   settings->beacon_interval,
3687                   settings->dtim_period);
3688         brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3689                   settings->ssid, settings->ssid_len, settings->auth_type,
3690                   settings->inactivity_timeout);
3691
3692         dev_role = ifp->vif->wdev.iftype;
3693
3694         memset(&ssid_le, 0, sizeof(ssid_le));
3695         if (settings->ssid == NULL || settings->ssid_len == 0) {
3696                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3697                 ssid_ie = brcmf_parse_tlvs(
3698                                 (u8 *)&settings->beacon.head[ie_offset],
3699                                 settings->beacon.head_len - ie_offset,
3700                                 WLAN_EID_SSID);
3701                 if (!ssid_ie)
3702                         return -EINVAL;
3703
3704                 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3705                 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3706                 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3707         } else {
3708                 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3709                 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3710         }
3711
3712         brcmf_set_mpc(ndev, 0);
3713
3714         /* find the RSN_IE */
3715         rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3716                                   settings->beacon.tail_len, WLAN_EID_RSN);
3717
3718         /* find the WPA_IE */
3719         wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3720                                   settings->beacon.tail_len);
3721
3722         if ((wpa_ie != NULL || rsn_ie != NULL)) {
3723                 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3724                 if (wpa_ie != NULL) {
3725                         /* WPA IE */
3726                         err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3727                         if (err < 0)
3728                                 goto exit;
3729                 } else {
3730                         /* RSN IE */
3731                         err = brcmf_configure_wpaie(ndev,
3732                                 (struct brcmf_vs_tlv *)rsn_ie, true);
3733                         if (err < 0)
3734                                 goto exit;
3735                 }
3736         } else {
3737                 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3738                 brcmf_configure_opensecurity(ifp);
3739         }
3740
3741         brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3742
3743         if (settings->beacon_interval) {
3744                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3745                                             settings->beacon_interval);
3746                 if (err < 0) {
3747                         brcmf_err("Beacon Interval Set Error, %d\n", err);
3748                         goto exit;
3749                 }
3750         }
3751         if (settings->dtim_period) {
3752                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3753                                             settings->dtim_period);
3754                 if (err < 0) {
3755                         brcmf_err("DTIM Interval Set Error, %d\n", err);
3756                         goto exit;
3757                 }
3758         }
3759
3760         if (dev_role == NL80211_IFTYPE_AP) {
3761                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3762                 if (err < 0) {
3763                         brcmf_err("BRCMF_C_DOWN error %d\n", err);
3764                         goto exit;
3765                 }
3766                 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3767         }
3768
3769         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3770         if (err < 0) {
3771                 brcmf_err("SET INFRA error %d\n", err);
3772                 goto exit;
3773         }
3774         if (dev_role == NL80211_IFTYPE_AP) {
3775                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3776                 if (err < 0) {
3777                         brcmf_err("setting AP mode failed %d\n", err);
3778                         goto exit;
3779                 }
3780                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3781                 if (err < 0) {
3782                         brcmf_err("BRCMF_C_UP error (%d)\n", err);
3783                         goto exit;
3784                 }
3785
3786                 memset(&join_params, 0, sizeof(join_params));
3787                 /* join parameters starts with ssid */
3788                 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3789                 /* create softap */
3790                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3791                                              &join_params, sizeof(join_params));
3792                 if (err < 0) {
3793                         brcmf_err("SET SSID error (%d)\n", err);
3794                         goto exit;
3795                 }
3796                 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3797         } else {
3798                 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3799                                                 sizeof(ssid_le));
3800                 if (err < 0) {
3801                         brcmf_err("setting ssid failed %d\n", err);
3802                         goto exit;
3803                 }
3804                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3805                 bss_enable.enable = cpu_to_le32(1);
3806                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3807                                                sizeof(bss_enable));
3808                 if (err < 0) {
3809                         brcmf_err("bss_enable config failed %d\n", err);
3810                         goto exit;
3811                 }
3812
3813                 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3814         }
3815         clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3816         set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3817
3818 exit:
3819         if (err)
3820                 brcmf_set_mpc(ndev, 1);
3821         return err;
3822 }
3823
3824 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3825 {
3826         struct brcmf_if *ifp = netdev_priv(ndev);
3827         s32 err = -EPERM;
3828         struct brcmf_fil_bss_enable_le bss_enable;
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                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3837                 if (err < 0) {
3838                         brcmf_err("setting AP mode failed %d\n", err);
3839                         goto exit;
3840                 }
3841                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3842                 if (err < 0) {
3843                         brcmf_err("BRCMF_C_UP error %d\n", err);
3844                         goto exit;
3845                 }
3846         } else {
3847                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3848                 bss_enable.enable = cpu_to_le32(0);
3849                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3850                                                sizeof(bss_enable));
3851                 if (err < 0)
3852                         brcmf_err("bss_enable config failed %d\n", err);
3853         }
3854         brcmf_set_mpc(ndev, 1);
3855         set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3856         clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3857
3858 exit:
3859         return err;
3860 }
3861
3862 static s32
3863 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3864                              struct cfg80211_beacon_data *info)
3865 {
3866         struct brcmf_if *ifp = netdev_priv(ndev);
3867         s32 err;
3868
3869         brcmf_dbg(TRACE, "Enter\n");
3870
3871         err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3872
3873         return err;
3874 }
3875
3876 static int
3877 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3878                            u8 *mac)
3879 {
3880         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3881         struct brcmf_scb_val_le scbval;
3882         struct brcmf_if *ifp = netdev_priv(ndev);
3883         s32 err;
3884
3885         if (!mac)
3886                 return -EFAULT;
3887
3888         brcmf_dbg(TRACE, "Enter %pM\n", mac);
3889
3890         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3891                 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3892         if (!check_vif_up(ifp->vif))
3893                 return -EIO;
3894
3895         memcpy(&scbval.ea, mac, ETH_ALEN);
3896         scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3897         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3898                                      &scbval, sizeof(scbval));
3899         if (err)
3900                 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3901
3902         brcmf_dbg(TRACE, "Exit\n");
3903         return err;
3904 }
3905
3906
3907 static void
3908 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3909                                    struct wireless_dev *wdev,
3910                                    u16 frame_type, bool reg)
3911 {
3912         struct brcmf_if *ifp = netdev_priv(wdev->netdev);
3913         struct brcmf_cfg80211_vif *vif = ifp->vif;
3914         u16 mgmt_type;
3915
3916         brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3917
3918         mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3919         if (reg)
3920                 vif->mgmt_rx_reg |= BIT(mgmt_type);
3921         else
3922                 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3923 }
3924
3925
3926 static int
3927 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3928                        struct ieee80211_channel *chan, bool offchan,
3929                        unsigned int wait, const u8 *buf, size_t len,
3930                        bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3931 {
3932         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3933         const struct ieee80211_mgmt *mgmt;
3934         struct brcmf_if *ifp;
3935         struct brcmf_cfg80211_vif *vif;
3936         s32 err = 0;
3937         s32 ie_offset;
3938         s32 ie_len;
3939         struct brcmf_fil_action_frame_le *action_frame;
3940         struct brcmf_fil_af_params_le *af_params;
3941         bool ack;
3942         s32 chan_nr;
3943
3944         brcmf_dbg(TRACE, "Enter\n");
3945
3946         *cookie = 0;
3947
3948         mgmt = (const struct ieee80211_mgmt *)buf;
3949
3950         if (!ieee80211_is_mgmt(mgmt->frame_control)) {
3951                 brcmf_err("Driver only allows MGMT packet type\n");
3952                 return -EPERM;
3953         }
3954
3955         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
3956                 /* Right now the only reason to get a probe response */
3957                 /* is for p2p listen response or for p2p GO from     */
3958                 /* wpa_supplicant. Unfortunately the probe is send   */
3959                 /* on primary ndev, while dongle wants it on the p2p */
3960                 /* vif. Since this is only reason for a probe        */
3961                 /* response to be sent, the vif is taken from cfg.   */
3962                 /* If ever desired to send proberesp for non p2p     */
3963                 /* response then data should be checked for          */
3964                 /* "DIRECT-". Note in future supplicant will take    */
3965                 /* dedicated p2p wdev to do this and then this 'hack'*/
3966                 /* is not needed anymore.                            */
3967                 ie_offset =  DOT11_MGMT_HDR_LEN +
3968                              DOT11_BCN_PRB_FIXED_LEN;
3969                 ie_len = len - ie_offset;
3970                 ifp = netdev_priv(wdev->netdev);
3971                 vif = ifp->vif;
3972                 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
3973                         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
3974                 err = brcmf_vif_set_mgmt_ie(vif,
3975                                             BRCMF_VNDR_IE_PRBRSP_FLAG,
3976                                             &buf[ie_offset],
3977                                             ie_len);
3978                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
3979                                         GFP_KERNEL);
3980         } else if (ieee80211_is_action(mgmt->frame_control)) {
3981                 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
3982                 if (af_params == NULL) {
3983                         brcmf_err("unable to allocate frame\n");
3984                         err = -ENOMEM;
3985                         goto exit;
3986                 }
3987                 action_frame = &af_params->action_frame;
3988                 /* Add the packet Id */
3989                 action_frame->packet_id = cpu_to_le32(*cookie);
3990                 /* Add BSSID */
3991                 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
3992                 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
3993                 /* Add the length exepted for 802.11 header  */
3994                 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
3995                 /* Add the channel */
3996                 chan_nr = ieee80211_frequency_to_channel(chan->center_freq);
3997                 af_params->channel = cpu_to_le32(chan_nr);
3998
3999                 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4000                        le16_to_cpu(action_frame->len));
4001
4002                 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4003                           *cookie, le16_to_cpu(action_frame->len),
4004                           chan->center_freq);
4005
4006                 ack = brcmf_p2p_send_action_frame(cfg, wdev->netdev,
4007                                                   af_params);
4008
4009                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4010                                         GFP_KERNEL);
4011                 kfree(af_params);
4012         } else {
4013                 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4014                 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4015         }
4016
4017 exit:
4018         return err;
4019 }
4020
4021
4022 static int
4023 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4024                                         struct wireless_dev *wdev,
4025                                         u64 cookie)
4026 {
4027         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4028         struct brcmf_cfg80211_vif *vif;
4029         int err = 0;
4030
4031         brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4032
4033         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4034         if (vif == NULL) {
4035                 brcmf_err("No p2p device available for probe response\n");
4036                 err = -ENODEV;
4037                 goto exit;
4038         }
4039         brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4040 exit:
4041         return err;
4042 }
4043
4044 static struct cfg80211_ops wl_cfg80211_ops = {
4045         .add_virtual_intf = brcmf_cfg80211_add_iface,
4046         .del_virtual_intf = brcmf_cfg80211_del_iface,
4047         .change_virtual_intf = brcmf_cfg80211_change_iface,
4048         .scan = brcmf_cfg80211_scan,
4049         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4050         .join_ibss = brcmf_cfg80211_join_ibss,
4051         .leave_ibss = brcmf_cfg80211_leave_ibss,
4052         .get_station = brcmf_cfg80211_get_station,
4053         .set_tx_power = brcmf_cfg80211_set_tx_power,
4054         .get_tx_power = brcmf_cfg80211_get_tx_power,
4055         .add_key = brcmf_cfg80211_add_key,
4056         .del_key = brcmf_cfg80211_del_key,
4057         .get_key = brcmf_cfg80211_get_key,
4058         .set_default_key = brcmf_cfg80211_config_default_key,
4059         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4060         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4061         .connect = brcmf_cfg80211_connect,
4062         .disconnect = brcmf_cfg80211_disconnect,
4063         .suspend = brcmf_cfg80211_suspend,
4064         .resume = brcmf_cfg80211_resume,
4065         .set_pmksa = brcmf_cfg80211_set_pmksa,
4066         .del_pmksa = brcmf_cfg80211_del_pmksa,
4067         .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4068         .start_ap = brcmf_cfg80211_start_ap,
4069         .stop_ap = brcmf_cfg80211_stop_ap,
4070         .change_beacon = brcmf_cfg80211_change_beacon,
4071         .del_station = brcmf_cfg80211_del_station,
4072         .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4073         .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4074         .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4075         .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4076         .remain_on_channel = brcmf_p2p_remain_on_channel,
4077         .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4078 #ifdef CONFIG_NL80211_TESTMODE
4079         .testmode_cmd = brcmf_cfg80211_testmode
4080 #endif
4081 };
4082
4083 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4084 {
4085         switch (type) {
4086         case NL80211_IFTYPE_AP_VLAN:
4087         case NL80211_IFTYPE_WDS:
4088         case NL80211_IFTYPE_MONITOR:
4089         case NL80211_IFTYPE_MESH_POINT:
4090                 return -ENOTSUPP;
4091         case NL80211_IFTYPE_ADHOC:
4092                 return WL_MODE_IBSS;
4093         case NL80211_IFTYPE_STATION:
4094         case NL80211_IFTYPE_P2P_CLIENT:
4095                 return WL_MODE_BSS;
4096         case NL80211_IFTYPE_AP:
4097         case NL80211_IFTYPE_P2P_GO:
4098                 return WL_MODE_AP;
4099         case NL80211_IFTYPE_P2P_DEVICE:
4100                 return WL_MODE_P2P;
4101         case NL80211_IFTYPE_UNSPECIFIED:
4102         default:
4103                 break;
4104         }
4105
4106         return -EINVAL;
4107 }
4108
4109 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4110 {
4111         /* scheduled scan settings */
4112         wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4113         wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4114         wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4115         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4116 }
4117
4118 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4119         {
4120                 .max = 2,
4121                 .types = BIT(NL80211_IFTYPE_STATION) |
4122                          BIT(NL80211_IFTYPE_ADHOC) |
4123                          BIT(NL80211_IFTYPE_AP)
4124         },
4125         {
4126                 .max = 1,
4127                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
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                                  BIT(NL80211_IFTYPE_P2P_DEVICE);
4188         wiphy->iface_combinations = brcmf_iface_combos;
4189         wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4190         wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4191         wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;  /* Set
4192                                                 * it as 11a by default.
4193                                                 * This will be updated with
4194                                                 * 11n phy tables in
4195                                                 * "ifconfig up"
4196                                                 * if phy has 11n capability
4197                                                 */
4198         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4199         wiphy->cipher_suites = __wl_cipher_suites;
4200         wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4201         wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4202                         WIPHY_FLAG_OFFCHAN_TX |
4203                         WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4204         wiphy->mgmt_stypes = brcmf_txrx_stypes;
4205         wiphy->max_remain_on_channel_duration = 5000;
4206         brcmf_wiphy_pno_params(wiphy);
4207         err = wiphy_register(wiphy);
4208         if (err < 0) {
4209                 brcmf_err("Could not register wiphy device (%d)\n", err);
4210                 wiphy_free(wiphy);
4211                 return ERR_PTR(err);
4212         }
4213         return wiphy;
4214 }
4215
4216 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4217                                            enum nl80211_iftype type,
4218                                            bool pm_block)
4219 {
4220         struct brcmf_cfg80211_vif *vif;
4221
4222         if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
4223                 return ERR_PTR(-ENOSPC);
4224
4225         brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4226                   sizeof(*vif));
4227         vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4228         if (!vif)
4229                 return ERR_PTR(-ENOMEM);
4230
4231         vif->wdev.wiphy = cfg->wiphy;
4232         vif->wdev.iftype = type;
4233
4234         vif->mode = brcmf_nl80211_iftype_to_mode(type);
4235         vif->pm_block = pm_block;
4236         vif->roam_off = -1;
4237
4238         brcmf_init_prof(&vif->profile);
4239
4240         list_add_tail(&vif->list, &cfg->vif_list);
4241         cfg->vif_cnt++;
4242         return vif;
4243 }
4244
4245 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4246 {
4247         struct brcmf_cfg80211_info *cfg;
4248         struct wiphy *wiphy;
4249
4250         wiphy = vif->wdev.wiphy;
4251         cfg = wiphy_priv(wiphy);
4252         list_del(&vif->list);
4253         cfg->vif_cnt--;
4254
4255         kfree(vif);
4256         if (!cfg->vif_cnt) {
4257                 wiphy_unregister(wiphy);
4258                 wiphy_free(wiphy);
4259         }
4260 }
4261
4262 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4263 {
4264         u32 event = e->event_code;
4265         u32 status = e->status;
4266
4267         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4268                 brcmf_dbg(CONN, "Processing set ssid\n");
4269                 return true;
4270         }
4271
4272         return false;
4273 }
4274
4275 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4276 {
4277         u32 event = e->event_code;
4278         u16 flags = e->flags;
4279
4280         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4281                 brcmf_dbg(CONN, "Processing link down\n");
4282                 return true;
4283         }
4284         return false;
4285 }
4286
4287 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4288                                const struct brcmf_event_msg *e)
4289 {
4290         u32 event = e->event_code;
4291         u32 status = e->status;
4292
4293         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4294                 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4295                           e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4296                 return true;
4297         }
4298
4299         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4300                 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4301                 return true;
4302         }
4303
4304         return false;
4305 }
4306
4307 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4308 {
4309         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4310
4311         kfree(conn_info->req_ie);
4312         conn_info->req_ie = NULL;
4313         conn_info->req_ie_len = 0;
4314         kfree(conn_info->resp_ie);
4315         conn_info->resp_ie = NULL;
4316         conn_info->resp_ie_len = 0;
4317 }
4318
4319 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4320                                struct brcmf_if *ifp)
4321 {
4322         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4323         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4324         u32 req_len;
4325         u32 resp_len;
4326         s32 err = 0;
4327
4328         brcmf_clear_assoc_ies(cfg);
4329
4330         err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4331                                        cfg->extra_buf, WL_ASSOC_INFO_MAX);
4332         if (err) {
4333                 brcmf_err("could not get assoc info (%d)\n", err);
4334                 return err;
4335         }
4336         assoc_info =
4337                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4338         req_len = le32_to_cpu(assoc_info->req_len);
4339         resp_len = le32_to_cpu(assoc_info->resp_len);
4340         if (req_len) {
4341                 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4342                                                cfg->extra_buf,
4343                                                WL_ASSOC_INFO_MAX);
4344                 if (err) {
4345                         brcmf_err("could not get assoc req (%d)\n", err);
4346                         return err;
4347                 }
4348                 conn_info->req_ie_len = req_len;
4349                 conn_info->req_ie =
4350                     kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4351                             GFP_KERNEL);
4352         } else {
4353                 conn_info->req_ie_len = 0;
4354                 conn_info->req_ie = NULL;
4355         }
4356         if (resp_len) {
4357                 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4358                                                cfg->extra_buf,
4359                                                WL_ASSOC_INFO_MAX);
4360                 if (err) {
4361                         brcmf_err("could not get assoc resp (%d)\n", err);
4362                         return err;
4363                 }
4364                 conn_info->resp_ie_len = resp_len;
4365                 conn_info->resp_ie =
4366                     kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4367                             GFP_KERNEL);
4368         } else {
4369                 conn_info->resp_ie_len = 0;
4370                 conn_info->resp_ie = NULL;
4371         }
4372         brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4373                   conn_info->req_ie_len, conn_info->resp_ie_len);
4374
4375         return err;
4376 }
4377
4378 static s32
4379 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4380                        struct net_device *ndev,
4381                        const struct brcmf_event_msg *e)
4382 {
4383         struct brcmf_if *ifp = netdev_priv(ndev);
4384         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4385         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4386         struct wiphy *wiphy = cfg_to_wiphy(cfg);
4387         struct ieee80211_channel *notify_channel = NULL;
4388         struct ieee80211_supported_band *band;
4389         struct brcmf_bss_info_le *bi;
4390         u32 freq;
4391         s32 err = 0;
4392         u32 target_channel;
4393         u8 *buf;
4394
4395         brcmf_dbg(TRACE, "Enter\n");
4396
4397         brcmf_get_assoc_ies(cfg, ifp);
4398         memcpy(profile->bssid, e->addr, ETH_ALEN);
4399         brcmf_update_bss_info(cfg, ifp);
4400
4401         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4402         if (buf == NULL) {
4403                 err = -ENOMEM;
4404                 goto done;
4405         }
4406
4407         /* data sent to dongle has to be little endian */
4408         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4409         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4410                                      buf, WL_BSS_INFO_MAX);
4411
4412         if (err)
4413                 goto done;
4414
4415         bi = (struct brcmf_bss_info_le *)(buf + 4);
4416         target_channel = bi->ctl_ch ? bi->ctl_ch :
4417                                       CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
4418
4419         if (target_channel <= CH_MAX_2G_CHANNEL)
4420                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4421         else
4422                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4423
4424         freq = ieee80211_channel_to_frequency(target_channel, band->band);
4425         notify_channel = ieee80211_get_channel(wiphy, freq);
4426
4427 done:
4428         kfree(buf);
4429         cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4430                         conn_info->req_ie, conn_info->req_ie_len,
4431                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4432         brcmf_dbg(CONN, "Report roaming result\n");
4433
4434         set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4435         brcmf_dbg(TRACE, "Exit\n");
4436         return err;
4437 }
4438
4439 static s32
4440 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4441                        struct net_device *ndev, const struct brcmf_event_msg *e,
4442                        bool completed)
4443 {
4444         struct brcmf_if *ifp = netdev_priv(ndev);
4445         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4446         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4447         s32 err = 0;
4448
4449         brcmf_dbg(TRACE, "Enter\n");
4450
4451         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4452                                &ifp->vif->sme_state)) {
4453                 if (completed) {
4454                         brcmf_get_assoc_ies(cfg, ifp);
4455                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4456                         brcmf_update_bss_info(cfg, ifp);
4457                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4458                                 &ifp->vif->sme_state);
4459                 }
4460                 cfg80211_connect_result(ndev,
4461                                         (u8 *)profile->bssid,
4462                                         conn_info->req_ie,
4463                                         conn_info->req_ie_len,
4464                                         conn_info->resp_ie,
4465                                         conn_info->resp_ie_len,
4466                                         completed ? WLAN_STATUS_SUCCESS :
4467                                                     WLAN_STATUS_AUTH_TIMEOUT,
4468                                         GFP_KERNEL);
4469                 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4470                           completed ? "succeeded" : "failed");
4471         }
4472         brcmf_dbg(TRACE, "Exit\n");
4473         return err;
4474 }
4475
4476 static s32
4477 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4478                                struct net_device *ndev,
4479                                const struct brcmf_event_msg *e, void *data)
4480 {
4481         static int generation;
4482         u32 event = e->event_code;
4483         u32 reason = e->reason;
4484         struct station_info sinfo;
4485
4486         brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4487         if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4488             ndev != cfg_to_ndev(cfg)) {
4489                 brcmf_dbg(CONN, "AP mode link down\n");
4490                 complete(&cfg->vif_disabled);
4491                 return 0;
4492         }
4493
4494         if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4495             (reason == BRCMF_E_STATUS_SUCCESS)) {
4496                 memset(&sinfo, 0, sizeof(sinfo));
4497                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4498                 if (!data) {
4499                         brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4500                         return -EINVAL;
4501                 }
4502                 sinfo.assoc_req_ies = data;
4503                 sinfo.assoc_req_ies_len = e->datalen;
4504                 generation++;
4505                 sinfo.generation = generation;
4506                 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4507         } else if ((event == BRCMF_E_DISASSOC_IND) ||
4508                    (event == BRCMF_E_DEAUTH_IND) ||
4509                    (event == BRCMF_E_DEAUTH)) {
4510                 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4511         }
4512         return 0;
4513 }
4514
4515 static s32
4516 brcmf_notify_connect_status(struct brcmf_if *ifp,
4517                             const struct brcmf_event_msg *e, void *data)
4518 {
4519         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4520         struct net_device *ndev = ifp->ndev;
4521         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4522         s32 err = 0;
4523
4524         if (ifp->vif->mode == WL_MODE_AP) {
4525                 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4526         } else if (brcmf_is_linkup(e)) {
4527                 brcmf_dbg(CONN, "Linkup\n");
4528                 if (brcmf_is_ibssmode(ifp->vif)) {
4529                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4530                         wl_inform_ibss(cfg, ndev, e->addr);
4531                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4532                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4533                                   &ifp->vif->sme_state);
4534                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4535                                 &ifp->vif->sme_state);
4536                 } else
4537                         brcmf_bss_connect_done(cfg, ndev, e, true);
4538         } else if (brcmf_is_linkdown(e)) {
4539                 brcmf_dbg(CONN, "Linkdown\n");
4540                 if (!brcmf_is_ibssmode(ifp->vif)) {
4541                         brcmf_bss_connect_done(cfg, ndev, e, false);
4542                         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4543                                                &ifp->vif->sme_state))
4544                                 cfg80211_disconnected(ndev, 0, NULL, 0,
4545                                                       GFP_KERNEL);
4546                 }
4547                 brcmf_link_down(ifp->vif);
4548                 brcmf_init_prof(ndev_to_prof(ndev));
4549                 if (ndev != cfg_to_ndev(cfg))
4550                         complete(&cfg->vif_disabled);
4551         } else if (brcmf_is_nonetwork(cfg, e)) {
4552                 if (brcmf_is_ibssmode(ifp->vif))
4553                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4554                                   &ifp->vif->sme_state);
4555                 else
4556                         brcmf_bss_connect_done(cfg, ndev, e, false);
4557         }
4558
4559         return err;
4560 }
4561
4562 static s32
4563 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4564                             const struct brcmf_event_msg *e, void *data)
4565 {
4566         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4567         s32 err = 0;
4568         u32 event = e->event_code;
4569         u32 status = e->status;
4570
4571         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4572                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4573                         brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4574                 else
4575                         brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4576         }
4577
4578         return err;
4579 }
4580
4581 static s32
4582 brcmf_notify_mic_status(struct brcmf_if *ifp,
4583                         const struct brcmf_event_msg *e, void *data)
4584 {
4585         u16 flags = e->flags;
4586         enum nl80211_key_type key_type;
4587
4588         if (flags & BRCMF_EVENT_MSG_GROUP)
4589                 key_type = NL80211_KEYTYPE_GROUP;
4590         else
4591                 key_type = NL80211_KEYTYPE_PAIRWISE;
4592
4593         cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4594                                      NULL, GFP_KERNEL);
4595
4596         return 0;
4597 }
4598
4599 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4600                                   const struct brcmf_event_msg *e, void *data)
4601 {
4602         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4603         struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4604         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4605         struct brcmf_cfg80211_vif *vif;
4606
4607         brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4608                   ifevent->action, ifevent->flags, ifevent->ifidx,
4609                   ifevent->bssidx);
4610
4611         mutex_lock(&event->vif_event_lock);
4612         event->action = ifevent->action;
4613         vif = event->vif;
4614
4615         switch (ifevent->action) {
4616         case BRCMF_E_IF_ADD:
4617                 /* waiting process may have timed out */
4618                 if (!cfg->vif_event.vif) {
4619                         mutex_unlock(&event->vif_event_lock);
4620                         return -EBADF;
4621                 }
4622
4623                 ifp->vif = vif;
4624                 vif->ifp = ifp;
4625                 vif->wdev.netdev = ifp->ndev;
4626                 ifp->ndev->ieee80211_ptr = &vif->wdev;
4627                 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4628                 mutex_unlock(&event->vif_event_lock);
4629                 wake_up(&event->vif_wq);
4630                 return 0;
4631
4632         case BRCMF_E_IF_DEL:
4633                 ifp->vif = NULL;
4634                 mutex_unlock(&event->vif_event_lock);
4635                 /* event may not be upon user request */
4636                 if (brcmf_cfg80211_vif_event_armed(cfg))
4637                         wake_up(&event->vif_wq);
4638                 return 0;
4639
4640         case BRCMF_E_IF_CHANGE:
4641                 mutex_unlock(&event->vif_event_lock);
4642                 wake_up(&event->vif_wq);
4643                 return 0;
4644
4645         default:
4646                 mutex_unlock(&event->vif_event_lock);
4647                 break;
4648         }
4649         return -EINVAL;
4650 }
4651
4652 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4653 {
4654         conf->frag_threshold = (u32)-1;
4655         conf->rts_threshold = (u32)-1;
4656         conf->retry_short = (u32)-1;
4657         conf->retry_long = (u32)-1;
4658         conf->tx_power = -1;
4659 }
4660
4661 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4662 {
4663         brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4664                             brcmf_notify_connect_status);
4665         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4666                             brcmf_notify_connect_status);
4667         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4668                             brcmf_notify_connect_status);
4669         brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4670                             brcmf_notify_connect_status);
4671         brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4672                             brcmf_notify_connect_status);
4673         brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4674                             brcmf_notify_connect_status);
4675         brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4676                             brcmf_notify_roaming_status);
4677         brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4678                             brcmf_notify_mic_status);
4679         brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4680                             brcmf_notify_connect_status);
4681         brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4682                             brcmf_notify_sched_scan_results);
4683         brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4684                             brcmf_notify_vif_event);
4685         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4686                             brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4687         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4688                             brcmf_p2p_notify_listen_complete);
4689         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4690                             brcmf_p2p_notify_action_frame_rx);
4691         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4692                             brcmf_p2p_notify_action_tx_complete);
4693         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4694                             brcmf_p2p_notify_action_tx_complete);
4695 }
4696
4697 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4698 {
4699         kfree(cfg->conf);
4700         cfg->conf = NULL;
4701         kfree(cfg->escan_ioctl_buf);
4702         cfg->escan_ioctl_buf = NULL;
4703         kfree(cfg->extra_buf);
4704         cfg->extra_buf = NULL;
4705         kfree(cfg->pmk_list);
4706         cfg->pmk_list = NULL;
4707 }
4708
4709 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4710 {
4711         cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4712         if (!cfg->conf)
4713                 goto init_priv_mem_out;
4714         cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4715         if (!cfg->escan_ioctl_buf)
4716                 goto init_priv_mem_out;
4717         cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4718         if (!cfg->extra_buf)
4719                 goto init_priv_mem_out;
4720         cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4721         if (!cfg->pmk_list)
4722                 goto init_priv_mem_out;
4723
4724         return 0;
4725
4726 init_priv_mem_out:
4727         brcmf_deinit_priv_mem(cfg);
4728
4729         return -ENOMEM;
4730 }
4731
4732 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4733 {
4734         s32 err = 0;
4735
4736         cfg->scan_request = NULL;
4737         cfg->pwr_save = true;
4738         cfg->roam_on = true;    /* roam on & off switch.
4739                                  we enable roam per default */
4740         cfg->active_scan = true;        /* we do active scan for
4741                                  specific scan per default */
4742         cfg->dongle_up = false; /* dongle is not up yet */
4743         err = brcmf_init_priv_mem(cfg);
4744         if (err)
4745                 return err;
4746         brcmf_register_event_handlers(cfg);
4747         mutex_init(&cfg->usr_sync);
4748         brcmf_init_escan(cfg);
4749         brcmf_init_conf(cfg->conf);
4750         init_completion(&cfg->vif_disabled);
4751         return err;
4752 }
4753
4754 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4755 {
4756         cfg->dongle_up = false; /* dongle down */
4757         brcmf_abort_scanning(cfg);
4758         brcmf_deinit_priv_mem(cfg);
4759 }
4760
4761 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4762 {
4763         init_waitqueue_head(&event->vif_wq);
4764         mutex_init(&event->vif_event_lock);
4765 }
4766
4767 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4768                                                   struct device *busdev)
4769 {
4770         struct net_device *ndev = drvr->iflist[0]->ndev;
4771         struct brcmf_cfg80211_info *cfg;
4772         struct wiphy *wiphy;
4773         struct brcmf_cfg80211_vif *vif;
4774         struct brcmf_if *ifp;
4775         s32 err = 0;
4776
4777         if (!ndev) {
4778                 brcmf_err("ndev is invalid\n");
4779                 return NULL;
4780         }
4781
4782         ifp = netdev_priv(ndev);
4783         wiphy = brcmf_setup_wiphy(busdev);
4784         if (IS_ERR(wiphy))
4785                 return NULL;
4786
4787         cfg = wiphy_priv(wiphy);
4788         cfg->wiphy = wiphy;
4789         cfg->pub = drvr;
4790         init_vif_event(&cfg->vif_event);
4791         INIT_LIST_HEAD(&cfg->vif_list);
4792
4793         vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4794         if (IS_ERR(vif)) {
4795                 wiphy_free(wiphy);
4796                 return NULL;
4797         }
4798
4799         vif->ifp = ifp;
4800         vif->wdev.netdev = ndev;
4801         ndev->ieee80211_ptr = &vif->wdev;
4802         SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4803
4804         err = wl_init_priv(cfg);
4805         if (err) {
4806                 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4807                 goto cfg80211_attach_out;
4808         }
4809         ifp->vif = vif;
4810
4811         err = brcmf_p2p_attach(cfg);
4812         if (err) {
4813                 brcmf_err("P2P initilisation failed (%d)\n", err);
4814                 goto cfg80211_p2p_attach_out;
4815         }
4816
4817         return cfg;
4818
4819 cfg80211_p2p_attach_out:
4820         wl_deinit_priv(cfg);
4821
4822 cfg80211_attach_out:
4823         brcmf_free_vif(vif);
4824         wiphy_free(wiphy);
4825         return NULL;
4826 }
4827
4828 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4829 {
4830         struct brcmf_cfg80211_vif *vif;
4831         struct brcmf_cfg80211_vif *tmp;
4832
4833         wl_deinit_priv(cfg);
4834         list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4835                 brcmf_free_vif(vif);
4836         }
4837 }
4838
4839 static s32
4840 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
4841 {
4842         s32 err = 0;
4843         __le32 roamtrigger[2];
4844         __le32 roam_delta[2];
4845
4846         /*
4847          * Setup timeout if Beacons are lost and roam is
4848          * off to report link down
4849          */
4850         if (roamvar) {
4851                 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4852                 if (err) {
4853                         brcmf_err("bcn_timeout error (%d)\n", err);
4854                         goto dongle_rom_out;
4855                 }
4856         }
4857
4858         /*
4859          * Enable/Disable built-in roaming to allow supplicant
4860          * to take care of roaming
4861          */
4862         brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4863         err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4864         if (err) {
4865                 brcmf_err("roam_off error (%d)\n", err);
4866                 goto dongle_rom_out;
4867         }
4868
4869         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4870         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4871         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4872                                      (void *)roamtrigger, sizeof(roamtrigger));
4873         if (err) {
4874                 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4875                 goto dongle_rom_out;
4876         }
4877
4878         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4879         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4880         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4881                                      (void *)roam_delta, sizeof(roam_delta));
4882         if (err) {
4883                 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4884                 goto dongle_rom_out;
4885         }
4886
4887 dongle_rom_out:
4888         return err;
4889 }
4890
4891 static s32
4892 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
4893                       s32 scan_unassoc_time, s32 scan_passive_time)
4894 {
4895         s32 err = 0;
4896
4897         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4898                                     scan_assoc_time);
4899         if (err) {
4900                 if (err == -EOPNOTSUPP)
4901                         brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4902                 else
4903                         brcmf_err("Scan assoc time error (%d)\n", err);
4904                 goto dongle_scantime_out;
4905         }
4906         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4907                                     scan_unassoc_time);
4908         if (err) {
4909                 if (err == -EOPNOTSUPP)
4910                         brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4911                 else
4912                         brcmf_err("Scan unassoc time error (%d)\n", err);
4913                 goto dongle_scantime_out;
4914         }
4915
4916         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4917                                     scan_passive_time);
4918         if (err) {
4919                 if (err == -EOPNOTSUPP)
4920                         brcmf_dbg(INFO, "Scan passive time is not supported\n");
4921                 else
4922                         brcmf_err("Scan passive time error (%d)\n", err);
4923                 goto dongle_scantime_out;
4924         }
4925
4926 dongle_scantime_out:
4927         return err;
4928 }
4929
4930 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4931 {
4932         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4933         struct wiphy *wiphy;
4934         s32 phy_list;
4935         s8 phy;
4936         s32 err = 0;
4937
4938         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4939                                      &phy_list, sizeof(phy_list));
4940         if (err) {
4941                 brcmf_err("error (%d)\n", err);
4942                 return err;
4943         }
4944
4945         phy = ((char *)&phy_list)[0];
4946         brcmf_dbg(INFO, "%c phy\n", phy);
4947         if (phy == 'n' || phy == 'a') {
4948                 wiphy = cfg_to_wiphy(cfg);
4949                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4950         }
4951
4952         return err;
4953 }
4954
4955 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4956 {
4957         return wl_update_wiphybands(cfg);
4958 }
4959
4960 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4961 {
4962         struct net_device *ndev;
4963         struct wireless_dev *wdev;
4964         struct brcmf_if *ifp;
4965         s32 power_mode;
4966         s32 err = 0;
4967
4968         if (cfg->dongle_up)
4969                 return err;
4970
4971         ndev = cfg_to_ndev(cfg);
4972         wdev = ndev->ieee80211_ptr;
4973         ifp = netdev_priv(ndev);
4974
4975         /* make sure RF is ready for work */
4976         brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
4977
4978         brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
4979                               WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4980
4981         power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4982         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
4983         if (err)
4984                 goto default_conf_out;
4985         brcmf_dbg(INFO, "power save set to %s\n",
4986                   (power_mode ? "enabled" : "disabled"));
4987
4988         err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
4989         if (err)
4990                 goto default_conf_out;
4991         err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4992                                           NULL, NULL);
4993         if (err)
4994                 goto default_conf_out;
4995         err = brcmf_dongle_probecap(cfg);
4996         if (err)
4997                 goto default_conf_out;
4998
4999         cfg->dongle_up = true;
5000 default_conf_out:
5001
5002         return err;
5003
5004 }
5005
5006 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5007 {
5008         set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5009
5010         return brcmf_config_dongle(ifp->drvr->config);
5011 }
5012
5013 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5014 {
5015         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5016
5017         /*
5018          * While going down, if associated with AP disassociate
5019          * from AP to save power
5020          */
5021         if (check_vif_up(ifp->vif)) {
5022                 brcmf_link_down(ifp->vif);
5023
5024                 /* Make sure WPA_Supplicant receives all the event
5025                    generated due to DISASSOC call to the fw to keep
5026                    the state fw and WPA_Supplicant state consistent
5027                  */
5028                 brcmf_delay(500);
5029         }
5030
5031         brcmf_abort_scanning(cfg);
5032         clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5033
5034         return 0;
5035 }
5036
5037 s32 brcmf_cfg80211_up(struct net_device *ndev)
5038 {
5039         struct brcmf_if *ifp = netdev_priv(ndev);
5040         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5041         s32 err = 0;
5042
5043         mutex_lock(&cfg->usr_sync);
5044         err = __brcmf_cfg80211_up(ifp);
5045         mutex_unlock(&cfg->usr_sync);
5046
5047         return err;
5048 }
5049
5050 s32 brcmf_cfg80211_down(struct net_device *ndev)
5051 {
5052         struct brcmf_if *ifp = netdev_priv(ndev);
5053         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5054         s32 err = 0;
5055
5056         mutex_lock(&cfg->usr_sync);
5057         err = __brcmf_cfg80211_down(ifp);
5058         mutex_unlock(&cfg->usr_sync);
5059
5060         return err;
5061 }
5062
5063 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5064 {
5065         struct brcmf_cfg80211_vif *vif;
5066         bool result = 0;
5067
5068         list_for_each_entry(vif, &cfg->vif_list, list) {
5069                 if (test_bit(state, &vif->sme_state))
5070                         result++;
5071         }
5072         return result;
5073 }
5074
5075 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5076                                     u8 action)
5077 {
5078         u8 evt_action;
5079
5080         mutex_lock(&event->vif_event_lock);
5081         evt_action = event->action;
5082         mutex_unlock(&event->vif_event_lock);
5083         return evt_action == action;
5084 }
5085
5086 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5087                                   struct brcmf_cfg80211_vif *vif)
5088 {
5089         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5090
5091         mutex_lock(&event->vif_event_lock);
5092         event->vif = vif;
5093         event->action = 0;
5094         mutex_unlock(&event->vif_event_lock);
5095 }
5096
5097 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5098 {
5099         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5100         bool armed;
5101
5102         mutex_lock(&event->vif_event_lock);
5103         armed = event->vif != NULL;
5104         mutex_unlock(&event->vif_event_lock);
5105
5106         return armed;
5107 }
5108 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5109                                           u8 action, ulong timeout)
5110 {
5111         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5112
5113         return wait_event_timeout(event->vif_wq,
5114                                   vif_event_equals(event, action), timeout);
5115 }
5116