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