OSDN Git Service

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