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