2 * Copyright (c) 2010 Broadcom Corporation
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.
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.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
19 #include <linux/kernel.h>
20 #include <linux/etherdevice.h>
21 #include <net/cfg80211.h>
22 #include <net/netlink.h>
24 #include <brcmu_utils.h>
26 #include <brcmu_wifi.h>
29 #include "fwil_types.h"
31 #include "wl_cfg80211.h"
34 #define BRCMF_SCAN_IE_LEN_MAX 2048
35 #define BRCMF_PNO_VERSION 2
36 #define BRCMF_PNO_TIME 30
37 #define BRCMF_PNO_REPEAT 4
38 #define BRCMF_PNO_FREQ_EXPO_MAX 3
39 #define BRCMF_PNO_MAX_PFN_COUNT 16
40 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
41 #define BRCMF_PNO_HIDDEN_BIT 2
42 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
43 #define BRCMF_PNO_SCAN_COMPLETE 1
44 #define BRCMF_PNO_SCAN_INCOMPLETE 0
46 #define BRCMF_IFACE_MAX_CNT 3
48 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
49 #define WPA_OUI_TYPE 1
50 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
51 #define WME_OUI_TYPE 2
52 #define WPS_OUI_TYPE 4
54 #define VS_IE_FIXED_HDR_LEN 6
55 #define WPA_IE_VERSION_LEN 2
56 #define WPA_IE_MIN_OUI_LEN 4
57 #define WPA_IE_SUITE_COUNT_LEN 2
59 #define WPA_CIPHER_NONE 0 /* None */
60 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
61 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
62 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
63 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
65 #define RSN_AKM_NONE 0 /* None (IBSS) */
66 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
67 #define RSN_AKM_PSK 2 /* Pre-shared Key */
68 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
69 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
71 #define VNDR_IE_CMD_LEN 4 /* length of the set command
72 * string :"add", "del" (+ NUL)
74 #define VNDR_IE_COUNT_OFFSET 4
75 #define VNDR_IE_PKTFLAG_OFFSET 8
76 #define VNDR_IE_VSIE_OFFSET 12
77 #define VNDR_IE_HDR_SIZE 12
78 #define VNDR_IE_PARSE_LIMIT 5
80 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
81 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
83 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
84 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
85 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
87 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
88 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
90 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
92 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
93 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
100 #define CHAN2G(_channel, _freq, _flags) { \
101 .band = IEEE80211_BAND_2GHZ, \
102 .center_freq = (_freq), \
103 .hw_value = (_channel), \
105 .max_antenna_gain = 0, \
109 #define CHAN5G(_channel, _flags) { \
110 .band = IEEE80211_BAND_5GHZ, \
111 .center_freq = 5000 + (5 * (_channel)), \
112 .hw_value = (_channel), \
114 .max_antenna_gain = 0, \
118 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
119 #define RATETAB_ENT(_rateid, _flags) \
121 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
122 .hw_value = (_rateid), \
126 static struct ieee80211_rate __wl_rates[] = {
127 RATETAB_ENT(BRCM_RATE_1M, 0),
128 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
129 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
130 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
131 RATETAB_ENT(BRCM_RATE_6M, 0),
132 RATETAB_ENT(BRCM_RATE_9M, 0),
133 RATETAB_ENT(BRCM_RATE_12M, 0),
134 RATETAB_ENT(BRCM_RATE_18M, 0),
135 RATETAB_ENT(BRCM_RATE_24M, 0),
136 RATETAB_ENT(BRCM_RATE_36M, 0),
137 RATETAB_ENT(BRCM_RATE_48M, 0),
138 RATETAB_ENT(BRCM_RATE_54M, 0),
141 #define wl_a_rates (__wl_rates + 4)
142 #define wl_a_rates_size 8
143 #define wl_g_rates (__wl_rates + 0)
144 #define wl_g_rates_size 12
146 static struct ieee80211_channel __wl_2ghz_channels[] = {
163 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
164 CHAN5G(34, 0), CHAN5G(36, 0),
165 CHAN5G(38, 0), CHAN5G(40, 0),
166 CHAN5G(42, 0), CHAN5G(44, 0),
167 CHAN5G(46, 0), CHAN5G(48, 0),
168 CHAN5G(52, 0), CHAN5G(56, 0),
169 CHAN5G(60, 0), CHAN5G(64, 0),
170 CHAN5G(100, 0), CHAN5G(104, 0),
171 CHAN5G(108, 0), CHAN5G(112, 0),
172 CHAN5G(116, 0), CHAN5G(120, 0),
173 CHAN5G(124, 0), CHAN5G(128, 0),
174 CHAN5G(132, 0), CHAN5G(136, 0),
175 CHAN5G(140, 0), CHAN5G(149, 0),
176 CHAN5G(153, 0), CHAN5G(157, 0),
177 CHAN5G(161, 0), CHAN5G(165, 0),
178 CHAN5G(184, 0), CHAN5G(188, 0),
179 CHAN5G(192, 0), CHAN5G(196, 0),
180 CHAN5G(200, 0), CHAN5G(204, 0),
181 CHAN5G(208, 0), CHAN5G(212, 0),
185 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
186 CHAN5G(32, 0), CHAN5G(34, 0),
187 CHAN5G(36, 0), CHAN5G(38, 0),
188 CHAN5G(40, 0), CHAN5G(42, 0),
189 CHAN5G(44, 0), CHAN5G(46, 0),
190 CHAN5G(48, 0), CHAN5G(50, 0),
191 CHAN5G(52, 0), CHAN5G(54, 0),
192 CHAN5G(56, 0), CHAN5G(58, 0),
193 CHAN5G(60, 0), CHAN5G(62, 0),
194 CHAN5G(64, 0), CHAN5G(66, 0),
195 CHAN5G(68, 0), CHAN5G(70, 0),
196 CHAN5G(72, 0), CHAN5G(74, 0),
197 CHAN5G(76, 0), CHAN5G(78, 0),
198 CHAN5G(80, 0), CHAN5G(82, 0),
199 CHAN5G(84, 0), CHAN5G(86, 0),
200 CHAN5G(88, 0), CHAN5G(90, 0),
201 CHAN5G(92, 0), CHAN5G(94, 0),
202 CHAN5G(96, 0), CHAN5G(98, 0),
203 CHAN5G(100, 0), CHAN5G(102, 0),
204 CHAN5G(104, 0), CHAN5G(106, 0),
205 CHAN5G(108, 0), CHAN5G(110, 0),
206 CHAN5G(112, 0), CHAN5G(114, 0),
207 CHAN5G(116, 0), CHAN5G(118, 0),
208 CHAN5G(120, 0), CHAN5G(122, 0),
209 CHAN5G(124, 0), CHAN5G(126, 0),
210 CHAN5G(128, 0), CHAN5G(130, 0),
211 CHAN5G(132, 0), CHAN5G(134, 0),
212 CHAN5G(136, 0), CHAN5G(138, 0),
213 CHAN5G(140, 0), CHAN5G(142, 0),
214 CHAN5G(144, 0), CHAN5G(145, 0),
215 CHAN5G(146, 0), CHAN5G(147, 0),
216 CHAN5G(148, 0), CHAN5G(149, 0),
217 CHAN5G(150, 0), CHAN5G(151, 0),
218 CHAN5G(152, 0), CHAN5G(153, 0),
219 CHAN5G(154, 0), CHAN5G(155, 0),
220 CHAN5G(156, 0), CHAN5G(157, 0),
221 CHAN5G(158, 0), CHAN5G(159, 0),
222 CHAN5G(160, 0), CHAN5G(161, 0),
223 CHAN5G(162, 0), CHAN5G(163, 0),
224 CHAN5G(164, 0), CHAN5G(165, 0),
225 CHAN5G(166, 0), CHAN5G(168, 0),
226 CHAN5G(170, 0), CHAN5G(172, 0),
227 CHAN5G(174, 0), CHAN5G(176, 0),
228 CHAN5G(178, 0), CHAN5G(180, 0),
229 CHAN5G(182, 0), CHAN5G(184, 0),
230 CHAN5G(186, 0), CHAN5G(188, 0),
231 CHAN5G(190, 0), CHAN5G(192, 0),
232 CHAN5G(194, 0), CHAN5G(196, 0),
233 CHAN5G(198, 0), CHAN5G(200, 0),
234 CHAN5G(202, 0), CHAN5G(204, 0),
235 CHAN5G(206, 0), CHAN5G(208, 0),
236 CHAN5G(210, 0), CHAN5G(212, 0),
237 CHAN5G(214, 0), CHAN5G(216, 0),
238 CHAN5G(218, 0), CHAN5G(220, 0),
239 CHAN5G(222, 0), CHAN5G(224, 0),
240 CHAN5G(226, 0), CHAN5G(228, 0),
243 static struct ieee80211_supported_band __wl_band_2ghz = {
244 .band = IEEE80211_BAND_2GHZ,
245 .channels = __wl_2ghz_channels,
246 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
247 .bitrates = wl_g_rates,
248 .n_bitrates = wl_g_rates_size,
251 static struct ieee80211_supported_band __wl_band_5ghz_a = {
252 .band = IEEE80211_BAND_5GHZ,
253 .channels = __wl_5ghz_a_channels,
254 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
255 .bitrates = wl_a_rates,
256 .n_bitrates = wl_a_rates_size,
259 static struct ieee80211_supported_band __wl_band_5ghz_n = {
260 .band = IEEE80211_BAND_5GHZ,
261 .channels = __wl_5ghz_n_channels,
262 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
263 .bitrates = wl_a_rates,
264 .n_bitrates = wl_a_rates_size,
267 static const u32 __wl_cipher_suites[] = {
268 WLAN_CIPHER_SUITE_WEP40,
269 WLAN_CIPHER_SUITE_WEP104,
270 WLAN_CIPHER_SUITE_TKIP,
271 WLAN_CIPHER_SUITE_CCMP,
272 WLAN_CIPHER_SUITE_AES_CMAC,
275 /* Vendor specific ie. id = 221, oui and type defines exact ie */
276 struct brcmf_vs_tlv {
283 struct parsed_vndr_ie_info {
285 u32 ie_len; /* total length including id & length field */
286 struct brcmf_vs_tlv vndrie;
289 struct parsed_vndr_ies {
291 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
294 /* Quarter dBm units to mW
295 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
296 * Table is offset so the last entry is largest mW value that fits in
300 #define QDBM_OFFSET 153 /* Offset for first entry */
301 #define QDBM_TABLE_LEN 40 /* Table size */
303 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
304 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
306 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
308 /* Largest mW value that will round down to the last table entry,
309 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
310 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
311 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
313 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
315 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
316 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
317 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
318 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
319 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
320 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
321 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
324 static u16 brcmf_qdbm_to_mw(u8 qdbm)
327 int idx = qdbm - QDBM_OFFSET;
329 if (idx >= QDBM_TABLE_LEN)
330 /* clamp to max u16 mW value */
333 /* scale the qdBm index up to the range of the table 0-40
334 * where an offset of 40 qdBm equals a factor of 10 mW.
341 /* return the mW value scaled down to the correct factor of 10,
342 * adding in factor/2 to get proper rounding.
344 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
347 static u8 brcmf_mw_to_qdbm(u16 mw)
354 /* handle boundary case */
358 offset = QDBM_OFFSET;
360 /* move mw into the range of the table */
361 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
366 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
367 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
368 nqdBm_to_mW_map[qdbm]) / 2;
369 if (mw_uint < boundary)
378 u16 channel_to_chanspec(struct ieee80211_channel *ch)
382 chanspec = ieee80211_frequency_to_channel(ch->center_freq);
383 chanspec &= WL_CHANSPEC_CHAN_MASK;
385 if (ch->band == IEEE80211_BAND_2GHZ)
386 chanspec |= WL_CHANSPEC_BAND_2G;
388 chanspec |= WL_CHANSPEC_BAND_5G;
390 chanspec |= WL_CHANSPEC_BW_20;
391 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
396 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
397 * triples, returning a pointer to the substring whose first element
400 struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
402 struct brcmf_tlv *elt;
405 elt = (struct brcmf_tlv *)buf;
408 /* find tagged parameter */
409 while (totlen >= TLV_HDR_LEN) {
412 /* validate remaining totlen */
413 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
416 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
417 totlen -= (len + TLV_HDR_LEN);
423 /* Is any of the tlvs the expected entry? If
424 * not update the tlvs buffer pointer/length.
427 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
428 u8 *oui, u32 oui_len, u8 type)
430 /* If the contents match the OUI and the type */
431 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
432 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
433 type == ie[TLV_BODY_OFF + oui_len]) {
439 /* point to the next ie */
440 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
441 /* calculate the length of the rest of the buffer */
442 *tlvs_len -= (int)(ie - *tlvs);
443 /* update the pointer to the start of the buffer */
449 static struct brcmf_vs_tlv *
450 brcmf_find_wpaie(u8 *parse, u32 len)
452 struct brcmf_tlv *ie;
454 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
455 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
456 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
457 return (struct brcmf_vs_tlv *)ie;
462 static struct brcmf_vs_tlv *
463 brcmf_find_wpsie(u8 *parse, u32 len)
465 struct brcmf_tlv *ie;
467 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
468 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
469 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
470 return (struct brcmf_vs_tlv *)ie;
476 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
477 struct brcmf_wsec_key_le *key_le)
479 key_le->index = cpu_to_le32(key->index);
480 key_le->len = cpu_to_le32(key->len);
481 key_le->algo = cpu_to_le32(key->algo);
482 key_le->flags = cpu_to_le32(key->flags);
483 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
484 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
485 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
486 memcpy(key_le->data, key->data, sizeof(key->data));
487 memcpy(key_le->ea, key->ea, sizeof(key->ea));
491 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
494 struct brcmf_wsec_key_le key_le;
496 convert_key_from_CPU(key, &key_le);
498 brcmf_netdev_wait_pend8021x(ndev);
500 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
504 brcmf_err("wsec_key error (%d)\n", err);
508 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
510 enum nl80211_iftype type,
512 struct vif_params *params)
514 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
516 case NL80211_IFTYPE_ADHOC:
517 case NL80211_IFTYPE_STATION:
518 case NL80211_IFTYPE_AP:
519 case NL80211_IFTYPE_AP_VLAN:
520 case NL80211_IFTYPE_WDS:
521 case NL80211_IFTYPE_MONITOR:
522 case NL80211_IFTYPE_MESH_POINT:
523 return ERR_PTR(-EOPNOTSUPP);
524 case NL80211_IFTYPE_P2P_CLIENT:
525 case NL80211_IFTYPE_P2P_GO:
526 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
527 case NL80211_IFTYPE_UNSPECIFIED:
528 case NL80211_IFTYPE_P2P_DEVICE:
530 return ERR_PTR(-EINVAL);
534 void brcmf_set_mpc(struct net_device *ndev, int mpc)
536 struct brcmf_if *ifp = netdev_priv(ndev);
539 if (check_vif_up(ifp->vif)) {
540 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
542 brcmf_err("fail to set mpc\n");
545 brcmf_dbg(INFO, "MPC : %d\n", mpc);
550 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
551 struct net_device *ndev,
552 bool aborted, bool fw_abort)
554 struct brcmf_scan_params_le params_le;
555 struct cfg80211_scan_request *scan_request;
558 brcmf_dbg(SCAN, "Enter\n");
560 /* clear scan request, because the FW abort can cause a second call */
561 /* to this functon and might cause a double cfg80211_scan_done */
562 scan_request = cfg->scan_request;
563 cfg->scan_request = NULL;
565 if (timer_pending(&cfg->escan_timeout))
566 del_timer_sync(&cfg->escan_timeout);
569 /* Do a scan abort to stop the driver's scan engine */
570 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
571 memset(¶ms_le, 0, sizeof(params_le));
572 memset(params_le.bssid, 0xFF, ETH_ALEN);
573 params_le.bss_type = DOT11_BSSTYPE_ANY;
574 params_le.scan_type = 0;
575 params_le.channel_num = cpu_to_le32(1);
576 params_le.nprobes = cpu_to_le32(1);
577 params_le.active_time = cpu_to_le32(-1);
578 params_le.passive_time = cpu_to_le32(-1);
579 params_le.home_time = cpu_to_le32(-1);
580 /* Scan is aborted by setting channel_list[0] to -1 */
581 params_le.channel_list[0] = cpu_to_le16(-1);
582 /* E-Scan (or anyother type) can be aborted by SCAN */
583 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
584 ¶ms_le, sizeof(params_le));
586 brcmf_err("Scan abort failed\n");
589 * e-scan can be initiated by scheduled scan
590 * which takes precedence.
592 if (cfg->sched_escan) {
593 brcmf_dbg(SCAN, "scheduled scan completed\n");
594 cfg->sched_escan = false;
596 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
597 brcmf_set_mpc(ndev, 1);
598 } else if (scan_request) {
599 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
600 aborted ? "Aborted" : "Done");
601 cfg80211_scan_done(scan_request, aborted);
602 brcmf_set_mpc(ndev, 1);
604 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
605 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
611 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
613 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
614 struct net_device *ndev = wdev->netdev;
616 /* vif event pending in firmware */
617 if (brcmf_cfg80211_vif_event_armed(cfg))
621 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
622 cfg->escan_info.ndev == ndev)
623 brcmf_notify_escan_complete(cfg, ndev, true,
626 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
629 switch (wdev->iftype) {
630 case NL80211_IFTYPE_ADHOC:
631 case NL80211_IFTYPE_STATION:
632 case NL80211_IFTYPE_AP:
633 case NL80211_IFTYPE_AP_VLAN:
634 case NL80211_IFTYPE_WDS:
635 case NL80211_IFTYPE_MONITOR:
636 case NL80211_IFTYPE_MESH_POINT:
638 case NL80211_IFTYPE_P2P_CLIENT:
639 case NL80211_IFTYPE_P2P_GO:
640 return brcmf_p2p_del_vif(wiphy, wdev);
641 case NL80211_IFTYPE_UNSPECIFIED:
642 case NL80211_IFTYPE_P2P_DEVICE:
650 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
651 enum nl80211_iftype type, u32 *flags,
652 struct vif_params *params)
654 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
655 struct brcmf_if *ifp = netdev_priv(ndev);
656 struct brcmf_cfg80211_vif *vif = ifp->vif;
661 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
664 case NL80211_IFTYPE_MONITOR:
665 case NL80211_IFTYPE_WDS:
666 brcmf_err("type (%d) : currently we do not support this type\n",
669 case NL80211_IFTYPE_ADHOC:
670 vif->mode = WL_MODE_IBSS;
673 case NL80211_IFTYPE_STATION:
674 /* Ignore change for p2p IF. Unclear why supplicant does this */
675 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
676 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
677 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
678 /* WAR: It is unexpected to get a change of VIF for P2P
679 * IF, but it happens. The request can not be handled
680 * but returning EPERM causes a crash. Returning 0
681 * without setting ieee80211_ptr->iftype causes trace
682 * (WARN_ON) but it works with wpa_supplicant
686 vif->mode = WL_MODE_BSS;
689 case NL80211_IFTYPE_AP:
690 case NL80211_IFTYPE_P2P_GO:
691 vif->mode = WL_MODE_AP;
700 if (type == NL80211_IFTYPE_P2P_GO) {
701 brcmf_dbg(INFO, "IF Type = P2P GO\n");
702 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
705 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
706 brcmf_dbg(INFO, "IF Type = AP\n");
709 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
711 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
715 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
718 ndev->ieee80211_ptr->iftype = type;
721 brcmf_dbg(TRACE, "Exit\n");
726 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
727 struct cfg80211_scan_request *request)
735 struct brcmf_ssid_le ssid_le;
737 memset(params_le->bssid, 0xFF, ETH_ALEN);
738 params_le->bss_type = DOT11_BSSTYPE_ANY;
739 params_le->scan_type = 0;
740 params_le->channel_num = 0;
741 params_le->nprobes = cpu_to_le32(-1);
742 params_le->active_time = cpu_to_le32(-1);
743 params_le->passive_time = cpu_to_le32(-1);
744 params_le->home_time = cpu_to_le32(-1);
745 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
747 /* if request is null exit so it will be all channel broadcast scan */
751 n_ssids = request->n_ssids;
752 n_channels = request->n_channels;
753 /* Copy channel array if applicable */
754 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
756 if (n_channels > 0) {
757 for (i = 0; i < n_channels; i++) {
758 chanspec = channel_to_chanspec(request->channels[i]);
759 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
760 request->channels[i]->hw_value, chanspec);
761 params_le->channel_list[i] = cpu_to_le16(chanspec);
764 brcmf_dbg(SCAN, "Scanning all channels\n");
766 /* Copy ssid array if applicable */
767 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
769 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
770 n_channels * sizeof(u16);
771 offset = roundup(offset, sizeof(u32));
772 ptr = (char *)params_le + offset;
773 for (i = 0; i < n_ssids; i++) {
774 memset(&ssid_le, 0, sizeof(ssid_le));
776 cpu_to_le32(request->ssids[i].ssid_len);
777 memcpy(ssid_le.SSID, request->ssids[i].ssid,
778 request->ssids[i].ssid_len);
779 if (!ssid_le.SSID_len)
780 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
782 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
783 i, ssid_le.SSID, ssid_le.SSID_len);
784 memcpy(ptr, &ssid_le, sizeof(ssid_le));
785 ptr += sizeof(ssid_le);
788 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
789 if ((request->ssids) && request->ssids->ssid_len) {
790 brcmf_dbg(SCAN, "SSID %s len=%d\n",
791 params_le->ssid_le.SSID,
792 request->ssids->ssid_len);
793 params_le->ssid_le.SSID_len =
794 cpu_to_le32(request->ssids->ssid_len);
795 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
796 request->ssids->ssid_len);
799 /* Adding mask to channel numbers */
800 params_le->channel_num =
801 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
802 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
806 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
807 struct cfg80211_scan_request *request, u16 action)
809 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
810 offsetof(struct brcmf_escan_params_le, params_le);
811 struct brcmf_escan_params_le *params;
814 brcmf_dbg(SCAN, "E-SCAN START\n");
816 if (request != NULL) {
817 /* Allocate space for populating ssids in struct */
818 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
820 /* Allocate space for populating ssids in struct */
821 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
824 params = kzalloc(params_size, GFP_KERNEL);
829 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
830 brcmf_escan_prep(¶ms->params_le, request);
831 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
832 params->action = cpu_to_le16(action);
833 params->sync_id = cpu_to_le16(0x1234);
835 err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan",
836 params, params_size);
839 brcmf_dbg(INFO, "system busy : escan canceled\n");
841 brcmf_err("error (%d)\n", err);
850 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
851 struct net_device *ndev, struct cfg80211_scan_request *request)
855 struct brcmf_scan_results *results;
856 struct escan_info *escan = &cfg->escan_info;
858 brcmf_dbg(SCAN, "Enter\n");
860 escan->wiphy = wiphy;
861 escan->escan_state = WL_ESCAN_STATE_SCANNING;
862 passive_scan = cfg->active_scan ? 0 : 1;
863 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
866 brcmf_err("error (%d)\n", err);
869 brcmf_set_mpc(ndev, 0);
870 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
871 results->version = 0;
873 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
875 err = escan->run(cfg, ndev, request, WL_ESCAN_ACTION_START);
877 brcmf_set_mpc(ndev, 1);
882 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
883 struct cfg80211_scan_request *request,
884 struct cfg80211_ssid *this_ssid)
886 struct brcmf_if *ifp = netdev_priv(ndev);
887 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
888 struct cfg80211_ssid *ssids;
889 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
896 brcmf_dbg(SCAN, "START ESCAN\n");
898 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
899 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
902 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
903 brcmf_err("Scanning being aborted: status (%lu)\n",
907 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
908 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
912 /* If scan req comes for p2p0, send it over primary I/F */
913 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) {
914 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
918 /* Arm scan timeout timer */
919 mod_timer(&cfg->escan_timeout, jiffies +
920 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
925 ssids = request->ssids;
929 /* we don't do escan in ibss */
933 cfg->scan_request = request;
934 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
936 cfg->escan_info.run = brcmf_run_escan;
937 err = brcmf_p2p_scan_prep(wiphy, request, ifp->vif);
941 err = brcmf_do_escan(cfg, wiphy, ndev, request);
945 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
946 ssids->ssid, ssids->ssid_len);
947 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
948 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
949 sr->ssid_le.SSID_len = cpu_to_le32(0);
952 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
953 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
956 brcmf_dbg(SCAN, "Broadcast scan\n");
958 passive_scan = cfg->active_scan ? 0 : 1;
959 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
962 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
965 brcmf_set_mpc(ndev, 0);
966 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
967 &sr->ssid_le, sizeof(sr->ssid_le));
970 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
973 brcmf_err("WLC_SCAN error (%d)\n", err);
975 brcmf_set_mpc(ndev, 1);
983 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
984 if (timer_pending(&cfg->escan_timeout))
985 del_timer_sync(&cfg->escan_timeout);
986 cfg->scan_request = NULL;
991 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
993 struct net_device *ndev = request->wdev->netdev;
996 brcmf_dbg(TRACE, "Enter\n");
998 if (!check_vif_up(container_of(request->wdev,
999 struct brcmf_cfg80211_vif, wdev)))
1002 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1005 brcmf_err("scan error (%d)\n", err);
1007 brcmf_dbg(TRACE, "Exit\n");
1011 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1015 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1018 brcmf_err("Error (%d)\n", err);
1023 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1027 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1030 brcmf_err("Error (%d)\n", err);
1035 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1038 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1040 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1042 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1048 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1050 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1051 struct net_device *ndev = cfg_to_ndev(cfg);
1052 struct brcmf_if *ifp = netdev_priv(ndev);
1055 brcmf_dbg(TRACE, "Enter\n");
1056 if (!check_vif_up(ifp->vif))
1059 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1060 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1061 cfg->conf->rts_threshold = wiphy->rts_threshold;
1062 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1066 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1067 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1068 cfg->conf->frag_threshold = wiphy->frag_threshold;
1069 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1073 if (changed & WIPHY_PARAM_RETRY_LONG
1074 && (cfg->conf->retry_long != wiphy->retry_long)) {
1075 cfg->conf->retry_long = wiphy->retry_long;
1076 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1080 if (changed & WIPHY_PARAM_RETRY_SHORT
1081 && (cfg->conf->retry_short != wiphy->retry_short)) {
1082 cfg->conf->retry_short = wiphy->retry_short;
1083 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1089 brcmf_dbg(TRACE, "Exit\n");
1093 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1095 memset(prof, 0, sizeof(*prof));
1098 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1102 brcmf_dbg(TRACE, "Enter\n");
1104 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1105 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1106 err = brcmf_fil_cmd_data_set(vif->ifp,
1107 BRCMF_C_DISASSOC, NULL, 0);
1109 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1110 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1112 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1113 brcmf_dbg(TRACE, "Exit\n");
1117 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1118 struct cfg80211_ibss_params *params)
1120 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1121 struct brcmf_if *ifp = netdev_priv(ndev);
1122 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1123 struct brcmf_join_params join_params;
1124 size_t join_params_size = 0;
1130 brcmf_dbg(TRACE, "Enter\n");
1131 if (!check_vif_up(ifp->vif))
1135 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1137 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1141 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1144 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1146 brcmf_dbg(CONN, "No BSSID specified\n");
1148 if (params->chandef.chan)
1149 brcmf_dbg(CONN, "channel: %d\n",
1150 params->chandef.chan->center_freq);
1152 brcmf_dbg(CONN, "no channel specified\n");
1154 if (params->channel_fixed)
1155 brcmf_dbg(CONN, "fixed channel required\n");
1157 brcmf_dbg(CONN, "no fixed channel required\n");
1159 if (params->ie && params->ie_len)
1160 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1162 brcmf_dbg(CONN, "no ie specified\n");
1164 if (params->beacon_interval)
1165 brcmf_dbg(CONN, "beacon interval: %d\n",
1166 params->beacon_interval);
1168 brcmf_dbg(CONN, "no beacon interval specified\n");
1170 if (params->basic_rates)
1171 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1173 brcmf_dbg(CONN, "no basic rates specified\n");
1175 if (params->privacy)
1176 brcmf_dbg(CONN, "privacy required\n");
1178 brcmf_dbg(CONN, "no privacy required\n");
1180 /* Configure Privacy for starter */
1181 if (params->privacy)
1182 wsec |= WEP_ENABLED;
1184 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1186 brcmf_err("wsec failed (%d)\n", err);
1190 /* Configure Beacon Interval for starter */
1191 if (params->beacon_interval)
1192 bcnprd = params->beacon_interval;
1196 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1198 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1202 /* Configure required join parameter */
1203 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1206 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1207 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1208 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1209 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1210 join_params_size = sizeof(join_params.ssid_le);
1213 if (params->bssid) {
1214 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1215 join_params_size = sizeof(join_params.ssid_le) +
1216 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1217 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1219 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1220 memset(profile->bssid, 0, ETH_ALEN);
1224 if (params->chandef.chan) {
1228 ieee80211_frequency_to_channel(
1229 params->chandef.chan->center_freq);
1230 if (params->channel_fixed) {
1231 /* adding chanspec */
1232 chanspec = channel_to_chanspec(params->chandef.chan);
1233 join_params.params_le.chanspec_list[0] =
1234 cpu_to_le16(chanspec);
1235 join_params.params_le.chanspec_num = cpu_to_le32(1);
1236 join_params_size += sizeof(join_params.params_le);
1239 /* set channel for starter */
1240 target_channel = cfg->channel;
1241 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1244 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1250 cfg->ibss_starter = false;
1253 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1254 &join_params, join_params_size);
1256 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1262 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1263 brcmf_dbg(TRACE, "Exit\n");
1268 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1270 struct brcmf_if *ifp = netdev_priv(ndev);
1273 brcmf_dbg(TRACE, "Enter\n");
1274 if (!check_vif_up(ifp->vif))
1277 brcmf_link_down(ifp->vif);
1279 brcmf_dbg(TRACE, "Exit\n");
1284 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1285 struct cfg80211_connect_params *sme)
1287 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1288 struct brcmf_cfg80211_security *sec;
1292 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1293 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1294 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1295 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1297 val = WPA_AUTH_DISABLED;
1298 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1299 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1301 brcmf_err("set wpa_auth failed (%d)\n", err);
1304 sec = &profile->sec;
1305 sec->wpa_versions = sme->crypto.wpa_versions;
1309 static s32 brcmf_set_auth_type(struct net_device *ndev,
1310 struct cfg80211_connect_params *sme)
1312 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1313 struct brcmf_cfg80211_security *sec;
1317 switch (sme->auth_type) {
1318 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1320 brcmf_dbg(CONN, "open system\n");
1322 case NL80211_AUTHTYPE_SHARED_KEY:
1324 brcmf_dbg(CONN, "shared key\n");
1326 case NL80211_AUTHTYPE_AUTOMATIC:
1328 brcmf_dbg(CONN, "automatic\n");
1330 case NL80211_AUTHTYPE_NETWORK_EAP:
1331 brcmf_dbg(CONN, "network eap\n");
1334 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1338 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1340 brcmf_err("set auth failed (%d)\n", err);
1343 sec = &profile->sec;
1344 sec->auth_type = sme->auth_type;
1349 brcmf_set_set_cipher(struct net_device *ndev,
1350 struct cfg80211_connect_params *sme)
1352 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1353 struct brcmf_cfg80211_security *sec;
1358 if (sme->crypto.n_ciphers_pairwise) {
1359 switch (sme->crypto.ciphers_pairwise[0]) {
1360 case WLAN_CIPHER_SUITE_WEP40:
1361 case WLAN_CIPHER_SUITE_WEP104:
1364 case WLAN_CIPHER_SUITE_TKIP:
1365 pval = TKIP_ENABLED;
1367 case WLAN_CIPHER_SUITE_CCMP:
1370 case WLAN_CIPHER_SUITE_AES_CMAC:
1374 brcmf_err("invalid cipher pairwise (%d)\n",
1375 sme->crypto.ciphers_pairwise[0]);
1379 if (sme->crypto.cipher_group) {
1380 switch (sme->crypto.cipher_group) {
1381 case WLAN_CIPHER_SUITE_WEP40:
1382 case WLAN_CIPHER_SUITE_WEP104:
1385 case WLAN_CIPHER_SUITE_TKIP:
1386 gval = TKIP_ENABLED;
1388 case WLAN_CIPHER_SUITE_CCMP:
1391 case WLAN_CIPHER_SUITE_AES_CMAC:
1395 brcmf_err("invalid cipher group (%d)\n",
1396 sme->crypto.cipher_group);
1401 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1402 /* In case of privacy, but no security and WPS then simulate */
1403 /* setting AES. WPS-2.0 allows no security */
1404 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1407 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
1409 brcmf_err("error (%d)\n", err);
1413 sec = &profile->sec;
1414 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1415 sec->cipher_group = sme->crypto.cipher_group;
1421 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1423 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1424 struct brcmf_cfg80211_security *sec;
1428 if (sme->crypto.n_akm_suites) {
1429 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1432 brcmf_err("could not get wpa_auth (%d)\n", err);
1435 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1436 switch (sme->crypto.akm_suites[0]) {
1437 case WLAN_AKM_SUITE_8021X:
1438 val = WPA_AUTH_UNSPECIFIED;
1440 case WLAN_AKM_SUITE_PSK:
1444 brcmf_err("invalid cipher group (%d)\n",
1445 sme->crypto.cipher_group);
1448 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1449 switch (sme->crypto.akm_suites[0]) {
1450 case WLAN_AKM_SUITE_8021X:
1451 val = WPA2_AUTH_UNSPECIFIED;
1453 case WLAN_AKM_SUITE_PSK:
1454 val = WPA2_AUTH_PSK;
1457 brcmf_err("invalid cipher group (%d)\n",
1458 sme->crypto.cipher_group);
1463 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1464 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1467 brcmf_err("could not set wpa_auth (%d)\n", err);
1471 sec = &profile->sec;
1472 sec->wpa_auth = sme->crypto.akm_suites[0];
1478 brcmf_set_sharedkey(struct net_device *ndev,
1479 struct cfg80211_connect_params *sme)
1481 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1482 struct brcmf_cfg80211_security *sec;
1483 struct brcmf_wsec_key key;
1487 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1489 if (sme->key_len == 0)
1492 sec = &profile->sec;
1493 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1494 sec->wpa_versions, sec->cipher_pairwise);
1496 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1499 if (!(sec->cipher_pairwise &
1500 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1503 memset(&key, 0, sizeof(key));
1504 key.len = (u32) sme->key_len;
1505 key.index = (u32) sme->key_idx;
1506 if (key.len > sizeof(key.data)) {
1507 brcmf_err("Too long key length (%u)\n", key.len);
1510 memcpy(key.data, sme->key, key.len);
1511 key.flags = BRCMF_PRIMARY_KEY;
1512 switch (sec->cipher_pairwise) {
1513 case WLAN_CIPHER_SUITE_WEP40:
1514 key.algo = CRYPTO_ALGO_WEP1;
1516 case WLAN_CIPHER_SUITE_WEP104:
1517 key.algo = CRYPTO_ALGO_WEP128;
1520 brcmf_err("Invalid algorithm (%d)\n",
1521 sme->crypto.ciphers_pairwise[0]);
1524 /* Set the new key/index */
1525 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1526 key.len, key.index, key.algo);
1527 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1528 err = send_key_to_dongle(ndev, &key);
1532 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1533 brcmf_dbg(CONN, "set auth_type to shared key\n");
1534 val = WL_AUTH_SHARED_KEY; /* shared key */
1535 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1537 brcmf_err("set auth failed (%d)\n", err);
1543 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1544 enum nl80211_auth_type type)
1547 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1548 /* shift to ignore chip revision */
1549 ci = brcmf_get_chip_info(ifp) >> 4;
1552 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1553 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1562 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1563 struct cfg80211_connect_params *sme)
1565 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1566 struct brcmf_if *ifp = netdev_priv(ndev);
1567 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1568 struct ieee80211_channel *chan = sme->channel;
1569 struct brcmf_join_params join_params;
1570 size_t join_params_size;
1571 struct brcmf_tlv *rsn_ie;
1572 struct brcmf_vs_tlv *wpa_ie;
1575 struct brcmf_ext_join_params_le *ext_join_params;
1580 brcmf_dbg(TRACE, "Enter\n");
1581 if (!check_vif_up(ifp->vif))
1585 brcmf_err("Invalid ssid\n");
1589 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1590 /* A normal (non P2P) connection request setup. */
1593 /* find the WPA_IE */
1594 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1597 ie_len = wpa_ie->len + TLV_HDR_LEN;
1599 /* find the RSN_IE */
1600 rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
1604 ie_len = rsn_ie->len + TLV_HDR_LEN;
1607 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1610 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1611 sme->ie, sme->ie_len);
1613 brcmf_err("Set Assoc REQ IE Failed\n");
1615 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1617 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1621 ieee80211_frequency_to_channel(chan->center_freq);
1622 chanspec = channel_to_chanspec(chan);
1623 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1624 cfg->channel, chan->center_freq, chanspec);
1630 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1632 err = brcmf_set_wpa_version(ndev, sme);
1634 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1638 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1639 err = brcmf_set_auth_type(ndev, sme);
1641 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1645 err = brcmf_set_set_cipher(ndev, sme);
1647 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1651 err = brcmf_set_key_mgmt(ndev, sme);
1653 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1657 err = brcmf_set_sharedkey(ndev, sme);
1659 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1663 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1664 (u32)sme->ssid_len);
1665 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1666 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1667 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1668 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1669 profile->ssid.SSID_len);
1672 /* Join with specific BSSID and cached SSID
1673 * If SSID is zero join based on BSSID only
1675 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1676 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1678 join_params_size += sizeof(u16);
1679 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1680 if (ext_join_params == NULL) {
1684 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1685 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1686 profile->ssid.SSID_len);
1687 /*increase dwell time to receive probe response or detect Beacon
1688 * from target AP at a noisy air only during connect command
1690 ext_join_params->scan_le.active_time =
1691 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1692 ext_join_params->scan_le.passive_time =
1693 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1694 /* Set up join scan parameters */
1695 ext_join_params->scan_le.scan_type = -1;
1696 /* to sync with presence period of VSDB GO.
1697 * Send probe request more frequently. Probe request will be stopped
1698 * when it gets probe response from target AP/GO.
1700 ext_join_params->scan_le.nprobes =
1701 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1702 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1703 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1706 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1708 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1711 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1713 ext_join_params->assoc_le.chanspec_list[0] =
1714 cpu_to_le16(chanspec);
1717 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1719 kfree(ext_join_params);
1721 /* This is it. join command worked, we are done */
1724 /* join command failed, fallback to set ssid */
1725 memset(&join_params, 0, sizeof(join_params));
1726 join_params_size = sizeof(join_params.ssid_le);
1728 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1729 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1732 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1734 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1737 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1738 join_params.params_le.chanspec_num = cpu_to_le32(1);
1739 join_params_size += sizeof(join_params.params_le);
1741 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1742 &join_params, join_params_size);
1744 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1748 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1749 brcmf_dbg(TRACE, "Exit\n");
1754 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1757 struct brcmf_if *ifp = netdev_priv(ndev);
1758 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1759 struct brcmf_scb_val_le scbval;
1762 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1763 if (!check_vif_up(ifp->vif))
1766 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1768 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1769 scbval.val = cpu_to_le32(reason_code);
1770 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1771 &scbval, sizeof(scbval));
1773 brcmf_err("error (%d)\n", err);
1775 brcmf_dbg(TRACE, "Exit\n");
1780 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1781 enum nl80211_tx_power_setting type, s32 mbm)
1784 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1785 struct net_device *ndev = cfg_to_ndev(cfg);
1786 struct brcmf_if *ifp = netdev_priv(ndev);
1790 s32 dbm = MBM_TO_DBM(mbm);
1792 brcmf_dbg(TRACE, "Enter\n");
1793 if (!check_vif_up(ifp->vif))
1797 case NL80211_TX_POWER_AUTOMATIC:
1799 case NL80211_TX_POWER_LIMITED:
1800 case NL80211_TX_POWER_FIXED:
1802 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1808 /* Make sure radio is off or on as far as software is concerned */
1809 disable = WL_RADIO_SW_DISABLE << 16;
1810 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1812 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1817 txpwrmw = (u16) dbm;
1818 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1819 (s32)brcmf_mw_to_qdbm(txpwrmw));
1821 brcmf_err("qtxpower error (%d)\n", err);
1822 cfg->conf->tx_power = dbm;
1825 brcmf_dbg(TRACE, "Exit\n");
1829 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1830 struct wireless_dev *wdev,
1833 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1834 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1839 brcmf_dbg(TRACE, "Enter\n");
1840 if (!check_vif_up(ifp->vif))
1843 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1845 brcmf_err("error (%d)\n", err);
1849 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1850 *dbm = (s32) brcmf_qdbm_to_mw(result);
1853 brcmf_dbg(TRACE, "Exit\n");
1858 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1859 u8 key_idx, bool unicast, bool multicast)
1861 struct brcmf_if *ifp = netdev_priv(ndev);
1866 brcmf_dbg(TRACE, "Enter\n");
1867 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1868 if (!check_vif_up(ifp->vif))
1871 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1873 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1877 if (wsec & WEP_ENABLED) {
1878 /* Just select a new current key */
1880 err = brcmf_fil_cmd_int_set(ifp,
1881 BRCMF_C_SET_KEY_PRIMARY, index);
1883 brcmf_err("error (%d)\n", err);
1886 brcmf_dbg(TRACE, "Exit\n");
1891 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1892 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1894 struct brcmf_if *ifp = netdev_priv(ndev);
1895 struct brcmf_wsec_key key;
1899 memset(&key, 0, sizeof(key));
1900 key.index = (u32) key_idx;
1901 /* Instead of bcast for ea address for default wep keys,
1902 driver needs it to be Null */
1903 if (!is_multicast_ether_addr(mac_addr))
1904 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1905 key.len = (u32) params->key_len;
1906 /* check for key index change */
1909 err = send_key_to_dongle(ndev, &key);
1911 brcmf_err("key delete error (%d)\n", err);
1913 if (key.len > sizeof(key.data)) {
1914 brcmf_err("Invalid key length (%d)\n", key.len);
1918 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1919 memcpy(key.data, params->key, key.len);
1921 if ((ifp->vif->mode != WL_MODE_AP) &&
1922 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1923 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1924 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1925 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1926 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1929 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1930 if (params->seq && params->seq_len == 6) {
1933 ivptr = (u8 *) params->seq;
1934 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1935 (ivptr[3] << 8) | ivptr[2];
1936 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1937 key.iv_initialized = true;
1940 switch (params->cipher) {
1941 case WLAN_CIPHER_SUITE_WEP40:
1942 key.algo = CRYPTO_ALGO_WEP1;
1943 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1945 case WLAN_CIPHER_SUITE_WEP104:
1946 key.algo = CRYPTO_ALGO_WEP128;
1947 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1949 case WLAN_CIPHER_SUITE_TKIP:
1950 key.algo = CRYPTO_ALGO_TKIP;
1951 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1953 case WLAN_CIPHER_SUITE_AES_CMAC:
1954 key.algo = CRYPTO_ALGO_AES_CCM;
1955 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1957 case WLAN_CIPHER_SUITE_CCMP:
1958 key.algo = CRYPTO_ALGO_AES_CCM;
1959 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1962 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1965 err = send_key_to_dongle(ndev, &key);
1967 brcmf_err("wsec_key error (%d)\n", err);
1973 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1974 u8 key_idx, bool pairwise, const u8 *mac_addr,
1975 struct key_params *params)
1977 struct brcmf_if *ifp = netdev_priv(ndev);
1978 struct brcmf_wsec_key key;
1984 brcmf_dbg(TRACE, "Enter\n");
1985 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1986 if (!check_vif_up(ifp->vif))
1990 brcmf_dbg(TRACE, "Exit");
1991 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1993 memset(&key, 0, sizeof(key));
1995 key.len = (u32) params->key_len;
1996 key.index = (u32) key_idx;
1998 if (key.len > sizeof(key.data)) {
1999 brcmf_err("Too long key length (%u)\n", key.len);
2003 memcpy(key.data, params->key, key.len);
2005 key.flags = BRCMF_PRIMARY_KEY;
2006 switch (params->cipher) {
2007 case WLAN_CIPHER_SUITE_WEP40:
2008 key.algo = CRYPTO_ALGO_WEP1;
2010 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2012 case WLAN_CIPHER_SUITE_WEP104:
2013 key.algo = CRYPTO_ALGO_WEP128;
2015 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2017 case WLAN_CIPHER_SUITE_TKIP:
2018 if (ifp->vif->mode != WL_MODE_AP) {
2019 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2020 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2021 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2022 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2024 key.algo = CRYPTO_ALGO_TKIP;
2026 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2028 case WLAN_CIPHER_SUITE_AES_CMAC:
2029 key.algo = CRYPTO_ALGO_AES_CCM;
2031 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2033 case WLAN_CIPHER_SUITE_CCMP:
2034 key.algo = CRYPTO_ALGO_AES_CCM;
2036 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2039 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2044 err = send_key_to_dongle(ndev, &key);
2048 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2050 brcmf_err("get wsec error (%d)\n", err);
2054 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2056 brcmf_err("set wsec error (%d)\n", err);
2061 brcmf_dbg(TRACE, "Exit\n");
2066 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2067 u8 key_idx, bool pairwise, const u8 *mac_addr)
2069 struct brcmf_if *ifp = netdev_priv(ndev);
2070 struct brcmf_wsec_key key;
2073 brcmf_dbg(TRACE, "Enter\n");
2074 if (!check_vif_up(ifp->vif))
2077 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2078 /* we ignore this key index in this case */
2079 brcmf_err("invalid key index (%d)\n", key_idx);
2083 memset(&key, 0, sizeof(key));
2085 key.index = (u32) key_idx;
2086 key.flags = BRCMF_PRIMARY_KEY;
2087 key.algo = CRYPTO_ALGO_OFF;
2089 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2091 /* Set the new key/index */
2092 err = send_key_to_dongle(ndev, &key);
2094 brcmf_dbg(TRACE, "Exit\n");
2099 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2100 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2101 void (*callback) (void *cookie, struct key_params * params))
2103 struct key_params params;
2104 struct brcmf_if *ifp = netdev_priv(ndev);
2105 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2106 struct brcmf_cfg80211_security *sec;
2110 brcmf_dbg(TRACE, "Enter\n");
2111 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2112 if (!check_vif_up(ifp->vif))
2115 memset(¶ms, 0, sizeof(params));
2117 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2119 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2120 /* Ignore this error, may happen during DISASSOC */
2124 if (wsec & WEP_ENABLED) {
2125 sec = &profile->sec;
2126 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2127 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2128 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2129 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2130 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2131 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2133 } else if (wsec & TKIP_ENABLED) {
2134 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2135 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2136 } else if (wsec & AES_ENABLED) {
2137 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2138 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2140 brcmf_err("Invalid algo (0x%x)\n", wsec);
2144 callback(cookie, ¶ms);
2147 brcmf_dbg(TRACE, "Exit\n");
2152 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2153 struct net_device *ndev, u8 key_idx)
2155 brcmf_dbg(INFO, "Not supported\n");
2161 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2162 u8 *mac, struct station_info *sinfo)
2164 struct brcmf_if *ifp = netdev_priv(ndev);
2165 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2166 struct brcmf_scb_val_le scb_val;
2170 u8 *bssid = profile->bssid;
2171 struct brcmf_sta_info_le sta_info_le;
2173 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2174 if (!check_vif_up(ifp->vif))
2177 if (ifp->vif->mode == WL_MODE_AP) {
2178 memcpy(&sta_info_le, mac, ETH_ALEN);
2179 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2181 sizeof(sta_info_le));
2183 brcmf_err("GET STA INFO failed, %d\n", err);
2186 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2187 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2188 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2189 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2190 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2192 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2193 sinfo->inactive_time, sinfo->connected_time);
2194 } else if (ifp->vif->mode == WL_MODE_BSS) {
2195 if (memcmp(mac, bssid, ETH_ALEN)) {
2196 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2201 /* Report the current tx rate */
2202 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2204 brcmf_err("Could not get rate (%d)\n", err);
2207 sinfo->filled |= STATION_INFO_TX_BITRATE;
2208 sinfo->txrate.legacy = rate * 5;
2209 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2212 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2213 &ifp->vif->sme_state)) {
2214 memset(&scb_val, 0, sizeof(scb_val));
2215 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2216 &scb_val, sizeof(scb_val));
2218 brcmf_err("Could not get rssi (%d)\n", err);
2221 rssi = le32_to_cpu(scb_val.val);
2222 sinfo->filled |= STATION_INFO_SIGNAL;
2223 sinfo->signal = rssi;
2224 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2230 brcmf_dbg(TRACE, "Exit\n");
2235 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2236 bool enabled, s32 timeout)
2240 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2241 struct brcmf_if *ifp = netdev_priv(ndev);
2243 brcmf_dbg(TRACE, "Enter\n");
2246 * Powersave enable/disable request is coming from the
2247 * cfg80211 even before the interface is up. In that
2248 * scenario, driver will be storing the power save
2249 * preference in cfg struct to apply this to
2250 * FW later while initializing the dongle
2252 cfg->pwr_save = enabled;
2253 if (!check_vif_up(ifp->vif)) {
2255 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2259 pm = enabled ? PM_FAST : PM_OFF;
2260 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2262 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2265 brcmf_err("net_device is not ready yet\n");
2267 brcmf_err("error (%d)\n", err);
2270 brcmf_dbg(TRACE, "Exit\n");
2274 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2275 struct brcmf_bss_info_le *bi)
2277 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2278 struct ieee80211_channel *notify_channel;
2279 struct cfg80211_bss *bss;
2280 struct ieee80211_supported_band *band;
2284 u16 notify_capability;
2285 u16 notify_interval;
2287 size_t notify_ielen;
2290 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2291 brcmf_err("Bss info is larger than buffer. Discarding\n");
2295 channel = bi->ctl_ch ? bi->ctl_ch :
2296 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2298 if (channel <= CH_MAX_2G_CHANNEL)
2299 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2301 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2303 freq = ieee80211_channel_to_frequency(channel, band->band);
2304 notify_channel = ieee80211_get_channel(wiphy, freq);
2306 notify_capability = le16_to_cpu(bi->capability);
2307 notify_interval = le16_to_cpu(bi->beacon_period);
2308 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2309 notify_ielen = le32_to_cpu(bi->ie_length);
2310 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2312 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2313 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2314 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2315 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2316 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2318 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2319 0, notify_capability, notify_interval, notify_ie,
2320 notify_ielen, notify_signal, GFP_KERNEL);
2325 cfg80211_put_bss(wiphy, bss);
2330 static struct brcmf_bss_info_le *
2331 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2334 return list->bss_info_le;
2335 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2336 le32_to_cpu(bss->length));
2339 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2341 struct brcmf_scan_results *bss_list;
2342 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2346 bss_list = cfg->bss_list;
2347 if (bss_list->count != 0 &&
2348 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2349 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2353 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2354 for (i = 0; i < bss_list->count; i++) {
2355 bi = next_bss_le(bss_list, bi);
2356 err = brcmf_inform_single_bss(cfg, bi);
2363 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2364 struct net_device *ndev, const u8 *bssid)
2366 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2367 struct ieee80211_channel *notify_channel;
2368 struct brcmf_bss_info_le *bi = NULL;
2369 struct ieee80211_supported_band *band;
2370 struct cfg80211_bss *bss;
2375 u16 notify_capability;
2376 u16 notify_interval;
2378 size_t notify_ielen;
2381 brcmf_dbg(TRACE, "Enter\n");
2383 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2389 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2391 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2392 buf, WL_BSS_INFO_MAX);
2394 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2398 bi = (struct brcmf_bss_info_le *)(buf + 4);
2400 channel = bi->ctl_ch ? bi->ctl_ch :
2401 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2403 if (channel <= CH_MAX_2G_CHANNEL)
2404 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2406 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2408 freq = ieee80211_channel_to_frequency(channel, band->band);
2409 notify_channel = ieee80211_get_channel(wiphy, freq);
2411 notify_capability = le16_to_cpu(bi->capability);
2412 notify_interval = le16_to_cpu(bi->beacon_period);
2413 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2414 notify_ielen = le32_to_cpu(bi->ie_length);
2415 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2417 brcmf_dbg(CONN, "channel: %d(%d)\n", channel, freq);
2418 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2419 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2420 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2422 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2423 0, notify_capability, notify_interval,
2424 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2431 cfg80211_put_bss(wiphy, bss);
2437 brcmf_dbg(TRACE, "Exit\n");
2442 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2444 return vif->mode == WL_MODE_IBSS;
2447 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2448 struct brcmf_if *ifp)
2450 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2451 struct brcmf_bss_info_le *bi;
2452 struct brcmf_ssid *ssid;
2453 struct brcmf_tlv *tim;
2454 u16 beacon_interval;
2460 brcmf_dbg(TRACE, "Enter\n");
2461 if (brcmf_is_ibssmode(ifp->vif))
2464 ssid = &profile->ssid;
2466 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2467 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2468 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2470 brcmf_err("Could not get bss info %d\n", err);
2471 goto update_bss_info_out;
2474 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2475 err = brcmf_inform_single_bss(cfg, bi);
2477 goto update_bss_info_out;
2479 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2480 ie_len = le32_to_cpu(bi->ie_length);
2481 beacon_interval = le16_to_cpu(bi->beacon_period);
2483 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2485 dtim_period = tim->data[1];
2488 * active scan was done so we could not get dtim
2489 * information out of probe response.
2490 * so we speficially query dtim information to dongle.
2493 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2495 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2496 goto update_bss_info_out;
2498 dtim_period = (u8)var;
2501 update_bss_info_out:
2502 brcmf_dbg(TRACE, "Exit");
2506 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2508 struct escan_info *escan = &cfg->escan_info;
2510 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2511 if (cfg->scan_request) {
2512 escan->escan_state = WL_ESCAN_STATE_IDLE;
2513 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2515 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2516 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2519 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2521 struct brcmf_cfg80211_info *cfg =
2522 container_of(work, struct brcmf_cfg80211_info,
2523 escan_timeout_work);
2525 brcmf_notify_escan_complete(cfg, cfg->escan_info.ndev, true, true);
2528 static void brcmf_escan_timeout(unsigned long data)
2530 struct brcmf_cfg80211_info *cfg =
2531 (struct brcmf_cfg80211_info *)data;
2533 if (cfg->scan_request) {
2534 brcmf_err("timer expired\n");
2535 schedule_work(&cfg->escan_timeout_work);
2540 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2541 struct brcmf_bss_info_le *bss_info_le)
2543 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2544 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2545 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2546 bss_info_le->SSID_len == bss->SSID_len &&
2547 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2548 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2549 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2550 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2551 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2553 /* preserve max RSSI if the measurements are
2554 * both on-channel or both off-channel
2556 if (bss_info_rssi > bss_rssi)
2557 bss->RSSI = bss_info_le->RSSI;
2558 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2559 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2560 /* preserve the on-channel rssi measurement
2561 * if the new measurement is off channel
2563 bss->RSSI = bss_info_le->RSSI;
2564 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2572 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2573 const struct brcmf_event_msg *e, void *data)
2575 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2576 struct net_device *ndev = ifp->ndev;
2579 struct brcmf_escan_result_le *escan_result_le;
2580 struct brcmf_bss_info_le *bss_info_le;
2581 struct brcmf_bss_info_le *bss = NULL;
2583 struct brcmf_scan_results *list;
2589 if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2590 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev,
2591 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2595 if (status == BRCMF_E_STATUS_PARTIAL) {
2596 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2597 escan_result_le = (struct brcmf_escan_result_le *) data;
2598 if (!escan_result_le) {
2599 brcmf_err("Invalid escan result (NULL pointer)\n");
2602 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2603 brcmf_err("Invalid bss_count %d: ignoring\n",
2604 escan_result_le->bss_count);
2607 bss_info_le = &escan_result_le->bss_info_le;
2609 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2612 if (!cfg->scan_request) {
2613 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2617 bi_length = le32_to_cpu(bss_info_le->length);
2618 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2619 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2620 brcmf_err("Invalid bss_info length %d: ignoring\n",
2625 if (!(cfg_to_wiphy(cfg)->interface_modes &
2626 BIT(NL80211_IFTYPE_ADHOC))) {
2627 if (le16_to_cpu(bss_info_le->capability) &
2628 WLAN_CAPABILITY_IBSS) {
2629 brcmf_err("Ignoring IBSS result\n");
2634 list = (struct brcmf_scan_results *)
2635 cfg->escan_info.escan_buf;
2636 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2637 brcmf_err("Buffer is too small: ignoring\n");
2641 for (i = 0; i < list->count; i++) {
2642 bss = bss ? (struct brcmf_bss_info_le *)
2643 ((unsigned char *)bss +
2644 le32_to_cpu(bss->length)) : list->bss_info_le;
2645 if (brcmf_compare_update_same_bss(bss, bss_info_le))
2648 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2649 bss_info_le, bi_length);
2650 list->version = le32_to_cpu(bss_info_le->version);
2651 list->buflen += bi_length;
2654 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2655 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2657 if (cfg->scan_request) {
2658 cfg->bss_list = (struct brcmf_scan_results *)
2659 cfg->escan_info.escan_buf;
2660 brcmf_inform_bss(cfg);
2661 aborted = status != BRCMF_E_STATUS_SUCCESS;
2662 brcmf_notify_escan_complete(cfg, ndev, aborted,
2665 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2672 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2674 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2675 brcmf_cfg80211_escan_handler);
2676 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2677 /* Init scan_timeout timer */
2678 init_timer(&cfg->escan_timeout);
2679 cfg->escan_timeout.data = (unsigned long) cfg;
2680 cfg->escan_timeout.function = brcmf_escan_timeout;
2681 INIT_WORK(&cfg->escan_timeout_work,
2682 brcmf_cfg80211_escan_timeout_worker);
2685 static __always_inline void brcmf_delay(u32 ms)
2687 if (ms < 1000 / HZ) {
2695 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2697 brcmf_dbg(TRACE, "Enter\n");
2702 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2703 struct cfg80211_wowlan *wow)
2705 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2706 struct net_device *ndev = cfg_to_ndev(cfg);
2707 struct brcmf_cfg80211_vif *vif;
2709 brcmf_dbg(TRACE, "Enter\n");
2712 * if the primary net_device is not READY there is nothing
2713 * we can do but pray resume goes smoothly.
2715 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2716 if (!check_vif_up(vif))
2719 list_for_each_entry(vif, &cfg->vif_list, list) {
2720 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2723 * While going to suspend if associated with AP disassociate
2724 * from AP to save power while system is in suspended state
2726 brcmf_link_down(vif);
2728 /* Make sure WPA_Supplicant receives all the event
2729 * generated due to DISASSOC call to the fw to keep
2730 * the state fw and WPA_Supplicant state consistent
2735 /* end any scanning */
2736 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2737 brcmf_abort_scanning(cfg);
2739 /* Turn off watchdog timer */
2740 brcmf_set_mpc(ndev, 1);
2743 brcmf_dbg(TRACE, "Exit\n");
2744 /* clear any scanning activity */
2745 cfg->scan_status = 0;
2750 brcmf_update_pmklist(struct net_device *ndev,
2751 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2756 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2758 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2759 for (i = 0; i < pmkid_len; i++) {
2760 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2761 &pmk_list->pmkids.pmkid[i].BSSID);
2762 for (j = 0; j < WLAN_PMKID_LEN; j++)
2763 brcmf_dbg(CONN, "%02x\n",
2764 pmk_list->pmkids.pmkid[i].PMKID[j]);
2768 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2769 (char *)pmk_list, sizeof(*pmk_list));
2775 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2776 struct cfg80211_pmksa *pmksa)
2778 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2779 struct brcmf_if *ifp = netdev_priv(ndev);
2780 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2785 brcmf_dbg(TRACE, "Enter\n");
2786 if (!check_vif_up(ifp->vif))
2789 pmkid_len = le32_to_cpu(pmkids->npmkid);
2790 for (i = 0; i < pmkid_len; i++)
2791 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2793 if (i < WL_NUM_PMKIDS_MAX) {
2794 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2795 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2796 if (i == pmkid_len) {
2798 pmkids->npmkid = cpu_to_le32(pmkid_len);
2803 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2804 pmkids->pmkid[pmkid_len].BSSID);
2805 for (i = 0; i < WLAN_PMKID_LEN; i++)
2806 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2808 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2810 brcmf_dbg(TRACE, "Exit\n");
2815 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2816 struct cfg80211_pmksa *pmksa)
2818 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2819 struct brcmf_if *ifp = netdev_priv(ndev);
2820 struct pmkid_list pmkid;
2824 brcmf_dbg(TRACE, "Enter\n");
2825 if (!check_vif_up(ifp->vif))
2828 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2829 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2831 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2832 &pmkid.pmkid[0].BSSID);
2833 for (i = 0; i < WLAN_PMKID_LEN; i++)
2834 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2836 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2837 for (i = 0; i < pmkid_len; i++)
2839 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2844 && (i < pmkid_len)) {
2845 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2846 sizeof(struct pmkid));
2847 for (; i < (pmkid_len - 1); i++) {
2848 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2849 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2851 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2852 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2855 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2859 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2861 brcmf_dbg(TRACE, "Exit\n");
2867 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2869 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2870 struct brcmf_if *ifp = netdev_priv(ndev);
2873 brcmf_dbg(TRACE, "Enter\n");
2874 if (!check_vif_up(ifp->vif))
2877 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2878 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2880 brcmf_dbg(TRACE, "Exit\n");
2886 * PFN result doesn't have all the info which are
2887 * required by the supplicant
2888 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2889 * via wl_inform_single_bss in the required format. Escan does require the
2890 * scan request in the form of cfg80211_scan_request. For timebeing, create
2891 * cfg80211_scan_request one out of the received PNO event.
2894 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2895 const struct brcmf_event_msg *e, void *data)
2897 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2898 struct net_device *ndev = ifp->ndev;
2899 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2900 struct cfg80211_scan_request *request = NULL;
2901 struct cfg80211_ssid *ssid = NULL;
2902 struct ieee80211_channel *channel = NULL;
2903 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2905 int channel_req = 0;
2907 struct brcmf_pno_scanresults_le *pfn_result;
2911 brcmf_dbg(SCAN, "Enter\n");
2913 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2914 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2918 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2919 result_count = le32_to_cpu(pfn_result->count);
2920 status = le32_to_cpu(pfn_result->status);
2923 * PFN event is limited to fit 512 bytes so we may get
2924 * multiple NET_FOUND events. For now place a warning here.
2926 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2927 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2928 if (result_count > 0) {
2931 request = kzalloc(sizeof(*request), GFP_KERNEL);
2932 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2933 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2934 if (!request || !ssid || !channel) {
2939 request->wiphy = wiphy;
2940 data += sizeof(struct brcmf_pno_scanresults_le);
2941 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2943 for (i = 0; i < result_count; i++) {
2944 netinfo = &netinfo_start[i];
2946 brcmf_err("Invalid netinfo ptr. index: %d\n",
2952 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2953 netinfo->SSID, netinfo->channel);
2954 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2955 ssid[i].ssid_len = netinfo->SSID_len;
2958 channel_req = netinfo->channel;
2959 if (channel_req <= CH_MAX_2G_CHANNEL)
2960 band = NL80211_BAND_2GHZ;
2962 band = NL80211_BAND_5GHZ;
2963 channel[i].center_freq =
2964 ieee80211_channel_to_frequency(channel_req,
2966 channel[i].band = band;
2967 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2968 request->channels[i] = &channel[i];
2969 request->n_channels++;
2972 /* assign parsed ssid array */
2973 if (request->n_ssids)
2974 request->ssids = &ssid[0];
2976 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2977 /* Abort any on-going scan */
2978 brcmf_abort_scanning(cfg);
2981 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2982 err = brcmf_do_escan(cfg, wiphy, ndev, request);
2984 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2987 cfg->sched_escan = true;
2988 cfg->scan_request = request;
2990 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3003 cfg80211_sched_scan_stopped(wiphy);
3007 static int brcmf_dev_pno_clean(struct net_device *ndev)
3012 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3015 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3019 brcmf_err("failed code %d\n", ret);
3024 static int brcmf_dev_pno_config(struct net_device *ndev)
3026 struct brcmf_pno_param_le pfn_param;
3028 memset(&pfn_param, 0, sizeof(pfn_param));
3029 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3031 /* set extra pno params */
3032 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3033 pfn_param.repeat = BRCMF_PNO_REPEAT;
3034 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3036 /* set up pno scan fr */
3037 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3039 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3040 &pfn_param, sizeof(pfn_param));
3044 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3045 struct net_device *ndev,
3046 struct cfg80211_sched_scan_request *request)
3048 struct brcmf_if *ifp = netdev_priv(ndev);
3049 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3050 struct brcmf_pno_net_param_le pfn;
3054 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3055 request->n_match_sets, request->n_ssids);
3056 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3057 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3061 if (!request || !request->n_ssids || !request->n_match_sets) {
3062 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3063 request ? request->n_ssids : 0);
3067 if (request->n_ssids > 0) {
3068 for (i = 0; i < request->n_ssids; i++) {
3069 /* Active scan req for ssids */
3070 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3071 request->ssids[i].ssid);
3074 * match_set ssids is a supert set of n_ssid list,
3075 * so we need not add these set seperately.
3080 if (request->n_match_sets > 0) {
3081 /* clean up everything */
3082 ret = brcmf_dev_pno_clean(ndev);
3084 brcmf_err("failed error=%d\n", ret);
3089 ret = brcmf_dev_pno_config(ndev);
3091 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3095 /* configure each match set */
3096 for (i = 0; i < request->n_match_sets; i++) {
3097 struct cfg80211_ssid *ssid;
3100 ssid = &request->match_sets[i].ssid;
3101 ssid_len = ssid->ssid_len;
3104 brcmf_err("skip broadcast ssid\n");
3107 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3108 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3109 pfn.wsec = cpu_to_le32(0);
3110 pfn.infra = cpu_to_le32(1);
3111 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3112 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3113 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3114 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3116 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3117 ret == 0 ? "set" : "failed", ssid->ssid);
3119 /* Enable the PNO */
3120 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3121 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3131 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3132 struct net_device *ndev)
3134 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3136 brcmf_dbg(SCAN, "enter\n");
3137 brcmf_dev_pno_clean(ndev);
3138 if (cfg->sched_escan)
3139 brcmf_notify_escan_complete(cfg, ndev, true, true);
3143 #ifdef CONFIG_NL80211_TESTMODE
3144 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3146 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3147 struct net_device *ndev = cfg_to_ndev(cfg);
3148 struct brcmf_dcmd *dcmd = data;
3149 struct sk_buff *reply;
3152 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3153 dcmd->buf, dcmd->len);
3156 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3157 dcmd->buf, dcmd->len);
3159 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3160 dcmd->buf, dcmd->len);
3162 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3163 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3164 ret = cfg80211_testmode_reply(reply);
3170 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3175 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3177 brcmf_err("auth error %d\n", err);
3181 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3183 brcmf_err("wsec error %d\n", err);
3186 /* set upper-layer auth */
3187 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3189 brcmf_err("wpa_auth error %d\n", err);
3196 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3199 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3201 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3205 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3208 struct brcmf_if *ifp = netdev_priv(ndev);
3209 u32 auth = 0; /* d11 open authentication */
3221 u32 wme_bss_disable;
3223 brcmf_dbg(TRACE, "Enter\n");
3227 len = wpa_ie->len + TLV_HDR_LEN;
3228 data = (u8 *)wpa_ie;
3229 offset = TLV_HDR_LEN;
3231 offset += VS_IE_FIXED_HDR_LEN;
3233 offset += WPA_IE_VERSION_LEN;
3235 /* check for multicast cipher suite */
3236 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3238 brcmf_err("no multicast cipher suite\n");
3242 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3244 brcmf_err("ivalid OUI\n");
3247 offset += TLV_OUI_LEN;
3249 /* pick up multicast cipher */
3250 switch (data[offset]) {
3251 case WPA_CIPHER_NONE:
3254 case WPA_CIPHER_WEP_40:
3255 case WPA_CIPHER_WEP_104:
3258 case WPA_CIPHER_TKIP:
3259 gval = TKIP_ENABLED;
3261 case WPA_CIPHER_AES_CCM:
3266 brcmf_err("Invalid multi cast cipher info\n");
3271 /* walk thru unicast cipher list and pick up what we recognize */
3272 count = data[offset] + (data[offset + 1] << 8);
3273 offset += WPA_IE_SUITE_COUNT_LEN;
3274 /* Check for unicast suite(s) */
3275 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3277 brcmf_err("no unicast cipher suite\n");
3280 for (i = 0; i < count; i++) {
3281 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3283 brcmf_err("ivalid OUI\n");
3286 offset += TLV_OUI_LEN;
3287 switch (data[offset]) {
3288 case WPA_CIPHER_NONE:
3290 case WPA_CIPHER_WEP_40:
3291 case WPA_CIPHER_WEP_104:
3292 pval |= WEP_ENABLED;
3294 case WPA_CIPHER_TKIP:
3295 pval |= TKIP_ENABLED;
3297 case WPA_CIPHER_AES_CCM:
3298 pval |= AES_ENABLED;
3301 brcmf_err("Ivalid unicast security info\n");
3305 /* walk thru auth management suite list and pick up what we recognize */
3306 count = data[offset] + (data[offset + 1] << 8);
3307 offset += WPA_IE_SUITE_COUNT_LEN;
3308 /* Check for auth key management suite(s) */
3309 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3311 brcmf_err("no auth key mgmt suite\n");
3314 for (i = 0; i < count; i++) {
3315 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3317 brcmf_err("ivalid OUI\n");
3320 offset += TLV_OUI_LEN;
3321 switch (data[offset]) {
3323 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3324 wpa_auth |= WPA_AUTH_NONE;
3326 case RSN_AKM_UNSPECIFIED:
3327 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3328 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3329 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3332 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3333 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3334 (wpa_auth |= WPA_AUTH_PSK);
3337 brcmf_err("Ivalid key mgmt info\n");
3343 wme_bss_disable = 1;
3344 if ((offset + RSN_CAP_LEN) <= len) {
3345 rsn_cap = data[offset] + (data[offset + 1] << 8);
3346 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3347 wme_bss_disable = 0;
3349 /* set wme_bss_disable to sync RSN Capabilities */
3350 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3353 brcmf_err("wme_bss_disable error %d\n", err);
3357 /* FOR WPS , set SES_OW_ENABLED */
3358 wsec = (pval | gval | SES_OW_ENABLED);
3361 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3363 brcmf_err("auth error %d\n", err);
3367 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3369 brcmf_err("wsec error %d\n", err);
3372 /* set upper-layer auth */
3373 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3375 brcmf_err("wpa_auth error %d\n", err);
3384 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3385 struct parsed_vndr_ies *vndr_ies)
3388 struct brcmf_vs_tlv *vndrie;
3389 struct brcmf_tlv *ie;
3390 struct parsed_vndr_ie_info *parsed_info;
3393 remaining_len = (s32)vndr_ie_len;
3394 memset(vndr_ies, 0, sizeof(*vndr_ies));
3396 ie = (struct brcmf_tlv *)vndr_ie_buf;
3398 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3400 vndrie = (struct brcmf_vs_tlv *)ie;
3401 /* len should be bigger than OUI length + one */
3402 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3403 brcmf_err("invalid vndr ie. length is too small %d\n",
3407 /* if wpa or wme ie, do not add ie */
3408 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3409 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3410 (vndrie->oui_type == WME_OUI_TYPE))) {
3411 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3415 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3417 /* save vndr ie information */
3418 parsed_info->ie_ptr = (char *)vndrie;
3419 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3420 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3424 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3425 parsed_info->vndrie.oui[0],
3426 parsed_info->vndrie.oui[1],
3427 parsed_info->vndrie.oui[2],
3428 parsed_info->vndrie.oui_type);
3430 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3433 remaining_len -= (ie->len + TLV_HDR_LEN);
3434 if (remaining_len <= TLV_HDR_LEN)
3437 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3444 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3450 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3451 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3453 iecount_le = cpu_to_le32(1);
3454 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3456 pktflag_le = cpu_to_le32(pktflag);
3457 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3459 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3461 return ie_len + VNDR_IE_HDR_SIZE;
3464 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3465 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3467 struct brcmf_if *ifp;
3468 struct vif_saved_ie *saved_ie;
3472 u8 *mgmt_ie_buf = NULL;
3473 int mgmt_ie_buf_len;
3475 u32 del_add_ie_buf_len = 0;
3476 u32 total_ie_buf_len = 0;
3477 u32 parsed_ie_buf_len = 0;
3478 struct parsed_vndr_ies old_vndr_ies;
3479 struct parsed_vndr_ies new_vndr_ies;
3480 struct parsed_vndr_ie_info *vndrie_info;
3483 int remained_buf_len;
3488 saved_ie = &vif->saved_ie;
3490 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3491 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3494 curr_ie_buf = iovar_ie_buf;
3496 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3497 mgmt_ie_buf = saved_ie->probe_req_ie;
3498 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3499 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3501 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3502 mgmt_ie_buf = saved_ie->probe_res_ie;
3503 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3504 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3506 case BRCMF_VNDR_IE_BEACON_FLAG:
3507 mgmt_ie_buf = saved_ie->beacon_ie;
3508 mgmt_ie_len = &saved_ie->beacon_ie_len;
3509 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3511 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3512 mgmt_ie_buf = saved_ie->assoc_req_ie;
3513 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3514 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3518 brcmf_err("not suitable type\n");
3522 if (vndr_ie_len > mgmt_ie_buf_len) {
3524 brcmf_err("extra IE size too big\n");
3528 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3529 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3531 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3532 for (i = 0; i < new_vndr_ies.count; i++) {
3533 vndrie_info = &new_vndr_ies.ie_info[i];
3534 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3535 vndrie_info->ie_len);
3536 parsed_ie_buf_len += vndrie_info->ie_len;
3540 if (mgmt_ie_buf && *mgmt_ie_len) {
3541 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3542 (memcmp(mgmt_ie_buf, curr_ie_buf,
3543 parsed_ie_buf_len) == 0)) {
3544 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3548 /* parse old vndr_ie */
3549 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3551 /* make a command to delete old ie */
3552 for (i = 0; i < old_vndr_ies.count; i++) {
3553 vndrie_info = &old_vndr_ies.ie_info[i];
3555 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3556 vndrie_info->vndrie.id,
3557 vndrie_info->vndrie.len,
3558 vndrie_info->vndrie.oui[0],
3559 vndrie_info->vndrie.oui[1],
3560 vndrie_info->vndrie.oui[2]);
3562 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3563 vndrie_info->ie_ptr,
3564 vndrie_info->ie_len,
3566 curr_ie_buf += del_add_ie_buf_len;
3567 total_ie_buf_len += del_add_ie_buf_len;
3572 /* Add if there is any extra IE */
3573 if (mgmt_ie_buf && parsed_ie_buf_len) {
3576 remained_buf_len = mgmt_ie_buf_len;
3578 /* make a command to add new ie */
3579 for (i = 0; i < new_vndr_ies.count; i++) {
3580 vndrie_info = &new_vndr_ies.ie_info[i];
3582 /* verify remained buf size before copy data */
3583 if (remained_buf_len < (vndrie_info->vndrie.len +
3584 VNDR_IE_VSIE_OFFSET)) {
3585 brcmf_err("no space in mgmt_ie_buf: len left %d",
3589 remained_buf_len -= (vndrie_info->ie_len +
3590 VNDR_IE_VSIE_OFFSET);
3592 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3593 vndrie_info->vndrie.id,
3594 vndrie_info->vndrie.len,
3595 vndrie_info->vndrie.oui[0],
3596 vndrie_info->vndrie.oui[1],
3597 vndrie_info->vndrie.oui[2]);
3599 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3600 vndrie_info->ie_ptr,
3601 vndrie_info->ie_len,
3604 /* save the parsed IE in wl struct */
3605 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3606 vndrie_info->ie_len);
3607 *mgmt_ie_len += vndrie_info->ie_len;
3609 curr_ie_buf += del_add_ie_buf_len;
3610 total_ie_buf_len += del_add_ie_buf_len;
3613 if (total_ie_buf_len) {
3614 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3617 brcmf_err("vndr ie set error : %d\n", err);
3621 kfree(iovar_ie_buf);
3625 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3628 BRCMF_VNDR_IE_PRBREQ_FLAG,
3629 BRCMF_VNDR_IE_PRBRSP_FLAG,
3630 BRCMF_VNDR_IE_BEACON_FLAG
3634 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3635 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3637 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3642 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3643 struct cfg80211_beacon_data *beacon)
3647 /* Set Beacon IEs to FW */
3648 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3649 beacon->tail, beacon->tail_len);
3651 brcmf_err("Set Beacon IE Failed\n");
3654 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3656 /* Set Probe Response IEs to FW */
3657 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3658 beacon->proberesp_ies,
3659 beacon->proberesp_ies_len);
3661 brcmf_err("Set Probe Resp IE Failed\n");
3663 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3669 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3670 struct cfg80211_ap_settings *settings)
3673 struct brcmf_if *ifp = netdev_priv(ndev);
3674 struct brcmf_tlv *ssid_ie;
3675 struct brcmf_ssid_le ssid_le;
3677 struct brcmf_tlv *rsn_ie;
3678 struct brcmf_vs_tlv *wpa_ie;
3679 struct brcmf_join_params join_params;
3680 enum nl80211_iftype dev_role;
3681 struct brcmf_fil_bss_enable_le bss_enable;
3683 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3684 cfg80211_get_chandef_type(&settings->chandef),
3685 settings->beacon_interval,
3686 settings->dtim_period);
3687 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3688 settings->ssid, settings->ssid_len, settings->auth_type,
3689 settings->inactivity_timeout);
3691 dev_role = ifp->vif->wdev.iftype;
3693 memset(&ssid_le, 0, sizeof(ssid_le));
3694 if (settings->ssid == NULL || settings->ssid_len == 0) {
3695 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3696 ssid_ie = brcmf_parse_tlvs(
3697 (u8 *)&settings->beacon.head[ie_offset],
3698 settings->beacon.head_len - ie_offset,
3703 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3704 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3705 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3707 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3708 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3711 brcmf_set_mpc(ndev, 0);
3713 /* find the RSN_IE */
3714 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3715 settings->beacon.tail_len, WLAN_EID_RSN);
3717 /* find the WPA_IE */
3718 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3719 settings->beacon.tail_len);
3721 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3722 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3723 if (wpa_ie != NULL) {
3725 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3730 err = brcmf_configure_wpaie(ndev,
3731 (struct brcmf_vs_tlv *)rsn_ie, true);
3736 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3737 brcmf_configure_opensecurity(ifp);
3740 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3742 if (settings->beacon_interval) {
3743 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3744 settings->beacon_interval);
3746 brcmf_err("Beacon Interval Set Error, %d\n", err);
3750 if (settings->dtim_period) {
3751 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3752 settings->dtim_period);
3754 brcmf_err("DTIM Interval Set Error, %d\n", err);
3759 if (dev_role == NL80211_IFTYPE_AP) {
3760 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3762 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3765 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3768 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3770 brcmf_err("SET INFRA error %d\n", err);
3773 if (dev_role == NL80211_IFTYPE_AP) {
3774 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3776 brcmf_err("setting AP mode failed %d\n", err);
3779 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3781 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3785 memset(&join_params, 0, sizeof(join_params));
3786 /* join parameters starts with ssid */
3787 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3789 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3790 &join_params, sizeof(join_params));
3792 brcmf_err("SET SSID error (%d)\n", err);
3795 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3797 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3800 brcmf_err("setting ssid failed %d\n", err);
3803 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3804 bss_enable.enable = cpu_to_le32(1);
3805 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3806 sizeof(bss_enable));
3808 brcmf_err("bss_enable config failed %d\n", err);
3812 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3814 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3815 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3819 brcmf_set_mpc(ndev, 1);
3823 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3825 struct brcmf_if *ifp = netdev_priv(ndev);
3827 struct brcmf_fil_bss_enable_le bss_enable;
3828 struct brcmf_join_params join_params;
3830 brcmf_dbg(TRACE, "Enter\n");
3832 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3833 /* Due to most likely deauths outstanding we sleep */
3834 /* first to make sure they get processed by fw. */
3837 memset(&join_params, 0, sizeof(join_params));
3838 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3839 &join_params, sizeof(join_params));
3841 brcmf_err("SET SSID error (%d)\n", err);
3842 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3844 brcmf_err("BRCMF_C_UP error %d\n", err);
3845 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3847 brcmf_err("setting AP mode failed %d\n", err);
3848 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3850 brcmf_err("setting INFRA mode failed %d\n", err);
3852 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3853 bss_enable.enable = cpu_to_le32(0);
3854 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3855 sizeof(bss_enable));
3857 brcmf_err("bss_enable config failed %d\n", err);
3859 brcmf_set_mpc(ndev, 1);
3860 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3861 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3867 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3868 struct cfg80211_beacon_data *info)
3870 struct brcmf_if *ifp = netdev_priv(ndev);
3873 brcmf_dbg(TRACE, "Enter\n");
3875 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3881 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3884 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3885 struct brcmf_scb_val_le scbval;
3886 struct brcmf_if *ifp = netdev_priv(ndev);
3892 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3894 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3895 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3896 if (!check_vif_up(ifp->vif))
3899 memcpy(&scbval.ea, mac, ETH_ALEN);
3900 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3901 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3902 &scbval, sizeof(scbval));
3904 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3906 brcmf_dbg(TRACE, "Exit\n");
3912 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3913 struct wireless_dev *wdev,
3914 u16 frame_type, bool reg)
3916 struct brcmf_if *ifp = netdev_priv(wdev->netdev);
3917 struct brcmf_cfg80211_vif *vif = ifp->vif;
3920 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3922 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3924 vif->mgmt_rx_reg |= BIT(mgmt_type);
3926 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3931 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3932 struct ieee80211_channel *chan, bool offchan,
3933 unsigned int wait, const u8 *buf, size_t len,
3934 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3936 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3937 const struct ieee80211_mgmt *mgmt;
3938 struct brcmf_if *ifp;
3939 struct brcmf_cfg80211_vif *vif;
3943 struct brcmf_fil_action_frame_le *action_frame;
3944 struct brcmf_fil_af_params_le *af_params;
3948 brcmf_dbg(TRACE, "Enter\n");
3952 mgmt = (const struct ieee80211_mgmt *)buf;
3954 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
3955 brcmf_err("Driver only allows MGMT packet type\n");
3959 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
3960 /* Right now the only reason to get a probe response */
3961 /* is for p2p listen response or for p2p GO from */
3962 /* wpa_supplicant. Unfortunately the probe is send */
3963 /* on primary ndev, while dongle wants it on the p2p */
3964 /* vif. Since this is only reason for a probe */
3965 /* response to be sent, the vif is taken from cfg. */
3966 /* If ever desired to send proberesp for non p2p */
3967 /* response then data should be checked for */
3968 /* "DIRECT-". Note in future supplicant will take */
3969 /* dedicated p2p wdev to do this and then this 'hack'*/
3970 /* is not needed anymore. */
3971 ie_offset = DOT11_MGMT_HDR_LEN +
3972 DOT11_BCN_PRB_FIXED_LEN;
3973 ie_len = len - ie_offset;
3974 ifp = netdev_priv(wdev->netdev);
3976 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
3977 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
3978 err = brcmf_vif_set_mgmt_ie(vif,
3979 BRCMF_VNDR_IE_PRBRSP_FLAG,
3982 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
3984 } else if (ieee80211_is_action(mgmt->frame_control)) {
3985 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
3986 if (af_params == NULL) {
3987 brcmf_err("unable to allocate frame\n");
3991 action_frame = &af_params->action_frame;
3992 /* Add the packet Id */
3993 action_frame->packet_id = cpu_to_le32(*cookie);
3995 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
3996 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
3997 /* Add the length exepted for 802.11 header */
3998 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
3999 /* Add the channel */
4000 chan_nr = ieee80211_frequency_to_channel(chan->center_freq);
4001 af_params->channel = cpu_to_le32(chan_nr);
4003 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4004 le16_to_cpu(action_frame->len));
4006 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4007 *cookie, le16_to_cpu(action_frame->len),
4010 ack = brcmf_p2p_send_action_frame(cfg, wdev->netdev,
4013 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4017 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4018 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4027 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4028 struct wireless_dev *wdev,
4031 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4032 struct brcmf_cfg80211_vif *vif;
4035 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4037 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4039 brcmf_err("No p2p device available for probe response\n");
4043 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4048 static struct cfg80211_ops wl_cfg80211_ops = {
4049 .add_virtual_intf = brcmf_cfg80211_add_iface,
4050 .del_virtual_intf = brcmf_cfg80211_del_iface,
4051 .change_virtual_intf = brcmf_cfg80211_change_iface,
4052 .scan = brcmf_cfg80211_scan,
4053 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4054 .join_ibss = brcmf_cfg80211_join_ibss,
4055 .leave_ibss = brcmf_cfg80211_leave_ibss,
4056 .get_station = brcmf_cfg80211_get_station,
4057 .set_tx_power = brcmf_cfg80211_set_tx_power,
4058 .get_tx_power = brcmf_cfg80211_get_tx_power,
4059 .add_key = brcmf_cfg80211_add_key,
4060 .del_key = brcmf_cfg80211_del_key,
4061 .get_key = brcmf_cfg80211_get_key,
4062 .set_default_key = brcmf_cfg80211_config_default_key,
4063 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4064 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4065 .connect = brcmf_cfg80211_connect,
4066 .disconnect = brcmf_cfg80211_disconnect,
4067 .suspend = brcmf_cfg80211_suspend,
4068 .resume = brcmf_cfg80211_resume,
4069 .set_pmksa = brcmf_cfg80211_set_pmksa,
4070 .del_pmksa = brcmf_cfg80211_del_pmksa,
4071 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4072 .start_ap = brcmf_cfg80211_start_ap,
4073 .stop_ap = brcmf_cfg80211_stop_ap,
4074 .change_beacon = brcmf_cfg80211_change_beacon,
4075 .del_station = brcmf_cfg80211_del_station,
4076 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4077 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4078 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4079 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4080 .remain_on_channel = brcmf_p2p_remain_on_channel,
4081 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4082 #ifdef CONFIG_NL80211_TESTMODE
4083 .testmode_cmd = brcmf_cfg80211_testmode
4087 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4090 case NL80211_IFTYPE_AP_VLAN:
4091 case NL80211_IFTYPE_WDS:
4092 case NL80211_IFTYPE_MONITOR:
4093 case NL80211_IFTYPE_MESH_POINT:
4095 case NL80211_IFTYPE_ADHOC:
4096 return WL_MODE_IBSS;
4097 case NL80211_IFTYPE_STATION:
4098 case NL80211_IFTYPE_P2P_CLIENT:
4100 case NL80211_IFTYPE_AP:
4101 case NL80211_IFTYPE_P2P_GO:
4103 case NL80211_IFTYPE_P2P_DEVICE:
4105 case NL80211_IFTYPE_UNSPECIFIED:
4113 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4115 /* scheduled scan settings */
4116 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4117 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4118 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4119 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4122 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4125 .types = BIT(NL80211_IFTYPE_STATION) |
4126 BIT(NL80211_IFTYPE_ADHOC) |
4127 BIT(NL80211_IFTYPE_AP)
4131 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4135 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4136 BIT(NL80211_IFTYPE_P2P_GO)
4139 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4141 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4142 .num_different_channels = 1, /* no multi-channel for now */
4143 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4144 .limits = brcmf_iface_limits
4148 static const struct ieee80211_txrx_stypes
4149 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4150 [NL80211_IFTYPE_STATION] = {
4152 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4153 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4155 [NL80211_IFTYPE_P2P_CLIENT] = {
4157 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4158 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4160 [NL80211_IFTYPE_P2P_GO] = {
4162 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4163 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4164 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4165 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4166 BIT(IEEE80211_STYPE_AUTH >> 4) |
4167 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4168 BIT(IEEE80211_STYPE_ACTION >> 4)
4172 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4174 struct wiphy *wiphy;
4177 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4179 brcmf_err("Could not allocate wiphy device\n");
4180 return ERR_PTR(-ENOMEM);
4182 set_wiphy_dev(wiphy, phydev);
4183 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4184 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4185 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4186 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4187 BIT(NL80211_IFTYPE_ADHOC) |
4188 BIT(NL80211_IFTYPE_AP) |
4189 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4190 BIT(NL80211_IFTYPE_P2P_GO) |
4191 BIT(NL80211_IFTYPE_P2P_DEVICE);
4192 wiphy->iface_combinations = brcmf_iface_combos;
4193 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4194 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4195 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
4196 * it as 11a by default.
4197 * This will be updated with
4200 * if phy has 11n capability
4202 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4203 wiphy->cipher_suites = __wl_cipher_suites;
4204 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4205 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4206 WIPHY_FLAG_OFFCHAN_TX |
4207 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4208 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4209 wiphy->max_remain_on_channel_duration = 5000;
4210 brcmf_wiphy_pno_params(wiphy);
4211 err = wiphy_register(wiphy);
4213 brcmf_err("Could not register wiphy device (%d)\n", err);
4215 return ERR_PTR(err);
4220 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4221 enum nl80211_iftype type,
4224 struct brcmf_cfg80211_vif *vif;
4226 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
4227 return ERR_PTR(-ENOSPC);
4229 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4231 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4233 return ERR_PTR(-ENOMEM);
4235 vif->wdev.wiphy = cfg->wiphy;
4236 vif->wdev.iftype = type;
4238 vif->mode = brcmf_nl80211_iftype_to_mode(type);
4239 vif->pm_block = pm_block;
4242 brcmf_init_prof(&vif->profile);
4244 list_add_tail(&vif->list, &cfg->vif_list);
4249 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4251 struct brcmf_cfg80211_info *cfg;
4252 struct wiphy *wiphy;
4254 wiphy = vif->wdev.wiphy;
4255 cfg = wiphy_priv(wiphy);
4256 list_del(&vif->list);
4260 if (!cfg->vif_cnt) {
4261 wiphy_unregister(wiphy);
4266 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4268 u32 event = e->event_code;
4269 u32 status = e->status;
4271 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4272 brcmf_dbg(CONN, "Processing set ssid\n");
4279 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4281 u32 event = e->event_code;
4282 u16 flags = e->flags;
4284 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4285 brcmf_dbg(CONN, "Processing link down\n");
4291 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4292 const struct brcmf_event_msg *e)
4294 u32 event = e->event_code;
4295 u32 status = e->status;
4297 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4298 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4299 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4303 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4304 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4311 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4313 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4315 kfree(conn_info->req_ie);
4316 conn_info->req_ie = NULL;
4317 conn_info->req_ie_len = 0;
4318 kfree(conn_info->resp_ie);
4319 conn_info->resp_ie = NULL;
4320 conn_info->resp_ie_len = 0;
4323 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4324 struct brcmf_if *ifp)
4326 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4327 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4332 brcmf_clear_assoc_ies(cfg);
4334 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4335 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4337 brcmf_err("could not get assoc info (%d)\n", err);
4341 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4342 req_len = le32_to_cpu(assoc_info->req_len);
4343 resp_len = le32_to_cpu(assoc_info->resp_len);
4345 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4349 brcmf_err("could not get assoc req (%d)\n", err);
4352 conn_info->req_ie_len = req_len;
4354 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4357 conn_info->req_ie_len = 0;
4358 conn_info->req_ie = NULL;
4361 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4365 brcmf_err("could not get assoc resp (%d)\n", err);
4368 conn_info->resp_ie_len = resp_len;
4369 conn_info->resp_ie =
4370 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4373 conn_info->resp_ie_len = 0;
4374 conn_info->resp_ie = NULL;
4376 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4377 conn_info->req_ie_len, conn_info->resp_ie_len);
4383 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4384 struct net_device *ndev,
4385 const struct brcmf_event_msg *e)
4387 struct brcmf_if *ifp = netdev_priv(ndev);
4388 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4389 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4390 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4391 struct ieee80211_channel *notify_channel = NULL;
4392 struct ieee80211_supported_band *band;
4393 struct brcmf_bss_info_le *bi;
4399 brcmf_dbg(TRACE, "Enter\n");
4401 brcmf_get_assoc_ies(cfg, ifp);
4402 memcpy(profile->bssid, e->addr, ETH_ALEN);
4403 brcmf_update_bss_info(cfg, ifp);
4405 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4411 /* data sent to dongle has to be little endian */
4412 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4413 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4414 buf, WL_BSS_INFO_MAX);
4419 bi = (struct brcmf_bss_info_le *)(buf + 4);
4420 target_channel = bi->ctl_ch ? bi->ctl_ch :
4421 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
4423 if (target_channel <= CH_MAX_2G_CHANNEL)
4424 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4426 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4428 freq = ieee80211_channel_to_frequency(target_channel, band->band);
4429 notify_channel = ieee80211_get_channel(wiphy, freq);
4433 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4434 conn_info->req_ie, conn_info->req_ie_len,
4435 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4436 brcmf_dbg(CONN, "Report roaming result\n");
4438 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4439 brcmf_dbg(TRACE, "Exit\n");
4444 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4445 struct net_device *ndev, const struct brcmf_event_msg *e,
4448 struct brcmf_if *ifp = netdev_priv(ndev);
4449 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4450 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4453 brcmf_dbg(TRACE, "Enter\n");
4455 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4456 &ifp->vif->sme_state)) {
4458 brcmf_get_assoc_ies(cfg, ifp);
4459 memcpy(profile->bssid, e->addr, ETH_ALEN);
4460 brcmf_update_bss_info(cfg, ifp);
4461 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4462 &ifp->vif->sme_state);
4464 cfg80211_connect_result(ndev,
4465 (u8 *)profile->bssid,
4467 conn_info->req_ie_len,
4469 conn_info->resp_ie_len,
4470 completed ? WLAN_STATUS_SUCCESS :
4471 WLAN_STATUS_AUTH_TIMEOUT,
4473 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4474 completed ? "succeeded" : "failed");
4476 brcmf_dbg(TRACE, "Exit\n");
4481 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4482 struct net_device *ndev,
4483 const struct brcmf_event_msg *e, void *data)
4485 static int generation;
4486 u32 event = e->event_code;
4487 u32 reason = e->reason;
4488 struct station_info sinfo;
4490 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4491 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4492 ndev != cfg_to_ndev(cfg)) {
4493 brcmf_dbg(CONN, "AP mode link down\n");
4494 complete(&cfg->vif_disabled);
4498 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4499 (reason == BRCMF_E_STATUS_SUCCESS)) {
4500 memset(&sinfo, 0, sizeof(sinfo));
4501 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4503 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4506 sinfo.assoc_req_ies = data;
4507 sinfo.assoc_req_ies_len = e->datalen;
4509 sinfo.generation = generation;
4510 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4511 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4512 (event == BRCMF_E_DEAUTH_IND) ||
4513 (event == BRCMF_E_DEAUTH)) {
4514 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4520 brcmf_notify_connect_status(struct brcmf_if *ifp,
4521 const struct brcmf_event_msg *e, void *data)
4523 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4524 struct net_device *ndev = ifp->ndev;
4525 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4528 if (ifp->vif->mode == WL_MODE_AP) {
4529 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4530 } else if (brcmf_is_linkup(e)) {
4531 brcmf_dbg(CONN, "Linkup\n");
4532 if (brcmf_is_ibssmode(ifp->vif)) {
4533 memcpy(profile->bssid, e->addr, ETH_ALEN);
4534 wl_inform_ibss(cfg, ndev, e->addr);
4535 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4536 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4537 &ifp->vif->sme_state);
4538 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4539 &ifp->vif->sme_state);
4541 brcmf_bss_connect_done(cfg, ndev, e, true);
4542 } else if (brcmf_is_linkdown(e)) {
4543 brcmf_dbg(CONN, "Linkdown\n");
4544 if (!brcmf_is_ibssmode(ifp->vif)) {
4545 brcmf_bss_connect_done(cfg, ndev, e, false);
4546 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4547 &ifp->vif->sme_state))
4548 cfg80211_disconnected(ndev, 0, NULL, 0,
4551 brcmf_link_down(ifp->vif);
4552 brcmf_init_prof(ndev_to_prof(ndev));
4553 if (ndev != cfg_to_ndev(cfg))
4554 complete(&cfg->vif_disabled);
4555 } else if (brcmf_is_nonetwork(cfg, e)) {
4556 if (brcmf_is_ibssmode(ifp->vif))
4557 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4558 &ifp->vif->sme_state);
4560 brcmf_bss_connect_done(cfg, ndev, e, false);
4567 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4568 const struct brcmf_event_msg *e, void *data)
4570 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4572 u32 event = e->event_code;
4573 u32 status = e->status;
4575 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4576 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4577 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4579 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4586 brcmf_notify_mic_status(struct brcmf_if *ifp,
4587 const struct brcmf_event_msg *e, void *data)
4589 u16 flags = e->flags;
4590 enum nl80211_key_type key_type;
4592 if (flags & BRCMF_EVENT_MSG_GROUP)
4593 key_type = NL80211_KEYTYPE_GROUP;
4595 key_type = NL80211_KEYTYPE_PAIRWISE;
4597 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4603 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4604 const struct brcmf_event_msg *e, void *data)
4606 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4607 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4608 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4609 struct brcmf_cfg80211_vif *vif;
4611 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4612 ifevent->action, ifevent->flags, ifevent->ifidx,
4615 mutex_lock(&event->vif_event_lock);
4616 event->action = ifevent->action;
4619 switch (ifevent->action) {
4620 case BRCMF_E_IF_ADD:
4621 /* waiting process may have timed out */
4622 if (!cfg->vif_event.vif) {
4623 mutex_unlock(&event->vif_event_lock);
4629 vif->wdev.netdev = ifp->ndev;
4630 ifp->ndev->ieee80211_ptr = &vif->wdev;
4631 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4632 mutex_unlock(&event->vif_event_lock);
4633 wake_up(&event->vif_wq);
4636 case BRCMF_E_IF_DEL:
4638 mutex_unlock(&event->vif_event_lock);
4639 /* event may not be upon user request */
4640 if (brcmf_cfg80211_vif_event_armed(cfg))
4641 wake_up(&event->vif_wq);
4644 case BRCMF_E_IF_CHANGE:
4645 mutex_unlock(&event->vif_event_lock);
4646 wake_up(&event->vif_wq);
4650 mutex_unlock(&event->vif_event_lock);
4656 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4658 conf->frag_threshold = (u32)-1;
4659 conf->rts_threshold = (u32)-1;
4660 conf->retry_short = (u32)-1;
4661 conf->retry_long = (u32)-1;
4662 conf->tx_power = -1;
4665 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4667 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4668 brcmf_notify_connect_status);
4669 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4670 brcmf_notify_connect_status);
4671 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4672 brcmf_notify_connect_status);
4673 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4674 brcmf_notify_connect_status);
4675 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4676 brcmf_notify_connect_status);
4677 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4678 brcmf_notify_connect_status);
4679 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4680 brcmf_notify_roaming_status);
4681 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4682 brcmf_notify_mic_status);
4683 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4684 brcmf_notify_connect_status);
4685 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4686 brcmf_notify_sched_scan_results);
4687 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4688 brcmf_notify_vif_event);
4689 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4690 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4691 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4692 brcmf_p2p_notify_listen_complete);
4693 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4694 brcmf_p2p_notify_action_frame_rx);
4695 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4696 brcmf_p2p_notify_action_tx_complete);
4697 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4698 brcmf_p2p_notify_action_tx_complete);
4701 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4705 kfree(cfg->escan_ioctl_buf);
4706 cfg->escan_ioctl_buf = NULL;
4707 kfree(cfg->extra_buf);
4708 cfg->extra_buf = NULL;
4709 kfree(cfg->pmk_list);
4710 cfg->pmk_list = NULL;
4713 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4715 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4717 goto init_priv_mem_out;
4718 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4719 if (!cfg->escan_ioctl_buf)
4720 goto init_priv_mem_out;
4721 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4722 if (!cfg->extra_buf)
4723 goto init_priv_mem_out;
4724 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4726 goto init_priv_mem_out;
4731 brcmf_deinit_priv_mem(cfg);
4736 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4740 cfg->scan_request = NULL;
4741 cfg->pwr_save = true;
4742 cfg->roam_on = true; /* roam on & off switch.
4743 we enable roam per default */
4744 cfg->active_scan = true; /* we do active scan for
4745 specific scan per default */
4746 cfg->dongle_up = false; /* dongle is not up yet */
4747 err = brcmf_init_priv_mem(cfg);
4750 brcmf_register_event_handlers(cfg);
4751 mutex_init(&cfg->usr_sync);
4752 brcmf_init_escan(cfg);
4753 brcmf_init_conf(cfg->conf);
4754 init_completion(&cfg->vif_disabled);
4758 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4760 cfg->dongle_up = false; /* dongle down */
4761 brcmf_abort_scanning(cfg);
4762 brcmf_deinit_priv_mem(cfg);
4765 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4767 init_waitqueue_head(&event->vif_wq);
4768 mutex_init(&event->vif_event_lock);
4771 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4772 struct device *busdev)
4774 struct net_device *ndev = drvr->iflist[0]->ndev;
4775 struct brcmf_cfg80211_info *cfg;
4776 struct wiphy *wiphy;
4777 struct brcmf_cfg80211_vif *vif;
4778 struct brcmf_if *ifp;
4782 brcmf_err("ndev is invalid\n");
4786 ifp = netdev_priv(ndev);
4787 wiphy = brcmf_setup_wiphy(busdev);
4791 cfg = wiphy_priv(wiphy);
4794 init_vif_event(&cfg->vif_event);
4795 INIT_LIST_HEAD(&cfg->vif_list);
4797 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4804 vif->wdev.netdev = ndev;
4805 ndev->ieee80211_ptr = &vif->wdev;
4806 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4808 err = wl_init_priv(cfg);
4810 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4811 goto cfg80211_attach_out;
4815 err = brcmf_p2p_attach(cfg);
4817 brcmf_err("P2P initilisation failed (%d)\n", err);
4818 goto cfg80211_p2p_attach_out;
4823 cfg80211_p2p_attach_out:
4824 wl_deinit_priv(cfg);
4826 cfg80211_attach_out:
4827 brcmf_free_vif(vif);
4832 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4834 struct brcmf_cfg80211_vif *vif;
4835 struct brcmf_cfg80211_vif *tmp;
4837 wl_deinit_priv(cfg);
4838 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4839 brcmf_free_vif(vif);
4844 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
4847 __le32 roamtrigger[2];
4848 __le32 roam_delta[2];
4851 * Setup timeout if Beacons are lost and roam is
4852 * off to report link down
4855 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4857 brcmf_err("bcn_timeout error (%d)\n", err);
4858 goto dongle_rom_out;
4863 * Enable/Disable built-in roaming to allow supplicant
4864 * to take care of roaming
4866 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4867 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4869 brcmf_err("roam_off error (%d)\n", err);
4870 goto dongle_rom_out;
4873 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4874 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4875 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4876 (void *)roamtrigger, sizeof(roamtrigger));
4878 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4879 goto dongle_rom_out;
4882 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4883 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4884 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4885 (void *)roam_delta, sizeof(roam_delta));
4887 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4888 goto dongle_rom_out;
4896 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
4897 s32 scan_unassoc_time, s32 scan_passive_time)
4901 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4904 if (err == -EOPNOTSUPP)
4905 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4907 brcmf_err("Scan assoc time error (%d)\n", err);
4908 goto dongle_scantime_out;
4910 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4913 if (err == -EOPNOTSUPP)
4914 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4916 brcmf_err("Scan unassoc time error (%d)\n", err);
4917 goto dongle_scantime_out;
4920 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4923 if (err == -EOPNOTSUPP)
4924 brcmf_dbg(INFO, "Scan passive time is not supported\n");
4926 brcmf_err("Scan passive time error (%d)\n", err);
4927 goto dongle_scantime_out;
4930 dongle_scantime_out:
4934 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4936 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4937 struct wiphy *wiphy;
4942 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4943 &phy_list, sizeof(phy_list));
4945 brcmf_err("error (%d)\n", err);
4949 phy = ((char *)&phy_list)[0];
4950 brcmf_dbg(INFO, "%c phy\n", phy);
4951 if (phy == 'n' || phy == 'a') {
4952 wiphy = cfg_to_wiphy(cfg);
4953 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4959 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4961 return wl_update_wiphybands(cfg);
4964 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4966 struct net_device *ndev;
4967 struct wireless_dev *wdev;
4968 struct brcmf_if *ifp;
4975 ndev = cfg_to_ndev(cfg);
4976 wdev = ndev->ieee80211_ptr;
4977 ifp = netdev_priv(ndev);
4979 /* make sure RF is ready for work */
4980 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
4982 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
4983 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4985 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4986 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
4988 goto default_conf_out;
4989 brcmf_dbg(INFO, "power save set to %s\n",
4990 (power_mode ? "enabled" : "disabled"));
4992 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
4994 goto default_conf_out;
4995 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4998 goto default_conf_out;
4999 err = brcmf_dongle_probecap(cfg);
5001 goto default_conf_out;
5003 cfg->dongle_up = true;
5010 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5012 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5014 return brcmf_config_dongle(ifp->drvr->config);
5017 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5019 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5022 * While going down, if associated with AP disassociate
5023 * from AP to save power
5025 if (check_vif_up(ifp->vif)) {
5026 brcmf_link_down(ifp->vif);
5028 /* Make sure WPA_Supplicant receives all the event
5029 generated due to DISASSOC call to the fw to keep
5030 the state fw and WPA_Supplicant state consistent
5035 brcmf_abort_scanning(cfg);
5036 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5041 s32 brcmf_cfg80211_up(struct net_device *ndev)
5043 struct brcmf_if *ifp = netdev_priv(ndev);
5044 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5047 mutex_lock(&cfg->usr_sync);
5048 err = __brcmf_cfg80211_up(ifp);
5049 mutex_unlock(&cfg->usr_sync);
5054 s32 brcmf_cfg80211_down(struct net_device *ndev)
5056 struct brcmf_if *ifp = netdev_priv(ndev);
5057 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5060 mutex_lock(&cfg->usr_sync);
5061 err = __brcmf_cfg80211_down(ifp);
5062 mutex_unlock(&cfg->usr_sync);
5067 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5069 struct brcmf_cfg80211_vif *vif;
5072 list_for_each_entry(vif, &cfg->vif_list, list) {
5073 if (test_bit(state, &vif->sme_state))
5079 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5084 mutex_lock(&event->vif_event_lock);
5085 evt_action = event->action;
5086 mutex_unlock(&event->vif_event_lock);
5087 return evt_action == action;
5090 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5091 struct brcmf_cfg80211_vif *vif)
5093 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5095 mutex_lock(&event->vif_event_lock);
5098 mutex_unlock(&event->vif_event_lock);
5101 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5103 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5106 mutex_lock(&event->vif_event_lock);
5107 armed = event->vif != NULL;
5108 mutex_unlock(&event->vif_event_lock);
5112 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5113 u8 action, ulong timeout)
5115 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5117 return wait_event_timeout(event->vif_wq,
5118 vif_event_equals(event, action), timeout);