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