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