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