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