OSDN Git Service

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