Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac802...
[platform/adaptation/renesas_rcar/renesas_kernel.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                         cfg80211_disconnected(vif->wdev.netdev, 0,
1099                                               NULL, 0, GFP_KERNEL);
1100                 }
1101                 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1102         }
1103         clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1104         clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1105         brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1106         brcmf_dbg(TRACE, "Exit\n");
1107 }
1108
1109 static s32
1110 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1111                       struct cfg80211_ibss_params *params)
1112 {
1113         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1114         struct brcmf_if *ifp = netdev_priv(ndev);
1115         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1116         struct brcmf_join_params join_params;
1117         size_t join_params_size = 0;
1118         s32 err = 0;
1119         s32 wsec = 0;
1120         s32 bcnprd;
1121         u16 chanspec;
1122
1123         brcmf_dbg(TRACE, "Enter\n");
1124         if (!check_vif_up(ifp->vif))
1125                 return -EIO;
1126
1127         if (params->ssid)
1128                 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1129         else {
1130                 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1131                 return -EOPNOTSUPP;
1132         }
1133
1134         set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1135
1136         if (params->bssid)
1137                 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1138         else
1139                 brcmf_dbg(CONN, "No BSSID specified\n");
1140
1141         if (params->chandef.chan)
1142                 brcmf_dbg(CONN, "channel: %d\n",
1143                           params->chandef.chan->center_freq);
1144         else
1145                 brcmf_dbg(CONN, "no channel specified\n");
1146
1147         if (params->channel_fixed)
1148                 brcmf_dbg(CONN, "fixed channel required\n");
1149         else
1150                 brcmf_dbg(CONN, "no fixed channel required\n");
1151
1152         if (params->ie && params->ie_len)
1153                 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1154         else
1155                 brcmf_dbg(CONN, "no ie specified\n");
1156
1157         if (params->beacon_interval)
1158                 brcmf_dbg(CONN, "beacon interval: %d\n",
1159                           params->beacon_interval);
1160         else
1161                 brcmf_dbg(CONN, "no beacon interval specified\n");
1162
1163         if (params->basic_rates)
1164                 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1165         else
1166                 brcmf_dbg(CONN, "no basic rates specified\n");
1167
1168         if (params->privacy)
1169                 brcmf_dbg(CONN, "privacy required\n");
1170         else
1171                 brcmf_dbg(CONN, "no privacy required\n");
1172
1173         /* Configure Privacy for starter */
1174         if (params->privacy)
1175                 wsec |= WEP_ENABLED;
1176
1177         err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1178         if (err) {
1179                 brcmf_err("wsec failed (%d)\n", err);
1180                 goto done;
1181         }
1182
1183         /* Configure Beacon Interval for starter */
1184         if (params->beacon_interval)
1185                 bcnprd = params->beacon_interval;
1186         else
1187                 bcnprd = 100;
1188
1189         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1190         if (err) {
1191                 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1192                 goto done;
1193         }
1194
1195         /* Configure required join parameter */
1196         memset(&join_params, 0, sizeof(struct brcmf_join_params));
1197
1198         /* SSID */
1199         profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1200         memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1201         memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1202         join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1203         join_params_size = sizeof(join_params.ssid_le);
1204
1205         /* BSSID */
1206         if (params->bssid) {
1207                 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1208                 join_params_size = sizeof(join_params.ssid_le) +
1209                                    BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1210                 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1211         } else {
1212                 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1213                 memset(profile->bssid, 0, ETH_ALEN);
1214         }
1215
1216         /* Channel */
1217         if (params->chandef.chan) {
1218                 u32 target_channel;
1219
1220                 cfg->channel =
1221                         ieee80211_frequency_to_channel(
1222                                 params->chandef.chan->center_freq);
1223                 if (params->channel_fixed) {
1224                         /* adding chanspec */
1225                         chanspec = channel_to_chanspec(&cfg->d11inf,
1226                                                        params->chandef.chan);
1227                         join_params.params_le.chanspec_list[0] =
1228                                 cpu_to_le16(chanspec);
1229                         join_params.params_le.chanspec_num = cpu_to_le32(1);
1230                         join_params_size += sizeof(join_params.params_le);
1231                 }
1232
1233                 /* set channel for starter */
1234                 target_channel = cfg->channel;
1235                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1236                                             target_channel);
1237                 if (err) {
1238                         brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1239                         goto done;
1240                 }
1241         } else
1242                 cfg->channel = 0;
1243
1244         cfg->ibss_starter = false;
1245
1246
1247         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1248                                      &join_params, join_params_size);
1249         if (err) {
1250                 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1251                 goto done;
1252         }
1253
1254 done:
1255         if (err)
1256                 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1257         brcmf_dbg(TRACE, "Exit\n");
1258         return err;
1259 }
1260
1261 static s32
1262 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1263 {
1264         struct brcmf_if *ifp = netdev_priv(ndev);
1265         s32 err = 0;
1266
1267         brcmf_dbg(TRACE, "Enter\n");
1268         if (!check_vif_up(ifp->vif))
1269                 return -EIO;
1270
1271         brcmf_link_down(ifp->vif);
1272
1273         brcmf_dbg(TRACE, "Exit\n");
1274
1275         return err;
1276 }
1277
1278 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1279                                  struct cfg80211_connect_params *sme)
1280 {
1281         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1282         struct brcmf_cfg80211_security *sec;
1283         s32 val = 0;
1284         s32 err = 0;
1285
1286         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1287                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1288         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1289                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1290         else
1291                 val = WPA_AUTH_DISABLED;
1292         brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1293         err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1294         if (err) {
1295                 brcmf_err("set wpa_auth failed (%d)\n", err);
1296                 return err;
1297         }
1298         sec = &profile->sec;
1299         sec->wpa_versions = sme->crypto.wpa_versions;
1300         return err;
1301 }
1302
1303 static s32 brcmf_set_auth_type(struct net_device *ndev,
1304                                struct cfg80211_connect_params *sme)
1305 {
1306         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1307         struct brcmf_cfg80211_security *sec;
1308         s32 val = 0;
1309         s32 err = 0;
1310
1311         switch (sme->auth_type) {
1312         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1313                 val = 0;
1314                 brcmf_dbg(CONN, "open system\n");
1315                 break;
1316         case NL80211_AUTHTYPE_SHARED_KEY:
1317                 val = 1;
1318                 brcmf_dbg(CONN, "shared key\n");
1319                 break;
1320         case NL80211_AUTHTYPE_AUTOMATIC:
1321                 val = 2;
1322                 brcmf_dbg(CONN, "automatic\n");
1323                 break;
1324         case NL80211_AUTHTYPE_NETWORK_EAP:
1325                 brcmf_dbg(CONN, "network eap\n");
1326         default:
1327                 val = 2;
1328                 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1329                 break;
1330         }
1331
1332         err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1333         if (err) {
1334                 brcmf_err("set auth failed (%d)\n", err);
1335                 return err;
1336         }
1337         sec = &profile->sec;
1338         sec->auth_type = sme->auth_type;
1339         return err;
1340 }
1341
1342 static s32
1343 brcmf_set_set_cipher(struct net_device *ndev,
1344                      struct cfg80211_connect_params *sme)
1345 {
1346         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1347         struct brcmf_cfg80211_security *sec;
1348         s32 pval = 0;
1349         s32 gval = 0;
1350         s32 err = 0;
1351
1352         if (sme->crypto.n_ciphers_pairwise) {
1353                 switch (sme->crypto.ciphers_pairwise[0]) {
1354                 case WLAN_CIPHER_SUITE_WEP40:
1355                 case WLAN_CIPHER_SUITE_WEP104:
1356                         pval = WEP_ENABLED;
1357                         break;
1358                 case WLAN_CIPHER_SUITE_TKIP:
1359                         pval = TKIP_ENABLED;
1360                         break;
1361                 case WLAN_CIPHER_SUITE_CCMP:
1362                         pval = AES_ENABLED;
1363                         break;
1364                 case WLAN_CIPHER_SUITE_AES_CMAC:
1365                         pval = AES_ENABLED;
1366                         break;
1367                 default:
1368                         brcmf_err("invalid cipher pairwise (%d)\n",
1369                                   sme->crypto.ciphers_pairwise[0]);
1370                         return -EINVAL;
1371                 }
1372         }
1373         if (sme->crypto.cipher_group) {
1374                 switch (sme->crypto.cipher_group) {
1375                 case WLAN_CIPHER_SUITE_WEP40:
1376                 case WLAN_CIPHER_SUITE_WEP104:
1377                         gval = WEP_ENABLED;
1378                         break;
1379                 case WLAN_CIPHER_SUITE_TKIP:
1380                         gval = TKIP_ENABLED;
1381                         break;
1382                 case WLAN_CIPHER_SUITE_CCMP:
1383                         gval = AES_ENABLED;
1384                         break;
1385                 case WLAN_CIPHER_SUITE_AES_CMAC:
1386                         gval = AES_ENABLED;
1387                         break;
1388                 default:
1389                         brcmf_err("invalid cipher group (%d)\n",
1390                                   sme->crypto.cipher_group);
1391                         return -EINVAL;
1392                 }
1393         }
1394
1395         brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1396         /* In case of privacy, but no security and WPS then simulate */
1397         /* setting AES. WPS-2.0 allows no security                   */
1398         if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1399             sme->privacy)
1400                 pval = AES_ENABLED;
1401         err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
1402         if (err) {
1403                 brcmf_err("error (%d)\n", err);
1404                 return err;
1405         }
1406
1407         sec = &profile->sec;
1408         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1409         sec->cipher_group = sme->crypto.cipher_group;
1410
1411         return err;
1412 }
1413
1414 static s32
1415 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1416 {
1417         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1418         struct brcmf_cfg80211_security *sec;
1419         s32 val = 0;
1420         s32 err = 0;
1421
1422         if (sme->crypto.n_akm_suites) {
1423                 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1424                                                "wpa_auth", &val);
1425                 if (err) {
1426                         brcmf_err("could not get wpa_auth (%d)\n", err);
1427                         return err;
1428                 }
1429                 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1430                         switch (sme->crypto.akm_suites[0]) {
1431                         case WLAN_AKM_SUITE_8021X:
1432                                 val = WPA_AUTH_UNSPECIFIED;
1433                                 break;
1434                         case WLAN_AKM_SUITE_PSK:
1435                                 val = WPA_AUTH_PSK;
1436                                 break;
1437                         default:
1438                                 brcmf_err("invalid cipher group (%d)\n",
1439                                           sme->crypto.cipher_group);
1440                                 return -EINVAL;
1441                         }
1442                 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1443                         switch (sme->crypto.akm_suites[0]) {
1444                         case WLAN_AKM_SUITE_8021X:
1445                                 val = WPA2_AUTH_UNSPECIFIED;
1446                                 break;
1447                         case WLAN_AKM_SUITE_PSK:
1448                                 val = WPA2_AUTH_PSK;
1449                                 break;
1450                         default:
1451                                 brcmf_err("invalid cipher group (%d)\n",
1452                                           sme->crypto.cipher_group);
1453                                 return -EINVAL;
1454                         }
1455                 }
1456
1457                 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1458                 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1459                                                "wpa_auth", val);
1460                 if (err) {
1461                         brcmf_err("could not set wpa_auth (%d)\n", err);
1462                         return err;
1463                 }
1464         }
1465         sec = &profile->sec;
1466         sec->wpa_auth = sme->crypto.akm_suites[0];
1467
1468         return err;
1469 }
1470
1471 static s32
1472 brcmf_set_sharedkey(struct net_device *ndev,
1473                     struct cfg80211_connect_params *sme)
1474 {
1475         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1476         struct brcmf_cfg80211_security *sec;
1477         struct brcmf_wsec_key key;
1478         s32 val;
1479         s32 err = 0;
1480
1481         brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1482
1483         if (sme->key_len == 0)
1484                 return 0;
1485
1486         sec = &profile->sec;
1487         brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1488                   sec->wpa_versions, sec->cipher_pairwise);
1489
1490         if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1491                 return 0;
1492
1493         if (!(sec->cipher_pairwise &
1494             (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1495                 return 0;
1496
1497         memset(&key, 0, sizeof(key));
1498         key.len = (u32) sme->key_len;
1499         key.index = (u32) sme->key_idx;
1500         if (key.len > sizeof(key.data)) {
1501                 brcmf_err("Too long key length (%u)\n", key.len);
1502                 return -EINVAL;
1503         }
1504         memcpy(key.data, sme->key, key.len);
1505         key.flags = BRCMF_PRIMARY_KEY;
1506         switch (sec->cipher_pairwise) {
1507         case WLAN_CIPHER_SUITE_WEP40:
1508                 key.algo = CRYPTO_ALGO_WEP1;
1509                 break;
1510         case WLAN_CIPHER_SUITE_WEP104:
1511                 key.algo = CRYPTO_ALGO_WEP128;
1512                 break;
1513         default:
1514                 brcmf_err("Invalid algorithm (%d)\n",
1515                           sme->crypto.ciphers_pairwise[0]);
1516                 return -EINVAL;
1517         }
1518         /* Set the new key/index */
1519         brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1520                   key.len, key.index, key.algo);
1521         brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1522         err = send_key_to_dongle(ndev, &key);
1523         if (err)
1524                 return err;
1525
1526         if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1527                 brcmf_dbg(CONN, "set auth_type to shared key\n");
1528                 val = WL_AUTH_SHARED_KEY;       /* shared key */
1529                 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1530                 if (err)
1531                         brcmf_err("set auth failed (%d)\n", err);
1532         }
1533         return err;
1534 }
1535
1536 static
1537 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1538                                            enum nl80211_auth_type type)
1539 {
1540         u32 ci;
1541         if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1542                 /* shift to ignore chip revision */
1543                 ci = brcmf_get_chip_info(ifp) >> 4;
1544                 switch (ci) {
1545                 case 43236:
1546                         brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1547                         return NL80211_AUTHTYPE_OPEN_SYSTEM;
1548                 default:
1549                         break;
1550                 }
1551         }
1552         return type;
1553 }
1554
1555 static s32
1556 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1557                        struct cfg80211_connect_params *sme)
1558 {
1559         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1560         struct brcmf_if *ifp = netdev_priv(ndev);
1561         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1562         struct ieee80211_channel *chan = sme->channel;
1563         struct brcmf_join_params join_params;
1564         size_t join_params_size;
1565         struct brcmf_tlv *rsn_ie;
1566         struct brcmf_vs_tlv *wpa_ie;
1567         void *ie;
1568         u32 ie_len;
1569         struct brcmf_ext_join_params_le *ext_join_params;
1570         u16 chanspec;
1571
1572         s32 err = 0;
1573
1574         brcmf_dbg(TRACE, "Enter\n");
1575         if (!check_vif_up(ifp->vif))
1576                 return -EIO;
1577
1578         if (!sme->ssid) {
1579                 brcmf_err("Invalid ssid\n");
1580                 return -EOPNOTSUPP;
1581         }
1582
1583         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1584                 /* A normal (non P2P) connection request setup. */
1585                 ie = NULL;
1586                 ie_len = 0;
1587                 /* find the WPA_IE */
1588                 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1589                 if (wpa_ie) {
1590                         ie = wpa_ie;
1591                         ie_len = wpa_ie->len + TLV_HDR_LEN;
1592                 } else {
1593                         /* find the RSN_IE */
1594                         rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
1595                                                   WLAN_EID_RSN);
1596                         if (rsn_ie) {
1597                                 ie = rsn_ie;
1598                                 ie_len = rsn_ie->len + TLV_HDR_LEN;
1599                         }
1600                 }
1601                 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1602         }
1603
1604         err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1605                                     sme->ie, sme->ie_len);
1606         if (err)
1607                 brcmf_err("Set Assoc REQ IE Failed\n");
1608         else
1609                 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1610
1611         set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1612
1613         if (chan) {
1614                 cfg->channel =
1615                         ieee80211_frequency_to_channel(chan->center_freq);
1616                 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1617                 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1618                           cfg->channel, chan->center_freq, chanspec);
1619         } else {
1620                 cfg->channel = 0;
1621                 chanspec = 0;
1622         }
1623
1624         brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1625
1626         err = brcmf_set_wpa_version(ndev, sme);
1627         if (err) {
1628                 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1629                 goto done;
1630         }
1631
1632         sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1633         err = brcmf_set_auth_type(ndev, sme);
1634         if (err) {
1635                 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1636                 goto done;
1637         }
1638
1639         err = brcmf_set_set_cipher(ndev, sme);
1640         if (err) {
1641                 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1642                 goto done;
1643         }
1644
1645         err = brcmf_set_key_mgmt(ndev, sme);
1646         if (err) {
1647                 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1648                 goto done;
1649         }
1650
1651         err = brcmf_set_sharedkey(ndev, sme);
1652         if (err) {
1653                 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1654                 goto done;
1655         }
1656
1657         profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1658                                        (u32)sme->ssid_len);
1659         memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1660         if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1661                 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1662                 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1663                           profile->ssid.SSID_len);
1664         }
1665
1666         /* Join with specific BSSID and cached SSID
1667          * If SSID is zero join based on BSSID only
1668          */
1669         join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1670                 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1671         if (cfg->channel)
1672                 join_params_size += sizeof(u16);
1673         ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1674         if (ext_join_params == NULL) {
1675                 err = -ENOMEM;
1676                 goto done;
1677         }
1678         ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1679         memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1680                profile->ssid.SSID_len);
1681         /*increase dwell time to receive probe response or detect Beacon
1682          * from target AP at a noisy air only during connect command
1683          */
1684         ext_join_params->scan_le.active_time =
1685                 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1686         ext_join_params->scan_le.passive_time =
1687                 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1688         /* Set up join scan parameters */
1689         ext_join_params->scan_le.scan_type = -1;
1690         /* to sync with presence period of VSDB GO.
1691          * Send probe request more frequently. Probe request will be stopped
1692          * when it gets probe response from target AP/GO.
1693          */
1694         ext_join_params->scan_le.nprobes =
1695                 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1696                             BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1697         ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1698
1699         if (sme->bssid)
1700                 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1701         else
1702                 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1703
1704         if (cfg->channel) {
1705                 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1706
1707                 ext_join_params->assoc_le.chanspec_list[0] =
1708                         cpu_to_le16(chanspec);
1709         }
1710
1711         err  = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1712                                          join_params_size);
1713         kfree(ext_join_params);
1714         if (!err)
1715                 /* This is it. join command worked, we are done */
1716                 goto done;
1717
1718         /* join command failed, fallback to set ssid */
1719         memset(&join_params, 0, sizeof(join_params));
1720         join_params_size = sizeof(join_params.ssid_le);
1721
1722         memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1723         join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1724
1725         if (sme->bssid)
1726                 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1727         else
1728                 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1729
1730         if (cfg->channel) {
1731                 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1732                 join_params.params_le.chanspec_num = cpu_to_le32(1);
1733                 join_params_size += sizeof(join_params.params_le);
1734         }
1735         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1736                                      &join_params, join_params_size);
1737         if (err)
1738                 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1739
1740 done:
1741         if (err)
1742                 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1743         brcmf_dbg(TRACE, "Exit\n");
1744         return err;
1745 }
1746
1747 static s32
1748 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1749                        u16 reason_code)
1750 {
1751         struct brcmf_if *ifp = netdev_priv(ndev);
1752         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1753         struct brcmf_scb_val_le scbval;
1754         s32 err = 0;
1755
1756         brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1757         if (!check_vif_up(ifp->vif))
1758                 return -EIO;
1759
1760         clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1761
1762         memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1763         scbval.val = cpu_to_le32(reason_code);
1764         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1765                                      &scbval, sizeof(scbval));
1766         if (err)
1767                 brcmf_err("error (%d)\n", err);
1768
1769         brcmf_dbg(TRACE, "Exit\n");
1770         return err;
1771 }
1772
1773 static s32
1774 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1775                             enum nl80211_tx_power_setting type, s32 mbm)
1776 {
1777
1778         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1779         struct net_device *ndev = cfg_to_ndev(cfg);
1780         struct brcmf_if *ifp = netdev_priv(ndev);
1781         u16 txpwrmw;
1782         s32 err = 0;
1783         s32 disable = 0;
1784         s32 dbm = MBM_TO_DBM(mbm);
1785
1786         brcmf_dbg(TRACE, "Enter\n");
1787         if (!check_vif_up(ifp->vif))
1788                 return -EIO;
1789
1790         switch (type) {
1791         case NL80211_TX_POWER_AUTOMATIC:
1792                 break;
1793         case NL80211_TX_POWER_LIMITED:
1794         case NL80211_TX_POWER_FIXED:
1795                 if (dbm < 0) {
1796                         brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1797                         err = -EINVAL;
1798                         goto done;
1799                 }
1800                 break;
1801         }
1802         /* Make sure radio is off or on as far as software is concerned */
1803         disable = WL_RADIO_SW_DISABLE << 16;
1804         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1805         if (err)
1806                 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1807
1808         if (dbm > 0xffff)
1809                 txpwrmw = 0xffff;
1810         else
1811                 txpwrmw = (u16) dbm;
1812         err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1813                                       (s32)brcmf_mw_to_qdbm(txpwrmw));
1814         if (err)
1815                 brcmf_err("qtxpower error (%d)\n", err);
1816         cfg->conf->tx_power = dbm;
1817
1818 done:
1819         brcmf_dbg(TRACE, "Exit\n");
1820         return err;
1821 }
1822
1823 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1824                                        struct wireless_dev *wdev,
1825                                        s32 *dbm)
1826 {
1827         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1828         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1829         s32 txpwrdbm;
1830         u8 result;
1831         s32 err = 0;
1832
1833         brcmf_dbg(TRACE, "Enter\n");
1834         if (!check_vif_up(ifp->vif))
1835                 return -EIO;
1836
1837         err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1838         if (err) {
1839                 brcmf_err("error (%d)\n", err);
1840                 goto done;
1841         }
1842
1843         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1844         *dbm = (s32) brcmf_qdbm_to_mw(result);
1845
1846 done:
1847         brcmf_dbg(TRACE, "Exit\n");
1848         return err;
1849 }
1850
1851 static s32
1852 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1853                                u8 key_idx, bool unicast, bool multicast)
1854 {
1855         struct brcmf_if *ifp = netdev_priv(ndev);
1856         u32 index;
1857         u32 wsec;
1858         s32 err = 0;
1859
1860         brcmf_dbg(TRACE, "Enter\n");
1861         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1862         if (!check_vif_up(ifp->vif))
1863                 return -EIO;
1864
1865         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1866         if (err) {
1867                 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1868                 goto done;
1869         }
1870
1871         if (wsec & WEP_ENABLED) {
1872                 /* Just select a new current key */
1873                 index = key_idx;
1874                 err = brcmf_fil_cmd_int_set(ifp,
1875                                             BRCMF_C_SET_KEY_PRIMARY, index);
1876                 if (err)
1877                         brcmf_err("error (%d)\n", err);
1878         }
1879 done:
1880         brcmf_dbg(TRACE, "Exit\n");
1881         return err;
1882 }
1883
1884 static s32
1885 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1886               u8 key_idx, const u8 *mac_addr, struct key_params *params)
1887 {
1888         struct brcmf_if *ifp = netdev_priv(ndev);
1889         struct brcmf_wsec_key key;
1890         s32 err = 0;
1891         u8 keybuf[8];
1892
1893         memset(&key, 0, sizeof(key));
1894         key.index = (u32) key_idx;
1895         /* Instead of bcast for ea address for default wep keys,
1896                  driver needs it to be Null */
1897         if (!is_multicast_ether_addr(mac_addr))
1898                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1899         key.len = (u32) params->key_len;
1900         /* check for key index change */
1901         if (key.len == 0) {
1902                 /* key delete */
1903                 err = send_key_to_dongle(ndev, &key);
1904                 if (err)
1905                         brcmf_err("key delete error (%d)\n", err);
1906         } else {
1907                 if (key.len > sizeof(key.data)) {
1908                         brcmf_err("Invalid key length (%d)\n", key.len);
1909                         return -EINVAL;
1910                 }
1911
1912                 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1913                 memcpy(key.data, params->key, key.len);
1914
1915                 if ((ifp->vif->mode != WL_MODE_AP) &&
1916                     (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1917                         brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1918                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1919                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1920                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1921                 }
1922
1923                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1924                 if (params->seq && params->seq_len == 6) {
1925                         /* rx iv */
1926                         u8 *ivptr;
1927                         ivptr = (u8 *) params->seq;
1928                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1929                             (ivptr[3] << 8) | ivptr[2];
1930                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1931                         key.iv_initialized = true;
1932                 }
1933
1934                 switch (params->cipher) {
1935                 case WLAN_CIPHER_SUITE_WEP40:
1936                         key.algo = CRYPTO_ALGO_WEP1;
1937                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1938                         break;
1939                 case WLAN_CIPHER_SUITE_WEP104:
1940                         key.algo = CRYPTO_ALGO_WEP128;
1941                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1942                         break;
1943                 case WLAN_CIPHER_SUITE_TKIP:
1944                         key.algo = CRYPTO_ALGO_TKIP;
1945                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1946                         break;
1947                 case WLAN_CIPHER_SUITE_AES_CMAC:
1948                         key.algo = CRYPTO_ALGO_AES_CCM;
1949                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1950                         break;
1951                 case WLAN_CIPHER_SUITE_CCMP:
1952                         key.algo = CRYPTO_ALGO_AES_CCM;
1953                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1954                         break;
1955                 default:
1956                         brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1957                         return -EINVAL;
1958                 }
1959                 err = send_key_to_dongle(ndev, &key);
1960                 if (err)
1961                         brcmf_err("wsec_key error (%d)\n", err);
1962         }
1963         return err;
1964 }
1965
1966 static s32
1967 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1968                     u8 key_idx, bool pairwise, const u8 *mac_addr,
1969                     struct key_params *params)
1970 {
1971         struct brcmf_if *ifp = netdev_priv(ndev);
1972         struct brcmf_wsec_key key;
1973         s32 val;
1974         s32 wsec;
1975         s32 err = 0;
1976         u8 keybuf[8];
1977
1978         brcmf_dbg(TRACE, "Enter\n");
1979         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1980         if (!check_vif_up(ifp->vif))
1981                 return -EIO;
1982
1983         if (mac_addr) {
1984                 brcmf_dbg(TRACE, "Exit");
1985                 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1986         }
1987         memset(&key, 0, sizeof(key));
1988
1989         key.len = (u32) params->key_len;
1990         key.index = (u32) key_idx;
1991
1992         if (key.len > sizeof(key.data)) {
1993                 brcmf_err("Too long key length (%u)\n", key.len);
1994                 err = -EINVAL;
1995                 goto done;
1996         }
1997         memcpy(key.data, params->key, key.len);
1998
1999         key.flags = BRCMF_PRIMARY_KEY;
2000         switch (params->cipher) {
2001         case WLAN_CIPHER_SUITE_WEP40:
2002                 key.algo = CRYPTO_ALGO_WEP1;
2003                 val = WEP_ENABLED;
2004                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2005                 break;
2006         case WLAN_CIPHER_SUITE_WEP104:
2007                 key.algo = CRYPTO_ALGO_WEP128;
2008                 val = WEP_ENABLED;
2009                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2010                 break;
2011         case WLAN_CIPHER_SUITE_TKIP:
2012                 if (ifp->vif->mode != WL_MODE_AP) {
2013                         brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2014                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
2015                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2016                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
2017                 }
2018                 key.algo = CRYPTO_ALGO_TKIP;
2019                 val = TKIP_ENABLED;
2020                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2021                 break;
2022         case WLAN_CIPHER_SUITE_AES_CMAC:
2023                 key.algo = CRYPTO_ALGO_AES_CCM;
2024                 val = AES_ENABLED;
2025                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2026                 break;
2027         case WLAN_CIPHER_SUITE_CCMP:
2028                 key.algo = CRYPTO_ALGO_AES_CCM;
2029                 val = AES_ENABLED;
2030                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2031                 break;
2032         default:
2033                 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2034                 err = -EINVAL;
2035                 goto done;
2036         }
2037
2038         err = send_key_to_dongle(ndev, &key);
2039         if (err)
2040                 goto done;
2041
2042         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2043         if (err) {
2044                 brcmf_err("get wsec error (%d)\n", err);
2045                 goto done;
2046         }
2047         wsec |= val;
2048         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2049         if (err) {
2050                 brcmf_err("set wsec error (%d)\n", err);
2051                 goto done;
2052         }
2053
2054 done:
2055         brcmf_dbg(TRACE, "Exit\n");
2056         return err;
2057 }
2058
2059 static s32
2060 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2061                     u8 key_idx, bool pairwise, const u8 *mac_addr)
2062 {
2063         struct brcmf_if *ifp = netdev_priv(ndev);
2064         struct brcmf_wsec_key key;
2065         s32 err = 0;
2066
2067         brcmf_dbg(TRACE, "Enter\n");
2068         if (!check_vif_up(ifp->vif))
2069                 return -EIO;
2070
2071         if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2072                 /* we ignore this key index in this case */
2073                 brcmf_err("invalid key index (%d)\n", key_idx);
2074                 return -EINVAL;
2075         }
2076
2077         memset(&key, 0, sizeof(key));
2078
2079         key.index = (u32) key_idx;
2080         key.flags = BRCMF_PRIMARY_KEY;
2081         key.algo = CRYPTO_ALGO_OFF;
2082
2083         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2084
2085         /* Set the new key/index */
2086         err = send_key_to_dongle(ndev, &key);
2087
2088         brcmf_dbg(TRACE, "Exit\n");
2089         return err;
2090 }
2091
2092 static s32
2093 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2094                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2095                     void (*callback) (void *cookie, struct key_params * params))
2096 {
2097         struct key_params params;
2098         struct brcmf_if *ifp = netdev_priv(ndev);
2099         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2100         struct brcmf_cfg80211_security *sec;
2101         s32 wsec;
2102         s32 err = 0;
2103
2104         brcmf_dbg(TRACE, "Enter\n");
2105         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2106         if (!check_vif_up(ifp->vif))
2107                 return -EIO;
2108
2109         memset(&params, 0, sizeof(params));
2110
2111         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2112         if (err) {
2113                 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2114                 /* Ignore this error, may happen during DISASSOC */
2115                 err = -EAGAIN;
2116                 goto done;
2117         }
2118         if (wsec & WEP_ENABLED) {
2119                 sec = &profile->sec;
2120                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2121                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
2122                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2123                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2124                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
2125                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2126                 }
2127         } else if (wsec & TKIP_ENABLED) {
2128                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2129                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2130         } else if (wsec & AES_ENABLED) {
2131                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2132                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2133         } else  {
2134                 brcmf_err("Invalid algo (0x%x)\n", wsec);
2135                 err = -EINVAL;
2136                 goto done;
2137         }
2138         callback(cookie, &params);
2139
2140 done:
2141         brcmf_dbg(TRACE, "Exit\n");
2142         return err;
2143 }
2144
2145 static s32
2146 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2147                                     struct net_device *ndev, u8 key_idx)
2148 {
2149         brcmf_dbg(INFO, "Not supported\n");
2150
2151         return -EOPNOTSUPP;
2152 }
2153
2154 static s32
2155 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2156                            u8 *mac, struct station_info *sinfo)
2157 {
2158         struct brcmf_if *ifp = netdev_priv(ndev);
2159         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2160         struct brcmf_scb_val_le scb_val;
2161         int rssi;
2162         s32 rate;
2163         s32 err = 0;
2164         u8 *bssid = profile->bssid;
2165         struct brcmf_sta_info_le sta_info_le;
2166
2167         brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2168         if (!check_vif_up(ifp->vif))
2169                 return -EIO;
2170
2171         if (ifp->vif->mode == WL_MODE_AP) {
2172                 memcpy(&sta_info_le, mac, ETH_ALEN);
2173                 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2174                                                &sta_info_le,
2175                                                sizeof(sta_info_le));
2176                 if (err < 0) {
2177                         brcmf_err("GET STA INFO failed, %d\n", err);
2178                         goto done;
2179                 }
2180                 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2181                 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2182                 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2183                         sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2184                         sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2185                 }
2186                 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2187                           sinfo->inactive_time, sinfo->connected_time);
2188         } else if (ifp->vif->mode == WL_MODE_BSS) {
2189                 if (memcmp(mac, bssid, ETH_ALEN)) {
2190                         brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2191                                   mac, bssid);
2192                         err = -ENOENT;
2193                         goto done;
2194                 }
2195                 /* Report the current tx rate */
2196                 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2197                 if (err) {
2198                         brcmf_err("Could not get rate (%d)\n", err);
2199                         goto done;
2200                 } else {
2201                         sinfo->filled |= STATION_INFO_TX_BITRATE;
2202                         sinfo->txrate.legacy = rate * 5;
2203                         brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2204                 }
2205
2206                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2207                              &ifp->vif->sme_state)) {
2208                         memset(&scb_val, 0, sizeof(scb_val));
2209                         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2210                                                      &scb_val, sizeof(scb_val));
2211                         if (err) {
2212                                 brcmf_err("Could not get rssi (%d)\n", err);
2213                                 goto done;
2214                         } else {
2215                                 rssi = le32_to_cpu(scb_val.val);
2216                                 sinfo->filled |= STATION_INFO_SIGNAL;
2217                                 sinfo->signal = rssi;
2218                                 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2219                         }
2220                 }
2221         } else
2222                 err = -EPERM;
2223 done:
2224         brcmf_dbg(TRACE, "Exit\n");
2225         return err;
2226 }
2227
2228 static s32
2229 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2230                            bool enabled, s32 timeout)
2231 {
2232         s32 pm;
2233         s32 err = 0;
2234         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2235         struct brcmf_if *ifp = netdev_priv(ndev);
2236
2237         brcmf_dbg(TRACE, "Enter\n");
2238
2239         /*
2240          * Powersave enable/disable request is coming from the
2241          * cfg80211 even before the interface is up. In that
2242          * scenario, driver will be storing the power save
2243          * preference in cfg struct to apply this to
2244          * FW later while initializing the dongle
2245          */
2246         cfg->pwr_save = enabled;
2247         if (!check_vif_up(ifp->vif)) {
2248
2249                 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2250                 goto done;
2251         }
2252
2253         pm = enabled ? PM_FAST : PM_OFF;
2254         /* Do not enable the power save after assoc if it is a p2p interface */
2255         if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2256                 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2257                 pm = PM_OFF;
2258         }
2259         brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2260
2261         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2262         if (err) {
2263                 if (err == -ENODEV)
2264                         brcmf_err("net_device is not ready yet\n");
2265                 else
2266                         brcmf_err("error (%d)\n", err);
2267         }
2268 done:
2269         brcmf_dbg(TRACE, "Exit\n");
2270         return err;
2271 }
2272
2273 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2274                                    struct brcmf_bss_info_le *bi)
2275 {
2276         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2277         struct ieee80211_channel *notify_channel;
2278         struct cfg80211_bss *bss;
2279         struct ieee80211_supported_band *band;
2280         struct brcmu_chan ch;
2281         s32 err = 0;
2282         u16 channel;
2283         u32 freq;
2284         u16 notify_capability;
2285         u16 notify_interval;
2286         u8 *notify_ie;
2287         size_t notify_ielen;
2288         s32 notify_signal;
2289
2290         if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2291                 brcmf_err("Bss info is larger than buffer. Discarding\n");
2292                 return 0;
2293         }
2294
2295         if (!bi->ctl_ch) {
2296                 ch.chspec = le16_to_cpu(bi->chanspec);
2297                 cfg->d11inf.decchspec(&ch);
2298                 bi->ctl_ch = ch.chnum;
2299         }
2300         channel = bi->ctl_ch;
2301
2302         if (channel <= CH_MAX_2G_CHANNEL)
2303                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2304         else
2305                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2306
2307         freq = ieee80211_channel_to_frequency(channel, band->band);
2308         notify_channel = ieee80211_get_channel(wiphy, freq);
2309
2310         notify_capability = le16_to_cpu(bi->capability);
2311         notify_interval = le16_to_cpu(bi->beacon_period);
2312         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2313         notify_ielen = le32_to_cpu(bi->ie_length);
2314         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2315
2316         brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2317         brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2318         brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2319         brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2320         brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2321
2322         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2323                 0, notify_capability, notify_interval, notify_ie,
2324                 notify_ielen, notify_signal, GFP_KERNEL);
2325
2326         if (!bss)
2327                 return -ENOMEM;
2328
2329         cfg80211_put_bss(wiphy, bss);
2330
2331         return err;
2332 }
2333
2334 static struct brcmf_bss_info_le *
2335 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2336 {
2337         if (bss == NULL)
2338                 return list->bss_info_le;
2339         return (struct brcmf_bss_info_le *)((unsigned long)bss +
2340                                             le32_to_cpu(bss->length));
2341 }
2342
2343 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2344 {
2345         struct brcmf_scan_results *bss_list;
2346         struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2347         s32 err = 0;
2348         int i;
2349
2350         bss_list = cfg->bss_list;
2351         if (bss_list->count != 0 &&
2352             bss_list->version != BRCMF_BSS_INFO_VERSION) {
2353                 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2354                           bss_list->version);
2355                 return -EOPNOTSUPP;
2356         }
2357         brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2358         for (i = 0; i < bss_list->count; i++) {
2359                 bi = next_bss_le(bss_list, bi);
2360                 err = brcmf_inform_single_bss(cfg, bi);
2361                 if (err)
2362                         break;
2363         }
2364         return err;
2365 }
2366
2367 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2368                           struct net_device *ndev, const u8 *bssid)
2369 {
2370         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2371         struct ieee80211_channel *notify_channel;
2372         struct brcmf_bss_info_le *bi = NULL;
2373         struct ieee80211_supported_band *band;
2374         struct cfg80211_bss *bss;
2375         struct brcmu_chan ch;
2376         u8 *buf = NULL;
2377         s32 err = 0;
2378         u32 freq;
2379         u16 notify_capability;
2380         u16 notify_interval;
2381         u8 *notify_ie;
2382         size_t notify_ielen;
2383         s32 notify_signal;
2384
2385         brcmf_dbg(TRACE, "Enter\n");
2386
2387         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2388         if (buf == NULL) {
2389                 err = -ENOMEM;
2390                 goto CleanUp;
2391         }
2392
2393         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2394
2395         err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2396                                      buf, WL_BSS_INFO_MAX);
2397         if (err) {
2398                 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2399                 goto CleanUp;
2400         }
2401
2402         bi = (struct brcmf_bss_info_le *)(buf + 4);
2403
2404         ch.chspec = le16_to_cpu(bi->chanspec);
2405         cfg->d11inf.decchspec(&ch);
2406
2407         if (ch.band == BRCMU_CHAN_BAND_2G)
2408                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2409         else
2410                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2411
2412         freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2413         notify_channel = ieee80211_get_channel(wiphy, freq);
2414
2415         notify_capability = le16_to_cpu(bi->capability);
2416         notify_interval = le16_to_cpu(bi->beacon_period);
2417         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2418         notify_ielen = le32_to_cpu(bi->ie_length);
2419         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2420
2421         brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2422         brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2423         brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2424         brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2425
2426         bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2427                 0, notify_capability, notify_interval,
2428                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2429
2430         if (!bss) {
2431                 err = -ENOMEM;
2432                 goto CleanUp;
2433         }
2434
2435         cfg80211_put_bss(wiphy, bss);
2436
2437 CleanUp:
2438
2439         kfree(buf);
2440
2441         brcmf_dbg(TRACE, "Exit\n");
2442
2443         return err;
2444 }
2445
2446 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2447 {
2448         return vif->mode == WL_MODE_IBSS;
2449 }
2450
2451 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2452                                  struct brcmf_if *ifp)
2453 {
2454         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2455         struct brcmf_bss_info_le *bi;
2456         struct brcmf_ssid *ssid;
2457         struct brcmf_tlv *tim;
2458         u16 beacon_interval;
2459         u8 dtim_period;
2460         size_t ie_len;
2461         u8 *ie;
2462         s32 err = 0;
2463
2464         brcmf_dbg(TRACE, "Enter\n");
2465         if (brcmf_is_ibssmode(ifp->vif))
2466                 return err;
2467
2468         ssid = &profile->ssid;
2469
2470         *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2471         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2472                                      cfg->extra_buf, WL_EXTRA_BUF_MAX);
2473         if (err) {
2474                 brcmf_err("Could not get bss info %d\n", err);
2475                 goto update_bss_info_out;
2476         }
2477
2478         bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2479         err = brcmf_inform_single_bss(cfg, bi);
2480         if (err)
2481                 goto update_bss_info_out;
2482
2483         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2484         ie_len = le32_to_cpu(bi->ie_length);
2485         beacon_interval = le16_to_cpu(bi->beacon_period);
2486
2487         tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2488         if (tim)
2489                 dtim_period = tim->data[1];
2490         else {
2491                 /*
2492                 * active scan was done so we could not get dtim
2493                 * information out of probe response.
2494                 * so we speficially query dtim information to dongle.
2495                 */
2496                 u32 var;
2497                 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2498                 if (err) {
2499                         brcmf_err("wl dtim_assoc failed (%d)\n", err);
2500                         goto update_bss_info_out;
2501                 }
2502                 dtim_period = (u8)var;
2503         }
2504
2505 update_bss_info_out:
2506         brcmf_dbg(TRACE, "Exit");
2507         return err;
2508 }
2509
2510 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2511 {
2512         struct escan_info *escan = &cfg->escan_info;
2513
2514         set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2515         if (cfg->scan_request) {
2516                 escan->escan_state = WL_ESCAN_STATE_IDLE;
2517                 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2518         }
2519         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2520         clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2521 }
2522
2523 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2524 {
2525         struct brcmf_cfg80211_info *cfg =
2526                         container_of(work, struct brcmf_cfg80211_info,
2527                                      escan_timeout_work);
2528
2529         brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2530 }
2531
2532 static void brcmf_escan_timeout(unsigned long data)
2533 {
2534         struct brcmf_cfg80211_info *cfg =
2535                         (struct brcmf_cfg80211_info *)data;
2536
2537         if (cfg->scan_request) {
2538                 brcmf_err("timer expired\n");
2539                 schedule_work(&cfg->escan_timeout_work);
2540         }
2541 }
2542
2543 static s32
2544 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2545                               struct brcmf_bss_info_le *bss,
2546                               struct brcmf_bss_info_le *bss_info_le)
2547 {
2548         struct brcmu_chan ch_bss, ch_bss_info_le;
2549
2550         ch_bss.chspec = le16_to_cpu(bss->chanspec);
2551         cfg->d11inf.decchspec(&ch_bss);
2552         ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2553         cfg->d11inf.decchspec(&ch_bss_info_le);
2554
2555         if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2556                 ch_bss.band == ch_bss_info_le.band &&
2557                 bss_info_le->SSID_len == bss->SSID_len &&
2558                 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2559                 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2560                         (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2561                         s16 bss_rssi = le16_to_cpu(bss->RSSI);
2562                         s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2563
2564                         /* preserve max RSSI if the measurements are
2565                         * both on-channel or both off-channel
2566                         */
2567                         if (bss_info_rssi > bss_rssi)
2568                                 bss->RSSI = bss_info_le->RSSI;
2569                 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2570                         (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2571                         /* preserve the on-channel rssi measurement
2572                         * if the new measurement is off channel
2573                         */
2574                         bss->RSSI = bss_info_le->RSSI;
2575                         bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2576                 }
2577                 return 1;
2578         }
2579         return 0;
2580 }
2581
2582 static s32
2583 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2584                              const struct brcmf_event_msg *e, void *data)
2585 {
2586         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2587         s32 status;
2588         s32 err = 0;
2589         struct brcmf_escan_result_le *escan_result_le;
2590         struct brcmf_bss_info_le *bss_info_le;
2591         struct brcmf_bss_info_le *bss = NULL;
2592         u32 bi_length;
2593         struct brcmf_scan_results *list;
2594         u32 i;
2595         bool aborted;
2596
2597         status = e->status;
2598
2599         if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2600                 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2601                 return -EPERM;
2602         }
2603
2604         if (status == BRCMF_E_STATUS_PARTIAL) {
2605                 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2606                 escan_result_le = (struct brcmf_escan_result_le *) data;
2607                 if (!escan_result_le) {
2608                         brcmf_err("Invalid escan result (NULL pointer)\n");
2609                         goto exit;
2610                 }
2611                 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2612                         brcmf_err("Invalid bss_count %d: ignoring\n",
2613                                   escan_result_le->bss_count);
2614                         goto exit;
2615                 }
2616                 bss_info_le = &escan_result_le->bss_info_le;
2617
2618                 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2619                         goto exit;
2620
2621                 if (!cfg->scan_request) {
2622                         brcmf_dbg(SCAN, "result without cfg80211 request\n");
2623                         goto exit;
2624                 }
2625
2626                 bi_length = le32_to_cpu(bss_info_le->length);
2627                 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2628                                         WL_ESCAN_RESULTS_FIXED_SIZE)) {
2629                         brcmf_err("Invalid bss_info length %d: ignoring\n",
2630                                   bi_length);
2631                         goto exit;
2632                 }
2633
2634                 if (!(cfg_to_wiphy(cfg)->interface_modes &
2635                                         BIT(NL80211_IFTYPE_ADHOC))) {
2636                         if (le16_to_cpu(bss_info_le->capability) &
2637                                                 WLAN_CAPABILITY_IBSS) {
2638                                 brcmf_err("Ignoring IBSS result\n");
2639                                 goto exit;
2640                         }
2641                 }
2642
2643                 list = (struct brcmf_scan_results *)
2644                                 cfg->escan_info.escan_buf;
2645                 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2646                         brcmf_err("Buffer is too small: ignoring\n");
2647                         goto exit;
2648                 }
2649
2650                 for (i = 0; i < list->count; i++) {
2651                         bss = bss ? (struct brcmf_bss_info_le *)
2652                                 ((unsigned char *)bss +
2653                                 le32_to_cpu(bss->length)) : list->bss_info_le;
2654                         if (brcmf_compare_update_same_bss(cfg, bss,
2655                                                           bss_info_le))
2656                                 goto exit;
2657                 }
2658                 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2659                         bss_info_le, bi_length);
2660                 list->version = le32_to_cpu(bss_info_le->version);
2661                 list->buflen += bi_length;
2662                 list->count++;
2663         } else {
2664                 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2665                 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2666                         goto exit;
2667                 if (cfg->scan_request) {
2668                         cfg->bss_list = (struct brcmf_scan_results *)
2669                                 cfg->escan_info.escan_buf;
2670                         brcmf_inform_bss(cfg);
2671                         aborted = status != BRCMF_E_STATUS_SUCCESS;
2672                         brcmf_notify_escan_complete(cfg, ifp, aborted,
2673                                                     false);
2674                 } else
2675                         brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2676                                   status);
2677         }
2678 exit:
2679         return err;
2680 }
2681
2682 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2683 {
2684         brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2685                             brcmf_cfg80211_escan_handler);
2686         cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2687         /* Init scan_timeout timer */
2688         init_timer(&cfg->escan_timeout);
2689         cfg->escan_timeout.data = (unsigned long) cfg;
2690         cfg->escan_timeout.function = brcmf_escan_timeout;
2691         INIT_WORK(&cfg->escan_timeout_work,
2692                   brcmf_cfg80211_escan_timeout_worker);
2693 }
2694
2695 static __always_inline void brcmf_delay(u32 ms)
2696 {
2697         if (ms < 1000 / HZ) {
2698                 cond_resched();
2699                 mdelay(ms);
2700         } else {
2701                 msleep(ms);
2702         }
2703 }
2704
2705 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2706 {
2707         brcmf_dbg(TRACE, "Enter\n");
2708
2709         return 0;
2710 }
2711
2712 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2713                                   struct cfg80211_wowlan *wow)
2714 {
2715         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2716         struct net_device *ndev = cfg_to_ndev(cfg);
2717         struct brcmf_cfg80211_vif *vif;
2718
2719         brcmf_dbg(TRACE, "Enter\n");
2720
2721         /*
2722          * if the primary net_device is not READY there is nothing
2723          * we can do but pray resume goes smoothly.
2724          */
2725         vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2726         if (!check_vif_up(vif))
2727                 goto exit;
2728
2729         list_for_each_entry(vif, &cfg->vif_list, list) {
2730                 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2731                         continue;
2732                 /*
2733                  * While going to suspend if associated with AP disassociate
2734                  * from AP to save power while system is in suspended state
2735                  */
2736                 brcmf_link_down(vif);
2737
2738                 /* Make sure WPA_Supplicant receives all the event
2739                  * generated due to DISASSOC call to the fw to keep
2740                  * the state fw and WPA_Supplicant state consistent
2741                  */
2742                 brcmf_delay(500);
2743         }
2744
2745         /* end any scanning */
2746         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2747                 brcmf_abort_scanning(cfg);
2748
2749         /* Turn off watchdog timer */
2750         brcmf_set_mpc(netdev_priv(ndev), 1);
2751
2752 exit:
2753         brcmf_dbg(TRACE, "Exit\n");
2754         /* clear any scanning activity */
2755         cfg->scan_status = 0;
2756         return 0;
2757 }
2758
2759 static __used s32
2760 brcmf_update_pmklist(struct net_device *ndev,
2761                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2762 {
2763         int i, j;
2764         int pmkid_len;
2765
2766         pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2767
2768         brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2769         for (i = 0; i < pmkid_len; i++) {
2770                 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2771                           &pmk_list->pmkids.pmkid[i].BSSID);
2772                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2773                         brcmf_dbg(CONN, "%02x\n",
2774                                   pmk_list->pmkids.pmkid[i].PMKID[j]);
2775         }
2776
2777         if (!err)
2778                 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2779                                          (char *)pmk_list, sizeof(*pmk_list));
2780
2781         return err;
2782 }
2783
2784 static s32
2785 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2786                          struct cfg80211_pmksa *pmksa)
2787 {
2788         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2789         struct brcmf_if *ifp = netdev_priv(ndev);
2790         struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2791         s32 err = 0;
2792         int i;
2793         int pmkid_len;
2794
2795         brcmf_dbg(TRACE, "Enter\n");
2796         if (!check_vif_up(ifp->vif))
2797                 return -EIO;
2798
2799         pmkid_len = le32_to_cpu(pmkids->npmkid);
2800         for (i = 0; i < pmkid_len; i++)
2801                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2802                         break;
2803         if (i < WL_NUM_PMKIDS_MAX) {
2804                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2805                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2806                 if (i == pmkid_len) {
2807                         pmkid_len++;
2808                         pmkids->npmkid = cpu_to_le32(pmkid_len);
2809                 }
2810         } else
2811                 err = -EINVAL;
2812
2813         brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2814                   pmkids->pmkid[pmkid_len].BSSID);
2815         for (i = 0; i < WLAN_PMKID_LEN; i++)
2816                 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2817
2818         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2819
2820         brcmf_dbg(TRACE, "Exit\n");
2821         return err;
2822 }
2823
2824 static s32
2825 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2826                       struct cfg80211_pmksa *pmksa)
2827 {
2828         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2829         struct brcmf_if *ifp = netdev_priv(ndev);
2830         struct pmkid_list pmkid;
2831         s32 err = 0;
2832         int i, pmkid_len;
2833
2834         brcmf_dbg(TRACE, "Enter\n");
2835         if (!check_vif_up(ifp->vif))
2836                 return -EIO;
2837
2838         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2839         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2840
2841         brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2842                   &pmkid.pmkid[0].BSSID);
2843         for (i = 0; i < WLAN_PMKID_LEN; i++)
2844                 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2845
2846         pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2847         for (i = 0; i < pmkid_len; i++)
2848                 if (!memcmp
2849                     (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2850                      ETH_ALEN))
2851                         break;
2852
2853         if ((pmkid_len > 0)
2854             && (i < pmkid_len)) {
2855                 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2856                        sizeof(struct pmkid));
2857                 for (; i < (pmkid_len - 1); i++) {
2858                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2859                                &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2860                                ETH_ALEN);
2861                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2862                                &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2863                                WLAN_PMKID_LEN);
2864                 }
2865                 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2866         } else
2867                 err = -EINVAL;
2868
2869         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2870
2871         brcmf_dbg(TRACE, "Exit\n");
2872         return err;
2873
2874 }
2875
2876 static s32
2877 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2878 {
2879         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2880         struct brcmf_if *ifp = netdev_priv(ndev);
2881         s32 err = 0;
2882
2883         brcmf_dbg(TRACE, "Enter\n");
2884         if (!check_vif_up(ifp->vif))
2885                 return -EIO;
2886
2887         memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2888         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2889
2890         brcmf_dbg(TRACE, "Exit\n");
2891         return err;
2892
2893 }
2894
2895 /*
2896  * PFN result doesn't have all the info which are
2897  * required by the supplicant
2898  * (For e.g IEs) Do a target Escan so that sched scan results are reported
2899  * via wl_inform_single_bss in the required format. Escan does require the
2900  * scan request in the form of cfg80211_scan_request. For timebeing, create
2901  * cfg80211_scan_request one out of the received PNO event.
2902  */
2903 static s32
2904 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2905                                 const struct brcmf_event_msg *e, void *data)
2906 {
2907         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2908         struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2909         struct cfg80211_scan_request *request = NULL;
2910         struct cfg80211_ssid *ssid = NULL;
2911         struct ieee80211_channel *channel = NULL;
2912         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2913         int err = 0;
2914         int channel_req = 0;
2915         int band = 0;
2916         struct brcmf_pno_scanresults_le *pfn_result;
2917         u32 result_count;
2918         u32 status;
2919
2920         brcmf_dbg(SCAN, "Enter\n");
2921
2922         if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2923                 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2924                 return 0;
2925         }
2926
2927         pfn_result = (struct brcmf_pno_scanresults_le *)data;
2928         result_count = le32_to_cpu(pfn_result->count);
2929         status = le32_to_cpu(pfn_result->status);
2930
2931         /*
2932          * PFN event is limited to fit 512 bytes so we may get
2933          * multiple NET_FOUND events. For now place a warning here.
2934          */
2935         WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2936         brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2937         if (result_count > 0) {
2938                 int i;
2939
2940                 request = kzalloc(sizeof(*request), GFP_KERNEL);
2941                 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2942                 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2943                 if (!request || !ssid || !channel) {
2944                         err = -ENOMEM;
2945                         goto out_err;
2946                 }
2947
2948                 request->wiphy = wiphy;
2949                 data += sizeof(struct brcmf_pno_scanresults_le);
2950                 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2951
2952                 for (i = 0; i < result_count; i++) {
2953                         netinfo = &netinfo_start[i];
2954                         if (!netinfo) {
2955                                 brcmf_err("Invalid netinfo ptr. index: %d\n",
2956                                           i);
2957                                 err = -EINVAL;
2958                                 goto out_err;
2959                         }
2960
2961                         brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2962                                   netinfo->SSID, netinfo->channel);
2963                         memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2964                         ssid[i].ssid_len = netinfo->SSID_len;
2965                         request->n_ssids++;
2966
2967                         channel_req = netinfo->channel;
2968                         if (channel_req <= CH_MAX_2G_CHANNEL)
2969                                 band = NL80211_BAND_2GHZ;
2970                         else
2971                                 band = NL80211_BAND_5GHZ;
2972                         channel[i].center_freq =
2973                                 ieee80211_channel_to_frequency(channel_req,
2974                                                                band);
2975                         channel[i].band = band;
2976                         channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2977                         request->channels[i] = &channel[i];
2978                         request->n_channels++;
2979                 }
2980
2981                 /* assign parsed ssid array */
2982                 if (request->n_ssids)
2983                         request->ssids = &ssid[0];
2984
2985                 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2986                         /* Abort any on-going scan */
2987                         brcmf_abort_scanning(cfg);
2988                 }
2989
2990                 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2991                 err = brcmf_do_escan(cfg, wiphy, ifp, request);
2992                 if (err) {
2993                         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2994                         goto out_err;
2995                 }
2996                 cfg->sched_escan = true;
2997                 cfg->scan_request = request;
2998         } else {
2999                 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3000                 goto out_err;
3001         }
3002
3003         kfree(ssid);
3004         kfree(channel);
3005         kfree(request);
3006         return 0;
3007
3008 out_err:
3009         kfree(ssid);
3010         kfree(channel);
3011         kfree(request);
3012         cfg80211_sched_scan_stopped(wiphy);
3013         return err;
3014 }
3015
3016 static int brcmf_dev_pno_clean(struct net_device *ndev)
3017 {
3018         int ret;
3019
3020         /* Disable pfn */
3021         ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3022         if (ret == 0) {
3023                 /* clear pfn */
3024                 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3025                                                NULL, 0);
3026         }
3027         if (ret < 0)
3028                 brcmf_err("failed code %d\n", ret);
3029
3030         return ret;
3031 }
3032
3033 static int brcmf_dev_pno_config(struct net_device *ndev)
3034 {
3035         struct brcmf_pno_param_le pfn_param;
3036
3037         memset(&pfn_param, 0, sizeof(pfn_param));
3038         pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3039
3040         /* set extra pno params */
3041         pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3042         pfn_param.repeat = BRCMF_PNO_REPEAT;
3043         pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3044
3045         /* set up pno scan fr */
3046         pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3047
3048         return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3049                                         &pfn_param, sizeof(pfn_param));
3050 }
3051
3052 static int
3053 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3054                                 struct net_device *ndev,
3055                                 struct cfg80211_sched_scan_request *request)
3056 {
3057         struct brcmf_if *ifp = netdev_priv(ndev);
3058         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3059         struct brcmf_pno_net_param_le pfn;
3060         int i;
3061         int ret = 0;
3062
3063         brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3064                   request->n_match_sets, request->n_ssids);
3065         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3066                 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3067                 return -EAGAIN;
3068         }
3069         if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3070                 brcmf_err("Scanning suppressed: status (%lu)\n",
3071                           cfg->scan_status);
3072                 return -EAGAIN;
3073         }
3074
3075         if (!request->n_ssids || !request->n_match_sets) {
3076                 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3077                           request->n_ssids);
3078                 return -EINVAL;
3079         }
3080
3081         if (request->n_ssids > 0) {
3082                 for (i = 0; i < request->n_ssids; i++) {
3083                         /* Active scan req for ssids */
3084                         brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3085                                   request->ssids[i].ssid);
3086
3087                         /*
3088                          * match_set ssids is a supert set of n_ssid list,
3089                          * so we need not add these set seperately.
3090                          */
3091                 }
3092         }
3093
3094         if (request->n_match_sets > 0) {
3095                 /* clean up everything */
3096                 ret = brcmf_dev_pno_clean(ndev);
3097                 if  (ret < 0) {
3098                         brcmf_err("failed error=%d\n", ret);
3099                         return ret;
3100                 }
3101
3102                 /* configure pno */
3103                 ret = brcmf_dev_pno_config(ndev);
3104                 if (ret < 0) {
3105                         brcmf_err("PNO setup failed!! ret=%d\n", ret);
3106                         return -EINVAL;
3107                 }
3108
3109                 /* configure each match set */
3110                 for (i = 0; i < request->n_match_sets; i++) {
3111                         struct cfg80211_ssid *ssid;
3112                         u32 ssid_len;
3113
3114                         ssid = &request->match_sets[i].ssid;
3115                         ssid_len = ssid->ssid_len;
3116
3117                         if (!ssid_len) {
3118                                 brcmf_err("skip broadcast ssid\n");
3119                                 continue;
3120                         }
3121                         pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3122                         pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3123                         pfn.wsec = cpu_to_le32(0);
3124                         pfn.infra = cpu_to_le32(1);
3125                         pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3126                         pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3127                         memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3128                         ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3129                                                        sizeof(pfn));
3130                         brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3131                                   ret == 0 ? "set" : "failed", ssid->ssid);
3132                 }
3133                 /* Enable the PNO */
3134                 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3135                         brcmf_err("PNO enable failed!! ret=%d\n", ret);
3136                         return -EINVAL;
3137                 }
3138         } else {
3139                 return -EINVAL;
3140         }
3141
3142         return 0;
3143 }
3144
3145 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3146                                           struct net_device *ndev)
3147 {
3148         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3149
3150         brcmf_dbg(SCAN, "enter\n");
3151         brcmf_dev_pno_clean(ndev);
3152         if (cfg->sched_escan)
3153                 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3154         return 0;
3155 }
3156
3157 #ifdef CONFIG_NL80211_TESTMODE
3158 static int brcmf_cfg80211_testmode(struct wiphy *wiphy,
3159                                    struct wireless_dev *wdev,
3160                                    void *data, int len)
3161 {
3162         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3163         struct net_device *ndev = cfg_to_ndev(cfg);
3164         struct brcmf_dcmd *dcmd = data;
3165         struct sk_buff *reply;
3166         int ret;
3167
3168         brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3169                   dcmd->buf, dcmd->len);
3170
3171         if (dcmd->set)
3172                 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3173                                              dcmd->buf, dcmd->len);
3174         else
3175                 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3176                                              dcmd->buf, dcmd->len);
3177         if (ret == 0) {
3178                 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3179                 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3180                 ret = cfg80211_testmode_reply(reply);
3181         }
3182         return ret;
3183 }
3184 #endif
3185
3186 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3187 {
3188         s32 err;
3189
3190         /* set auth */
3191         err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3192         if (err < 0) {
3193                 brcmf_err("auth error %d\n", err);
3194                 return err;
3195         }
3196         /* set wsec */
3197         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3198         if (err < 0) {
3199                 brcmf_err("wsec error %d\n", err);
3200                 return err;
3201         }
3202         /* set upper-layer auth */
3203         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3204         if (err < 0) {
3205                 brcmf_err("wpa_auth error %d\n", err);
3206                 return err;
3207         }
3208
3209         return 0;
3210 }
3211
3212 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3213 {
3214         if (is_rsn_ie)
3215                 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3216
3217         return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3218 }
3219
3220 static s32
3221 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3222                      bool is_rsn_ie)
3223 {
3224         struct brcmf_if *ifp = netdev_priv(ndev);
3225         u32 auth = 0; /* d11 open authentication */
3226         u16 count;
3227         s32 err = 0;
3228         s32 len = 0;
3229         u32 i;
3230         u32 wsec;
3231         u32 pval = 0;
3232         u32 gval = 0;
3233         u32 wpa_auth = 0;
3234         u32 offset;
3235         u8 *data;
3236         u16 rsn_cap;
3237         u32 wme_bss_disable;
3238
3239         brcmf_dbg(TRACE, "Enter\n");
3240         if (wpa_ie == NULL)
3241                 goto exit;
3242
3243         len = wpa_ie->len + TLV_HDR_LEN;
3244         data = (u8 *)wpa_ie;
3245         offset = TLV_HDR_LEN;
3246         if (!is_rsn_ie)
3247                 offset += VS_IE_FIXED_HDR_LEN;
3248         else
3249                 offset += WPA_IE_VERSION_LEN;
3250
3251         /* check for multicast cipher suite */
3252         if (offset + WPA_IE_MIN_OUI_LEN > len) {
3253                 err = -EINVAL;
3254                 brcmf_err("no multicast cipher suite\n");
3255                 goto exit;
3256         }
3257
3258         if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3259                 err = -EINVAL;
3260                 brcmf_err("ivalid OUI\n");
3261                 goto exit;
3262         }
3263         offset += TLV_OUI_LEN;
3264
3265         /* pick up multicast cipher */
3266         switch (data[offset]) {
3267         case WPA_CIPHER_NONE:
3268                 gval = 0;
3269                 break;
3270         case WPA_CIPHER_WEP_40:
3271         case WPA_CIPHER_WEP_104:
3272                 gval = WEP_ENABLED;
3273                 break;
3274         case WPA_CIPHER_TKIP:
3275                 gval = TKIP_ENABLED;
3276                 break;
3277         case WPA_CIPHER_AES_CCM:
3278                 gval = AES_ENABLED;
3279                 break;
3280         default:
3281                 err = -EINVAL;
3282                 brcmf_err("Invalid multi cast cipher info\n");
3283                 goto exit;
3284         }
3285
3286         offset++;
3287         /* walk thru unicast cipher list and pick up what we recognize */
3288         count = data[offset] + (data[offset + 1] << 8);
3289         offset += WPA_IE_SUITE_COUNT_LEN;
3290         /* Check for unicast suite(s) */
3291         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3292                 err = -EINVAL;
3293                 brcmf_err("no unicast cipher suite\n");
3294                 goto exit;
3295         }
3296         for (i = 0; i < count; i++) {
3297                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3298                         err = -EINVAL;
3299                         brcmf_err("ivalid OUI\n");
3300                         goto exit;
3301                 }
3302                 offset += TLV_OUI_LEN;
3303                 switch (data[offset]) {
3304                 case WPA_CIPHER_NONE:
3305                         break;
3306                 case WPA_CIPHER_WEP_40:
3307                 case WPA_CIPHER_WEP_104:
3308                         pval |= WEP_ENABLED;
3309                         break;
3310                 case WPA_CIPHER_TKIP:
3311                         pval |= TKIP_ENABLED;
3312                         break;
3313                 case WPA_CIPHER_AES_CCM:
3314                         pval |= AES_ENABLED;
3315                         break;
3316                 default:
3317                         brcmf_err("Ivalid unicast security info\n");
3318                 }
3319                 offset++;
3320         }
3321         /* walk thru auth management suite list and pick up what we recognize */
3322         count = data[offset] + (data[offset + 1] << 8);
3323         offset += WPA_IE_SUITE_COUNT_LEN;
3324         /* Check for auth key management suite(s) */
3325         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3326                 err = -EINVAL;
3327                 brcmf_err("no auth key mgmt suite\n");
3328                 goto exit;
3329         }
3330         for (i = 0; i < count; i++) {
3331                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3332                         err = -EINVAL;
3333                         brcmf_err("ivalid OUI\n");
3334                         goto exit;
3335                 }
3336                 offset += TLV_OUI_LEN;
3337                 switch (data[offset]) {
3338                 case RSN_AKM_NONE:
3339                         brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3340                         wpa_auth |= WPA_AUTH_NONE;
3341                         break;
3342                 case RSN_AKM_UNSPECIFIED:
3343                         brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3344                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3345                                     (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3346                         break;
3347                 case RSN_AKM_PSK:
3348                         brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3349                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3350                                     (wpa_auth |= WPA_AUTH_PSK);
3351                         break;
3352                 default:
3353                         brcmf_err("Ivalid key mgmt info\n");
3354                 }
3355                 offset++;
3356         }
3357
3358         if (is_rsn_ie) {
3359                 wme_bss_disable = 1;
3360                 if ((offset + RSN_CAP_LEN) <= len) {
3361                         rsn_cap = data[offset] + (data[offset + 1] << 8);
3362                         if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3363                                 wme_bss_disable = 0;
3364                 }
3365                 /* set wme_bss_disable to sync RSN Capabilities */
3366                 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3367                                                wme_bss_disable);
3368                 if (err < 0) {
3369                         brcmf_err("wme_bss_disable error %d\n", err);
3370                         goto exit;
3371                 }
3372         }
3373         /* FOR WPS , set SES_OW_ENABLED */
3374         wsec = (pval | gval | SES_OW_ENABLED);
3375
3376         /* set auth */
3377         err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3378         if (err < 0) {
3379                 brcmf_err("auth error %d\n", err);
3380                 goto exit;
3381         }
3382         /* set wsec */
3383         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3384         if (err < 0) {
3385                 brcmf_err("wsec error %d\n", err);
3386                 goto exit;
3387         }
3388         /* set upper-layer auth */
3389         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3390         if (err < 0) {
3391                 brcmf_err("wpa_auth error %d\n", err);
3392                 goto exit;
3393         }
3394
3395 exit:
3396         return err;
3397 }
3398
3399 static s32
3400 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3401                      struct parsed_vndr_ies *vndr_ies)
3402 {
3403         s32 err = 0;
3404         struct brcmf_vs_tlv *vndrie;
3405         struct brcmf_tlv *ie;
3406         struct parsed_vndr_ie_info *parsed_info;
3407         s32 remaining_len;
3408
3409         remaining_len = (s32)vndr_ie_len;
3410         memset(vndr_ies, 0, sizeof(*vndr_ies));
3411
3412         ie = (struct brcmf_tlv *)vndr_ie_buf;
3413         while (ie) {
3414                 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3415                         goto next;
3416                 vndrie = (struct brcmf_vs_tlv *)ie;
3417                 /* len should be bigger than OUI length + one */
3418                 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3419                         brcmf_err("invalid vndr ie. length is too small %d\n",
3420                                   vndrie->len);
3421                         goto next;
3422                 }
3423                 /* if wpa or wme ie, do not add ie */
3424                 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3425                     ((vndrie->oui_type == WPA_OUI_TYPE) ||
3426                     (vndrie->oui_type == WME_OUI_TYPE))) {
3427                         brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3428                         goto next;
3429                 }
3430
3431                 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3432
3433                 /* save vndr ie information */
3434                 parsed_info->ie_ptr = (char *)vndrie;
3435                 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3436                 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3437
3438                 vndr_ies->count++;
3439
3440                 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3441                           parsed_info->vndrie.oui[0],
3442                           parsed_info->vndrie.oui[1],
3443                           parsed_info->vndrie.oui[2],
3444                           parsed_info->vndrie.oui_type);
3445
3446                 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3447                         break;
3448 next:
3449                 remaining_len -= (ie->len + TLV_HDR_LEN);
3450                 if (remaining_len <= TLV_HDR_LEN)
3451                         ie = NULL;
3452                 else
3453                         ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3454                                 TLV_HDR_LEN);
3455         }
3456         return err;
3457 }
3458
3459 static u32
3460 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3461 {
3462
3463         __le32 iecount_le;
3464         __le32 pktflag_le;
3465
3466         strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3467         iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3468
3469         iecount_le = cpu_to_le32(1);
3470         memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3471
3472         pktflag_le = cpu_to_le32(pktflag);
3473         memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3474
3475         memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3476
3477         return ie_len + VNDR_IE_HDR_SIZE;
3478 }
3479
3480 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3481                           const u8 *vndr_ie_buf, u32 vndr_ie_len)
3482 {
3483         struct brcmf_if *ifp;
3484         struct vif_saved_ie *saved_ie;
3485         s32 err = 0;
3486         u8  *iovar_ie_buf;
3487         u8  *curr_ie_buf;
3488         u8  *mgmt_ie_buf = NULL;
3489         int mgmt_ie_buf_len;
3490         u32 *mgmt_ie_len;
3491         u32 del_add_ie_buf_len = 0;
3492         u32 total_ie_buf_len = 0;
3493         u32 parsed_ie_buf_len = 0;
3494         struct parsed_vndr_ies old_vndr_ies;
3495         struct parsed_vndr_ies new_vndr_ies;
3496         struct parsed_vndr_ie_info *vndrie_info;
3497         s32 i;
3498         u8 *ptr;
3499         int remained_buf_len;
3500
3501         if (!vif)
3502                 return -ENODEV;
3503         ifp = vif->ifp;
3504         saved_ie = &vif->saved_ie;
3505
3506         brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3507         iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3508         if (!iovar_ie_buf)
3509                 return -ENOMEM;
3510         curr_ie_buf = iovar_ie_buf;
3511         switch (pktflag) {
3512         case BRCMF_VNDR_IE_PRBREQ_FLAG:
3513                 mgmt_ie_buf = saved_ie->probe_req_ie;
3514                 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3515                 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3516                 break;
3517         case BRCMF_VNDR_IE_PRBRSP_FLAG:
3518                 mgmt_ie_buf = saved_ie->probe_res_ie;
3519                 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3520                 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3521                 break;
3522         case BRCMF_VNDR_IE_BEACON_FLAG:
3523                 mgmt_ie_buf = saved_ie->beacon_ie;
3524                 mgmt_ie_len = &saved_ie->beacon_ie_len;
3525                 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3526                 break;
3527         case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3528                 mgmt_ie_buf = saved_ie->assoc_req_ie;
3529                 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3530                 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3531                 break;
3532         default:
3533                 err = -EPERM;
3534                 brcmf_err("not suitable type\n");
3535                 goto exit;
3536         }
3537
3538         if (vndr_ie_len > mgmt_ie_buf_len) {
3539                 err = -ENOMEM;
3540                 brcmf_err("extra IE size too big\n");
3541                 goto exit;
3542         }
3543
3544         /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3545         if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3546                 ptr = curr_ie_buf;
3547                 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3548                 for (i = 0; i < new_vndr_ies.count; i++) {
3549                         vndrie_info = &new_vndr_ies.ie_info[i];
3550                         memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3551                                vndrie_info->ie_len);
3552                         parsed_ie_buf_len += vndrie_info->ie_len;
3553                 }
3554         }
3555
3556         if (mgmt_ie_buf && *mgmt_ie_len) {
3557                 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3558                     (memcmp(mgmt_ie_buf, curr_ie_buf,
3559                             parsed_ie_buf_len) == 0)) {
3560                         brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3561                         goto exit;
3562                 }
3563
3564                 /* parse old vndr_ie */
3565                 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3566
3567                 /* make a command to delete old ie */
3568                 for (i = 0; i < old_vndr_ies.count; i++) {
3569                         vndrie_info = &old_vndr_ies.ie_info[i];
3570
3571                         brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3572                                   vndrie_info->vndrie.id,
3573                                   vndrie_info->vndrie.len,
3574                                   vndrie_info->vndrie.oui[0],
3575                                   vndrie_info->vndrie.oui[1],
3576                                   vndrie_info->vndrie.oui[2]);
3577
3578                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3579                                                            vndrie_info->ie_ptr,
3580                                                            vndrie_info->ie_len,
3581                                                            "del");
3582                         curr_ie_buf += del_add_ie_buf_len;
3583                         total_ie_buf_len += del_add_ie_buf_len;
3584                 }
3585         }
3586
3587         *mgmt_ie_len = 0;
3588         /* Add if there is any extra IE */
3589         if (mgmt_ie_buf && parsed_ie_buf_len) {
3590                 ptr = mgmt_ie_buf;
3591
3592                 remained_buf_len = mgmt_ie_buf_len;
3593
3594                 /* make a command to add new ie */
3595                 for (i = 0; i < new_vndr_ies.count; i++) {
3596                         vndrie_info = &new_vndr_ies.ie_info[i];
3597
3598                         /* verify remained buf size before copy data */
3599                         if (remained_buf_len < (vndrie_info->vndrie.len +
3600                                                         VNDR_IE_VSIE_OFFSET)) {
3601                                 brcmf_err("no space in mgmt_ie_buf: len left %d",
3602                                           remained_buf_len);
3603                                 break;
3604                         }
3605                         remained_buf_len -= (vndrie_info->ie_len +
3606                                              VNDR_IE_VSIE_OFFSET);
3607
3608                         brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3609                                   vndrie_info->vndrie.id,
3610                                   vndrie_info->vndrie.len,
3611                                   vndrie_info->vndrie.oui[0],
3612                                   vndrie_info->vndrie.oui[1],
3613                                   vndrie_info->vndrie.oui[2]);
3614
3615                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3616                                                            vndrie_info->ie_ptr,
3617                                                            vndrie_info->ie_len,
3618                                                            "add");
3619
3620                         /* save the parsed IE in wl struct */
3621                         memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3622                                vndrie_info->ie_len);
3623                         *mgmt_ie_len += vndrie_info->ie_len;
3624
3625                         curr_ie_buf += del_add_ie_buf_len;
3626                         total_ie_buf_len += del_add_ie_buf_len;
3627                 }
3628         }
3629         if (total_ie_buf_len) {
3630                 err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3631                                                  total_ie_buf_len);
3632                 if (err)
3633                         brcmf_err("vndr ie set error : %d\n", err);
3634         }
3635
3636 exit:
3637         kfree(iovar_ie_buf);
3638         return err;
3639 }
3640
3641 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3642 {
3643         s32 pktflags[] = {
3644                 BRCMF_VNDR_IE_PRBREQ_FLAG,
3645                 BRCMF_VNDR_IE_PRBRSP_FLAG,
3646                 BRCMF_VNDR_IE_BEACON_FLAG
3647         };
3648         int i;
3649
3650         for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3651                 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3652
3653         memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3654         return 0;
3655 }
3656
3657 static s32
3658 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3659                         struct cfg80211_beacon_data *beacon)
3660 {
3661         s32 err;
3662
3663         /* Set Beacon IEs to FW */
3664         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3665                                     beacon->tail, beacon->tail_len);
3666         if (err) {
3667                 brcmf_err("Set Beacon IE Failed\n");
3668                 return err;
3669         }
3670         brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3671
3672         /* Set Probe Response IEs to FW */
3673         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3674                                     beacon->proberesp_ies,
3675                                     beacon->proberesp_ies_len);
3676         if (err)
3677                 brcmf_err("Set Probe Resp IE Failed\n");
3678         else
3679                 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3680
3681         return err;
3682 }
3683
3684 static s32
3685 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
3686                            struct brcmf_if *ifp,
3687                            struct ieee80211_channel *channel)
3688 {
3689         u16 chanspec;
3690         s32 err;
3691
3692         brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
3693                   channel->center_freq);
3694
3695         chanspec = channel_to_chanspec(&cfg->d11inf, channel);
3696         err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3697
3698         return err;
3699 }
3700
3701 static s32
3702 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3703                         struct cfg80211_ap_settings *settings)
3704 {
3705         s32 ie_offset;
3706         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3707         struct brcmf_if *ifp = netdev_priv(ndev);
3708         struct brcmf_tlv *ssid_ie;
3709         struct brcmf_ssid_le ssid_le;
3710         s32 err = -EPERM;
3711         struct brcmf_tlv *rsn_ie;
3712         struct brcmf_vs_tlv *wpa_ie;
3713         struct brcmf_join_params join_params;
3714         enum nl80211_iftype dev_role;
3715         struct brcmf_fil_bss_enable_le bss_enable;
3716
3717         brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3718                   cfg80211_get_chandef_type(&settings->chandef),
3719                   settings->beacon_interval,
3720                   settings->dtim_period);
3721         brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3722                   settings->ssid, settings->ssid_len, settings->auth_type,
3723                   settings->inactivity_timeout);
3724
3725         dev_role = ifp->vif->wdev.iftype;
3726
3727         memset(&ssid_le, 0, sizeof(ssid_le));
3728         if (settings->ssid == NULL || settings->ssid_len == 0) {
3729                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3730                 ssid_ie = brcmf_parse_tlvs(
3731                                 (u8 *)&settings->beacon.head[ie_offset],
3732                                 settings->beacon.head_len - ie_offset,
3733                                 WLAN_EID_SSID);
3734                 if (!ssid_ie)
3735                         return -EINVAL;
3736
3737                 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3738                 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3739                 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3740         } else {
3741                 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3742                 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3743         }
3744
3745         brcmf_set_mpc(ifp, 0);
3746         brcmf_configure_arp_offload(ifp, false);
3747
3748         /* find the RSN_IE */
3749         rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3750                                   settings->beacon.tail_len, WLAN_EID_RSN);
3751
3752         /* find the WPA_IE */
3753         wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3754                                   settings->beacon.tail_len);
3755
3756         if ((wpa_ie != NULL || rsn_ie != NULL)) {
3757                 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3758                 if (wpa_ie != NULL) {
3759                         /* WPA IE */
3760                         err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3761                         if (err < 0)
3762                                 goto exit;
3763                 } else {
3764                         /* RSN IE */
3765                         err = brcmf_configure_wpaie(ndev,
3766                                 (struct brcmf_vs_tlv *)rsn_ie, true);
3767                         if (err < 0)
3768                                 goto exit;
3769                 }
3770         } else {
3771                 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3772                 brcmf_configure_opensecurity(ifp);
3773         }
3774
3775         brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3776
3777         err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
3778         if (err < 0) {
3779                 brcmf_err("Set Channel failed, %d\n", err);
3780                 goto exit;
3781         }
3782
3783         if (settings->beacon_interval) {
3784                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3785                                             settings->beacon_interval);
3786                 if (err < 0) {
3787                         brcmf_err("Beacon Interval Set Error, %d\n", err);
3788                         goto exit;
3789                 }
3790         }
3791         if (settings->dtim_period) {
3792                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3793                                             settings->dtim_period);
3794                 if (err < 0) {
3795                         brcmf_err("DTIM Interval Set Error, %d\n", err);
3796                         goto exit;
3797                 }
3798         }
3799
3800         if (dev_role == NL80211_IFTYPE_AP) {
3801                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3802                 if (err < 0) {
3803                         brcmf_err("BRCMF_C_DOWN error %d\n", err);
3804                         goto exit;
3805                 }
3806                 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3807         }
3808
3809         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3810         if (err < 0) {
3811                 brcmf_err("SET INFRA error %d\n", err);
3812                 goto exit;
3813         }
3814         if (dev_role == NL80211_IFTYPE_AP) {
3815                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3816                 if (err < 0) {
3817                         brcmf_err("setting AP mode failed %d\n", err);
3818                         goto exit;
3819                 }
3820                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3821                 if (err < 0) {
3822                         brcmf_err("BRCMF_C_UP error (%d)\n", err);
3823                         goto exit;
3824                 }
3825
3826                 memset(&join_params, 0, sizeof(join_params));
3827                 /* join parameters starts with ssid */
3828                 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3829                 /* create softap */
3830                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3831                                              &join_params, sizeof(join_params));
3832                 if (err < 0) {
3833                         brcmf_err("SET SSID error (%d)\n", err);
3834                         goto exit;
3835                 }
3836                 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3837         } else {
3838                 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3839                                                 sizeof(ssid_le));
3840                 if (err < 0) {
3841                         brcmf_err("setting ssid failed %d\n", err);
3842                         goto exit;
3843                 }
3844                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3845                 bss_enable.enable = cpu_to_le32(1);
3846                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3847                                                sizeof(bss_enable));
3848                 if (err < 0) {
3849                         brcmf_err("bss_enable config failed %d\n", err);
3850                         goto exit;
3851                 }
3852
3853                 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3854         }
3855         clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3856         set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3857
3858 exit:
3859         if (err) {
3860                 brcmf_set_mpc(ifp, 1);
3861                 brcmf_configure_arp_offload(ifp, true);
3862         }
3863         return err;
3864 }
3865
3866 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3867 {
3868         struct brcmf_if *ifp = netdev_priv(ndev);
3869         s32 err;
3870         struct brcmf_fil_bss_enable_le bss_enable;
3871         struct brcmf_join_params join_params;
3872
3873         brcmf_dbg(TRACE, "Enter\n");
3874
3875         if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3876                 /* Due to most likely deauths outstanding we sleep */
3877                 /* first to make sure they get processed by fw. */
3878                 msleep(400);
3879
3880                 memset(&join_params, 0, sizeof(join_params));
3881                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3882                                              &join_params, sizeof(join_params));
3883                 if (err < 0)
3884                         brcmf_err("SET SSID error (%d)\n", err);
3885                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3886                 if (err < 0)
3887                         brcmf_err("BRCMF_C_UP error %d\n", err);
3888                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3889                 if (err < 0)
3890                         brcmf_err("setting AP mode failed %d\n", err);
3891                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3892                 if (err < 0)
3893                         brcmf_err("setting INFRA mode failed %d\n", err);
3894         } else {
3895                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3896                 bss_enable.enable = cpu_to_le32(0);
3897                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3898                                                sizeof(bss_enable));
3899                 if (err < 0)
3900                         brcmf_err("bss_enable config failed %d\n", err);
3901         }
3902         brcmf_set_mpc(ifp, 1);
3903         brcmf_configure_arp_offload(ifp, true);
3904         set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3905         clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3906
3907         return err;
3908 }
3909
3910 static s32
3911 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3912                              struct cfg80211_beacon_data *info)
3913 {
3914         struct brcmf_if *ifp = netdev_priv(ndev);
3915         s32 err;
3916
3917         brcmf_dbg(TRACE, "Enter\n");
3918
3919         err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3920
3921         return err;
3922 }
3923
3924 static int
3925 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3926                            u8 *mac)
3927 {
3928         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3929         struct brcmf_scb_val_le scbval;
3930         struct brcmf_if *ifp = netdev_priv(ndev);
3931         s32 err;
3932
3933         if (!mac)
3934                 return -EFAULT;
3935
3936         brcmf_dbg(TRACE, "Enter %pM\n", mac);
3937
3938         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3939                 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3940         if (!check_vif_up(ifp->vif))
3941                 return -EIO;
3942
3943         memcpy(&scbval.ea, mac, ETH_ALEN);
3944         scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3945         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3946                                      &scbval, sizeof(scbval));
3947         if (err)
3948                 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3949
3950         brcmf_dbg(TRACE, "Exit\n");
3951         return err;
3952 }
3953
3954
3955 static void
3956 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3957                                    struct wireless_dev *wdev,
3958                                    u16 frame_type, bool reg)
3959 {
3960         struct brcmf_cfg80211_vif *vif;
3961         u16 mgmt_type;
3962
3963         brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3964
3965         mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3966         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3967         if (reg)
3968                 vif->mgmt_rx_reg |= BIT(mgmt_type);
3969         else
3970                 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3971 }
3972
3973
3974 static int
3975 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3976                        struct ieee80211_channel *chan, bool offchan,
3977                        unsigned int wait, const u8 *buf, size_t len,
3978                        bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3979 {
3980         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3981         const struct ieee80211_mgmt *mgmt;
3982         struct brcmf_cfg80211_vif *vif;
3983         s32 err = 0;
3984         s32 ie_offset;
3985         s32 ie_len;
3986         struct brcmf_fil_action_frame_le *action_frame;
3987         struct brcmf_fil_af_params_le *af_params;
3988         bool ack;
3989         s32 chan_nr;
3990         u32 freq;
3991
3992         brcmf_dbg(TRACE, "Enter\n");
3993
3994         *cookie = 0;
3995
3996         mgmt = (const struct ieee80211_mgmt *)buf;
3997
3998         if (!ieee80211_is_mgmt(mgmt->frame_control)) {
3999                 brcmf_err("Driver only allows MGMT packet type\n");
4000                 return -EPERM;
4001         }
4002
4003         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4004
4005         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4006                 /* Right now the only reason to get a probe response */
4007                 /* is for p2p listen response or for p2p GO from     */
4008                 /* wpa_supplicant. Unfortunately the probe is send   */
4009                 /* on primary ndev, while dongle wants it on the p2p */
4010                 /* vif. Since this is only reason for a probe        */
4011                 /* response to be sent, the vif is taken from cfg.   */
4012                 /* If ever desired to send proberesp for non p2p     */
4013                 /* response then data should be checked for          */
4014                 /* "DIRECT-". Note in future supplicant will take    */
4015                 /* dedicated p2p wdev to do this and then this 'hack'*/
4016                 /* is not needed anymore.                            */
4017                 ie_offset =  DOT11_MGMT_HDR_LEN +
4018                              DOT11_BCN_PRB_FIXED_LEN;
4019                 ie_len = len - ie_offset;
4020                 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4021                         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4022                 err = brcmf_vif_set_mgmt_ie(vif,
4023                                             BRCMF_VNDR_IE_PRBRSP_FLAG,
4024                                             &buf[ie_offset],
4025                                             ie_len);
4026                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4027                                         GFP_KERNEL);
4028         } else if (ieee80211_is_action(mgmt->frame_control)) {
4029                 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4030                 if (af_params == NULL) {
4031                         brcmf_err("unable to allocate frame\n");
4032                         err = -ENOMEM;
4033                         goto exit;
4034                 }
4035                 action_frame = &af_params->action_frame;
4036                 /* Add the packet Id */
4037                 action_frame->packet_id = cpu_to_le32(*cookie);
4038                 /* Add BSSID */
4039                 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4040                 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4041                 /* Add the length exepted for 802.11 header  */
4042                 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4043                 /* Add the channel. Use the one specified as parameter if any or
4044                  * the current one (got from the firmware) otherwise
4045                  */
4046                 if (chan)
4047                         freq = chan->center_freq;
4048                 else
4049                         brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4050                                               &freq);
4051                 chan_nr = ieee80211_frequency_to_channel(freq);
4052                 af_params->channel = cpu_to_le32(chan_nr);
4053
4054                 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4055                        le16_to_cpu(action_frame->len));
4056
4057                 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4058                           *cookie, le16_to_cpu(action_frame->len), freq);
4059
4060                 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4061                                                   af_params);
4062
4063                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4064                                         GFP_KERNEL);
4065                 kfree(af_params);
4066         } else {
4067                 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4068                 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4069         }
4070
4071 exit:
4072         return err;
4073 }
4074
4075
4076 static int
4077 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4078                                         struct wireless_dev *wdev,
4079                                         u64 cookie)
4080 {
4081         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4082         struct brcmf_cfg80211_vif *vif;
4083         int err = 0;
4084
4085         brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4086
4087         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4088         if (vif == NULL) {
4089                 brcmf_err("No p2p device available for probe response\n");
4090                 err = -ENODEV;
4091                 goto exit;
4092         }
4093         brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4094 exit:
4095         return err;
4096 }
4097
4098 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4099                                            struct wireless_dev *wdev,
4100                                            enum nl80211_crit_proto_id proto,
4101                                            u16 duration)
4102 {
4103         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4104         struct brcmf_cfg80211_vif *vif;
4105
4106         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4107
4108         /* only DHCP support for now */
4109         if (proto != NL80211_CRIT_PROTO_DHCP)
4110                 return -EINVAL;
4111
4112         /* suppress and abort scanning */
4113         set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4114         brcmf_abort_scanning(cfg);
4115
4116         return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4117 }
4118
4119 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4120                                            struct wireless_dev *wdev)
4121 {
4122         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4123         struct brcmf_cfg80211_vif *vif;
4124
4125         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4126
4127         brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4128         clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4129 }
4130
4131 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4132 {
4133         int ret;
4134
4135         switch (oper) {
4136         case NL80211_TDLS_DISCOVERY_REQ:
4137                 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4138                 break;
4139         case NL80211_TDLS_SETUP:
4140                 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4141                 break;
4142         case NL80211_TDLS_TEARDOWN:
4143                 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4144                 break;
4145         default:
4146                 brcmf_err("unsupported operation: %d\n", oper);
4147                 ret = -EOPNOTSUPP;
4148         }
4149         return ret;
4150 }
4151
4152 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4153                                     struct net_device *ndev, u8 *peer,
4154                                     enum nl80211_tdls_operation oper)
4155 {
4156         struct brcmf_if *ifp;
4157         struct brcmf_tdls_iovar_le info;
4158         int ret = 0;
4159
4160         ret = brcmf_convert_nl80211_tdls_oper(oper);
4161         if (ret < 0)
4162                 return ret;
4163
4164         ifp = netdev_priv(ndev);
4165         memset(&info, 0, sizeof(info));
4166         info.mode = (u8)ret;
4167         if (peer)
4168                 memcpy(info.ea, peer, ETH_ALEN);
4169
4170         ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4171                                        &info, sizeof(info));
4172         if (ret < 0)
4173                 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4174
4175         return ret;
4176 }
4177
4178 static struct cfg80211_ops wl_cfg80211_ops = {
4179         .add_virtual_intf = brcmf_cfg80211_add_iface,
4180         .del_virtual_intf = brcmf_cfg80211_del_iface,
4181         .change_virtual_intf = brcmf_cfg80211_change_iface,
4182         .scan = brcmf_cfg80211_scan,
4183         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4184         .join_ibss = brcmf_cfg80211_join_ibss,
4185         .leave_ibss = brcmf_cfg80211_leave_ibss,
4186         .get_station = brcmf_cfg80211_get_station,
4187         .set_tx_power = brcmf_cfg80211_set_tx_power,
4188         .get_tx_power = brcmf_cfg80211_get_tx_power,
4189         .add_key = brcmf_cfg80211_add_key,
4190         .del_key = brcmf_cfg80211_del_key,
4191         .get_key = brcmf_cfg80211_get_key,
4192         .set_default_key = brcmf_cfg80211_config_default_key,
4193         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4194         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4195         .connect = brcmf_cfg80211_connect,
4196         .disconnect = brcmf_cfg80211_disconnect,
4197         .suspend = brcmf_cfg80211_suspend,
4198         .resume = brcmf_cfg80211_resume,
4199         .set_pmksa = brcmf_cfg80211_set_pmksa,
4200         .del_pmksa = brcmf_cfg80211_del_pmksa,
4201         .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4202         .start_ap = brcmf_cfg80211_start_ap,
4203         .stop_ap = brcmf_cfg80211_stop_ap,
4204         .change_beacon = brcmf_cfg80211_change_beacon,
4205         .del_station = brcmf_cfg80211_del_station,
4206         .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4207         .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4208         .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4209         .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4210         .remain_on_channel = brcmf_p2p_remain_on_channel,
4211         .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4212         .start_p2p_device = brcmf_p2p_start_device,
4213         .stop_p2p_device = brcmf_p2p_stop_device,
4214         .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4215         .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4216         .tdls_oper = brcmf_cfg80211_tdls_oper,
4217         CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4218 };
4219
4220 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4221 {
4222         switch (type) {
4223         case NL80211_IFTYPE_AP_VLAN:
4224         case NL80211_IFTYPE_WDS:
4225         case NL80211_IFTYPE_MONITOR:
4226         case NL80211_IFTYPE_MESH_POINT:
4227                 return -ENOTSUPP;
4228         case NL80211_IFTYPE_ADHOC:
4229                 return WL_MODE_IBSS;
4230         case NL80211_IFTYPE_STATION:
4231         case NL80211_IFTYPE_P2P_CLIENT:
4232                 return WL_MODE_BSS;
4233         case NL80211_IFTYPE_AP:
4234         case NL80211_IFTYPE_P2P_GO:
4235                 return WL_MODE_AP;
4236         case NL80211_IFTYPE_P2P_DEVICE:
4237                 return WL_MODE_P2P;
4238         case NL80211_IFTYPE_UNSPECIFIED:
4239         default:
4240                 break;
4241         }
4242
4243         return -EINVAL;
4244 }
4245
4246 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4247 {
4248         /* scheduled scan settings */
4249         wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4250         wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4251         wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4252         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4253 }
4254
4255 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4256         {
4257                 .max = 2,
4258                 .types = BIT(NL80211_IFTYPE_STATION) |
4259                          BIT(NL80211_IFTYPE_ADHOC) |
4260                          BIT(NL80211_IFTYPE_AP)
4261         },
4262         {
4263                 .max = 1,
4264                 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4265                          BIT(NL80211_IFTYPE_P2P_GO)
4266         },
4267         {
4268                 .max = 1,
4269                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4270         }
4271 };
4272 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4273         {
4274                  .max_interfaces = BRCMF_IFACE_MAX_CNT,
4275                  .num_different_channels = 2,
4276                  .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4277                  .limits = brcmf_iface_limits
4278         }
4279 };
4280
4281 static const struct ieee80211_txrx_stypes
4282 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4283         [NL80211_IFTYPE_STATION] = {
4284                 .tx = 0xffff,
4285                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4286                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4287         },
4288         [NL80211_IFTYPE_P2P_CLIENT] = {
4289                 .tx = 0xffff,
4290                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4291                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4292         },
4293         [NL80211_IFTYPE_P2P_GO] = {
4294                 .tx = 0xffff,
4295                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4296                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4297                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4298                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4299                       BIT(IEEE80211_STYPE_AUTH >> 4) |
4300                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4301                       BIT(IEEE80211_STYPE_ACTION >> 4)
4302         },
4303         [NL80211_IFTYPE_P2P_DEVICE] = {
4304                 .tx = 0xffff,
4305                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4306                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4307         }
4308 };
4309
4310 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4311 {
4312         struct wiphy *wiphy;
4313         s32 err = 0;
4314
4315         wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4316         if (!wiphy) {
4317                 brcmf_err("Could not allocate wiphy device\n");
4318                 return ERR_PTR(-ENOMEM);
4319         }
4320         set_wiphy_dev(wiphy, phydev);
4321         wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4322         wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4323         wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4324         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4325                                  BIT(NL80211_IFTYPE_ADHOC) |
4326                                  BIT(NL80211_IFTYPE_AP) |
4327                                  BIT(NL80211_IFTYPE_P2P_CLIENT) |
4328                                  BIT(NL80211_IFTYPE_P2P_GO) |
4329                                  BIT(NL80211_IFTYPE_P2P_DEVICE);
4330         wiphy->iface_combinations = brcmf_iface_combos;
4331         wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4332         wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4333         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4334         wiphy->cipher_suites = __wl_cipher_suites;
4335         wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4336         wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4337                         WIPHY_FLAG_OFFCHAN_TX |
4338                         WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4339                         WIPHY_FLAG_SUPPORTS_TDLS;
4340         wiphy->mgmt_stypes = brcmf_txrx_stypes;
4341         wiphy->max_remain_on_channel_duration = 5000;
4342         brcmf_wiphy_pno_params(wiphy);
4343         brcmf_dbg(INFO, "Registering custom regulatory\n");
4344         wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
4345         wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4346         err = wiphy_register(wiphy);
4347         if (err < 0) {
4348                 brcmf_err("Could not register wiphy device (%d)\n", err);
4349                 wiphy_free(wiphy);
4350                 return ERR_PTR(err);
4351         }
4352         return wiphy;
4353 }
4354
4355 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4356                                            enum nl80211_iftype type,
4357                                            bool pm_block)
4358 {
4359         struct brcmf_cfg80211_vif *vif;
4360
4361         if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
4362                 return ERR_PTR(-ENOSPC);
4363
4364         brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4365                   sizeof(*vif));
4366         vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4367         if (!vif)
4368                 return ERR_PTR(-ENOMEM);
4369
4370         vif->wdev.wiphy = cfg->wiphy;
4371         vif->wdev.iftype = type;
4372
4373         vif->mode = brcmf_nl80211_iftype_to_mode(type);
4374         vif->pm_block = pm_block;
4375         vif->roam_off = -1;
4376
4377         brcmf_init_prof(&vif->profile);
4378
4379         list_add_tail(&vif->list, &cfg->vif_list);
4380         cfg->vif_cnt++;
4381         return vif;
4382 }
4383
4384 void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
4385                     struct brcmf_cfg80211_vif *vif)
4386 {
4387         list_del(&vif->list);
4388         cfg->vif_cnt--;
4389
4390         kfree(vif);
4391         if (!cfg->vif_cnt) {
4392                 wiphy_unregister(cfg->wiphy);
4393                 wiphy_free(cfg->wiphy);
4394         }
4395 }
4396
4397 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4398 {
4399         u32 event = e->event_code;
4400         u32 status = e->status;
4401
4402         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4403                 brcmf_dbg(CONN, "Processing set ssid\n");
4404                 return true;
4405         }
4406
4407         return false;
4408 }
4409
4410 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4411 {
4412         u32 event = e->event_code;
4413         u16 flags = e->flags;
4414
4415         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4416                 brcmf_dbg(CONN, "Processing link down\n");
4417                 return true;
4418         }
4419         return false;
4420 }
4421
4422 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4423                                const struct brcmf_event_msg *e)
4424 {
4425         u32 event = e->event_code;
4426         u32 status = e->status;
4427
4428         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4429                 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4430                           e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4431                 return true;
4432         }
4433
4434         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4435                 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4436                 return true;
4437         }
4438
4439         return false;
4440 }
4441
4442 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4443 {
4444         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4445
4446         kfree(conn_info->req_ie);
4447         conn_info->req_ie = NULL;
4448         conn_info->req_ie_len = 0;
4449         kfree(conn_info->resp_ie);
4450         conn_info->resp_ie = NULL;
4451         conn_info->resp_ie_len = 0;
4452 }
4453
4454 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4455                                struct brcmf_if *ifp)
4456 {
4457         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4458         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4459         u32 req_len;
4460         u32 resp_len;
4461         s32 err = 0;
4462
4463         brcmf_clear_assoc_ies(cfg);
4464
4465         err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4466                                        cfg->extra_buf, WL_ASSOC_INFO_MAX);
4467         if (err) {
4468                 brcmf_err("could not get assoc info (%d)\n", err);
4469                 return err;
4470         }
4471         assoc_info =
4472                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4473         req_len = le32_to_cpu(assoc_info->req_len);
4474         resp_len = le32_to_cpu(assoc_info->resp_len);
4475         if (req_len) {
4476                 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4477                                                cfg->extra_buf,
4478                                                WL_ASSOC_INFO_MAX);
4479                 if (err) {
4480                         brcmf_err("could not get assoc req (%d)\n", err);
4481                         return err;
4482                 }
4483                 conn_info->req_ie_len = req_len;
4484                 conn_info->req_ie =
4485                     kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4486                             GFP_KERNEL);
4487         } else {
4488                 conn_info->req_ie_len = 0;
4489                 conn_info->req_ie = NULL;
4490         }
4491         if (resp_len) {
4492                 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4493                                                cfg->extra_buf,
4494                                                WL_ASSOC_INFO_MAX);
4495                 if (err) {
4496                         brcmf_err("could not get assoc resp (%d)\n", err);
4497                         return err;
4498                 }
4499                 conn_info->resp_ie_len = resp_len;
4500                 conn_info->resp_ie =
4501                     kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4502                             GFP_KERNEL);
4503         } else {
4504                 conn_info->resp_ie_len = 0;
4505                 conn_info->resp_ie = NULL;
4506         }
4507         brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4508                   conn_info->req_ie_len, conn_info->resp_ie_len);
4509
4510         return err;
4511 }
4512
4513 static s32
4514 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4515                        struct net_device *ndev,
4516                        const struct brcmf_event_msg *e)
4517 {
4518         struct brcmf_if *ifp = netdev_priv(ndev);
4519         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4520         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4521         struct wiphy *wiphy = cfg_to_wiphy(cfg);
4522         struct ieee80211_channel *notify_channel = NULL;
4523         struct ieee80211_supported_band *band;
4524         struct brcmf_bss_info_le *bi;
4525         struct brcmu_chan ch;
4526         u32 freq;
4527         s32 err = 0;
4528         u8 *buf;
4529
4530         brcmf_dbg(TRACE, "Enter\n");
4531
4532         brcmf_get_assoc_ies(cfg, ifp);
4533         memcpy(profile->bssid, e->addr, ETH_ALEN);
4534         brcmf_update_bss_info(cfg, ifp);
4535
4536         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4537         if (buf == NULL) {
4538                 err = -ENOMEM;
4539                 goto done;
4540         }
4541
4542         /* data sent to dongle has to be little endian */
4543         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4544         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4545                                      buf, WL_BSS_INFO_MAX);
4546
4547         if (err)
4548                 goto done;
4549
4550         bi = (struct brcmf_bss_info_le *)(buf + 4);
4551         ch.chspec = le16_to_cpu(bi->chanspec);
4552         cfg->d11inf.decchspec(&ch);
4553
4554         if (ch.band == BRCMU_CHAN_BAND_2G)
4555                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4556         else
4557                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4558
4559         freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4560         notify_channel = ieee80211_get_channel(wiphy, freq);
4561
4562 done:
4563         kfree(buf);
4564         cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4565                         conn_info->req_ie, conn_info->req_ie_len,
4566                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4567         brcmf_dbg(CONN, "Report roaming result\n");
4568
4569         set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4570         brcmf_dbg(TRACE, "Exit\n");
4571         return err;
4572 }
4573
4574 static s32
4575 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4576                        struct net_device *ndev, const struct brcmf_event_msg *e,
4577                        bool completed)
4578 {
4579         struct brcmf_if *ifp = netdev_priv(ndev);
4580         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4581         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4582         s32 err = 0;
4583
4584         brcmf_dbg(TRACE, "Enter\n");
4585
4586         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4587                                &ifp->vif->sme_state)) {
4588                 if (completed) {
4589                         brcmf_get_assoc_ies(cfg, ifp);
4590                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4591                         brcmf_update_bss_info(cfg, ifp);
4592                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4593                                 &ifp->vif->sme_state);
4594                 }
4595                 cfg80211_connect_result(ndev,
4596                                         (u8 *)profile->bssid,
4597                                         conn_info->req_ie,
4598                                         conn_info->req_ie_len,
4599                                         conn_info->resp_ie,
4600                                         conn_info->resp_ie_len,
4601                                         completed ? WLAN_STATUS_SUCCESS :
4602                                                     WLAN_STATUS_AUTH_TIMEOUT,
4603                                         GFP_KERNEL);
4604                 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4605                           completed ? "succeeded" : "failed");
4606         }
4607         brcmf_dbg(TRACE, "Exit\n");
4608         return err;
4609 }
4610
4611 static s32
4612 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4613                                struct net_device *ndev,
4614                                const struct brcmf_event_msg *e, void *data)
4615 {
4616         static int generation;
4617         u32 event = e->event_code;
4618         u32 reason = e->reason;
4619         struct station_info sinfo;
4620
4621         brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4622         if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4623             ndev != cfg_to_ndev(cfg)) {
4624                 brcmf_dbg(CONN, "AP mode link down\n");
4625                 complete(&cfg->vif_disabled);
4626                 return 0;
4627         }
4628
4629         if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4630             (reason == BRCMF_E_STATUS_SUCCESS)) {
4631                 memset(&sinfo, 0, sizeof(sinfo));
4632                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4633                 if (!data) {
4634                         brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4635                         return -EINVAL;
4636                 }
4637                 sinfo.assoc_req_ies = data;
4638                 sinfo.assoc_req_ies_len = e->datalen;
4639                 generation++;
4640                 sinfo.generation = generation;
4641                 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4642         } else if ((event == BRCMF_E_DISASSOC_IND) ||
4643                    (event == BRCMF_E_DEAUTH_IND) ||
4644                    (event == BRCMF_E_DEAUTH)) {
4645                 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4646         }
4647         return 0;
4648 }
4649
4650 static s32
4651 brcmf_notify_connect_status(struct brcmf_if *ifp,
4652                             const struct brcmf_event_msg *e, void *data)
4653 {
4654         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4655         struct net_device *ndev = ifp->ndev;
4656         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4657         s32 err = 0;
4658
4659         if (ifp->vif->mode == WL_MODE_AP) {
4660                 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4661         } else if (brcmf_is_linkup(e)) {
4662                 brcmf_dbg(CONN, "Linkup\n");
4663                 if (brcmf_is_ibssmode(ifp->vif)) {
4664                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4665                         wl_inform_ibss(cfg, ndev, e->addr);
4666                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4667                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4668                                   &ifp->vif->sme_state);
4669                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4670                                 &ifp->vif->sme_state);
4671                 } else
4672                         brcmf_bss_connect_done(cfg, ndev, e, true);
4673         } else if (brcmf_is_linkdown(e)) {
4674                 brcmf_dbg(CONN, "Linkdown\n");
4675                 if (!brcmf_is_ibssmode(ifp->vif)) {
4676                         brcmf_bss_connect_done(cfg, ndev, e, false);
4677                         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4678                                                &ifp->vif->sme_state))
4679                                 cfg80211_disconnected(ndev, 0, NULL, 0,
4680                                                       GFP_KERNEL);
4681                 }
4682                 brcmf_link_down(ifp->vif);
4683                 brcmf_init_prof(ndev_to_prof(ndev));
4684                 if (ndev != cfg_to_ndev(cfg))
4685                         complete(&cfg->vif_disabled);
4686         } else if (brcmf_is_nonetwork(cfg, e)) {
4687                 if (brcmf_is_ibssmode(ifp->vif))
4688                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4689                                   &ifp->vif->sme_state);
4690                 else
4691                         brcmf_bss_connect_done(cfg, ndev, e, false);
4692         }
4693
4694         return err;
4695 }
4696
4697 static s32
4698 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4699                             const struct brcmf_event_msg *e, void *data)
4700 {
4701         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4702         s32 err = 0;
4703         u32 event = e->event_code;
4704         u32 status = e->status;
4705
4706         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4707                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4708                         brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4709                 else
4710                         brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4711         }
4712
4713         return err;
4714 }
4715
4716 static s32
4717 brcmf_notify_mic_status(struct brcmf_if *ifp,
4718                         const struct brcmf_event_msg *e, void *data)
4719 {
4720         u16 flags = e->flags;
4721         enum nl80211_key_type key_type;
4722
4723         if (flags & BRCMF_EVENT_MSG_GROUP)
4724                 key_type = NL80211_KEYTYPE_GROUP;
4725         else
4726                 key_type = NL80211_KEYTYPE_PAIRWISE;
4727
4728         cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4729                                      NULL, GFP_KERNEL);
4730
4731         return 0;
4732 }
4733
4734 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4735                                   const struct brcmf_event_msg *e, void *data)
4736 {
4737         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4738         struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4739         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4740         struct brcmf_cfg80211_vif *vif;
4741
4742         brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4743                   ifevent->action, ifevent->flags, ifevent->ifidx,
4744                   ifevent->bssidx);
4745
4746         mutex_lock(&event->vif_event_lock);
4747         event->action = ifevent->action;
4748         vif = event->vif;
4749
4750         switch (ifevent->action) {
4751         case BRCMF_E_IF_ADD:
4752                 /* waiting process may have timed out */
4753                 if (!cfg->vif_event.vif) {
4754                         mutex_unlock(&event->vif_event_lock);
4755                         return -EBADF;
4756                 }
4757
4758                 ifp->vif = vif;
4759                 vif->ifp = ifp;
4760                 if (ifp->ndev) {
4761                         vif->wdev.netdev = ifp->ndev;
4762                         ifp->ndev->ieee80211_ptr = &vif->wdev;
4763                         SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4764                 }
4765                 mutex_unlock(&event->vif_event_lock);
4766                 wake_up(&event->vif_wq);
4767                 return 0;
4768
4769         case BRCMF_E_IF_DEL:
4770                 mutex_unlock(&event->vif_event_lock);
4771                 /* event may not be upon user request */
4772                 if (brcmf_cfg80211_vif_event_armed(cfg))
4773                         wake_up(&event->vif_wq);
4774                 return 0;
4775
4776         case BRCMF_E_IF_CHANGE:
4777                 mutex_unlock(&event->vif_event_lock);
4778                 wake_up(&event->vif_wq);
4779                 return 0;
4780
4781         default:
4782                 mutex_unlock(&event->vif_event_lock);
4783                 break;
4784         }
4785         return -EINVAL;
4786 }
4787
4788 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4789 {
4790         conf->frag_threshold = (u32)-1;
4791         conf->rts_threshold = (u32)-1;
4792         conf->retry_short = (u32)-1;
4793         conf->retry_long = (u32)-1;
4794         conf->tx_power = -1;
4795 }
4796
4797 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4798 {
4799         brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4800                             brcmf_notify_connect_status);
4801         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4802                             brcmf_notify_connect_status);
4803         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4804                             brcmf_notify_connect_status);
4805         brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4806                             brcmf_notify_connect_status);
4807         brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4808                             brcmf_notify_connect_status);
4809         brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4810                             brcmf_notify_connect_status);
4811         brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4812                             brcmf_notify_roaming_status);
4813         brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4814                             brcmf_notify_mic_status);
4815         brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4816                             brcmf_notify_connect_status);
4817         brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4818                             brcmf_notify_sched_scan_results);
4819         brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4820                             brcmf_notify_vif_event);
4821         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4822                             brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4823         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4824                             brcmf_p2p_notify_listen_complete);
4825         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4826                             brcmf_p2p_notify_action_frame_rx);
4827         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4828                             brcmf_p2p_notify_action_tx_complete);
4829         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4830                             brcmf_p2p_notify_action_tx_complete);
4831 }
4832
4833 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4834 {
4835         kfree(cfg->conf);
4836         cfg->conf = NULL;
4837         kfree(cfg->escan_ioctl_buf);
4838         cfg->escan_ioctl_buf = NULL;
4839         kfree(cfg->extra_buf);
4840         cfg->extra_buf = NULL;
4841         kfree(cfg->pmk_list);
4842         cfg->pmk_list = NULL;
4843 }
4844
4845 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4846 {
4847         cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4848         if (!cfg->conf)
4849                 goto init_priv_mem_out;
4850         cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4851         if (!cfg->escan_ioctl_buf)
4852                 goto init_priv_mem_out;
4853         cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4854         if (!cfg->extra_buf)
4855                 goto init_priv_mem_out;
4856         cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4857         if (!cfg->pmk_list)
4858                 goto init_priv_mem_out;
4859
4860         return 0;
4861
4862 init_priv_mem_out:
4863         brcmf_deinit_priv_mem(cfg);
4864
4865         return -ENOMEM;
4866 }
4867
4868 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4869 {
4870         s32 err = 0;
4871
4872         cfg->scan_request = NULL;
4873         cfg->pwr_save = true;
4874         cfg->roam_on = true;    /* roam on & off switch.
4875                                  we enable roam per default */
4876         cfg->active_scan = true;        /* we do active scan for
4877                                  specific scan per default */
4878         cfg->dongle_up = false; /* dongle is not up yet */
4879         err = brcmf_init_priv_mem(cfg);
4880         if (err)
4881                 return err;
4882         brcmf_register_event_handlers(cfg);
4883         mutex_init(&cfg->usr_sync);
4884         brcmf_init_escan(cfg);
4885         brcmf_init_conf(cfg->conf);
4886         init_completion(&cfg->vif_disabled);
4887         return err;
4888 }
4889
4890 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4891 {
4892         cfg->dongle_up = false; /* dongle down */
4893         brcmf_abort_scanning(cfg);
4894         brcmf_deinit_priv_mem(cfg);
4895 }
4896
4897 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4898 {
4899         init_waitqueue_head(&event->vif_wq);
4900         mutex_init(&event->vif_event_lock);
4901 }
4902
4903 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4904                                                   struct device *busdev)
4905 {
4906         struct net_device *ndev = drvr->iflist[0]->ndev;
4907         struct brcmf_cfg80211_info *cfg;
4908         struct wiphy *wiphy;
4909         struct brcmf_cfg80211_vif *vif;
4910         struct brcmf_if *ifp;
4911         s32 err = 0;
4912         s32 io_type;
4913
4914         if (!ndev) {
4915                 brcmf_err("ndev is invalid\n");
4916                 return NULL;
4917         }
4918
4919         ifp = netdev_priv(ndev);
4920         wiphy = brcmf_setup_wiphy(busdev);
4921         if (IS_ERR(wiphy))
4922                 return NULL;
4923
4924         cfg = wiphy_priv(wiphy);
4925         cfg->wiphy = wiphy;
4926         cfg->pub = drvr;
4927         init_vif_event(&cfg->vif_event);
4928         INIT_LIST_HEAD(&cfg->vif_list);
4929
4930         vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4931         if (IS_ERR(vif)) {
4932                 wiphy_free(wiphy);
4933                 return NULL;
4934         }
4935
4936         vif->ifp = ifp;
4937         vif->wdev.netdev = ndev;
4938         ndev->ieee80211_ptr = &vif->wdev;
4939         SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4940
4941         err = wl_init_priv(cfg);
4942         if (err) {
4943                 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4944                 goto cfg80211_attach_out;
4945         }
4946         ifp->vif = vif;
4947
4948         err = brcmf_p2p_attach(cfg);
4949         if (err) {
4950                 brcmf_err("P2P initilisation failed (%d)\n", err);
4951                 goto cfg80211_p2p_attach_out;
4952         }
4953         err = brcmf_btcoex_attach(cfg);
4954         if (err) {
4955                 brcmf_err("BT-coex initialisation failed (%d)\n", err);
4956                 brcmf_p2p_detach(&cfg->p2p);
4957                 goto cfg80211_p2p_attach_out;
4958         }
4959
4960         err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
4961         if (err) {
4962                 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
4963                 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
4964         }
4965
4966         err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
4967                                     &io_type);
4968         if (err) {
4969                 brcmf_err("Failed to get D11 version (%d)\n", err);
4970                 goto cfg80211_p2p_attach_out;
4971         }
4972         cfg->d11inf.io_type = (u8)io_type;
4973         brcmu_d11_attach(&cfg->d11inf);
4974
4975         return cfg;
4976
4977 cfg80211_p2p_attach_out:
4978         wl_deinit_priv(cfg);
4979
4980 cfg80211_attach_out:
4981         brcmf_free_vif(cfg, vif);
4982         return NULL;
4983 }
4984
4985 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4986 {
4987         struct brcmf_cfg80211_vif *vif;
4988         struct brcmf_cfg80211_vif *tmp;
4989
4990         wl_deinit_priv(cfg);
4991         brcmf_btcoex_detach(cfg);
4992         list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4993                 brcmf_free_vif(cfg, vif);
4994         }
4995 }
4996
4997 static s32
4998 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
4999 {
5000         s32 err = 0;
5001         __le32 roamtrigger[2];
5002         __le32 roam_delta[2];
5003
5004         /*
5005          * Setup timeout if Beacons are lost and roam is
5006          * off to report link down
5007          */
5008         if (roamvar) {
5009                 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5010                 if (err) {
5011                         brcmf_err("bcn_timeout error (%d)\n", err);
5012                         goto dongle_rom_out;
5013                 }
5014         }
5015
5016         /*
5017          * Enable/Disable built-in roaming to allow supplicant
5018          * to take care of roaming
5019          */
5020         brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
5021         err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
5022         if (err) {
5023                 brcmf_err("roam_off error (%d)\n", err);
5024                 goto dongle_rom_out;
5025         }
5026
5027         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5028         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5029         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5030                                      (void *)roamtrigger, sizeof(roamtrigger));
5031         if (err) {
5032                 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5033                 goto dongle_rom_out;
5034         }
5035
5036         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5037         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5038         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5039                                      (void *)roam_delta, sizeof(roam_delta));
5040         if (err) {
5041                 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5042                 goto dongle_rom_out;
5043         }
5044
5045 dongle_rom_out:
5046         return err;
5047 }
5048
5049 static s32
5050 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5051                       s32 scan_unassoc_time, s32 scan_passive_time)
5052 {
5053         s32 err = 0;
5054
5055         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5056                                     scan_assoc_time);
5057         if (err) {
5058                 if (err == -EOPNOTSUPP)
5059                         brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5060                 else
5061                         brcmf_err("Scan assoc time error (%d)\n", err);
5062                 goto dongle_scantime_out;
5063         }
5064         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5065                                     scan_unassoc_time);
5066         if (err) {
5067                 if (err == -EOPNOTSUPP)
5068                         brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5069                 else
5070                         brcmf_err("Scan unassoc time error (%d)\n", err);
5071                 goto dongle_scantime_out;
5072         }
5073
5074         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5075                                     scan_passive_time);
5076         if (err) {
5077                 if (err == -EOPNOTSUPP)
5078                         brcmf_dbg(INFO, "Scan passive time is not supported\n");
5079                 else
5080                         brcmf_err("Scan passive time error (%d)\n", err);
5081                 goto dongle_scantime_out;
5082         }
5083
5084 dongle_scantime_out:
5085         return err;
5086 }
5087
5088
5089 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
5090 {
5091         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5092         struct ieee80211_channel *band_chan_arr;
5093         struct brcmf_chanspec_list *list;
5094         struct brcmu_chan ch;
5095         s32 err;
5096         u8 *pbuf;
5097         u32 i, j;
5098         u32 total;
5099         enum ieee80211_band band;
5100         u32 channel;
5101         u32 *n_cnt;
5102         bool ht40_allowed;
5103         u32 index;
5104         u32 ht40_flag;
5105         bool update;
5106         u32 array_size;
5107
5108         pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5109
5110         if (pbuf == NULL)
5111                 return -ENOMEM;
5112
5113         list = (struct brcmf_chanspec_list *)pbuf;
5114
5115         err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5116                                        BRCMF_DCMD_MEDLEN);
5117         if (err) {
5118                 brcmf_err("get chanspecs error (%d)\n", err);
5119                 goto exit;
5120         }
5121
5122         __wl_band_2ghz.n_channels = 0;
5123         __wl_band_5ghz_a.n_channels = 0;
5124
5125         total = le32_to_cpu(list->count);
5126         for (i = 0; i < total; i++) {
5127                 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5128                 cfg->d11inf.decchspec(&ch);
5129
5130                 if (ch.band == BRCMU_CHAN_BAND_2G) {
5131                         band_chan_arr = __wl_2ghz_channels;
5132                         array_size = ARRAY_SIZE(__wl_2ghz_channels);
5133                         n_cnt = &__wl_band_2ghz.n_channels;
5134                         band = IEEE80211_BAND_2GHZ;
5135                         ht40_allowed = (bw_cap == WLC_N_BW_40ALL);
5136                 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5137                         band_chan_arr = __wl_5ghz_a_channels;
5138                         array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5139                         n_cnt = &__wl_band_5ghz_a.n_channels;
5140                         band = IEEE80211_BAND_5GHZ;
5141                         ht40_allowed = !(bw_cap == WLC_N_BW_20ALL);
5142                 } else {
5143                         brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec);
5144                         continue;
5145                 }
5146                 if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40)
5147                         continue;
5148                 update = false;
5149                 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5150                         if (band_chan_arr[j].hw_value == ch.chnum) {
5151                                 update = true;
5152                                 break;
5153                         }
5154                 }
5155                 if (update)
5156                         index = j;
5157                 else
5158                         index = *n_cnt;
5159                 if (index <  array_size) {
5160                         band_chan_arr[index].center_freq =
5161                                 ieee80211_channel_to_frequency(ch.chnum, band);
5162                         band_chan_arr[index].hw_value = ch.chnum;
5163
5164                         if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) {
5165                                 /* assuming the order is HT20, HT40 Upper,
5166                                  * HT40 lower from chanspecs
5167                                  */
5168                                 ht40_flag = band_chan_arr[index].flags &
5169                                             IEEE80211_CHAN_NO_HT40;
5170                                 if (ch.sb == BRCMU_CHAN_SB_U) {
5171                                         if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5172                                                 band_chan_arr[index].flags &=
5173                                                         ~IEEE80211_CHAN_NO_HT40;
5174                                         band_chan_arr[index].flags |=
5175                                                 IEEE80211_CHAN_NO_HT40PLUS;
5176                                 } else {
5177                                         /* It should be one of
5178                                          * IEEE80211_CHAN_NO_HT40 or
5179                                          * IEEE80211_CHAN_NO_HT40PLUS
5180                                          */
5181                                         band_chan_arr[index].flags &=
5182                                                         ~IEEE80211_CHAN_NO_HT40;
5183                                         if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5184                                                 band_chan_arr[index].flags |=
5185                                                     IEEE80211_CHAN_NO_HT40MINUS;
5186                                 }
5187                         } else {
5188                                 band_chan_arr[index].flags =
5189                                                         IEEE80211_CHAN_NO_HT40;
5190                                 ch.bw = BRCMU_CHAN_BW_20;
5191                                 cfg->d11inf.encchspec(&ch);
5192                                 channel = ch.chspec;
5193                                 err = brcmf_fil_bsscfg_int_get(ifp,
5194                                                                "per_chan_info",
5195                                                                &channel);
5196                                 if (!err) {
5197                                         if (channel & WL_CHAN_RADAR)
5198                                                 band_chan_arr[index].flags |=
5199                                                         (IEEE80211_CHAN_RADAR |
5200                                                         IEEE80211_CHAN_NO_IBSS);
5201                                         if (channel & WL_CHAN_PASSIVE)
5202                                                 band_chan_arr[index].flags |=
5203                                                     IEEE80211_CHAN_PASSIVE_SCAN;
5204                                 }
5205                         }
5206                         if (!update)
5207                                 (*n_cnt)++;
5208                 }
5209         }
5210 exit:
5211         kfree(pbuf);
5212         return err;
5213 }
5214
5215
5216 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5217 {
5218         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5219         struct wiphy *wiphy;
5220         s32 phy_list;
5221         u32 band_list[3];
5222         u32 nmode;
5223         u32 bw_cap = 0;
5224         s8 phy;
5225         s32 err;
5226         u32 nband;
5227         s32 i;
5228         struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
5229         s32 index;
5230
5231         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5232                                      &phy_list, sizeof(phy_list));
5233         if (err) {
5234                 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5235                 return err;
5236         }
5237
5238         phy = ((char *)&phy_list)[0];
5239         brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5240
5241
5242         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5243                                      &band_list, sizeof(band_list));
5244         if (err) {
5245                 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5246                 return err;
5247         }
5248         brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5249                   band_list[0], band_list[1], band_list[2]);
5250
5251         err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5252         if (err) {
5253                 brcmf_err("nmode error (%d)\n", err);
5254         } else {
5255                 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap);
5256                 if (err)
5257                         brcmf_err("mimo_bw_cap error (%d)\n", err);
5258         }
5259         brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap);
5260
5261         err = brcmf_construct_reginfo(cfg, bw_cap);
5262         if (err) {
5263                 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5264                 return err;
5265         }
5266
5267         nband = band_list[0];
5268         memset(bands, 0, sizeof(bands));
5269
5270         for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5271                 index = -1;
5272                 if ((band_list[i] == WLC_BAND_5G) &&
5273                     (__wl_band_5ghz_a.n_channels > 0)) {
5274                         index = IEEE80211_BAND_5GHZ;
5275                         bands[index] = &__wl_band_5ghz_a;
5276                         if ((bw_cap == WLC_N_BW_40ALL) ||
5277                             (bw_cap == WLC_N_BW_20IN2G_40IN5G))
5278                                 bands[index]->ht_cap.cap |=
5279                                                         IEEE80211_HT_CAP_SGI_40;
5280                 } else if ((band_list[i] == WLC_BAND_2G) &&
5281                            (__wl_band_2ghz.n_channels > 0)) {
5282                         index = IEEE80211_BAND_2GHZ;
5283                         bands[index] = &__wl_band_2ghz;
5284                         if (bw_cap == WLC_N_BW_40ALL)
5285                                 bands[index]->ht_cap.cap |=
5286                                                         IEEE80211_HT_CAP_SGI_40;
5287                 }
5288
5289                 if ((index >= 0) && nmode) {
5290                         bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5291                         bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5292                         bands[index]->ht_cap.ht_supported = true;
5293                         bands[index]->ht_cap.ampdu_factor =
5294                                                 IEEE80211_HT_MAX_AMPDU_64K;
5295                         bands[index]->ht_cap.ampdu_density =
5296                                                 IEEE80211_HT_MPDU_DENSITY_16;
5297                         /* An HT shall support all EQM rates for one spatial
5298                          * stream
5299                          */
5300                         bands[index]->ht_cap.mcs.rx_mask[0] = 0xff;
5301                 }
5302         }
5303
5304         wiphy = cfg_to_wiphy(cfg);
5305         wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5306         wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5307         wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5308
5309         return err;
5310 }
5311
5312
5313 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5314 {
5315         return brcmf_update_wiphybands(cfg);
5316 }
5317
5318 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5319 {
5320         struct net_device *ndev;
5321         struct wireless_dev *wdev;
5322         struct brcmf_if *ifp;
5323         s32 power_mode;
5324         s32 err = 0;
5325
5326         if (cfg->dongle_up)
5327                 return err;
5328
5329         ndev = cfg_to_ndev(cfg);
5330         wdev = ndev->ieee80211_ptr;
5331         ifp = netdev_priv(ndev);
5332
5333         /* make sure RF is ready for work */
5334         brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5335
5336         brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5337                               WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5338
5339         power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5340         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5341         if (err)
5342                 goto default_conf_out;
5343         brcmf_dbg(INFO, "power save set to %s\n",
5344                   (power_mode ? "enabled" : "disabled"));
5345
5346         err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
5347         if (err)
5348                 goto default_conf_out;
5349         err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5350                                           NULL, NULL);
5351         if (err)
5352                 goto default_conf_out;
5353         err = brcmf_dongle_probecap(cfg);
5354         if (err)
5355                 goto default_conf_out;
5356
5357         brcmf_configure_arp_offload(ifp, true);
5358
5359         cfg->dongle_up = true;
5360 default_conf_out:
5361
5362         return err;
5363
5364 }
5365
5366 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5367 {
5368         set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5369
5370         return brcmf_config_dongle(ifp->drvr->config);
5371 }
5372
5373 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5374 {
5375         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5376
5377         /*
5378          * While going down, if associated with AP disassociate
5379          * from AP to save power
5380          */
5381         if (check_vif_up(ifp->vif)) {
5382                 brcmf_link_down(ifp->vif);
5383
5384                 /* Make sure WPA_Supplicant receives all the event
5385                    generated due to DISASSOC call to the fw to keep
5386                    the state fw and WPA_Supplicant state consistent
5387                  */
5388                 brcmf_delay(500);
5389         }
5390
5391         brcmf_abort_scanning(cfg);
5392         clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5393
5394         return 0;
5395 }
5396
5397 s32 brcmf_cfg80211_up(struct net_device *ndev)
5398 {
5399         struct brcmf_if *ifp = netdev_priv(ndev);
5400         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5401         s32 err = 0;
5402
5403         mutex_lock(&cfg->usr_sync);
5404         err = __brcmf_cfg80211_up(ifp);
5405         mutex_unlock(&cfg->usr_sync);
5406
5407         return err;
5408 }
5409
5410 s32 brcmf_cfg80211_down(struct net_device *ndev)
5411 {
5412         struct brcmf_if *ifp = netdev_priv(ndev);
5413         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5414         s32 err = 0;
5415
5416         mutex_lock(&cfg->usr_sync);
5417         err = __brcmf_cfg80211_down(ifp);
5418         mutex_unlock(&cfg->usr_sync);
5419
5420         return err;
5421 }
5422
5423 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5424 {
5425         struct wireless_dev *wdev = &ifp->vif->wdev;
5426
5427         return wdev->iftype;
5428 }
5429
5430 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5431 {
5432         struct brcmf_cfg80211_vif *vif;
5433         bool result = 0;
5434
5435         list_for_each_entry(vif, &cfg->vif_list, list) {
5436                 if (test_bit(state, &vif->sme_state))
5437                         result++;
5438         }
5439         return result;
5440 }
5441
5442 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5443                                     u8 action)
5444 {
5445         u8 evt_action;
5446
5447         mutex_lock(&event->vif_event_lock);
5448         evt_action = event->action;
5449         mutex_unlock(&event->vif_event_lock);
5450         return evt_action == action;
5451 }
5452
5453 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5454                                   struct brcmf_cfg80211_vif *vif)
5455 {
5456         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5457
5458         mutex_lock(&event->vif_event_lock);
5459         event->vif = vif;
5460         event->action = 0;
5461         mutex_unlock(&event->vif_event_lock);
5462 }
5463
5464 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5465 {
5466         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5467         bool armed;
5468
5469         mutex_lock(&event->vif_event_lock);
5470         armed = event->vif != NULL;
5471         mutex_unlock(&event->vif_event_lock);
5472
5473         return armed;
5474 }
5475 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5476                                           u8 action, ulong timeout)
5477 {
5478         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5479
5480         return wait_event_timeout(event->vif_wq,
5481                                   vif_event_equals(event, action), timeout);
5482 }
5483