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