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