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