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