Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[pandora-kernel.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,
2401                                   CFG80211_BSS_FTYPE_UNKNOWN,
2402                                   (const u8 *)bi->BSSID,
2403                                   0, notify_capability,
2404                                   notify_interval, notify_ie,
2405                                   notify_ielen, notify_signal,
2406                                   GFP_KERNEL);
2407
2408         if (!bss)
2409                 return -ENOMEM;
2410
2411         cfg80211_put_bss(wiphy, bss);
2412
2413         return 0;
2414 }
2415
2416 static struct brcmf_bss_info_le *
2417 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2418 {
2419         if (bss == NULL)
2420                 return list->bss_info_le;
2421         return (struct brcmf_bss_info_le *)((unsigned long)bss +
2422                                             le32_to_cpu(bss->length));
2423 }
2424
2425 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2426 {
2427         struct brcmf_scan_results *bss_list;
2428         struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2429         s32 err = 0;
2430         int i;
2431
2432         bss_list = cfg->bss_list;
2433         if (bss_list->count != 0 &&
2434             bss_list->version != BRCMF_BSS_INFO_VERSION) {
2435                 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2436                           bss_list->version);
2437                 return -EOPNOTSUPP;
2438         }
2439         brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2440         for (i = 0; i < bss_list->count; i++) {
2441                 bi = next_bss_le(bss_list, bi);
2442                 err = brcmf_inform_single_bss(cfg, bi);
2443                 if (err)
2444                         break;
2445         }
2446         return err;
2447 }
2448
2449 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2450                           struct net_device *ndev, const u8 *bssid)
2451 {
2452         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2453         struct ieee80211_channel *notify_channel;
2454         struct brcmf_bss_info_le *bi = NULL;
2455         struct ieee80211_supported_band *band;
2456         struct cfg80211_bss *bss;
2457         struct brcmu_chan ch;
2458         u8 *buf = NULL;
2459         s32 err = 0;
2460         u32 freq;
2461         u16 notify_capability;
2462         u16 notify_interval;
2463         u8 *notify_ie;
2464         size_t notify_ielen;
2465         s32 notify_signal;
2466
2467         brcmf_dbg(TRACE, "Enter\n");
2468
2469         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2470         if (buf == NULL) {
2471                 err = -ENOMEM;
2472                 goto CleanUp;
2473         }
2474
2475         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2476
2477         err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2478                                      buf, WL_BSS_INFO_MAX);
2479         if (err) {
2480                 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2481                 goto CleanUp;
2482         }
2483
2484         bi = (struct brcmf_bss_info_le *)(buf + 4);
2485
2486         ch.chspec = le16_to_cpu(bi->chanspec);
2487         cfg->d11inf.decchspec(&ch);
2488
2489         if (ch.band == BRCMU_CHAN_BAND_2G)
2490                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2491         else
2492                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2493
2494         freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2495         notify_channel = ieee80211_get_channel(wiphy, freq);
2496
2497         notify_capability = le16_to_cpu(bi->capability);
2498         notify_interval = le16_to_cpu(bi->beacon_period);
2499         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2500         notify_ielen = le32_to_cpu(bi->ie_length);
2501         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2502
2503         brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2504         brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2505         brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2506         brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2507
2508         bss = cfg80211_inform_bss(wiphy, notify_channel,
2509                                   CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2510                                   notify_capability, notify_interval,
2511                                   notify_ie, notify_ielen, notify_signal,
2512                                   GFP_KERNEL);
2513
2514         if (!bss) {
2515                 err = -ENOMEM;
2516                 goto CleanUp;
2517         }
2518
2519         cfg80211_put_bss(wiphy, bss);
2520
2521 CleanUp:
2522
2523         kfree(buf);
2524
2525         brcmf_dbg(TRACE, "Exit\n");
2526
2527         return err;
2528 }
2529
2530 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2531                                  struct brcmf_if *ifp)
2532 {
2533         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2534         struct brcmf_bss_info_le *bi;
2535         struct brcmf_ssid *ssid;
2536         const struct brcmf_tlv *tim;
2537         u16 beacon_interval;
2538         u8 dtim_period;
2539         size_t ie_len;
2540         u8 *ie;
2541         s32 err = 0;
2542
2543         brcmf_dbg(TRACE, "Enter\n");
2544         if (brcmf_is_ibssmode(ifp->vif))
2545                 return err;
2546
2547         ssid = &profile->ssid;
2548
2549         *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2550         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2551                                      cfg->extra_buf, WL_EXTRA_BUF_MAX);
2552         if (err) {
2553                 brcmf_err("Could not get bss info %d\n", err);
2554                 goto update_bss_info_out;
2555         }
2556
2557         bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2558         err = brcmf_inform_single_bss(cfg, bi);
2559         if (err)
2560                 goto update_bss_info_out;
2561
2562         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2563         ie_len = le32_to_cpu(bi->ie_length);
2564         beacon_interval = le16_to_cpu(bi->beacon_period);
2565
2566         tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2567         if (tim)
2568                 dtim_period = tim->data[1];
2569         else {
2570                 /*
2571                 * active scan was done so we could not get dtim
2572                 * information out of probe response.
2573                 * so we speficially query dtim information to dongle.
2574                 */
2575                 u32 var;
2576                 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2577                 if (err) {
2578                         brcmf_err("wl dtim_assoc failed (%d)\n", err);
2579                         goto update_bss_info_out;
2580                 }
2581                 dtim_period = (u8)var;
2582         }
2583
2584 update_bss_info_out:
2585         brcmf_dbg(TRACE, "Exit");
2586         return err;
2587 }
2588
2589 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2590 {
2591         struct escan_info *escan = &cfg->escan_info;
2592
2593         set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2594         if (cfg->scan_request) {
2595                 escan->escan_state = WL_ESCAN_STATE_IDLE;
2596                 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2597         }
2598         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2599         clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2600 }
2601
2602 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2603 {
2604         struct brcmf_cfg80211_info *cfg =
2605                         container_of(work, struct brcmf_cfg80211_info,
2606                                      escan_timeout_work);
2607
2608         brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2609 }
2610
2611 static void brcmf_escan_timeout(unsigned long data)
2612 {
2613         struct brcmf_cfg80211_info *cfg =
2614                         (struct brcmf_cfg80211_info *)data;
2615
2616         if (cfg->scan_request) {
2617                 brcmf_err("timer expired\n");
2618                 schedule_work(&cfg->escan_timeout_work);
2619         }
2620 }
2621
2622 static s32
2623 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2624                               struct brcmf_bss_info_le *bss,
2625                               struct brcmf_bss_info_le *bss_info_le)
2626 {
2627         struct brcmu_chan ch_bss, ch_bss_info_le;
2628
2629         ch_bss.chspec = le16_to_cpu(bss->chanspec);
2630         cfg->d11inf.decchspec(&ch_bss);
2631         ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2632         cfg->d11inf.decchspec(&ch_bss_info_le);
2633
2634         if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2635                 ch_bss.band == ch_bss_info_le.band &&
2636                 bss_info_le->SSID_len == bss->SSID_len &&
2637                 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2638                 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2639                         (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2640                         s16 bss_rssi = le16_to_cpu(bss->RSSI);
2641                         s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2642
2643                         /* preserve max RSSI if the measurements are
2644                         * both on-channel or both off-channel
2645                         */
2646                         if (bss_info_rssi > bss_rssi)
2647                                 bss->RSSI = bss_info_le->RSSI;
2648                 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2649                         (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2650                         /* preserve the on-channel rssi measurement
2651                         * if the new measurement is off channel
2652                         */
2653                         bss->RSSI = bss_info_le->RSSI;
2654                         bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2655                 }
2656                 return 1;
2657         }
2658         return 0;
2659 }
2660
2661 static s32
2662 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2663                              const struct brcmf_event_msg *e, void *data)
2664 {
2665         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2666         s32 status;
2667         struct brcmf_escan_result_le *escan_result_le;
2668         struct brcmf_bss_info_le *bss_info_le;
2669         struct brcmf_bss_info_le *bss = NULL;
2670         u32 bi_length;
2671         struct brcmf_scan_results *list;
2672         u32 i;
2673         bool aborted;
2674
2675         status = e->status;
2676
2677         if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2678                 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2679                 return -EPERM;
2680         }
2681
2682         if (status == BRCMF_E_STATUS_PARTIAL) {
2683                 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2684                 escan_result_le = (struct brcmf_escan_result_le *) data;
2685                 if (!escan_result_le) {
2686                         brcmf_err("Invalid escan result (NULL pointer)\n");
2687                         goto exit;
2688                 }
2689                 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2690                         brcmf_err("Invalid bss_count %d: ignoring\n",
2691                                   escan_result_le->bss_count);
2692                         goto exit;
2693                 }
2694                 bss_info_le = &escan_result_le->bss_info_le;
2695
2696                 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2697                         goto exit;
2698
2699                 if (!cfg->scan_request) {
2700                         brcmf_dbg(SCAN, "result without cfg80211 request\n");
2701                         goto exit;
2702                 }
2703
2704                 bi_length = le32_to_cpu(bss_info_le->length);
2705                 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2706                                         WL_ESCAN_RESULTS_FIXED_SIZE)) {
2707                         brcmf_err("Invalid bss_info length %d: ignoring\n",
2708                                   bi_length);
2709                         goto exit;
2710                 }
2711
2712                 if (!(cfg_to_wiphy(cfg)->interface_modes &
2713                                         BIT(NL80211_IFTYPE_ADHOC))) {
2714                         if (le16_to_cpu(bss_info_le->capability) &
2715                                                 WLAN_CAPABILITY_IBSS) {
2716                                 brcmf_err("Ignoring IBSS result\n");
2717                                 goto exit;
2718                         }
2719                 }
2720
2721                 list = (struct brcmf_scan_results *)
2722                                 cfg->escan_info.escan_buf;
2723                 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2724                         brcmf_err("Buffer is too small: ignoring\n");
2725                         goto exit;
2726                 }
2727
2728                 for (i = 0; i < list->count; i++) {
2729                         bss = bss ? (struct brcmf_bss_info_le *)
2730                                 ((unsigned char *)bss +
2731                                 le32_to_cpu(bss->length)) : list->bss_info_le;
2732                         if (brcmf_compare_update_same_bss(cfg, bss,
2733                                                           bss_info_le))
2734                                 goto exit;
2735                 }
2736                 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2737                         bss_info_le, bi_length);
2738                 list->version = le32_to_cpu(bss_info_le->version);
2739                 list->buflen += bi_length;
2740                 list->count++;
2741         } else {
2742                 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2743                 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2744                         goto exit;
2745                 if (cfg->scan_request) {
2746                         cfg->bss_list = (struct brcmf_scan_results *)
2747                                 cfg->escan_info.escan_buf;
2748                         brcmf_inform_bss(cfg);
2749                         aborted = status != BRCMF_E_STATUS_SUCCESS;
2750                         brcmf_notify_escan_complete(cfg, ifp, aborted,
2751                                                     false);
2752                 } else
2753                         brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2754                                   status);
2755         }
2756 exit:
2757         return 0;
2758 }
2759
2760 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2761 {
2762         brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2763                             brcmf_cfg80211_escan_handler);
2764         cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2765         /* Init scan_timeout timer */
2766         init_timer(&cfg->escan_timeout);
2767         cfg->escan_timeout.data = (unsigned long) cfg;
2768         cfg->escan_timeout.function = brcmf_escan_timeout;
2769         INIT_WORK(&cfg->escan_timeout_work,
2770                   brcmf_cfg80211_escan_timeout_worker);
2771 }
2772
2773 static __always_inline void brcmf_delay(u32 ms)
2774 {
2775         if (ms < 1000 / HZ) {
2776                 cond_resched();
2777                 mdelay(ms);
2778         } else {
2779                 msleep(ms);
2780         }
2781 }
2782
2783 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2784 {
2785         brcmf_dbg(TRACE, "Enter\n");
2786
2787         return 0;
2788 }
2789
2790 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2791                                   struct cfg80211_wowlan *wow)
2792 {
2793         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2794         struct net_device *ndev = cfg_to_ndev(cfg);
2795         struct brcmf_cfg80211_vif *vif;
2796
2797         brcmf_dbg(TRACE, "Enter\n");
2798
2799         /*
2800          * if the primary net_device is not READY there is nothing
2801          * we can do but pray resume goes smoothly.
2802          */
2803         vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2804         if (!check_vif_up(vif))
2805                 goto exit;
2806
2807         list_for_each_entry(vif, &cfg->vif_list, list) {
2808                 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2809                         continue;
2810                 /*
2811                  * While going to suspend if associated with AP disassociate
2812                  * from AP to save power while system is in suspended state
2813                  */
2814                 brcmf_link_down(vif);
2815
2816                 /* Make sure WPA_Supplicant receives all the event
2817                  * generated due to DISASSOC call to the fw to keep
2818                  * the state fw and WPA_Supplicant state consistent
2819                  */
2820                 brcmf_delay(500);
2821         }
2822
2823         /* end any scanning */
2824         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2825                 brcmf_abort_scanning(cfg);
2826
2827         /* Turn off watchdog timer */
2828         brcmf_set_mpc(netdev_priv(ndev), 1);
2829
2830 exit:
2831         brcmf_dbg(TRACE, "Exit\n");
2832         /* clear any scanning activity */
2833         cfg->scan_status = 0;
2834         return 0;
2835 }
2836
2837 static __used s32
2838 brcmf_update_pmklist(struct net_device *ndev,
2839                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2840 {
2841         int i, j;
2842         int pmkid_len;
2843
2844         pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2845
2846         brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2847         for (i = 0; i < pmkid_len; i++) {
2848                 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2849                           &pmk_list->pmkids.pmkid[i].BSSID);
2850                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2851                         brcmf_dbg(CONN, "%02x\n",
2852                                   pmk_list->pmkids.pmkid[i].PMKID[j]);
2853         }
2854
2855         if (!err)
2856                 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2857                                          (char *)pmk_list, sizeof(*pmk_list));
2858
2859         return err;
2860 }
2861
2862 static s32
2863 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2864                          struct cfg80211_pmksa *pmksa)
2865 {
2866         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2867         struct brcmf_if *ifp = netdev_priv(ndev);
2868         struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2869         s32 err = 0;
2870         int i;
2871         int pmkid_len;
2872
2873         brcmf_dbg(TRACE, "Enter\n");
2874         if (!check_vif_up(ifp->vif))
2875                 return -EIO;
2876
2877         pmkid_len = le32_to_cpu(pmkids->npmkid);
2878         for (i = 0; i < pmkid_len; i++)
2879                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2880                         break;
2881         if (i < WL_NUM_PMKIDS_MAX) {
2882                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2883                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2884                 if (i == pmkid_len) {
2885                         pmkid_len++;
2886                         pmkids->npmkid = cpu_to_le32(pmkid_len);
2887                 }
2888         } else
2889                 err = -EINVAL;
2890
2891         brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2892                   pmkids->pmkid[pmkid_len].BSSID);
2893         for (i = 0; i < WLAN_PMKID_LEN; i++)
2894                 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2895
2896         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2897
2898         brcmf_dbg(TRACE, "Exit\n");
2899         return err;
2900 }
2901
2902 static s32
2903 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2904                       struct cfg80211_pmksa *pmksa)
2905 {
2906         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2907         struct brcmf_if *ifp = netdev_priv(ndev);
2908         struct pmkid_list pmkid;
2909         s32 err = 0;
2910         int i, pmkid_len;
2911
2912         brcmf_dbg(TRACE, "Enter\n");
2913         if (!check_vif_up(ifp->vif))
2914                 return -EIO;
2915
2916         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2917         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2918
2919         brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2920                   &pmkid.pmkid[0].BSSID);
2921         for (i = 0; i < WLAN_PMKID_LEN; i++)
2922                 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2923
2924         pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2925         for (i = 0; i < pmkid_len; i++)
2926                 if (!memcmp
2927                     (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2928                      ETH_ALEN))
2929                         break;
2930
2931         if ((pmkid_len > 0)
2932             && (i < pmkid_len)) {
2933                 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2934                        sizeof(struct pmkid));
2935                 for (; i < (pmkid_len - 1); i++) {
2936                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2937                                &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2938                                ETH_ALEN);
2939                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2940                                &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2941                                WLAN_PMKID_LEN);
2942                 }
2943                 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2944         } else
2945                 err = -EINVAL;
2946
2947         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2948
2949         brcmf_dbg(TRACE, "Exit\n");
2950         return err;
2951
2952 }
2953
2954 static s32
2955 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2956 {
2957         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2958         struct brcmf_if *ifp = netdev_priv(ndev);
2959         s32 err = 0;
2960
2961         brcmf_dbg(TRACE, "Enter\n");
2962         if (!check_vif_up(ifp->vif))
2963                 return -EIO;
2964
2965         memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2966         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2967
2968         brcmf_dbg(TRACE, "Exit\n");
2969         return err;
2970
2971 }
2972
2973 /*
2974  * PFN result doesn't have all the info which are
2975  * required by the supplicant
2976  * (For e.g IEs) Do a target Escan so that sched scan results are reported
2977  * via wl_inform_single_bss in the required format. Escan does require the
2978  * scan request in the form of cfg80211_scan_request. For timebeing, create
2979  * cfg80211_scan_request one out of the received PNO event.
2980  */
2981 static s32
2982 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2983                                 const struct brcmf_event_msg *e, void *data)
2984 {
2985         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2986         struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2987         struct cfg80211_scan_request *request = NULL;
2988         struct cfg80211_ssid *ssid = NULL;
2989         struct ieee80211_channel *channel = NULL;
2990         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2991         int err = 0;
2992         int channel_req = 0;
2993         int band = 0;
2994         struct brcmf_pno_scanresults_le *pfn_result;
2995         u32 result_count;
2996         u32 status;
2997
2998         brcmf_dbg(SCAN, "Enter\n");
2999
3000         if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3001                 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3002                 return 0;
3003         }
3004
3005         pfn_result = (struct brcmf_pno_scanresults_le *)data;
3006         result_count = le32_to_cpu(pfn_result->count);
3007         status = le32_to_cpu(pfn_result->status);
3008
3009         /*
3010          * PFN event is limited to fit 512 bytes so we may get
3011          * multiple NET_FOUND events. For now place a warning here.
3012          */
3013         WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3014         brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3015         if (result_count > 0) {
3016                 int i;
3017
3018                 request = kzalloc(sizeof(*request), GFP_KERNEL);
3019                 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3020                 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3021                 if (!request || !ssid || !channel) {
3022                         err = -ENOMEM;
3023                         goto out_err;
3024                 }
3025
3026                 request->wiphy = wiphy;
3027                 data += sizeof(struct brcmf_pno_scanresults_le);
3028                 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3029
3030                 for (i = 0; i < result_count; i++) {
3031                         netinfo = &netinfo_start[i];
3032                         if (!netinfo) {
3033                                 brcmf_err("Invalid netinfo ptr. index: %d\n",
3034                                           i);
3035                                 err = -EINVAL;
3036                                 goto out_err;
3037                         }
3038
3039                         brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3040                                   netinfo->SSID, netinfo->channel);
3041                         memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3042                         ssid[i].ssid_len = netinfo->SSID_len;
3043                         request->n_ssids++;
3044
3045                         channel_req = netinfo->channel;
3046                         if (channel_req <= CH_MAX_2G_CHANNEL)
3047                                 band = NL80211_BAND_2GHZ;
3048                         else
3049                                 band = NL80211_BAND_5GHZ;
3050                         channel[i].center_freq =
3051                                 ieee80211_channel_to_frequency(channel_req,
3052                                                                band);
3053                         channel[i].band = band;
3054                         channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3055                         request->channels[i] = &channel[i];
3056                         request->n_channels++;
3057                 }
3058
3059                 /* assign parsed ssid array */
3060                 if (request->n_ssids)
3061                         request->ssids = &ssid[0];
3062
3063                 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3064                         /* Abort any on-going scan */
3065                         brcmf_abort_scanning(cfg);
3066                 }
3067
3068                 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3069                 cfg->escan_info.run = brcmf_run_escan;
3070                 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3071                 if (err) {
3072                         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3073                         goto out_err;
3074                 }
3075                 cfg->sched_escan = true;
3076                 cfg->scan_request = request;
3077         } else {
3078                 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3079                 goto out_err;
3080         }
3081
3082         kfree(ssid);
3083         kfree(channel);
3084         kfree(request);
3085         return 0;
3086
3087 out_err:
3088         kfree(ssid);
3089         kfree(channel);
3090         kfree(request);
3091         cfg80211_sched_scan_stopped(wiphy);
3092         return err;
3093 }
3094
3095 static int brcmf_dev_pno_clean(struct net_device *ndev)
3096 {
3097         int ret;
3098
3099         /* Disable pfn */
3100         ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3101         if (ret == 0) {
3102                 /* clear pfn */
3103                 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3104                                                NULL, 0);
3105         }
3106         if (ret < 0)
3107                 brcmf_err("failed code %d\n", ret);
3108
3109         return ret;
3110 }
3111
3112 static int brcmf_dev_pno_config(struct net_device *ndev)
3113 {
3114         struct brcmf_pno_param_le pfn_param;
3115
3116         memset(&pfn_param, 0, sizeof(pfn_param));
3117         pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3118
3119         /* set extra pno params */
3120         pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3121         pfn_param.repeat = BRCMF_PNO_REPEAT;
3122         pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3123
3124         /* set up pno scan fr */
3125         pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3126
3127         return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3128                                         &pfn_param, sizeof(pfn_param));
3129 }
3130
3131 static int
3132 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3133                                 struct net_device *ndev,
3134                                 struct cfg80211_sched_scan_request *request)
3135 {
3136         struct brcmf_if *ifp = netdev_priv(ndev);
3137         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3138         struct brcmf_pno_net_param_le pfn;
3139         int i;
3140         int ret = 0;
3141
3142         brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3143                   request->n_match_sets, request->n_ssids);
3144         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3145                 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3146                 return -EAGAIN;
3147         }
3148         if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3149                 brcmf_err("Scanning suppressed: status (%lu)\n",
3150                           cfg->scan_status);
3151                 return -EAGAIN;
3152         }
3153
3154         if (!request->n_ssids || !request->n_match_sets) {
3155                 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3156                           request->n_ssids);
3157                 return -EINVAL;
3158         }
3159
3160         if (request->n_ssids > 0) {
3161                 for (i = 0; i < request->n_ssids; i++) {
3162                         /* Active scan req for ssids */
3163                         brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3164                                   request->ssids[i].ssid);
3165
3166                         /*
3167                          * match_set ssids is a supert set of n_ssid list,
3168                          * so we need not add these set seperately.
3169                          */
3170                 }
3171         }
3172
3173         if (request->n_match_sets > 0) {
3174                 /* clean up everything */
3175                 ret = brcmf_dev_pno_clean(ndev);
3176                 if  (ret < 0) {
3177                         brcmf_err("failed error=%d\n", ret);
3178                         return ret;
3179                 }
3180
3181                 /* configure pno */
3182                 ret = brcmf_dev_pno_config(ndev);
3183                 if (ret < 0) {
3184                         brcmf_err("PNO setup failed!! ret=%d\n", ret);
3185                         return -EINVAL;
3186                 }
3187
3188                 /* configure each match set */
3189                 for (i = 0; i < request->n_match_sets; i++) {
3190                         struct cfg80211_ssid *ssid;
3191                         u32 ssid_len;
3192
3193                         ssid = &request->match_sets[i].ssid;
3194                         ssid_len = ssid->ssid_len;
3195
3196                         if (!ssid_len) {
3197                                 brcmf_err("skip broadcast ssid\n");
3198                                 continue;
3199                         }
3200                         pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3201                         pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3202                         pfn.wsec = cpu_to_le32(0);
3203                         pfn.infra = cpu_to_le32(1);
3204                         pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3205                         pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3206                         memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3207                         ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3208                                                        sizeof(pfn));
3209                         brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3210                                   ret == 0 ? "set" : "failed", ssid->ssid);
3211                 }
3212                 /* Enable the PNO */
3213                 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3214                         brcmf_err("PNO enable failed!! ret=%d\n", ret);
3215                         return -EINVAL;
3216                 }
3217         } else {
3218                 return -EINVAL;
3219         }
3220
3221         return 0;
3222 }
3223
3224 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3225                                           struct net_device *ndev)
3226 {
3227         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3228
3229         brcmf_dbg(SCAN, "enter\n");
3230         brcmf_dev_pno_clean(ndev);
3231         if (cfg->sched_escan)
3232                 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3233         return 0;
3234 }
3235
3236 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3237 {
3238         s32 err;
3239
3240         /* set auth */
3241         err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3242         if (err < 0) {
3243                 brcmf_err("auth error %d\n", err);
3244                 return err;
3245         }
3246         /* set wsec */
3247         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3248         if (err < 0) {
3249                 brcmf_err("wsec error %d\n", err);
3250                 return err;
3251         }
3252         /* set upper-layer auth */
3253         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3254         if (err < 0) {
3255                 brcmf_err("wpa_auth error %d\n", err);
3256                 return err;
3257         }
3258
3259         return 0;
3260 }
3261
3262 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3263 {
3264         if (is_rsn_ie)
3265                 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3266
3267         return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3268 }
3269
3270 static s32
3271 brcmf_configure_wpaie(struct net_device *ndev,
3272                       const struct brcmf_vs_tlv *wpa_ie,
3273                       bool is_rsn_ie)
3274 {
3275         struct brcmf_if *ifp = netdev_priv(ndev);
3276         u32 auth = 0; /* d11 open authentication */
3277         u16 count;
3278         s32 err = 0;
3279         s32 len = 0;
3280         u32 i;
3281         u32 wsec;
3282         u32 pval = 0;
3283         u32 gval = 0;
3284         u32 wpa_auth = 0;
3285         u32 offset;
3286         u8 *data;
3287         u16 rsn_cap;
3288         u32 wme_bss_disable;
3289
3290         brcmf_dbg(TRACE, "Enter\n");
3291         if (wpa_ie == NULL)
3292                 goto exit;
3293
3294         len = wpa_ie->len + TLV_HDR_LEN;
3295         data = (u8 *)wpa_ie;
3296         offset = TLV_HDR_LEN;
3297         if (!is_rsn_ie)
3298                 offset += VS_IE_FIXED_HDR_LEN;
3299         else
3300                 offset += WPA_IE_VERSION_LEN;
3301
3302         /* check for multicast cipher suite */
3303         if (offset + WPA_IE_MIN_OUI_LEN > len) {
3304                 err = -EINVAL;
3305                 brcmf_err("no multicast cipher suite\n");
3306                 goto exit;
3307         }
3308
3309         if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3310                 err = -EINVAL;
3311                 brcmf_err("ivalid OUI\n");
3312                 goto exit;
3313         }
3314         offset += TLV_OUI_LEN;
3315
3316         /* pick up multicast cipher */
3317         switch (data[offset]) {
3318         case WPA_CIPHER_NONE:
3319                 gval = 0;
3320                 break;
3321         case WPA_CIPHER_WEP_40:
3322         case WPA_CIPHER_WEP_104:
3323                 gval = WEP_ENABLED;
3324                 break;
3325         case WPA_CIPHER_TKIP:
3326                 gval = TKIP_ENABLED;
3327                 break;
3328         case WPA_CIPHER_AES_CCM:
3329                 gval = AES_ENABLED;
3330                 break;
3331         default:
3332                 err = -EINVAL;
3333                 brcmf_err("Invalid multi cast cipher info\n");
3334                 goto exit;
3335         }
3336
3337         offset++;
3338         /* walk thru unicast cipher list and pick up what we recognize */
3339         count = data[offset] + (data[offset + 1] << 8);
3340         offset += WPA_IE_SUITE_COUNT_LEN;
3341         /* Check for unicast suite(s) */
3342         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3343                 err = -EINVAL;
3344                 brcmf_err("no unicast cipher suite\n");
3345                 goto exit;
3346         }
3347         for (i = 0; i < count; i++) {
3348                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3349                         err = -EINVAL;
3350                         brcmf_err("ivalid OUI\n");
3351                         goto exit;
3352                 }
3353                 offset += TLV_OUI_LEN;
3354                 switch (data[offset]) {
3355                 case WPA_CIPHER_NONE:
3356                         break;
3357                 case WPA_CIPHER_WEP_40:
3358                 case WPA_CIPHER_WEP_104:
3359                         pval |= WEP_ENABLED;
3360                         break;
3361                 case WPA_CIPHER_TKIP:
3362                         pval |= TKIP_ENABLED;
3363                         break;
3364                 case WPA_CIPHER_AES_CCM:
3365                         pval |= AES_ENABLED;
3366                         break;
3367                 default:
3368                         brcmf_err("Ivalid unicast security info\n");
3369                 }
3370                 offset++;
3371         }
3372         /* walk thru auth management suite list and pick up what we recognize */
3373         count = data[offset] + (data[offset + 1] << 8);
3374         offset += WPA_IE_SUITE_COUNT_LEN;
3375         /* Check for auth key management suite(s) */
3376         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3377                 err = -EINVAL;
3378                 brcmf_err("no auth key mgmt suite\n");
3379                 goto exit;
3380         }
3381         for (i = 0; i < count; i++) {
3382                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3383                         err = -EINVAL;
3384                         brcmf_err("ivalid OUI\n");
3385                         goto exit;
3386                 }
3387                 offset += TLV_OUI_LEN;
3388                 switch (data[offset]) {
3389                 case RSN_AKM_NONE:
3390                         brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3391                         wpa_auth |= WPA_AUTH_NONE;
3392                         break;
3393                 case RSN_AKM_UNSPECIFIED:
3394                         brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3395                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3396                                     (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3397                         break;
3398                 case RSN_AKM_PSK:
3399                         brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3400                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3401                                     (wpa_auth |= WPA_AUTH_PSK);
3402                         break;
3403                 default:
3404                         brcmf_err("Ivalid key mgmt info\n");
3405                 }
3406                 offset++;
3407         }
3408
3409         if (is_rsn_ie) {
3410                 wme_bss_disable = 1;
3411                 if ((offset + RSN_CAP_LEN) <= len) {
3412                         rsn_cap = data[offset] + (data[offset + 1] << 8);
3413                         if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3414                                 wme_bss_disable = 0;
3415                 }
3416                 /* set wme_bss_disable to sync RSN Capabilities */
3417                 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3418                                                wme_bss_disable);
3419                 if (err < 0) {
3420                         brcmf_err("wme_bss_disable error %d\n", err);
3421                         goto exit;
3422                 }
3423         }
3424         /* FOR WPS , set SES_OW_ENABLED */
3425         wsec = (pval | gval | SES_OW_ENABLED);
3426
3427         /* set auth */
3428         err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3429         if (err < 0) {
3430                 brcmf_err("auth error %d\n", err);
3431                 goto exit;
3432         }
3433         /* set wsec */
3434         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3435         if (err < 0) {
3436                 brcmf_err("wsec error %d\n", err);
3437                 goto exit;
3438         }
3439         /* set upper-layer auth */
3440         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3441         if (err < 0) {
3442                 brcmf_err("wpa_auth error %d\n", err);
3443                 goto exit;
3444         }
3445
3446 exit:
3447         return err;
3448 }
3449
3450 static s32
3451 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3452                      struct parsed_vndr_ies *vndr_ies)
3453 {
3454         struct brcmf_vs_tlv *vndrie;
3455         struct brcmf_tlv *ie;
3456         struct parsed_vndr_ie_info *parsed_info;
3457         s32 remaining_len;
3458
3459         remaining_len = (s32)vndr_ie_len;
3460         memset(vndr_ies, 0, sizeof(*vndr_ies));
3461
3462         ie = (struct brcmf_tlv *)vndr_ie_buf;
3463         while (ie) {
3464                 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3465                         goto next;
3466                 vndrie = (struct brcmf_vs_tlv *)ie;
3467                 /* len should be bigger than OUI length + one */
3468                 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3469                         brcmf_err("invalid vndr ie. length is too small %d\n",
3470                                   vndrie->len);
3471                         goto next;
3472                 }
3473                 /* if wpa or wme ie, do not add ie */
3474                 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3475                     ((vndrie->oui_type == WPA_OUI_TYPE) ||
3476                     (vndrie->oui_type == WME_OUI_TYPE))) {
3477                         brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3478                         goto next;
3479                 }
3480
3481                 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3482
3483                 /* save vndr ie information */
3484                 parsed_info->ie_ptr = (char *)vndrie;
3485                 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3486                 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3487
3488                 vndr_ies->count++;
3489
3490                 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3491                           parsed_info->vndrie.oui[0],
3492                           parsed_info->vndrie.oui[1],
3493                           parsed_info->vndrie.oui[2],
3494                           parsed_info->vndrie.oui_type);
3495
3496                 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3497                         break;
3498 next:
3499                 remaining_len -= (ie->len + TLV_HDR_LEN);
3500                 if (remaining_len <= TLV_HDR_LEN)
3501                         ie = NULL;
3502                 else
3503                         ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3504                                 TLV_HDR_LEN);
3505         }
3506         return 0;
3507 }
3508
3509 static u32
3510 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3511 {
3512
3513         __le32 iecount_le;
3514         __le32 pktflag_le;
3515
3516         strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3517         iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3518
3519         iecount_le = cpu_to_le32(1);
3520         memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3521
3522         pktflag_le = cpu_to_le32(pktflag);
3523         memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3524
3525         memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3526
3527         return ie_len + VNDR_IE_HDR_SIZE;
3528 }
3529
3530 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3531                           const u8 *vndr_ie_buf, u32 vndr_ie_len)
3532 {
3533         struct brcmf_if *ifp;
3534         struct vif_saved_ie *saved_ie;
3535         s32 err = 0;
3536         u8  *iovar_ie_buf;
3537         u8  *curr_ie_buf;
3538         u8  *mgmt_ie_buf = NULL;
3539         int mgmt_ie_buf_len;
3540         u32 *mgmt_ie_len;
3541         u32 del_add_ie_buf_len = 0;
3542         u32 total_ie_buf_len = 0;
3543         u32 parsed_ie_buf_len = 0;
3544         struct parsed_vndr_ies old_vndr_ies;
3545         struct parsed_vndr_ies new_vndr_ies;
3546         struct parsed_vndr_ie_info *vndrie_info;
3547         s32 i;
3548         u8 *ptr;
3549         int remained_buf_len;
3550
3551         if (!vif)
3552                 return -ENODEV;
3553         ifp = vif->ifp;
3554         saved_ie = &vif->saved_ie;
3555
3556         brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3557         iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3558         if (!iovar_ie_buf)
3559                 return -ENOMEM;
3560         curr_ie_buf = iovar_ie_buf;
3561         switch (pktflag) {
3562         case BRCMF_VNDR_IE_PRBREQ_FLAG:
3563                 mgmt_ie_buf = saved_ie->probe_req_ie;
3564                 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3565                 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3566                 break;
3567         case BRCMF_VNDR_IE_PRBRSP_FLAG:
3568                 mgmt_ie_buf = saved_ie->probe_res_ie;
3569                 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3570                 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3571                 break;
3572         case BRCMF_VNDR_IE_BEACON_FLAG:
3573                 mgmt_ie_buf = saved_ie->beacon_ie;
3574                 mgmt_ie_len = &saved_ie->beacon_ie_len;
3575                 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3576                 break;
3577         case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3578                 mgmt_ie_buf = saved_ie->assoc_req_ie;
3579                 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3580                 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3581                 break;
3582         default:
3583                 err = -EPERM;
3584                 brcmf_err("not suitable type\n");
3585                 goto exit;
3586         }
3587
3588         if (vndr_ie_len > mgmt_ie_buf_len) {
3589                 err = -ENOMEM;
3590                 brcmf_err("extra IE size too big\n");
3591                 goto exit;
3592         }
3593
3594         /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3595         if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3596                 ptr = curr_ie_buf;
3597                 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3598                 for (i = 0; i < new_vndr_ies.count; i++) {
3599                         vndrie_info = &new_vndr_ies.ie_info[i];
3600                         memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3601                                vndrie_info->ie_len);
3602                         parsed_ie_buf_len += vndrie_info->ie_len;
3603                 }
3604         }
3605
3606         if (mgmt_ie_buf && *mgmt_ie_len) {
3607                 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3608                     (memcmp(mgmt_ie_buf, curr_ie_buf,
3609                             parsed_ie_buf_len) == 0)) {
3610                         brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3611                         goto exit;
3612                 }
3613
3614                 /* parse old vndr_ie */
3615                 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3616
3617                 /* make a command to delete old ie */
3618                 for (i = 0; i < old_vndr_ies.count; i++) {
3619                         vndrie_info = &old_vndr_ies.ie_info[i];
3620
3621                         brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3622                                   vndrie_info->vndrie.id,
3623                                   vndrie_info->vndrie.len,
3624                                   vndrie_info->vndrie.oui[0],
3625                                   vndrie_info->vndrie.oui[1],
3626                                   vndrie_info->vndrie.oui[2]);
3627
3628                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3629                                                            vndrie_info->ie_ptr,
3630                                                            vndrie_info->ie_len,
3631                                                            "del");
3632                         curr_ie_buf += del_add_ie_buf_len;
3633                         total_ie_buf_len += del_add_ie_buf_len;
3634                 }
3635         }
3636
3637         *mgmt_ie_len = 0;
3638         /* Add if there is any extra IE */
3639         if (mgmt_ie_buf && parsed_ie_buf_len) {
3640                 ptr = mgmt_ie_buf;
3641
3642                 remained_buf_len = mgmt_ie_buf_len;
3643
3644                 /* make a command to add new ie */
3645                 for (i = 0; i < new_vndr_ies.count; i++) {
3646                         vndrie_info = &new_vndr_ies.ie_info[i];
3647
3648                         /* verify remained buf size before copy data */
3649                         if (remained_buf_len < (vndrie_info->vndrie.len +
3650                                                         VNDR_IE_VSIE_OFFSET)) {
3651                                 brcmf_err("no space in mgmt_ie_buf: len left %d",
3652                                           remained_buf_len);
3653                                 break;
3654                         }
3655                         remained_buf_len -= (vndrie_info->ie_len +
3656                                              VNDR_IE_VSIE_OFFSET);
3657
3658                         brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3659                                   vndrie_info->vndrie.id,
3660                                   vndrie_info->vndrie.len,
3661                                   vndrie_info->vndrie.oui[0],
3662                                   vndrie_info->vndrie.oui[1],
3663                                   vndrie_info->vndrie.oui[2]);
3664
3665                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3666                                                            vndrie_info->ie_ptr,
3667                                                            vndrie_info->ie_len,
3668                                                            "add");
3669
3670                         /* save the parsed IE in wl struct */
3671                         memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3672                                vndrie_info->ie_len);
3673                         *mgmt_ie_len += vndrie_info->ie_len;
3674
3675                         curr_ie_buf += del_add_ie_buf_len;
3676                         total_ie_buf_len += del_add_ie_buf_len;
3677                 }
3678         }
3679         if (total_ie_buf_len) {
3680                 err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3681                                                  total_ie_buf_len);
3682                 if (err)
3683                         brcmf_err("vndr ie set error : %d\n", err);
3684         }
3685
3686 exit:
3687         kfree(iovar_ie_buf);
3688         return err;
3689 }
3690
3691 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3692 {
3693         s32 pktflags[] = {
3694                 BRCMF_VNDR_IE_PRBREQ_FLAG,
3695                 BRCMF_VNDR_IE_PRBRSP_FLAG,
3696                 BRCMF_VNDR_IE_BEACON_FLAG
3697         };
3698         int i;
3699
3700         for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3701                 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3702
3703         memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3704         return 0;
3705 }
3706
3707 static s32
3708 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3709                         struct cfg80211_beacon_data *beacon)
3710 {
3711         s32 err;
3712
3713         /* Set Beacon IEs to FW */
3714         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3715                                     beacon->tail, beacon->tail_len);
3716         if (err) {
3717                 brcmf_err("Set Beacon IE Failed\n");
3718                 return err;
3719         }
3720         brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3721
3722         /* Set Probe Response IEs to FW */
3723         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3724                                     beacon->proberesp_ies,
3725                                     beacon->proberesp_ies_len);
3726         if (err)
3727                 brcmf_err("Set Probe Resp IE Failed\n");
3728         else
3729                 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3730
3731         return err;
3732 }
3733
3734 static s32
3735 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3736                         struct cfg80211_ap_settings *settings)
3737 {
3738         s32 ie_offset;
3739         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3740         struct brcmf_if *ifp = netdev_priv(ndev);
3741         const struct brcmf_tlv *ssid_ie;
3742         struct brcmf_ssid_le ssid_le;
3743         s32 err = -EPERM;
3744         const struct brcmf_tlv *rsn_ie;
3745         const struct brcmf_vs_tlv *wpa_ie;
3746         struct brcmf_join_params join_params;
3747         enum nl80211_iftype dev_role;
3748         struct brcmf_fil_bss_enable_le bss_enable;
3749         u16 chanspec;
3750
3751         brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
3752                   settings->chandef.chan->hw_value,
3753                   settings->chandef.center_freq1, settings->chandef.width,
3754                   settings->beacon_interval, settings->dtim_period);
3755         brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3756                   settings->ssid, settings->ssid_len, settings->auth_type,
3757                   settings->inactivity_timeout);
3758
3759         dev_role = ifp->vif->wdev.iftype;
3760
3761         memset(&ssid_le, 0, sizeof(ssid_le));
3762         if (settings->ssid == NULL || settings->ssid_len == 0) {
3763                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3764                 ssid_ie = brcmf_parse_tlvs(
3765                                 (u8 *)&settings->beacon.head[ie_offset],
3766                                 settings->beacon.head_len - ie_offset,
3767                                 WLAN_EID_SSID);
3768                 if (!ssid_ie)
3769                         return -EINVAL;
3770
3771                 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3772                 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3773                 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3774         } else {
3775                 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3776                 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3777         }
3778
3779         brcmf_set_mpc(ifp, 0);
3780         brcmf_configure_arp_offload(ifp, false);
3781
3782         /* find the RSN_IE */
3783         rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3784                                   settings->beacon.tail_len, WLAN_EID_RSN);
3785
3786         /* find the WPA_IE */
3787         wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3788                                   settings->beacon.tail_len);
3789
3790         if ((wpa_ie != NULL || rsn_ie != NULL)) {
3791                 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3792                 if (wpa_ie != NULL) {
3793                         /* WPA IE */
3794                         err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3795                         if (err < 0)
3796                                 goto exit;
3797                 } else {
3798                         /* RSN IE */
3799                         err = brcmf_configure_wpaie(ndev,
3800                                 (struct brcmf_vs_tlv *)rsn_ie, true);
3801                         if (err < 0)
3802                                 goto exit;
3803                 }
3804         } else {
3805                 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3806                 brcmf_configure_opensecurity(ifp);
3807         }
3808
3809         brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3810
3811         chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
3812         err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3813         if (err < 0) {
3814                 brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err);
3815                 goto exit;
3816         }
3817
3818         if (settings->beacon_interval) {
3819                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3820                                             settings->beacon_interval);
3821                 if (err < 0) {
3822                         brcmf_err("Beacon Interval Set Error, %d\n", err);
3823                         goto exit;
3824                 }
3825         }
3826         if (settings->dtim_period) {
3827                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3828                                             settings->dtim_period);
3829                 if (err < 0) {
3830                         brcmf_err("DTIM Interval Set Error, %d\n", err);
3831                         goto exit;
3832                 }
3833         }
3834
3835         if (dev_role == NL80211_IFTYPE_AP) {
3836                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3837                 if (err < 0) {
3838                         brcmf_err("BRCMF_C_DOWN error %d\n", err);
3839                         goto exit;
3840                 }
3841                 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3842         }
3843
3844         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3845         if (err < 0) {
3846                 brcmf_err("SET INFRA error %d\n", err);
3847                 goto exit;
3848         }
3849         if (dev_role == NL80211_IFTYPE_AP) {
3850                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3851                 if (err < 0) {
3852                         brcmf_err("setting AP mode failed %d\n", err);
3853                         goto exit;
3854                 }
3855                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3856                 if (err < 0) {
3857                         brcmf_err("BRCMF_C_UP error (%d)\n", err);
3858                         goto exit;
3859                 }
3860
3861                 memset(&join_params, 0, sizeof(join_params));
3862                 /* join parameters starts with ssid */
3863                 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3864                 /* create softap */
3865                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3866                                              &join_params, sizeof(join_params));
3867                 if (err < 0) {
3868                         brcmf_err("SET SSID error (%d)\n", err);
3869                         goto exit;
3870                 }
3871                 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3872         } else {
3873                 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3874                                                 sizeof(ssid_le));
3875                 if (err < 0) {
3876                         brcmf_err("setting ssid failed %d\n", err);
3877                         goto exit;
3878                 }
3879                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3880                 bss_enable.enable = cpu_to_le32(1);
3881                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3882                                                sizeof(bss_enable));
3883                 if (err < 0) {
3884                         brcmf_err("bss_enable config failed %d\n", err);
3885                         goto exit;
3886                 }
3887
3888                 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3889         }
3890         clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3891         set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3892
3893 exit:
3894         if (err) {
3895                 brcmf_set_mpc(ifp, 1);
3896                 brcmf_configure_arp_offload(ifp, true);
3897         }
3898         return err;
3899 }
3900
3901 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3902 {
3903         struct brcmf_if *ifp = netdev_priv(ndev);
3904         s32 err;
3905         struct brcmf_fil_bss_enable_le bss_enable;
3906         struct brcmf_join_params join_params;
3907
3908         brcmf_dbg(TRACE, "Enter\n");
3909
3910         if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3911                 /* Due to most likely deauths outstanding we sleep */
3912                 /* first to make sure they get processed by fw. */
3913                 msleep(400);
3914
3915                 memset(&join_params, 0, sizeof(join_params));
3916                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3917                                              &join_params, sizeof(join_params));
3918                 if (err < 0)
3919                         brcmf_err("SET SSID error (%d)\n", err);
3920                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3921                 if (err < 0)
3922                         brcmf_err("BRCMF_C_UP error %d\n", err);
3923                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3924                 if (err < 0)
3925                         brcmf_err("setting AP mode failed %d\n", err);
3926                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3927                 if (err < 0)
3928                         brcmf_err("setting INFRA mode failed %d\n", err);
3929         } else {
3930                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3931                 bss_enable.enable = cpu_to_le32(0);
3932                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3933                                                sizeof(bss_enable));
3934                 if (err < 0)
3935                         brcmf_err("bss_enable config failed %d\n", err);
3936         }
3937         brcmf_set_mpc(ifp, 1);
3938         brcmf_configure_arp_offload(ifp, true);
3939         set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3940         clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3941
3942         return err;
3943 }
3944
3945 static s32
3946 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3947                              struct cfg80211_beacon_data *info)
3948 {
3949         struct brcmf_if *ifp = netdev_priv(ndev);
3950         s32 err;
3951
3952         brcmf_dbg(TRACE, "Enter\n");
3953
3954         err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3955
3956         return err;
3957 }
3958
3959 static int
3960 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3961                            const u8 *mac)
3962 {
3963         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3964         struct brcmf_scb_val_le scbval;
3965         struct brcmf_if *ifp = netdev_priv(ndev);
3966         s32 err;
3967
3968         if (!mac)
3969                 return -EFAULT;
3970
3971         brcmf_dbg(TRACE, "Enter %pM\n", mac);
3972
3973         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3974                 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3975         if (!check_vif_up(ifp->vif))
3976                 return -EIO;
3977
3978         memcpy(&scbval.ea, mac, ETH_ALEN);
3979         scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3980         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3981                                      &scbval, sizeof(scbval));
3982         if (err)
3983                 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3984
3985         brcmf_dbg(TRACE, "Exit\n");
3986         return err;
3987 }
3988
3989
3990 static void
3991 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3992                                    struct wireless_dev *wdev,
3993                                    u16 frame_type, bool reg)
3994 {
3995         struct brcmf_cfg80211_vif *vif;
3996         u16 mgmt_type;
3997
3998         brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3999
4000         mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4001         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4002         if (reg)
4003                 vif->mgmt_rx_reg |= BIT(mgmt_type);
4004         else
4005                 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4006 }
4007
4008
4009 static int
4010 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4011                        struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4012 {
4013         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4014         struct ieee80211_channel *chan = params->chan;
4015         const u8 *buf = params->buf;
4016         size_t len = params->len;
4017         const struct ieee80211_mgmt *mgmt;
4018         struct brcmf_cfg80211_vif *vif;
4019         s32 err = 0;
4020         s32 ie_offset;
4021         s32 ie_len;
4022         struct brcmf_fil_action_frame_le *action_frame;
4023         struct brcmf_fil_af_params_le *af_params;
4024         bool ack;
4025         s32 chan_nr;
4026         u32 freq;
4027
4028         brcmf_dbg(TRACE, "Enter\n");
4029
4030         *cookie = 0;
4031
4032         mgmt = (const struct ieee80211_mgmt *)buf;
4033
4034         if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4035                 brcmf_err("Driver only allows MGMT packet type\n");
4036                 return -EPERM;
4037         }
4038
4039         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4040
4041         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4042                 /* Right now the only reason to get a probe response */
4043                 /* is for p2p listen response or for p2p GO from     */
4044                 /* wpa_supplicant. Unfortunately the probe is send   */
4045                 /* on primary ndev, while dongle wants it on the p2p */
4046                 /* vif. Since this is only reason for a probe        */
4047                 /* response to be sent, the vif is taken from cfg.   */
4048                 /* If ever desired to send proberesp for non p2p     */
4049                 /* response then data should be checked for          */
4050                 /* "DIRECT-". Note in future supplicant will take    */
4051                 /* dedicated p2p wdev to do this and then this 'hack'*/
4052                 /* is not needed anymore.                            */
4053                 ie_offset =  DOT11_MGMT_HDR_LEN +
4054                              DOT11_BCN_PRB_FIXED_LEN;
4055                 ie_len = len - ie_offset;
4056                 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4057                         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4058                 err = brcmf_vif_set_mgmt_ie(vif,
4059                                             BRCMF_VNDR_IE_PRBRSP_FLAG,
4060                                             &buf[ie_offset],
4061                                             ie_len);
4062                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4063                                         GFP_KERNEL);
4064         } else if (ieee80211_is_action(mgmt->frame_control)) {
4065                 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4066                 if (af_params == NULL) {
4067                         brcmf_err("unable to allocate frame\n");
4068                         err = -ENOMEM;
4069                         goto exit;
4070                 }
4071                 action_frame = &af_params->action_frame;
4072                 /* Add the packet Id */
4073                 action_frame->packet_id = cpu_to_le32(*cookie);
4074                 /* Add BSSID */
4075                 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4076                 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4077                 /* Add the length exepted for 802.11 header  */
4078                 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4079                 /* Add the channel. Use the one specified as parameter if any or
4080                  * the current one (got from the firmware) otherwise
4081                  */
4082                 if (chan)
4083                         freq = chan->center_freq;
4084                 else
4085                         brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4086                                               &freq);
4087                 chan_nr = ieee80211_frequency_to_channel(freq);
4088                 af_params->channel = cpu_to_le32(chan_nr);
4089
4090                 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4091                        le16_to_cpu(action_frame->len));
4092
4093                 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4094                           *cookie, le16_to_cpu(action_frame->len), freq);
4095
4096                 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4097                                                   af_params);
4098
4099                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4100                                         GFP_KERNEL);
4101                 kfree(af_params);
4102         } else {
4103                 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4104                 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4105         }
4106
4107 exit:
4108         return err;
4109 }
4110
4111
4112 static int
4113 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4114                                         struct wireless_dev *wdev,
4115                                         u64 cookie)
4116 {
4117         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4118         struct brcmf_cfg80211_vif *vif;
4119         int err = 0;
4120
4121         brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4122
4123         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4124         if (vif == NULL) {
4125                 brcmf_err("No p2p device available for probe response\n");
4126                 err = -ENODEV;
4127                 goto exit;
4128         }
4129         brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4130 exit:
4131         return err;
4132 }
4133
4134 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4135                                            struct wireless_dev *wdev,
4136                                            enum nl80211_crit_proto_id proto,
4137                                            u16 duration)
4138 {
4139         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4140         struct brcmf_cfg80211_vif *vif;
4141
4142         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4143
4144         /* only DHCP support for now */
4145         if (proto != NL80211_CRIT_PROTO_DHCP)
4146                 return -EINVAL;
4147
4148         /* suppress and abort scanning */
4149         set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4150         brcmf_abort_scanning(cfg);
4151
4152         return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4153 }
4154
4155 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4156                                            struct wireless_dev *wdev)
4157 {
4158         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4159         struct brcmf_cfg80211_vif *vif;
4160
4161         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4162
4163         brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4164         clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4165 }
4166
4167 static s32
4168 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4169                              const struct brcmf_event_msg *e, void *data)
4170 {
4171         switch (e->reason) {
4172         case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4173                 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4174                 break;
4175         case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4176                 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4177                 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4178                 break;
4179         case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4180                 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4181                 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4182                 break;
4183         }
4184
4185         return 0;
4186 }
4187
4188 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4189 {
4190         int ret;
4191
4192         switch (oper) {
4193         case NL80211_TDLS_DISCOVERY_REQ:
4194                 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4195                 break;
4196         case NL80211_TDLS_SETUP:
4197                 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4198                 break;
4199         case NL80211_TDLS_TEARDOWN:
4200                 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4201                 break;
4202         default:
4203                 brcmf_err("unsupported operation: %d\n", oper);
4204                 ret = -EOPNOTSUPP;
4205         }
4206         return ret;
4207 }
4208
4209 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4210                                     struct net_device *ndev, const u8 *peer,
4211                                     enum nl80211_tdls_operation oper)
4212 {
4213         struct brcmf_if *ifp;
4214         struct brcmf_tdls_iovar_le info;
4215         int ret = 0;
4216
4217         ret = brcmf_convert_nl80211_tdls_oper(oper);
4218         if (ret < 0)
4219                 return ret;
4220
4221         ifp = netdev_priv(ndev);
4222         memset(&info, 0, sizeof(info));
4223         info.mode = (u8)ret;
4224         if (peer)
4225                 memcpy(info.ea, peer, ETH_ALEN);
4226
4227         ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4228                                        &info, sizeof(info));
4229         if (ret < 0)
4230                 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4231
4232         return ret;
4233 }
4234
4235 static struct cfg80211_ops wl_cfg80211_ops = {
4236         .add_virtual_intf = brcmf_cfg80211_add_iface,
4237         .del_virtual_intf = brcmf_cfg80211_del_iface,
4238         .change_virtual_intf = brcmf_cfg80211_change_iface,
4239         .scan = brcmf_cfg80211_scan,
4240         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4241         .join_ibss = brcmf_cfg80211_join_ibss,
4242         .leave_ibss = brcmf_cfg80211_leave_ibss,
4243         .get_station = brcmf_cfg80211_get_station,
4244         .set_tx_power = brcmf_cfg80211_set_tx_power,
4245         .get_tx_power = brcmf_cfg80211_get_tx_power,
4246         .add_key = brcmf_cfg80211_add_key,
4247         .del_key = brcmf_cfg80211_del_key,
4248         .get_key = brcmf_cfg80211_get_key,
4249         .set_default_key = brcmf_cfg80211_config_default_key,
4250         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4251         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4252         .connect = brcmf_cfg80211_connect,
4253         .disconnect = brcmf_cfg80211_disconnect,
4254         .suspend = brcmf_cfg80211_suspend,
4255         .resume = brcmf_cfg80211_resume,
4256         .set_pmksa = brcmf_cfg80211_set_pmksa,
4257         .del_pmksa = brcmf_cfg80211_del_pmksa,
4258         .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4259         .start_ap = brcmf_cfg80211_start_ap,
4260         .stop_ap = brcmf_cfg80211_stop_ap,
4261         .change_beacon = brcmf_cfg80211_change_beacon,
4262         .del_station = brcmf_cfg80211_del_station,
4263         .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4264         .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4265         .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4266         .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4267         .remain_on_channel = brcmf_p2p_remain_on_channel,
4268         .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4269         .start_p2p_device = brcmf_p2p_start_device,
4270         .stop_p2p_device = brcmf_p2p_stop_device,
4271         .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4272         .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4273         .tdls_oper = brcmf_cfg80211_tdls_oper,
4274 };
4275
4276 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4277                                            enum nl80211_iftype type,
4278                                            bool pm_block)
4279 {
4280         struct brcmf_cfg80211_vif *vif;
4281
4282         brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4283                   sizeof(*vif));
4284         vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4285         if (!vif)
4286                 return ERR_PTR(-ENOMEM);
4287
4288         vif->wdev.wiphy = cfg->wiphy;
4289         vif->wdev.iftype = type;
4290
4291         vif->pm_block = pm_block;
4292         vif->roam_off = -1;
4293
4294         brcmf_init_prof(&vif->profile);
4295
4296         list_add_tail(&vif->list, &cfg->vif_list);
4297         return vif;
4298 }
4299
4300 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4301 {
4302         list_del(&vif->list);
4303         kfree(vif);
4304 }
4305
4306 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4307 {
4308         struct brcmf_cfg80211_vif *vif;
4309         struct brcmf_if *ifp;
4310
4311         ifp = netdev_priv(ndev);
4312         vif = ifp->vif;
4313
4314         brcmf_free_vif(vif);
4315         free_netdev(ndev);
4316 }
4317
4318 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4319 {
4320         u32 event = e->event_code;
4321         u32 status = e->status;
4322
4323         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4324                 brcmf_dbg(CONN, "Processing set ssid\n");
4325                 return true;
4326         }
4327
4328         return false;
4329 }
4330
4331 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4332 {
4333         u32 event = e->event_code;
4334         u16 flags = e->flags;
4335
4336         if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4337             (event == BRCMF_E_DISASSOC_IND) ||
4338             ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4339                 brcmf_dbg(CONN, "Processing link down\n");
4340                 return true;
4341         }
4342         return false;
4343 }
4344
4345 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4346                                const struct brcmf_event_msg *e)
4347 {
4348         u32 event = e->event_code;
4349         u32 status = e->status;
4350
4351         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4352                 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4353                           e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4354                 return true;
4355         }
4356
4357         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4358                 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4359                 return true;
4360         }
4361
4362         return false;
4363 }
4364
4365 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4366 {
4367         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4368
4369         kfree(conn_info->req_ie);
4370         conn_info->req_ie = NULL;
4371         conn_info->req_ie_len = 0;
4372         kfree(conn_info->resp_ie);
4373         conn_info->resp_ie = NULL;
4374         conn_info->resp_ie_len = 0;
4375 }
4376
4377 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4378                                struct brcmf_if *ifp)
4379 {
4380         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4381         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4382         u32 req_len;
4383         u32 resp_len;
4384         s32 err = 0;
4385
4386         brcmf_clear_assoc_ies(cfg);
4387
4388         err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4389                                        cfg->extra_buf, WL_ASSOC_INFO_MAX);
4390         if (err) {
4391                 brcmf_err("could not get assoc info (%d)\n", err);
4392                 return err;
4393         }
4394         assoc_info =
4395                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4396         req_len = le32_to_cpu(assoc_info->req_len);
4397         resp_len = le32_to_cpu(assoc_info->resp_len);
4398         if (req_len) {
4399                 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4400                                                cfg->extra_buf,
4401                                                WL_ASSOC_INFO_MAX);
4402                 if (err) {
4403                         brcmf_err("could not get assoc req (%d)\n", err);
4404                         return err;
4405                 }
4406                 conn_info->req_ie_len = req_len;
4407                 conn_info->req_ie =
4408                     kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4409                             GFP_KERNEL);
4410         } else {
4411                 conn_info->req_ie_len = 0;
4412                 conn_info->req_ie = NULL;
4413         }
4414         if (resp_len) {
4415                 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4416                                                cfg->extra_buf,
4417                                                WL_ASSOC_INFO_MAX);
4418                 if (err) {
4419                         brcmf_err("could not get assoc resp (%d)\n", err);
4420                         return err;
4421                 }
4422                 conn_info->resp_ie_len = resp_len;
4423                 conn_info->resp_ie =
4424                     kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4425                             GFP_KERNEL);
4426         } else {
4427                 conn_info->resp_ie_len = 0;
4428                 conn_info->resp_ie = NULL;
4429         }
4430         brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4431                   conn_info->req_ie_len, conn_info->resp_ie_len);
4432
4433         return err;
4434 }
4435
4436 static s32
4437 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4438                        struct net_device *ndev,
4439                        const struct brcmf_event_msg *e)
4440 {
4441         struct brcmf_if *ifp = netdev_priv(ndev);
4442         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4443         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4444         struct wiphy *wiphy = cfg_to_wiphy(cfg);
4445         struct ieee80211_channel *notify_channel = NULL;
4446         struct ieee80211_supported_band *band;
4447         struct brcmf_bss_info_le *bi;
4448         struct brcmu_chan ch;
4449         u32 freq;
4450         s32 err = 0;
4451         u8 *buf;
4452
4453         brcmf_dbg(TRACE, "Enter\n");
4454
4455         brcmf_get_assoc_ies(cfg, ifp);
4456         memcpy(profile->bssid, e->addr, ETH_ALEN);
4457         brcmf_update_bss_info(cfg, ifp);
4458
4459         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4460         if (buf == NULL) {
4461                 err = -ENOMEM;
4462                 goto done;
4463         }
4464
4465         /* data sent to dongle has to be little endian */
4466         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4467         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4468                                      buf, WL_BSS_INFO_MAX);
4469
4470         if (err)
4471                 goto done;
4472
4473         bi = (struct brcmf_bss_info_le *)(buf + 4);
4474         ch.chspec = le16_to_cpu(bi->chanspec);
4475         cfg->d11inf.decchspec(&ch);
4476
4477         if (ch.band == BRCMU_CHAN_BAND_2G)
4478                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4479         else
4480                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4481
4482         freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4483         notify_channel = ieee80211_get_channel(wiphy, freq);
4484
4485 done:
4486         kfree(buf);
4487         cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4488                         conn_info->req_ie, conn_info->req_ie_len,
4489                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4490         brcmf_dbg(CONN, "Report roaming result\n");
4491
4492         set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4493         brcmf_dbg(TRACE, "Exit\n");
4494         return err;
4495 }
4496
4497 static s32
4498 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4499                        struct net_device *ndev, const struct brcmf_event_msg *e,
4500                        bool completed)
4501 {
4502         struct brcmf_if *ifp = netdev_priv(ndev);
4503         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4504         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4505
4506         brcmf_dbg(TRACE, "Enter\n");
4507
4508         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4509                                &ifp->vif->sme_state)) {
4510                 if (completed) {
4511                         brcmf_get_assoc_ies(cfg, ifp);
4512                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4513                         brcmf_update_bss_info(cfg, ifp);
4514                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4515                                 &ifp->vif->sme_state);
4516                 }
4517                 cfg80211_connect_result(ndev,
4518                                         (u8 *)profile->bssid,
4519                                         conn_info->req_ie,
4520                                         conn_info->req_ie_len,
4521                                         conn_info->resp_ie,
4522                                         conn_info->resp_ie_len,
4523                                         completed ? WLAN_STATUS_SUCCESS :
4524                                                     WLAN_STATUS_AUTH_TIMEOUT,
4525                                         GFP_KERNEL);
4526                 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4527                           completed ? "succeeded" : "failed");
4528         }
4529         brcmf_dbg(TRACE, "Exit\n");
4530         return 0;
4531 }
4532
4533 static s32
4534 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4535                                struct net_device *ndev,
4536                                const struct brcmf_event_msg *e, void *data)
4537 {
4538         static int generation;
4539         u32 event = e->event_code;
4540         u32 reason = e->reason;
4541         struct station_info sinfo;
4542
4543         brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4544         if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4545             ndev != cfg_to_ndev(cfg)) {
4546                 brcmf_dbg(CONN, "AP mode link down\n");
4547                 complete(&cfg->vif_disabled);
4548                 return 0;
4549         }
4550
4551         if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4552             (reason == BRCMF_E_STATUS_SUCCESS)) {
4553                 memset(&sinfo, 0, sizeof(sinfo));
4554                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4555                 if (!data) {
4556                         brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4557                         return -EINVAL;
4558                 }
4559                 sinfo.assoc_req_ies = data;
4560                 sinfo.assoc_req_ies_len = e->datalen;
4561                 generation++;
4562                 sinfo.generation = generation;
4563                 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4564         } else if ((event == BRCMF_E_DISASSOC_IND) ||
4565                    (event == BRCMF_E_DEAUTH_IND) ||
4566                    (event == BRCMF_E_DEAUTH)) {
4567                 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4568         }
4569         return 0;
4570 }
4571
4572 static s32
4573 brcmf_notify_connect_status(struct brcmf_if *ifp,
4574                             const struct brcmf_event_msg *e, void *data)
4575 {
4576         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4577         struct net_device *ndev = ifp->ndev;
4578         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4579         struct ieee80211_channel *chan;
4580         s32 err = 0;
4581
4582         if ((e->event_code == BRCMF_E_DEAUTH) ||
4583             (e->event_code == BRCMF_E_DEAUTH_IND) ||
4584             (e->event_code == BRCMF_E_DISASSOC_IND) ||
4585             ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
4586                 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4587         }
4588
4589         if (brcmf_is_apmode(ifp->vif)) {
4590                 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4591         } else if (brcmf_is_linkup(e)) {
4592                 brcmf_dbg(CONN, "Linkup\n");
4593                 if (brcmf_is_ibssmode(ifp->vif)) {
4594                         chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
4595                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4596                         wl_inform_ibss(cfg, ndev, e->addr);
4597                         cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
4598                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4599                                   &ifp->vif->sme_state);
4600                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4601                                 &ifp->vif->sme_state);
4602                 } else
4603                         brcmf_bss_connect_done(cfg, ndev, e, true);
4604         } else if (brcmf_is_linkdown(e)) {
4605                 brcmf_dbg(CONN, "Linkdown\n");
4606                 if (!brcmf_is_ibssmode(ifp->vif)) {
4607                         brcmf_bss_connect_done(cfg, ndev, e, false);
4608                 }
4609                 brcmf_link_down(ifp->vif);
4610                 brcmf_init_prof(ndev_to_prof(ndev));
4611                 if (ndev != cfg_to_ndev(cfg))
4612                         complete(&cfg->vif_disabled);
4613         } else if (brcmf_is_nonetwork(cfg, e)) {
4614                 if (brcmf_is_ibssmode(ifp->vif))
4615                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4616                                   &ifp->vif->sme_state);
4617                 else
4618                         brcmf_bss_connect_done(cfg, ndev, e, false);
4619         }
4620
4621         return err;
4622 }
4623
4624 static s32
4625 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4626                             const struct brcmf_event_msg *e, void *data)
4627 {
4628         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4629         u32 event = e->event_code;
4630         u32 status = e->status;
4631
4632         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4633                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4634                         brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4635                 else
4636                         brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4637         }
4638
4639         return 0;
4640 }
4641
4642 static s32
4643 brcmf_notify_mic_status(struct brcmf_if *ifp,
4644                         const struct brcmf_event_msg *e, void *data)
4645 {
4646         u16 flags = e->flags;
4647         enum nl80211_key_type key_type;
4648
4649         if (flags & BRCMF_EVENT_MSG_GROUP)
4650                 key_type = NL80211_KEYTYPE_GROUP;
4651         else
4652                 key_type = NL80211_KEYTYPE_PAIRWISE;
4653
4654         cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4655                                      NULL, GFP_KERNEL);
4656
4657         return 0;
4658 }
4659
4660 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4661                                   const struct brcmf_event_msg *e, void *data)
4662 {
4663         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4664         struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4665         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4666         struct brcmf_cfg80211_vif *vif;
4667
4668         brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4669                   ifevent->action, ifevent->flags, ifevent->ifidx,
4670                   ifevent->bssidx);
4671
4672         mutex_lock(&event->vif_event_lock);
4673         event->action = ifevent->action;
4674         vif = event->vif;
4675
4676         switch (ifevent->action) {
4677         case BRCMF_E_IF_ADD:
4678                 /* waiting process may have timed out */
4679                 if (!cfg->vif_event.vif) {
4680                         mutex_unlock(&event->vif_event_lock);
4681                         return -EBADF;
4682                 }
4683
4684                 ifp->vif = vif;
4685                 vif->ifp = ifp;
4686                 if (ifp->ndev) {
4687                         vif->wdev.netdev = ifp->ndev;
4688                         ifp->ndev->ieee80211_ptr = &vif->wdev;
4689                         SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4690                 }
4691                 mutex_unlock(&event->vif_event_lock);
4692                 wake_up(&event->vif_wq);
4693                 return 0;
4694
4695         case BRCMF_E_IF_DEL:
4696                 mutex_unlock(&event->vif_event_lock);
4697                 /* event may not be upon user request */
4698                 if (brcmf_cfg80211_vif_event_armed(cfg))
4699                         wake_up(&event->vif_wq);
4700                 return 0;
4701
4702         case BRCMF_E_IF_CHANGE:
4703                 mutex_unlock(&event->vif_event_lock);
4704                 wake_up(&event->vif_wq);
4705                 return 0;
4706
4707         default:
4708                 mutex_unlock(&event->vif_event_lock);
4709                 break;
4710         }
4711         return -EINVAL;
4712 }
4713
4714 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4715 {
4716         conf->frag_threshold = (u32)-1;
4717         conf->rts_threshold = (u32)-1;
4718         conf->retry_short = (u32)-1;
4719         conf->retry_long = (u32)-1;
4720         conf->tx_power = -1;
4721 }
4722
4723 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4724 {
4725         brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4726                             brcmf_notify_connect_status);
4727         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4728                             brcmf_notify_connect_status);
4729         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4730                             brcmf_notify_connect_status);
4731         brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4732                             brcmf_notify_connect_status);
4733         brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4734                             brcmf_notify_connect_status);
4735         brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4736                             brcmf_notify_connect_status);
4737         brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4738                             brcmf_notify_roaming_status);
4739         brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4740                             brcmf_notify_mic_status);
4741         brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4742                             brcmf_notify_connect_status);
4743         brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4744                             brcmf_notify_sched_scan_results);
4745         brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4746                             brcmf_notify_vif_event);
4747         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4748                             brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4749         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4750                             brcmf_p2p_notify_listen_complete);
4751         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4752                             brcmf_p2p_notify_action_frame_rx);
4753         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4754                             brcmf_p2p_notify_action_tx_complete);
4755         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4756                             brcmf_p2p_notify_action_tx_complete);
4757 }
4758
4759 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4760 {
4761         kfree(cfg->conf);
4762         cfg->conf = NULL;
4763         kfree(cfg->escan_ioctl_buf);
4764         cfg->escan_ioctl_buf = NULL;
4765         kfree(cfg->extra_buf);
4766         cfg->extra_buf = NULL;
4767         kfree(cfg->pmk_list);
4768         cfg->pmk_list = NULL;
4769 }
4770
4771 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4772 {
4773         cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4774         if (!cfg->conf)
4775                 goto init_priv_mem_out;
4776         cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4777         if (!cfg->escan_ioctl_buf)
4778                 goto init_priv_mem_out;
4779         cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4780         if (!cfg->extra_buf)
4781                 goto init_priv_mem_out;
4782         cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4783         if (!cfg->pmk_list)
4784                 goto init_priv_mem_out;
4785
4786         return 0;
4787
4788 init_priv_mem_out:
4789         brcmf_deinit_priv_mem(cfg);
4790
4791         return -ENOMEM;
4792 }
4793
4794 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4795 {
4796         s32 err = 0;
4797
4798         cfg->scan_request = NULL;
4799         cfg->pwr_save = true;
4800         cfg->active_scan = true;        /* we do active scan per default */
4801         cfg->dongle_up = false;         /* dongle is not up yet */
4802         err = brcmf_init_priv_mem(cfg);
4803         if (err)
4804                 return err;
4805         brcmf_register_event_handlers(cfg);
4806         mutex_init(&cfg->usr_sync);
4807         brcmf_init_escan(cfg);
4808         brcmf_init_conf(cfg->conf);
4809         init_completion(&cfg->vif_disabled);
4810         return err;
4811 }
4812
4813 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4814 {
4815         cfg->dongle_up = false; /* dongle down */
4816         brcmf_abort_scanning(cfg);
4817         brcmf_deinit_priv_mem(cfg);
4818 }
4819
4820 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4821 {
4822         init_waitqueue_head(&event->vif_wq);
4823         mutex_init(&event->vif_event_lock);
4824 }
4825
4826 static s32
4827 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
4828 {
4829         s32 err = 0;
4830         __le32 roamtrigger[2];
4831         __le32 roam_delta[2];
4832
4833         /*
4834          * Setup timeout if Beacons are lost and roam is
4835          * off to report link down
4836          */
4837         if (brcmf_roamoff) {
4838                 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4839                 if (err) {
4840                         brcmf_err("bcn_timeout error (%d)\n", err);
4841                         goto dongle_rom_out;
4842                 }
4843         }
4844
4845         /*
4846          * Enable/Disable built-in roaming to allow supplicant
4847          * to take care of roaming
4848          */
4849         brcmf_dbg(INFO, "Internal Roaming = %s\n",
4850                   brcmf_roamoff ? "Off" : "On");
4851         err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
4852         if (err) {
4853                 brcmf_err("roam_off error (%d)\n", err);
4854                 goto dongle_rom_out;
4855         }
4856
4857         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4858         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4859         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4860                                      (void *)roamtrigger, sizeof(roamtrigger));
4861         if (err) {
4862                 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4863                 goto dongle_rom_out;
4864         }
4865
4866         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4867         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4868         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4869                                      (void *)roam_delta, sizeof(roam_delta));
4870         if (err) {
4871                 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4872                 goto dongle_rom_out;
4873         }
4874
4875 dongle_rom_out:
4876         return err;
4877 }
4878
4879 static s32
4880 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
4881                       s32 scan_unassoc_time, s32 scan_passive_time)
4882 {
4883         s32 err = 0;
4884
4885         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4886                                     scan_assoc_time);
4887         if (err) {
4888                 if (err == -EOPNOTSUPP)
4889                         brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4890                 else
4891                         brcmf_err("Scan assoc time error (%d)\n", err);
4892                 goto dongle_scantime_out;
4893         }
4894         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4895                                     scan_unassoc_time);
4896         if (err) {
4897                 if (err == -EOPNOTSUPP)
4898                         brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4899                 else
4900                         brcmf_err("Scan unassoc time error (%d)\n", err);
4901                 goto dongle_scantime_out;
4902         }
4903
4904         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4905                                     scan_passive_time);
4906         if (err) {
4907                 if (err == -EOPNOTSUPP)
4908                         brcmf_dbg(INFO, "Scan passive time is not supported\n");
4909                 else
4910                         brcmf_err("Scan passive time error (%d)\n", err);
4911                 goto dongle_scantime_out;
4912         }
4913
4914 dongle_scantime_out:
4915         return err;
4916 }
4917
4918 /* Filter the list of channels received from firmware counting only
4919  * the 20MHz channels. The wiphy band data only needs those which get
4920  * flagged to indicate if they can take part in higher bandwidth.
4921  */
4922 static void brcmf_count_20mhz_channels(struct brcmf_cfg80211_info *cfg,
4923                                        struct brcmf_chanspec_list *chlist,
4924                                        u32 chcnt[])
4925 {
4926         u32 total = le32_to_cpu(chlist->count);
4927         struct brcmu_chan ch;
4928         int i;
4929
4930         for (i = 0; i < total; i++) {
4931                 ch.chspec = (u16)le32_to_cpu(chlist->element[i]);
4932                 cfg->d11inf.decchspec(&ch);
4933
4934                 /* Firmware gives a ordered list. We skip non-20MHz
4935                  * channels is 2G. For 5G we can abort upon reaching
4936                  * a non-20MHz channel in the list.
4937                  */
4938                 if (ch.bw != BRCMU_CHAN_BW_20) {
4939                         if (ch.band == BRCMU_CHAN_BAND_5G)
4940                                 break;
4941                         else
4942                                 continue;
4943                 }
4944
4945                 if (ch.band == BRCMU_CHAN_BAND_2G)
4946                         chcnt[0] += 1;
4947                 else if (ch.band == BRCMU_CHAN_BAND_5G)
4948                         chcnt[1] += 1;
4949         }
4950 }
4951
4952 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
4953                                            struct brcmu_chan *ch)
4954 {
4955         u32 ht40_flag;
4956
4957         ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
4958         if (ch->sb == BRCMU_CHAN_SB_U) {
4959                 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
4960                         channel->flags &= ~IEEE80211_CHAN_NO_HT40;
4961                 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
4962         } else {
4963                 /* It should be one of
4964                  * IEEE80211_CHAN_NO_HT40 or
4965                  * IEEE80211_CHAN_NO_HT40PLUS
4966                  */
4967                 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
4968                 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
4969                         channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
4970         }
4971 }
4972
4973 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
4974                                     u32 bw_cap[])
4975 {
4976         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4977         struct ieee80211_supported_band *band;
4978         struct ieee80211_channel *channel;
4979         struct wiphy *wiphy;
4980         struct brcmf_chanspec_list *list;
4981         struct brcmu_chan ch;
4982         int err;
4983         u8 *pbuf;
4984         u32 i, j;
4985         u32 total;
4986         u32 chaninfo;
4987         u32 chcnt[2] = { 0, 0 };
4988         u32 index;
4989
4990         pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4991
4992         if (pbuf == NULL)
4993                 return -ENOMEM;
4994
4995         list = (struct brcmf_chanspec_list *)pbuf;
4996
4997         err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
4998                                        BRCMF_DCMD_MEDLEN);
4999         if (err) {
5000                 brcmf_err("get chanspecs error (%d)\n", err);
5001                 goto fail_pbuf;
5002         }
5003
5004         brcmf_count_20mhz_channels(cfg, list, chcnt);
5005         wiphy = cfg_to_wiphy(cfg);
5006         if (chcnt[0]) {
5007                 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
5008                                GFP_KERNEL);
5009                 if (band == NULL) {
5010                         err = -ENOMEM;
5011                         goto fail_pbuf;
5012                 }
5013                 band->channels = kcalloc(chcnt[0], sizeof(*channel),
5014                                          GFP_KERNEL);
5015                 if (band->channels == NULL) {
5016                         kfree(band);
5017                         err = -ENOMEM;
5018                         goto fail_pbuf;
5019                 }
5020                 band->n_channels = 0;
5021                 wiphy->bands[IEEE80211_BAND_2GHZ] = band;
5022         }
5023         if (chcnt[1]) {
5024                 band = kmemdup(&__wl_band_5ghz_a, sizeof(__wl_band_5ghz_a),
5025                                GFP_KERNEL);
5026                 if (band == NULL) {
5027                         err = -ENOMEM;
5028                         goto fail_band2g;
5029                 }
5030                 band->channels = kcalloc(chcnt[1], sizeof(*channel),
5031                                          GFP_KERNEL);
5032                 if (band->channels == NULL) {
5033                         kfree(band);
5034                         err = -ENOMEM;
5035                         goto fail_band2g;
5036                 }
5037                 band->n_channels = 0;
5038                 wiphy->bands[IEEE80211_BAND_5GHZ] = band;
5039         }
5040
5041         total = le32_to_cpu(list->count);
5042         for (i = 0; i < total; i++) {
5043                 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5044                 cfg->d11inf.decchspec(&ch);
5045
5046                 if (ch.band == BRCMU_CHAN_BAND_2G) {
5047                         band = wiphy->bands[IEEE80211_BAND_2GHZ];
5048                 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5049                         band = wiphy->bands[IEEE80211_BAND_5GHZ];
5050                 } else {
5051                         brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5052                         continue;
5053                 }
5054                 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5055                     ch.bw == BRCMU_CHAN_BW_40)
5056                         continue;
5057                 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5058                     ch.bw == BRCMU_CHAN_BW_80)
5059                         continue;
5060
5061                 channel = band->channels;
5062                 index = band->n_channels;
5063                 for (j = 0; j < band->n_channels; j++) {
5064                         if (channel[j].hw_value == ch.chnum) {
5065                                 index = j;
5066                                 break;
5067                         }
5068                 }
5069                 channel[index].center_freq =
5070                         ieee80211_channel_to_frequency(ch.chnum, band->band);
5071                 channel[index].hw_value = ch.chnum;
5072
5073                 /* assuming the chanspecs order is HT20,
5074                  * HT40 upper, HT40 lower, and VHT80.
5075                  */
5076                 if (ch.bw == BRCMU_CHAN_BW_80) {
5077                         channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5078                 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5079                         brcmf_update_bw40_channel_flag(&channel[index], &ch);
5080                 } else {
5081                         /* disable other bandwidths for now as mentioned
5082                          * order assure they are enabled for subsequent
5083                          * chanspecs.
5084                          */
5085                         channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5086                                                IEEE80211_CHAN_NO_80MHZ;
5087                         ch.bw = BRCMU_CHAN_BW_20;
5088                         cfg->d11inf.encchspec(&ch);
5089                         chaninfo = ch.chspec;
5090                         err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5091                                                        &chaninfo);
5092                         if (!err) {
5093                                 if (chaninfo & WL_CHAN_RADAR)
5094                                         channel[index].flags |=
5095                                                 (IEEE80211_CHAN_RADAR |
5096                                                  IEEE80211_CHAN_NO_IR);
5097                                 if (chaninfo & WL_CHAN_PASSIVE)
5098                                         channel[index].flags |=
5099                                                 IEEE80211_CHAN_NO_IR;
5100                         }
5101                 }
5102                 if (index == band->n_channels)
5103                         band->n_channels++;
5104         }
5105         kfree(pbuf);
5106         return 0;
5107
5108 fail_band2g:
5109         kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
5110         kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
5111         wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
5112 fail_pbuf:
5113         kfree(pbuf);
5114         return err;
5115 }
5116
5117 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5118 {
5119         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5120         struct ieee80211_supported_band *band;
5121         struct brcmf_fil_bwcap_le band_bwcap;
5122         struct brcmf_chanspec_list *list;
5123         u8 *pbuf;
5124         u32 val;
5125         int err;
5126         struct brcmu_chan ch;
5127         u32 num_chan;
5128         int i, j;
5129
5130         /* verify support for bw_cap command */
5131         val = WLC_BAND_5G;
5132         err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5133
5134         if (!err) {
5135                 /* only set 2G bandwidth using bw_cap command */
5136                 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5137                 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5138                 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5139                                                sizeof(band_bwcap));
5140         } else {
5141                 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5142                 val = WLC_N_BW_40ALL;
5143                 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5144         }
5145
5146         if (!err) {
5147                 /* update channel info in 2G band */
5148                 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5149
5150                 if (pbuf == NULL)
5151                         return -ENOMEM;
5152
5153                 ch.band = BRCMU_CHAN_BAND_2G;
5154                 ch.bw = BRCMU_CHAN_BW_40;
5155                 ch.sb = BRCMU_CHAN_SB_NONE;
5156                 ch.chnum = 0;
5157                 cfg->d11inf.encchspec(&ch);
5158
5159                 /* pass encoded chanspec in query */
5160                 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5161
5162                 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5163                                                BRCMF_DCMD_MEDLEN);
5164                 if (err) {
5165                         brcmf_err("get chanspecs error (%d)\n", err);
5166                         kfree(pbuf);
5167                         return err;
5168                 }
5169
5170                 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5171                 list = (struct brcmf_chanspec_list *)pbuf;
5172                 num_chan = le32_to_cpu(list->count);
5173                 for (i = 0; i < num_chan; i++) {
5174                         ch.chspec = (u16)le32_to_cpu(list->element[i]);
5175                         cfg->d11inf.decchspec(&ch);
5176                         if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5177                                 continue;
5178                         if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5179                                 continue;
5180                         for (j = 0; j < band->n_channels; j++) {
5181                                 if (band->channels[j].hw_value == ch.chnum)
5182                                         break;
5183                         }
5184                         if (WARN_ON(j == band->n_channels))
5185                                 continue;
5186
5187                         brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5188                 }
5189                 kfree(pbuf);
5190         }
5191         return err;
5192 }
5193
5194 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5195 {
5196         u32 band, mimo_bwcap;
5197         int err;
5198
5199         band = WLC_BAND_2G;
5200         err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5201         if (!err) {
5202                 bw_cap[IEEE80211_BAND_2GHZ] = band;
5203                 band = WLC_BAND_5G;
5204                 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5205                 if (!err) {
5206                         bw_cap[IEEE80211_BAND_5GHZ] = band;
5207                         return;
5208                 }
5209                 WARN_ON(1);
5210                 return;
5211         }
5212         brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5213         mimo_bwcap = 0;
5214         err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5215         if (err)
5216                 /* assume 20MHz if firmware does not give a clue */
5217                 mimo_bwcap = WLC_N_BW_20ALL;
5218
5219         switch (mimo_bwcap) {
5220         case WLC_N_BW_40ALL:
5221                 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5222                 /* fall-thru */
5223         case WLC_N_BW_20IN2G_40IN5G:
5224                 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5225                 /* fall-thru */
5226         case WLC_N_BW_20ALL:
5227                 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5228                 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5229                 break;
5230         default:
5231                 brcmf_err("invalid mimo_bw_cap value\n");
5232         }
5233 }
5234
5235 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5236                                 u32 bw_cap[2], u32 nchain)
5237 {
5238         band->ht_cap.ht_supported = true;
5239         if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5240                 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5241                 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5242         }
5243         band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5244         band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5245         band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5246         band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5247         memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5248         band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5249 }
5250
5251 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5252 {
5253         u16 mcs_map;
5254         int i;
5255
5256         for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5257                 mcs_map = (mcs_map << 2) | supp;
5258
5259         return cpu_to_le16(mcs_map);
5260 }
5261
5262 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5263                                  u32 bw_cap[2], u32 nchain)
5264 {
5265         __le16 mcs_map;
5266
5267         /* not allowed in 2.4G band */
5268         if (band->band == IEEE80211_BAND_2GHZ)
5269                 return;
5270
5271         band->vht_cap.vht_supported = true;
5272         /* 80MHz is mandatory */
5273         band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5274         if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5275                 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5276                 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5277         }
5278         /* all support 256-QAM */
5279         mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5280         band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5281         band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5282 }
5283
5284 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5285 {
5286         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5287         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5288         u32 nmode = 0;
5289         u32 vhtmode = 0;
5290         u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5291         u32 rxchain;
5292         u32 nchain;
5293         int err;
5294         s32 i;
5295         struct ieee80211_supported_band *band;
5296
5297         (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5298         err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5299         if (err) {
5300                 brcmf_err("nmode error (%d)\n", err);
5301         } else {
5302                 brcmf_get_bwcap(ifp, bw_cap);
5303         }
5304         brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5305                   nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5306                   bw_cap[IEEE80211_BAND_5GHZ]);
5307
5308         err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5309         if (err) {
5310                 brcmf_err("rxchain error (%d)\n", err);
5311                 nchain = 1;
5312         } else {
5313                 for (nchain = 0; rxchain; nchain++)
5314                         rxchain = rxchain & (rxchain - 1);
5315         }
5316         brcmf_dbg(INFO, "nchain=%d\n", nchain);
5317
5318         err = brcmf_construct_chaninfo(cfg, bw_cap);
5319         if (err) {
5320                 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5321                 return err;
5322         }
5323
5324         wiphy = cfg_to_wiphy(cfg);
5325         for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5326                 band = wiphy->bands[i];
5327                 if (band == NULL)
5328                         continue;
5329
5330                 if (nmode)
5331                         brcmf_update_ht_cap(band, bw_cap, nchain);
5332                 if (vhtmode)
5333                         brcmf_update_vht_cap(band, bw_cap, nchain);
5334         }
5335
5336         return 0;
5337 }
5338
5339 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
5340         {
5341                 .max = 2,
5342                 .types = BIT(NL80211_IFTYPE_STATION) |
5343                          BIT(NL80211_IFTYPE_ADHOC) |
5344                          BIT(NL80211_IFTYPE_AP)
5345         },
5346         {
5347                 .max = 1,
5348                 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5349                          BIT(NL80211_IFTYPE_P2P_GO)
5350         },
5351         {
5352                 .max = 1,
5353                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
5354         }
5355 };
5356 static struct ieee80211_iface_combination brcmf_iface_combos[] = {
5357         {
5358                  .max_interfaces = BRCMF_IFACE_MAX_CNT,
5359                  .num_different_channels = 1,
5360                  .n_limits = ARRAY_SIZE(brcmf_iface_limits),
5361                  .limits = brcmf_iface_limits
5362         }
5363 };
5364
5365 static const struct ieee80211_txrx_stypes
5366 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5367         [NL80211_IFTYPE_STATION] = {
5368                 .tx = 0xffff,
5369                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5370                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5371         },
5372         [NL80211_IFTYPE_P2P_CLIENT] = {
5373                 .tx = 0xffff,
5374                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5375                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5376         },
5377         [NL80211_IFTYPE_P2P_GO] = {
5378                 .tx = 0xffff,
5379                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5380                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5381                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5382                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5383                       BIT(IEEE80211_STYPE_AUTH >> 4) |
5384                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5385                       BIT(IEEE80211_STYPE_ACTION >> 4)
5386         },
5387         [NL80211_IFTYPE_P2P_DEVICE] = {
5388                 .tx = 0xffff,
5389                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5390                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5391         }
5392 };
5393
5394 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5395 {
5396         /* scheduled scan settings */
5397         wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
5398         wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
5399         wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5400         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5401 }
5402
5403 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5404 {
5405         struct ieee80211_iface_combination ifc_combo;
5406         wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
5407         wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5408         wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
5409         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
5410                                  BIT(NL80211_IFTYPE_ADHOC) |
5411                                  BIT(NL80211_IFTYPE_AP) |
5412                                  BIT(NL80211_IFTYPE_P2P_CLIENT) |
5413                                  BIT(NL80211_IFTYPE_P2P_GO) |
5414                                  BIT(NL80211_IFTYPE_P2P_DEVICE);
5415         /* need VSDB firmware feature for concurrent channels */
5416         ifc_combo = brcmf_iface_combos[0];
5417         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5418                 ifc_combo.num_different_channels = 2;
5419         wiphy->iface_combinations = kmemdup(&ifc_combo,
5420                                             sizeof(ifc_combo),
5421                                             GFP_KERNEL);
5422         wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
5423         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5424         wiphy->cipher_suites = __wl_cipher_suites;
5425         wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
5426         wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
5427                         WIPHY_FLAG_OFFCHAN_TX |
5428                         WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5429                         WIPHY_FLAG_SUPPORTS_TDLS;
5430         if (!brcmf_roamoff)
5431                 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5432         wiphy->mgmt_stypes = brcmf_txrx_stypes;
5433         wiphy->max_remain_on_channel_duration = 5000;
5434         brcmf_wiphy_pno_params(wiphy);
5435
5436         /* vendor commands/events support */
5437         wiphy->vendor_commands = brcmf_vendor_cmds;
5438         wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
5439
5440         return brcmf_setup_wiphybands(wiphy);
5441 }
5442
5443 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5444 {
5445         struct net_device *ndev;
5446         struct wireless_dev *wdev;
5447         struct brcmf_if *ifp;
5448         s32 power_mode;
5449         s32 err = 0;
5450
5451         if (cfg->dongle_up)
5452                 return err;
5453
5454         ndev = cfg_to_ndev(cfg);
5455         wdev = ndev->ieee80211_ptr;
5456         ifp = netdev_priv(ndev);
5457
5458         /* make sure RF is ready for work */
5459         brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5460
5461         brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5462                               WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5463
5464         power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5465         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5466         if (err)
5467                 goto default_conf_out;
5468         brcmf_dbg(INFO, "power save set to %s\n",
5469                   (power_mode ? "enabled" : "disabled"));
5470
5471         err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5472         if (err)
5473                 goto default_conf_out;
5474         err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5475                                           NULL, NULL);
5476         if (err)
5477                 goto default_conf_out;
5478
5479         brcmf_configure_arp_offload(ifp, true);
5480
5481         cfg->dongle_up = true;
5482 default_conf_out:
5483
5484         return err;
5485
5486 }
5487
5488 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5489 {
5490         set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5491
5492         return brcmf_config_dongle(ifp->drvr->config);
5493 }
5494
5495 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5496 {
5497         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5498
5499         /*
5500          * While going down, if associated with AP disassociate
5501          * from AP to save power
5502          */
5503         if (check_vif_up(ifp->vif)) {
5504                 brcmf_link_down(ifp->vif);
5505
5506                 /* Make sure WPA_Supplicant receives all the event
5507                    generated due to DISASSOC call to the fw to keep
5508                    the state fw and WPA_Supplicant state consistent
5509                  */
5510                 brcmf_delay(500);
5511         }
5512
5513         brcmf_abort_scanning(cfg);
5514         clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5515
5516         return 0;
5517 }
5518
5519 s32 brcmf_cfg80211_up(struct net_device *ndev)
5520 {
5521         struct brcmf_if *ifp = netdev_priv(ndev);
5522         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5523         s32 err = 0;
5524
5525         mutex_lock(&cfg->usr_sync);
5526         err = __brcmf_cfg80211_up(ifp);
5527         mutex_unlock(&cfg->usr_sync);
5528
5529         return err;
5530 }
5531
5532 s32 brcmf_cfg80211_down(struct net_device *ndev)
5533 {
5534         struct brcmf_if *ifp = netdev_priv(ndev);
5535         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5536         s32 err = 0;
5537
5538         mutex_lock(&cfg->usr_sync);
5539         err = __brcmf_cfg80211_down(ifp);
5540         mutex_unlock(&cfg->usr_sync);
5541
5542         return err;
5543 }
5544
5545 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5546 {
5547         struct wireless_dev *wdev = &ifp->vif->wdev;
5548
5549         return wdev->iftype;
5550 }
5551
5552 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state)
5553 {
5554         struct brcmf_cfg80211_vif *vif;
5555
5556         list_for_each_entry(vif, &cfg->vif_list, list) {
5557                 if (test_bit(state, &vif->sme_state))
5558                         return true;
5559         }
5560         return false;
5561 }
5562
5563 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5564                                     u8 action)
5565 {
5566         u8 evt_action;
5567
5568         mutex_lock(&event->vif_event_lock);
5569         evt_action = event->action;
5570         mutex_unlock(&event->vif_event_lock);
5571         return evt_action == action;
5572 }
5573
5574 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5575                                   struct brcmf_cfg80211_vif *vif)
5576 {
5577         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5578
5579         mutex_lock(&event->vif_event_lock);
5580         event->vif = vif;
5581         event->action = 0;
5582         mutex_unlock(&event->vif_event_lock);
5583 }
5584
5585 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5586 {
5587         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5588         bool armed;
5589
5590         mutex_lock(&event->vif_event_lock);
5591         armed = event->vif != NULL;
5592         mutex_unlock(&event->vif_event_lock);
5593
5594         return armed;
5595 }
5596 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5597                                           u8 action, ulong timeout)
5598 {
5599         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5600
5601         return wait_event_timeout(event->vif_wq,
5602                                   vif_event_equals(event, action), timeout);
5603 }
5604
5605 static void brcmf_free_wiphy(struct wiphy *wiphy)
5606 {
5607         kfree(wiphy->iface_combinations);
5608         if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
5609                 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
5610                 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
5611         }
5612         if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
5613                 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
5614                 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
5615         }
5616         wiphy_free(wiphy);
5617 }
5618
5619 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
5620                                                   struct device *busdev)
5621 {
5622         struct net_device *ndev = drvr->iflist[0]->ndev;
5623         struct brcmf_cfg80211_info *cfg;
5624         struct wiphy *wiphy;
5625         struct brcmf_cfg80211_vif *vif;
5626         struct brcmf_if *ifp;
5627         s32 err = 0;
5628         s32 io_type;
5629         u16 *cap = NULL;
5630
5631         if (!ndev) {
5632                 brcmf_err("ndev is invalid\n");
5633                 return NULL;
5634         }
5635
5636         ifp = netdev_priv(ndev);
5637         wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
5638         if (!wiphy) {
5639                 brcmf_err("Could not allocate wiphy device\n");
5640                 return NULL;
5641         }
5642         set_wiphy_dev(wiphy, busdev);
5643
5644         cfg = wiphy_priv(wiphy);
5645         cfg->wiphy = wiphy;
5646         cfg->pub = drvr;
5647         init_vif_event(&cfg->vif_event);
5648         INIT_LIST_HEAD(&cfg->vif_list);
5649
5650         vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
5651         if (IS_ERR(vif))
5652                 goto wiphy_out;
5653
5654         vif->ifp = ifp;
5655         vif->wdev.netdev = ndev;
5656         ndev->ieee80211_ptr = &vif->wdev;
5657         SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
5658
5659         err = wl_init_priv(cfg);
5660         if (err) {
5661                 brcmf_err("Failed to init iwm_priv (%d)\n", err);
5662                 brcmf_free_vif(vif);
5663                 goto wiphy_out;
5664         }
5665         ifp->vif = vif;
5666
5667         /* determine d11 io type before wiphy setup */
5668         err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
5669         if (err) {
5670                 brcmf_err("Failed to get D11 version (%d)\n", err);
5671                 goto priv_out;
5672         }
5673         cfg->d11inf.io_type = (u8)io_type;
5674         brcmu_d11_attach(&cfg->d11inf);
5675
5676         err = brcmf_setup_wiphy(wiphy, ifp);
5677         if (err < 0)
5678                 goto priv_out;
5679
5680         brcmf_dbg(INFO, "Registering custom regulatory\n");
5681         wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
5682         wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5683
5684         /* firmware defaults to 40MHz disabled in 2G band. We signal
5685          * cfg80211 here that we do and have it decide we can enable
5686          * it. But first check if device does support 2G operation.
5687          */
5688         if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
5689                 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
5690                 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5691         }
5692         err = wiphy_register(wiphy);
5693         if (err < 0) {
5694                 brcmf_err("Could not register wiphy device (%d)\n", err);
5695                 goto priv_out;
5696         }
5697
5698         /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
5699          * setup 40MHz in 2GHz band and enable OBSS scanning.
5700          */
5701         if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
5702                 err = brcmf_enable_bw40_2g(cfg);
5703                 if (!err)
5704                         err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
5705                                                       BRCMF_OBSS_COEX_AUTO);
5706                 else
5707                         *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5708         }
5709
5710         err = brcmf_p2p_attach(cfg);
5711         if (err) {
5712                 brcmf_err("P2P initilisation failed (%d)\n", err);
5713                 goto wiphy_unreg_out;
5714         }
5715         err = brcmf_btcoex_attach(cfg);
5716         if (err) {
5717                 brcmf_err("BT-coex initialisation failed (%d)\n", err);
5718                 brcmf_p2p_detach(&cfg->p2p);
5719                 goto wiphy_unreg_out;
5720         }
5721
5722         err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
5723         if (err) {
5724                 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
5725                 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
5726         } else {
5727                 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
5728                                     brcmf_notify_tdls_peer_event);
5729         }
5730
5731         return cfg;
5732
5733 wiphy_unreg_out:
5734         wiphy_unregister(cfg->wiphy);
5735 priv_out:
5736         wl_deinit_priv(cfg);
5737         brcmf_free_vif(vif);
5738 wiphy_out:
5739         brcmf_free_wiphy(wiphy);
5740         return NULL;
5741 }
5742
5743 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5744 {
5745         if (!cfg)
5746                 return;
5747
5748         WARN_ON(!list_empty(&cfg->vif_list));
5749         wiphy_unregister(cfg->wiphy);
5750         brcmf_btcoex_detach(cfg);
5751         brcmf_p2p_detach(&cfg->p2p);
5752         wl_deinit_priv(cfg);
5753         brcmf_free_wiphy(cfg->wiphy);
5754 }