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