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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include <linux/kernel.h>
22 #include <linux/etherdevice.h>
23 #include <net/cfg80211.h>
24 #include <net/netlink.h>
26 #include <brcmu_utils.h>
28 #include <brcmu_wifi.h>
30 #include "wl_cfg80211.h"
33 #define BRCMF_SCAN_IE_LEN_MAX 2048
34 #define BRCMF_PNO_VERSION 2
35 #define BRCMF_PNO_TIME 30
36 #define BRCMF_PNO_REPEAT 4
37 #define BRCMF_PNO_FREQ_EXPO_MAX 3
38 #define BRCMF_PNO_MAX_PFN_COUNT 16
39 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
40 #define BRCMF_PNO_HIDDEN_BIT 2
41 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
42 #define BRCMF_PNO_SCAN_COMPLETE 1
43 #define BRCMF_PNO_SCAN_INCOMPLETE 0
45 #define BRCMF_IFACE_MAX_CNT 2
47 #define TLV_LEN_OFF 1 /* length offset */
48 #define TLV_HDR_LEN 2 /* header length */
49 #define TLV_BODY_OFF 2 /* body offset */
50 #define TLV_OUI_LEN 3 /* oui id length */
51 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
52 #define WPA_OUI_TYPE 1
53 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
54 #define WME_OUI_TYPE 2
56 #define VS_IE_FIXED_HDR_LEN 6
57 #define WPA_IE_VERSION_LEN 2
58 #define WPA_IE_MIN_OUI_LEN 4
59 #define WPA_IE_SUITE_COUNT_LEN 2
61 #define WPA_CIPHER_NONE 0 /* None */
62 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
63 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
64 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
65 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
67 #define RSN_AKM_NONE 0 /* None (IBSS) */
68 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
69 #define RSN_AKM_PSK 2 /* Pre-shared Key */
70 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
71 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
73 #define VNDR_IE_CMD_LEN 4 /* length of the set command
74 * string :"add", "del" (+ NUL)
76 #define VNDR_IE_COUNT_OFFSET 4
77 #define VNDR_IE_PKTFLAG_OFFSET 8
78 #define VNDR_IE_VSIE_OFFSET 12
79 #define VNDR_IE_HDR_SIZE 12
80 #define VNDR_IE_BEACON_FLAG 0x1
81 #define VNDR_IE_PRBRSP_FLAG 0x2
82 #define MAX_VNDR_IE_NUMBER 5
84 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
85 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
87 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
88 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
90 static u32 brcmf_dbg_level = WL_DBG_ERR;
92 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
94 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
95 WL_INFO("device is not ready : status (%lu)\n",
102 #define CHAN2G(_channel, _freq, _flags) { \
103 .band = IEEE80211_BAND_2GHZ, \
104 .center_freq = (_freq), \
105 .hw_value = (_channel), \
107 .max_antenna_gain = 0, \
111 #define CHAN5G(_channel, _flags) { \
112 .band = IEEE80211_BAND_5GHZ, \
113 .center_freq = 5000 + (5 * (_channel)), \
114 .hw_value = (_channel), \
116 .max_antenna_gain = 0, \
120 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
121 #define RATETAB_ENT(_rateid, _flags) \
123 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
124 .hw_value = (_rateid), \
128 static struct ieee80211_rate __wl_rates[] = {
129 RATETAB_ENT(BRCM_RATE_1M, 0),
130 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
131 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
132 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
133 RATETAB_ENT(BRCM_RATE_6M, 0),
134 RATETAB_ENT(BRCM_RATE_9M, 0),
135 RATETAB_ENT(BRCM_RATE_12M, 0),
136 RATETAB_ENT(BRCM_RATE_18M, 0),
137 RATETAB_ENT(BRCM_RATE_24M, 0),
138 RATETAB_ENT(BRCM_RATE_36M, 0),
139 RATETAB_ENT(BRCM_RATE_48M, 0),
140 RATETAB_ENT(BRCM_RATE_54M, 0),
143 #define wl_a_rates (__wl_rates + 4)
144 #define wl_a_rates_size 8
145 #define wl_g_rates (__wl_rates + 0)
146 #define wl_g_rates_size 12
148 static struct ieee80211_channel __wl_2ghz_channels[] = {
165 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
166 CHAN5G(34, 0), CHAN5G(36, 0),
167 CHAN5G(38, 0), CHAN5G(40, 0),
168 CHAN5G(42, 0), CHAN5G(44, 0),
169 CHAN5G(46, 0), CHAN5G(48, 0),
170 CHAN5G(52, 0), CHAN5G(56, 0),
171 CHAN5G(60, 0), CHAN5G(64, 0),
172 CHAN5G(100, 0), CHAN5G(104, 0),
173 CHAN5G(108, 0), CHAN5G(112, 0),
174 CHAN5G(116, 0), CHAN5G(120, 0),
175 CHAN5G(124, 0), CHAN5G(128, 0),
176 CHAN5G(132, 0), CHAN5G(136, 0),
177 CHAN5G(140, 0), CHAN5G(149, 0),
178 CHAN5G(153, 0), CHAN5G(157, 0),
179 CHAN5G(161, 0), CHAN5G(165, 0),
180 CHAN5G(184, 0), CHAN5G(188, 0),
181 CHAN5G(192, 0), CHAN5G(196, 0),
182 CHAN5G(200, 0), CHAN5G(204, 0),
183 CHAN5G(208, 0), CHAN5G(212, 0),
187 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
188 CHAN5G(32, 0), CHAN5G(34, 0),
189 CHAN5G(36, 0), CHAN5G(38, 0),
190 CHAN5G(40, 0), CHAN5G(42, 0),
191 CHAN5G(44, 0), CHAN5G(46, 0),
192 CHAN5G(48, 0), CHAN5G(50, 0),
193 CHAN5G(52, 0), CHAN5G(54, 0),
194 CHAN5G(56, 0), CHAN5G(58, 0),
195 CHAN5G(60, 0), CHAN5G(62, 0),
196 CHAN5G(64, 0), CHAN5G(66, 0),
197 CHAN5G(68, 0), CHAN5G(70, 0),
198 CHAN5G(72, 0), CHAN5G(74, 0),
199 CHAN5G(76, 0), CHAN5G(78, 0),
200 CHAN5G(80, 0), CHAN5G(82, 0),
201 CHAN5G(84, 0), CHAN5G(86, 0),
202 CHAN5G(88, 0), CHAN5G(90, 0),
203 CHAN5G(92, 0), CHAN5G(94, 0),
204 CHAN5G(96, 0), CHAN5G(98, 0),
205 CHAN5G(100, 0), CHAN5G(102, 0),
206 CHAN5G(104, 0), CHAN5G(106, 0),
207 CHAN5G(108, 0), CHAN5G(110, 0),
208 CHAN5G(112, 0), CHAN5G(114, 0),
209 CHAN5G(116, 0), CHAN5G(118, 0),
210 CHAN5G(120, 0), CHAN5G(122, 0),
211 CHAN5G(124, 0), CHAN5G(126, 0),
212 CHAN5G(128, 0), CHAN5G(130, 0),
213 CHAN5G(132, 0), CHAN5G(134, 0),
214 CHAN5G(136, 0), CHAN5G(138, 0),
215 CHAN5G(140, 0), CHAN5G(142, 0),
216 CHAN5G(144, 0), CHAN5G(145, 0),
217 CHAN5G(146, 0), CHAN5G(147, 0),
218 CHAN5G(148, 0), CHAN5G(149, 0),
219 CHAN5G(150, 0), CHAN5G(151, 0),
220 CHAN5G(152, 0), CHAN5G(153, 0),
221 CHAN5G(154, 0), CHAN5G(155, 0),
222 CHAN5G(156, 0), CHAN5G(157, 0),
223 CHAN5G(158, 0), CHAN5G(159, 0),
224 CHAN5G(160, 0), CHAN5G(161, 0),
225 CHAN5G(162, 0), CHAN5G(163, 0),
226 CHAN5G(164, 0), CHAN5G(165, 0),
227 CHAN5G(166, 0), CHAN5G(168, 0),
228 CHAN5G(170, 0), CHAN5G(172, 0),
229 CHAN5G(174, 0), CHAN5G(176, 0),
230 CHAN5G(178, 0), CHAN5G(180, 0),
231 CHAN5G(182, 0), CHAN5G(184, 0),
232 CHAN5G(186, 0), CHAN5G(188, 0),
233 CHAN5G(190, 0), CHAN5G(192, 0),
234 CHAN5G(194, 0), CHAN5G(196, 0),
235 CHAN5G(198, 0), CHAN5G(200, 0),
236 CHAN5G(202, 0), CHAN5G(204, 0),
237 CHAN5G(206, 0), CHAN5G(208, 0),
238 CHAN5G(210, 0), CHAN5G(212, 0),
239 CHAN5G(214, 0), CHAN5G(216, 0),
240 CHAN5G(218, 0), CHAN5G(220, 0),
241 CHAN5G(222, 0), CHAN5G(224, 0),
242 CHAN5G(226, 0), CHAN5G(228, 0),
245 static struct ieee80211_supported_band __wl_band_2ghz = {
246 .band = IEEE80211_BAND_2GHZ,
247 .channels = __wl_2ghz_channels,
248 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
249 .bitrates = wl_g_rates,
250 .n_bitrates = wl_g_rates_size,
253 static struct ieee80211_supported_band __wl_band_5ghz_a = {
254 .band = IEEE80211_BAND_5GHZ,
255 .channels = __wl_5ghz_a_channels,
256 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
257 .bitrates = wl_a_rates,
258 .n_bitrates = wl_a_rates_size,
261 static struct ieee80211_supported_band __wl_band_5ghz_n = {
262 .band = IEEE80211_BAND_5GHZ,
263 .channels = __wl_5ghz_n_channels,
264 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
265 .bitrates = wl_a_rates,
266 .n_bitrates = wl_a_rates_size,
269 static const u32 __wl_cipher_suites[] = {
270 WLAN_CIPHER_SUITE_WEP40,
271 WLAN_CIPHER_SUITE_WEP104,
272 WLAN_CIPHER_SUITE_TKIP,
273 WLAN_CIPHER_SUITE_CCMP,
274 WLAN_CIPHER_SUITE_AES_CMAC,
277 /* tag_ID/length/value_buffer tuple */
284 /* Vendor specific ie. id = 221, oui and type defines exact ie */
285 struct brcmf_vs_tlv {
292 struct parsed_vndr_ie_info {
294 u32 ie_len; /* total length including id & length field */
295 struct brcmf_vs_tlv vndrie;
298 struct parsed_vndr_ies {
300 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
303 /* Quarter dBm units to mW
304 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
305 * Table is offset so the last entry is largest mW value that fits in
309 #define QDBM_OFFSET 153 /* Offset for first entry */
310 #define QDBM_TABLE_LEN 40 /* Table size */
312 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
313 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
315 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
317 /* Largest mW value that will round down to the last table entry,
318 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
319 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
320 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
322 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
324 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
325 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
326 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
327 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
328 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
329 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
330 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
333 static u16 brcmf_qdbm_to_mw(u8 qdbm)
336 int idx = qdbm - QDBM_OFFSET;
338 if (idx >= QDBM_TABLE_LEN)
339 /* clamp to max u16 mW value */
342 /* scale the qdBm index up to the range of the table 0-40
343 * where an offset of 40 qdBm equals a factor of 10 mW.
350 /* return the mW value scaled down to the correct factor of 10,
351 * adding in factor/2 to get proper rounding.
353 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
356 static u8 brcmf_mw_to_qdbm(u16 mw)
363 /* handle boundary case */
367 offset = QDBM_OFFSET;
369 /* move mw into the range of the table */
370 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
375 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
376 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
377 nqdBm_to_mW_map[qdbm]) / 2;
378 if (mw_uint < boundary)
387 static u16 channel_to_chanspec(struct ieee80211_channel *ch)
391 chanspec = ieee80211_frequency_to_channel(ch->center_freq);
392 chanspec &= WL_CHANSPEC_CHAN_MASK;
394 if (ch->band == IEEE80211_BAND_2GHZ)
395 chanspec |= WL_CHANSPEC_BAND_2G;
397 chanspec |= WL_CHANSPEC_BAND_5G;
399 if (ch->flags & IEEE80211_CHAN_NO_HT40) {
400 chanspec |= WL_CHANSPEC_BW_20;
401 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
403 chanspec |= WL_CHANSPEC_BW_40;
404 if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS)
405 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
407 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
412 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
413 struct brcmf_wsec_key_le *key_le)
415 key_le->index = cpu_to_le32(key->index);
416 key_le->len = cpu_to_le32(key->len);
417 key_le->algo = cpu_to_le32(key->algo);
418 key_le->flags = cpu_to_le32(key->flags);
419 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
420 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
421 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
422 memcpy(key_le->data, key->data, sizeof(key->data));
423 memcpy(key_le->ea, key->ea, sizeof(key->ea));
427 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
430 struct brcmf_wsec_key_le key_le;
432 convert_key_from_CPU(key, &key_le);
434 brcmf_netdev_wait_pend8021x(ndev);
436 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
440 WL_ERR("wsec_key error (%d)\n", err);
445 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
446 enum nl80211_iftype type, u32 *flags,
447 struct vif_params *params)
449 struct brcmf_if *ifp = netdev_priv(ndev);
450 struct brcmf_cfg80211_vif *vif = ifp->vif;
455 WL_TRACE("Enter, ndev=%p, type=%d\n", ndev, type);
458 case NL80211_IFTYPE_MONITOR:
459 case NL80211_IFTYPE_WDS:
460 WL_ERR("type (%d) : currently we do not support this type\n",
463 case NL80211_IFTYPE_ADHOC:
464 vif->mode = WL_MODE_IBSS;
467 case NL80211_IFTYPE_STATION:
468 vif->mode = WL_MODE_BSS;
471 case NL80211_IFTYPE_AP:
472 vif->mode = WL_MODE_AP;
481 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
482 WL_INFO("IF Type = AP\n");
484 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
486 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
490 WL_INFO("IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
493 ndev->ieee80211_ptr->iftype = type;
501 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
503 struct brcmf_if *ifp = netdev_priv(ndev);
506 if (check_vif_up(ifp->vif)) {
507 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
509 WL_ERR("fail to set mpc\n");
512 WL_INFO("MPC : %d\n", mpc);
516 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
517 struct cfg80211_scan_request *request)
525 struct brcmf_ssid_le ssid_le;
527 memset(params_le->bssid, 0xFF, ETH_ALEN);
528 params_le->bss_type = DOT11_BSSTYPE_ANY;
529 params_le->scan_type = 0;
530 params_le->channel_num = 0;
531 params_le->nprobes = cpu_to_le32(-1);
532 params_le->active_time = cpu_to_le32(-1);
533 params_le->passive_time = cpu_to_le32(-1);
534 params_le->home_time = cpu_to_le32(-1);
535 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
537 /* if request is null exit so it will be all channel broadcast scan */
541 n_ssids = request->n_ssids;
542 n_channels = request->n_channels;
543 /* Copy channel array if applicable */
544 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
545 if (n_channels > 0) {
546 for (i = 0; i < n_channels; i++) {
547 chanspec = channel_to_chanspec(request->channels[i]);
548 WL_SCAN("Chan : %d, Channel spec: %x\n",
549 request->channels[i]->hw_value, chanspec);
550 params_le->channel_list[i] = cpu_to_le16(chanspec);
553 WL_SCAN("Scanning all channels\n");
555 /* Copy ssid array if applicable */
556 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
558 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
559 n_channels * sizeof(u16);
560 offset = roundup(offset, sizeof(u32));
561 ptr = (char *)params_le + offset;
562 for (i = 0; i < n_ssids; i++) {
563 memset(&ssid_le, 0, sizeof(ssid_le));
565 cpu_to_le32(request->ssids[i].ssid_len);
566 memcpy(ssid_le.SSID, request->ssids[i].ssid,
567 request->ssids[i].ssid_len);
568 if (!ssid_le.SSID_len)
569 WL_SCAN("%d: Broadcast scan\n", i);
571 WL_SCAN("%d: scan for %s size =%d\n", i,
572 ssid_le.SSID, ssid_le.SSID_len);
573 memcpy(ptr, &ssid_le, sizeof(ssid_le));
574 ptr += sizeof(ssid_le);
577 WL_SCAN("Broadcast scan %p\n", request->ssids);
578 if ((request->ssids) && request->ssids->ssid_len) {
579 WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
580 request->ssids->ssid_len);
581 params_le->ssid_le.SSID_len =
582 cpu_to_le32(request->ssids->ssid_len);
583 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
584 request->ssids->ssid_len);
587 /* Adding mask to channel numbers */
588 params_le->channel_num =
589 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
590 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
594 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
595 struct net_device *ndev,
596 bool aborted, bool fw_abort)
598 struct brcmf_scan_params_le params_le;
599 struct cfg80211_scan_request *scan_request;
604 /* clear scan request, because the FW abort can cause a second call */
605 /* to this functon and might cause a double cfg80211_scan_done */
606 scan_request = cfg->scan_request;
607 cfg->scan_request = NULL;
609 if (timer_pending(&cfg->escan_timeout))
610 del_timer_sync(&cfg->escan_timeout);
613 /* Do a scan abort to stop the driver's scan engine */
614 WL_SCAN("ABORT scan in firmware\n");
615 memset(¶ms_le, 0, sizeof(params_le));
616 memset(params_le.bssid, 0xFF, ETH_ALEN);
617 params_le.bss_type = DOT11_BSSTYPE_ANY;
618 params_le.scan_type = 0;
619 params_le.channel_num = cpu_to_le32(1);
620 params_le.nprobes = cpu_to_le32(1);
621 params_le.active_time = cpu_to_le32(-1);
622 params_le.passive_time = cpu_to_le32(-1);
623 params_le.home_time = cpu_to_le32(-1);
624 /* Scan is aborted by setting channel_list[0] to -1 */
625 params_le.channel_list[0] = cpu_to_le16(-1);
626 /* E-Scan (or anyother type) can be aborted by SCAN */
627 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
628 ¶ms_le, sizeof(params_le));
630 WL_ERR("Scan abort failed\n");
633 * e-scan can be initiated by scheduled scan
634 * which takes precedence.
636 if (cfg->sched_escan) {
637 WL_SCAN("scheduled scan completed\n");
638 cfg->sched_escan = false;
640 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
641 brcmf_set_mpc(ndev, 1);
642 } else if (scan_request) {
643 WL_SCAN("ESCAN Completed scan: %s\n",
644 aborted ? "Aborted" : "Done");
645 cfg80211_scan_done(scan_request, aborted);
646 brcmf_set_mpc(ndev, 1);
648 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
649 WL_ERR("Scan complete while device not scanning\n");
657 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
658 struct cfg80211_scan_request *request, u16 action)
660 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
661 offsetof(struct brcmf_escan_params_le, params_le);
662 struct brcmf_escan_params_le *params;
665 WL_SCAN("E-SCAN START\n");
667 if (request != NULL) {
668 /* Allocate space for populating ssids in struct */
669 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
671 /* Allocate space for populating ssids in struct */
672 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
675 params = kzalloc(params_size, GFP_KERNEL);
680 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
681 brcmf_escan_prep(¶ms->params_le, request);
682 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
683 params->action = cpu_to_le16(action);
684 params->sync_id = cpu_to_le16(0x1234);
686 err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan",
687 params, params_size);
690 WL_INFO("system busy : escan canceled\n");
692 WL_ERR("error (%d)\n", err);
701 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
702 struct net_device *ndev, struct cfg80211_scan_request *request)
706 struct brcmf_scan_results *results;
709 cfg->escan_info.ndev = ndev;
710 cfg->escan_info.wiphy = wiphy;
711 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
712 passive_scan = cfg->active_scan ? 0 : 1;
713 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
716 WL_ERR("error (%d)\n", err);
719 brcmf_set_mpc(ndev, 0);
720 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
721 results->version = 0;
723 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
725 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
727 brcmf_set_mpc(ndev, 1);
732 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
733 struct cfg80211_scan_request *request,
734 struct cfg80211_ssid *this_ssid)
736 struct brcmf_if *ifp = netdev_priv(ndev);
737 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
738 struct cfg80211_ssid *ssids;
739 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
746 WL_SCAN("START ESCAN\n");
748 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
749 WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
752 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
753 WL_ERR("Scanning being aborted: status (%lu)\n",
757 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
758 WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state);
762 /* Arm scan timeout timer */
763 mod_timer(&cfg->escan_timeout, jiffies +
764 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
769 ssids = request->ssids;
773 /* we don't do escan in ibss */
777 cfg->scan_request = request;
778 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
780 err = brcmf_do_escan(cfg, wiphy, ndev, request);
784 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
785 ssids->ssid, ssids->ssid_len);
786 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
787 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
788 sr->ssid_le.SSID_len = cpu_to_le32(0);
791 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
792 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
795 WL_SCAN("Broadcast scan\n");
797 passive_scan = cfg->active_scan ? 0 : 1;
798 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
801 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
804 brcmf_set_mpc(ndev, 0);
805 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
806 &sr->ssid_le, sizeof(sr->ssid_le));
809 WL_INFO("BUSY: scan for \"%s\" canceled\n",
812 WL_ERR("WLC_SCAN error (%d)\n", err);
814 brcmf_set_mpc(ndev, 1);
822 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
823 if (timer_pending(&cfg->escan_timeout))
824 del_timer_sync(&cfg->escan_timeout);
825 cfg->scan_request = NULL;
830 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
832 struct net_device *ndev = request->wdev->netdev;
837 if (!check_vif_up(container_of(request->wdev,
838 struct brcmf_cfg80211_vif, wdev)))
841 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
844 WL_ERR("scan error (%d)\n", err);
850 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
854 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
857 WL_ERR("Error (%d)\n", err);
862 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
866 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
869 WL_ERR("Error (%d)\n", err);
874 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
877 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
879 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
881 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
887 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
889 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
890 struct net_device *ndev = cfg_to_ndev(cfg);
891 struct brcmf_if *ifp = netdev_priv(ndev);
895 if (!check_vif_up(ifp->vif))
898 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
899 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
900 cfg->conf->rts_threshold = wiphy->rts_threshold;
901 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
905 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
906 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
907 cfg->conf->frag_threshold = wiphy->frag_threshold;
908 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
912 if (changed & WIPHY_PARAM_RETRY_LONG
913 && (cfg->conf->retry_long != wiphy->retry_long)) {
914 cfg->conf->retry_long = wiphy->retry_long;
915 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
919 if (changed & WIPHY_PARAM_RETRY_SHORT
920 && (cfg->conf->retry_short != wiphy->retry_short)) {
921 cfg->conf->retry_short = wiphy->retry_short;
922 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
932 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
934 memset(prof, 0, sizeof(*prof));
937 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
938 size_t *join_params_size)
943 if (ch <= CH_MAX_2G_CHANNEL)
944 chanspec |= WL_CHANSPEC_BAND_2G;
946 chanspec |= WL_CHANSPEC_BAND_5G;
948 chanspec |= WL_CHANSPEC_BW_20;
949 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
951 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
954 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
955 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
956 join_params->params_le.chanspec_num = cpu_to_le32(1);
958 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
959 "channel %d, chanspec %#X\n",
960 chanspec, ch, chanspec);
964 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
970 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
971 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
972 err = brcmf_fil_cmd_data_set(vif->ifp,
973 BRCMF_C_DISASSOC, NULL, 0);
975 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
976 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
978 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
983 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
984 struct cfg80211_ibss_params *params)
986 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
987 struct brcmf_if *ifp = netdev_priv(ndev);
988 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
989 struct brcmf_join_params join_params;
990 size_t join_params_size = 0;
996 if (!check_vif_up(ifp->vif))
1000 WL_CONN("SSID: %s\n", params->ssid);
1002 WL_CONN("SSID: NULL, Not supported\n");
1006 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1009 WL_CONN("BSSID: %pM\n", params->bssid);
1011 WL_CONN("No BSSID specified\n");
1013 if (params->chandef.chan)
1014 WL_CONN("channel: %d\n", params->chandef.chan->center_freq);
1016 WL_CONN("no channel specified\n");
1018 if (params->channel_fixed)
1019 WL_CONN("fixed channel required\n");
1021 WL_CONN("no fixed channel required\n");
1023 if (params->ie && params->ie_len)
1024 WL_CONN("ie len: %d\n", params->ie_len);
1026 WL_CONN("no ie specified\n");
1028 if (params->beacon_interval)
1029 WL_CONN("beacon interval: %d\n", params->beacon_interval);
1031 WL_CONN("no beacon interval specified\n");
1033 if (params->basic_rates)
1034 WL_CONN("basic rates: %08X\n", params->basic_rates);
1036 WL_CONN("no basic rates specified\n");
1038 if (params->privacy)
1039 WL_CONN("privacy required\n");
1041 WL_CONN("no privacy required\n");
1043 /* Configure Privacy for starter */
1044 if (params->privacy)
1045 wsec |= WEP_ENABLED;
1047 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1049 WL_ERR("wsec failed (%d)\n", err);
1053 /* Configure Beacon Interval for starter */
1054 if (params->beacon_interval)
1055 bcnprd = params->beacon_interval;
1059 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1061 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1065 /* Configure required join parameter */
1066 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1069 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1070 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1071 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1072 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1073 join_params_size = sizeof(join_params.ssid_le);
1076 if (params->bssid) {
1077 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1078 join_params_size = sizeof(join_params.ssid_le) +
1079 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1080 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1082 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1083 memset(profile->bssid, 0, ETH_ALEN);
1087 if (params->chandef.chan) {
1091 ieee80211_frequency_to_channel(
1092 params->chandef.chan->center_freq);
1093 if (params->channel_fixed) {
1094 /* adding chanspec */
1095 brcmf_ch_to_chanspec(cfg->channel,
1096 &join_params, &join_params_size);
1099 /* set channel for starter */
1100 target_channel = cfg->channel;
1101 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1104 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1110 cfg->ibss_starter = false;
1113 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1114 &join_params, join_params_size);
1116 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1122 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1128 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1130 struct brcmf_if *ifp = netdev_priv(ndev);
1133 WL_TRACE("Enter\n");
1134 if (!check_vif_up(ifp->vif))
1137 brcmf_link_down(ifp->vif);
1144 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1145 struct cfg80211_connect_params *sme)
1147 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1148 struct brcmf_cfg80211_security *sec;
1152 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1153 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1154 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1155 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1157 val = WPA_AUTH_DISABLED;
1158 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1159 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val);
1161 WL_ERR("set wpa_auth failed (%d)\n", err);
1164 sec = &profile->sec;
1165 sec->wpa_versions = sme->crypto.wpa_versions;
1169 static s32 brcmf_set_auth_type(struct net_device *ndev,
1170 struct cfg80211_connect_params *sme)
1172 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1173 struct brcmf_cfg80211_security *sec;
1177 switch (sme->auth_type) {
1178 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1180 WL_CONN("open system\n");
1182 case NL80211_AUTHTYPE_SHARED_KEY:
1184 WL_CONN("shared key\n");
1186 case NL80211_AUTHTYPE_AUTOMATIC:
1188 WL_CONN("automatic\n");
1190 case NL80211_AUTHTYPE_NETWORK_EAP:
1191 WL_CONN("network eap\n");
1194 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1198 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val);
1200 WL_ERR("set auth failed (%d)\n", err);
1203 sec = &profile->sec;
1204 sec->auth_type = sme->auth_type;
1209 brcmf_set_set_cipher(struct net_device *ndev,
1210 struct cfg80211_connect_params *sme)
1212 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1213 struct brcmf_cfg80211_security *sec;
1218 if (sme->crypto.n_ciphers_pairwise) {
1219 switch (sme->crypto.ciphers_pairwise[0]) {
1220 case WLAN_CIPHER_SUITE_WEP40:
1221 case WLAN_CIPHER_SUITE_WEP104:
1224 case WLAN_CIPHER_SUITE_TKIP:
1225 pval = TKIP_ENABLED;
1227 case WLAN_CIPHER_SUITE_CCMP:
1230 case WLAN_CIPHER_SUITE_AES_CMAC:
1234 WL_ERR("invalid cipher pairwise (%d)\n",
1235 sme->crypto.ciphers_pairwise[0]);
1239 if (sme->crypto.cipher_group) {
1240 switch (sme->crypto.cipher_group) {
1241 case WLAN_CIPHER_SUITE_WEP40:
1242 case WLAN_CIPHER_SUITE_WEP104:
1245 case WLAN_CIPHER_SUITE_TKIP:
1246 gval = TKIP_ENABLED;
1248 case WLAN_CIPHER_SUITE_CCMP:
1251 case WLAN_CIPHER_SUITE_AES_CMAC:
1255 WL_ERR("invalid cipher group (%d)\n",
1256 sme->crypto.cipher_group);
1261 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1262 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval);
1264 WL_ERR("error (%d)\n", err);
1268 sec = &profile->sec;
1269 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1270 sec->cipher_group = sme->crypto.cipher_group;
1276 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1278 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1279 struct brcmf_cfg80211_security *sec;
1283 if (sme->crypto.n_akm_suites) {
1284 err = brcmf_fil_iovar_int_get(netdev_priv(ndev),
1287 WL_ERR("could not get wpa_auth (%d)\n", err);
1290 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1291 switch (sme->crypto.akm_suites[0]) {
1292 case WLAN_AKM_SUITE_8021X:
1293 val = WPA_AUTH_UNSPECIFIED;
1295 case WLAN_AKM_SUITE_PSK:
1299 WL_ERR("invalid cipher group (%d)\n",
1300 sme->crypto.cipher_group);
1303 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1304 switch (sme->crypto.akm_suites[0]) {
1305 case WLAN_AKM_SUITE_8021X:
1306 val = WPA2_AUTH_UNSPECIFIED;
1308 case WLAN_AKM_SUITE_PSK:
1309 val = WPA2_AUTH_PSK;
1312 WL_ERR("invalid cipher group (%d)\n",
1313 sme->crypto.cipher_group);
1318 WL_CONN("setting wpa_auth to %d\n", val);
1319 err = brcmf_fil_iovar_int_set(netdev_priv(ndev),
1322 WL_ERR("could not set wpa_auth (%d)\n", err);
1326 sec = &profile->sec;
1327 sec->wpa_auth = sme->crypto.akm_suites[0];
1333 brcmf_set_sharedkey(struct net_device *ndev,
1334 struct cfg80211_connect_params *sme)
1336 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1337 struct brcmf_cfg80211_security *sec;
1338 struct brcmf_wsec_key key;
1342 WL_CONN("key len (%d)\n", sme->key_len);
1344 if (sme->key_len == 0)
1347 sec = &profile->sec;
1348 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1349 sec->wpa_versions, sec->cipher_pairwise);
1351 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1354 if (!(sec->cipher_pairwise &
1355 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1358 memset(&key, 0, sizeof(key));
1359 key.len = (u32) sme->key_len;
1360 key.index = (u32) sme->key_idx;
1361 if (key.len > sizeof(key.data)) {
1362 WL_ERR("Too long key length (%u)\n", key.len);
1365 memcpy(key.data, sme->key, key.len);
1366 key.flags = BRCMF_PRIMARY_KEY;
1367 switch (sec->cipher_pairwise) {
1368 case WLAN_CIPHER_SUITE_WEP40:
1369 key.algo = CRYPTO_ALGO_WEP1;
1371 case WLAN_CIPHER_SUITE_WEP104:
1372 key.algo = CRYPTO_ALGO_WEP128;
1375 WL_ERR("Invalid algorithm (%d)\n",
1376 sme->crypto.ciphers_pairwise[0]);
1379 /* Set the new key/index */
1380 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1381 key.len, key.index, key.algo);
1382 WL_CONN("key \"%s\"\n", key.data);
1383 err = send_key_to_dongle(ndev, &key);
1387 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1388 WL_CONN("set auth_type to shared key\n");
1389 val = WL_AUTH_SHARED_KEY; /* shared key */
1390 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1392 WL_ERR("set auth failed (%d)\n", err);
1398 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1399 struct cfg80211_connect_params *sme)
1401 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1402 struct brcmf_if *ifp = netdev_priv(ndev);
1403 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1404 struct ieee80211_channel *chan = sme->channel;
1405 struct brcmf_join_params join_params;
1406 size_t join_params_size;
1407 struct brcmf_ssid ssid;
1411 WL_TRACE("Enter\n");
1412 if (!check_vif_up(ifp->vif))
1416 WL_ERR("Invalid ssid\n");
1420 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1424 ieee80211_frequency_to_channel(chan->center_freq);
1425 WL_CONN("channel (%d), center_req (%d)\n",
1426 cfg->channel, chan->center_freq);
1430 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1432 err = brcmf_set_wpa_version(ndev, sme);
1434 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1438 err = brcmf_set_auth_type(ndev, sme);
1440 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1444 err = brcmf_set_set_cipher(ndev, sme);
1446 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1450 err = brcmf_set_key_mgmt(ndev, sme);
1452 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1456 err = brcmf_set_sharedkey(ndev, sme);
1458 WL_ERR("brcmf_set_sharedkey failed (%d)\n", err);
1462 memset(&join_params, 0, sizeof(join_params));
1463 join_params_size = sizeof(join_params.ssid_le);
1465 profile->ssid.SSID_len = min_t(u32,
1466 sizeof(ssid.SSID), (u32)sme->ssid_len);
1467 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1468 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1469 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1471 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1473 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1474 WL_CONN("ssid \"%s\", len (%d)\n",
1475 ssid.SSID, ssid.SSID_len);
1477 brcmf_ch_to_chanspec(cfg->channel,
1478 &join_params, &join_params_size);
1479 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1480 &join_params, join_params_size);
1482 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1486 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1492 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1495 struct brcmf_if *ifp = netdev_priv(ndev);
1496 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1497 struct brcmf_scb_val_le scbval;
1500 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1501 if (!check_vif_up(ifp->vif))
1504 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1506 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1507 scbval.val = cpu_to_le32(reason_code);
1508 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1509 &scbval, sizeof(scbval));
1511 WL_ERR("error (%d)\n", err);
1518 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1519 enum nl80211_tx_power_setting type, s32 mbm)
1522 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1523 struct net_device *ndev = cfg_to_ndev(cfg);
1524 struct brcmf_if *ifp = netdev_priv(ndev);
1528 s32 dbm = MBM_TO_DBM(mbm);
1530 WL_TRACE("Enter\n");
1531 if (!check_vif_up(ifp->vif))
1535 case NL80211_TX_POWER_AUTOMATIC:
1537 case NL80211_TX_POWER_LIMITED:
1538 case NL80211_TX_POWER_FIXED:
1540 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1546 /* Make sure radio is off or on as far as software is concerned */
1547 disable = WL_RADIO_SW_DISABLE << 16;
1548 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1550 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1555 txpwrmw = (u16) dbm;
1556 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1557 (s32)brcmf_mw_to_qdbm(txpwrmw));
1559 WL_ERR("qtxpower error (%d)\n", err);
1560 cfg->conf->tx_power = dbm;
1567 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1568 struct wireless_dev *wdev,
1571 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1572 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1577 WL_TRACE("Enter\n");
1578 if (!check_vif_up(ifp->vif))
1581 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1583 WL_ERR("error (%d)\n", err);
1587 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1588 *dbm = (s32) brcmf_qdbm_to_mw(result);
1596 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1597 u8 key_idx, bool unicast, bool multicast)
1599 struct brcmf_if *ifp = netdev_priv(ndev);
1604 WL_TRACE("Enter\n");
1605 WL_CONN("key index (%d)\n", key_idx);
1606 if (!check_vif_up(ifp->vif))
1609 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1611 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1615 if (wsec & WEP_ENABLED) {
1616 /* Just select a new current key */
1618 err = brcmf_fil_cmd_int_set(ifp,
1619 BRCMF_C_SET_KEY_PRIMARY, index);
1621 WL_ERR("error (%d)\n", err);
1629 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1630 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1632 struct brcmf_wsec_key key;
1635 memset(&key, 0, sizeof(key));
1636 key.index = (u32) key_idx;
1637 /* Instead of bcast for ea address for default wep keys,
1638 driver needs it to be Null */
1639 if (!is_multicast_ether_addr(mac_addr))
1640 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1641 key.len = (u32) params->key_len;
1642 /* check for key index change */
1645 err = send_key_to_dongle(ndev, &key);
1647 WL_ERR("key delete error (%d)\n", err);
1649 if (key.len > sizeof(key.data)) {
1650 WL_ERR("Invalid key length (%d)\n", key.len);
1654 WL_CONN("Setting the key index %d\n", key.index);
1655 memcpy(key.data, params->key, key.len);
1657 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1659 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1660 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1661 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1664 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1665 if (params->seq && params->seq_len == 6) {
1668 ivptr = (u8 *) params->seq;
1669 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1670 (ivptr[3] << 8) | ivptr[2];
1671 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1672 key.iv_initialized = true;
1675 switch (params->cipher) {
1676 case WLAN_CIPHER_SUITE_WEP40:
1677 key.algo = CRYPTO_ALGO_WEP1;
1678 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1680 case WLAN_CIPHER_SUITE_WEP104:
1681 key.algo = CRYPTO_ALGO_WEP128;
1682 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1684 case WLAN_CIPHER_SUITE_TKIP:
1685 key.algo = CRYPTO_ALGO_TKIP;
1686 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1688 case WLAN_CIPHER_SUITE_AES_CMAC:
1689 key.algo = CRYPTO_ALGO_AES_CCM;
1690 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1692 case WLAN_CIPHER_SUITE_CCMP:
1693 key.algo = CRYPTO_ALGO_AES_CCM;
1694 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1697 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1700 err = send_key_to_dongle(ndev, &key);
1702 WL_ERR("wsec_key error (%d)\n", err);
1708 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1709 u8 key_idx, bool pairwise, const u8 *mac_addr,
1710 struct key_params *params)
1712 struct brcmf_if *ifp = netdev_priv(ndev);
1713 struct brcmf_wsec_key key;
1719 WL_TRACE("Enter\n");
1720 WL_CONN("key index (%d)\n", key_idx);
1721 if (!check_vif_up(ifp->vif))
1726 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1728 memset(&key, 0, sizeof(key));
1730 key.len = (u32) params->key_len;
1731 key.index = (u32) key_idx;
1733 if (key.len > sizeof(key.data)) {
1734 WL_ERR("Too long key length (%u)\n", key.len);
1738 memcpy(key.data, params->key, key.len);
1740 key.flags = BRCMF_PRIMARY_KEY;
1741 switch (params->cipher) {
1742 case WLAN_CIPHER_SUITE_WEP40:
1743 key.algo = CRYPTO_ALGO_WEP1;
1745 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1747 case WLAN_CIPHER_SUITE_WEP104:
1748 key.algo = CRYPTO_ALGO_WEP128;
1750 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1752 case WLAN_CIPHER_SUITE_TKIP:
1753 if (ifp->vif->mode != WL_MODE_AP) {
1754 WL_CONN("Swapping key\n");
1755 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1756 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1757 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1759 key.algo = CRYPTO_ALGO_TKIP;
1761 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1763 case WLAN_CIPHER_SUITE_AES_CMAC:
1764 key.algo = CRYPTO_ALGO_AES_CCM;
1766 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1768 case WLAN_CIPHER_SUITE_CCMP:
1769 key.algo = CRYPTO_ALGO_AES_CCM;
1771 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1774 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1779 err = send_key_to_dongle(ndev, &key);
1783 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1785 WL_ERR("get wsec error (%d)\n", err);
1789 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1791 WL_ERR("set wsec error (%d)\n", err);
1801 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1802 u8 key_idx, bool pairwise, const u8 *mac_addr)
1804 struct brcmf_if *ifp = netdev_priv(ndev);
1805 struct brcmf_wsec_key key;
1808 WL_TRACE("Enter\n");
1809 if (!check_vif_up(ifp->vif))
1812 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
1813 /* we ignore this key index in this case */
1814 WL_ERR("invalid key index (%d)\n", key_idx);
1818 memset(&key, 0, sizeof(key));
1820 key.index = (u32) key_idx;
1821 key.flags = BRCMF_PRIMARY_KEY;
1822 key.algo = CRYPTO_ALGO_OFF;
1824 WL_CONN("key index (%d)\n", key_idx);
1826 /* Set the new key/index */
1827 err = send_key_to_dongle(ndev, &key);
1834 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1835 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1836 void (*callback) (void *cookie, struct key_params * params))
1838 struct key_params params;
1839 struct brcmf_if *ifp = netdev_priv(ndev);
1840 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1841 struct brcmf_cfg80211_security *sec;
1845 WL_TRACE("Enter\n");
1846 WL_CONN("key index (%d)\n", key_idx);
1847 if (!check_vif_up(ifp->vif))
1850 memset(¶ms, 0, sizeof(params));
1852 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1854 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1855 /* Ignore this error, may happen during DISASSOC */
1859 switch (wsec & ~SES_OW_ENABLED) {
1861 sec = &profile->sec;
1862 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1863 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1864 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1865 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1866 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1867 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1871 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1872 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1875 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1876 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1879 WL_ERR("Invalid algo (0x%x)\n", wsec);
1883 callback(cookie, ¶ms);
1891 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1892 struct net_device *ndev, u8 key_idx)
1894 WL_INFO("Not supported\n");
1900 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1901 u8 *mac, struct station_info *sinfo)
1903 struct brcmf_if *ifp = netdev_priv(ndev);
1904 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1905 struct brcmf_scb_val_le scb_val;
1909 u8 *bssid = profile->bssid;
1910 struct brcmf_sta_info_le sta_info_le;
1912 WL_TRACE("Enter, MAC %pM\n", mac);
1913 if (!check_vif_up(ifp->vif))
1916 if (ifp->vif->mode == WL_MODE_AP) {
1917 memcpy(&sta_info_le, mac, ETH_ALEN);
1918 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
1920 sizeof(sta_info_le));
1922 WL_ERR("GET STA INFO failed, %d\n", err);
1925 sinfo->filled = STATION_INFO_INACTIVE_TIME;
1926 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
1927 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
1928 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
1929 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
1931 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
1932 sinfo->inactive_time, sinfo->connected_time);
1933 } else if (ifp->vif->mode == WL_MODE_BSS) {
1934 if (memcmp(mac, bssid, ETH_ALEN)) {
1935 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1940 /* Report the current tx rate */
1941 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
1943 WL_ERR("Could not get rate (%d)\n", err);
1946 sinfo->filled |= STATION_INFO_TX_BITRATE;
1947 sinfo->txrate.legacy = rate * 5;
1948 WL_CONN("Rate %d Mbps\n", rate / 2);
1951 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
1952 &ifp->vif->sme_state)) {
1953 memset(&scb_val, 0, sizeof(scb_val));
1954 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
1955 &scb_val, sizeof(scb_val));
1957 WL_ERR("Could not get rssi (%d)\n", err);
1960 rssi = le32_to_cpu(scb_val.val);
1961 sinfo->filled |= STATION_INFO_SIGNAL;
1962 sinfo->signal = rssi;
1963 WL_CONN("RSSI %d dBm\n", rssi);
1974 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1975 bool enabled, s32 timeout)
1979 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1980 struct brcmf_if *ifp = netdev_priv(ndev);
1982 WL_TRACE("Enter\n");
1985 * Powersave enable/disable request is coming from the
1986 * cfg80211 even before the interface is up. In that
1987 * scenario, driver will be storing the power save
1988 * preference in cfg struct to apply this to
1989 * FW later while initializing the dongle
1991 cfg->pwr_save = enabled;
1992 if (!check_vif_up(ifp->vif)) {
1994 WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
1998 pm = enabled ? PM_FAST : PM_OFF;
1999 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
2001 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2004 WL_ERR("net_device is not ready yet\n");
2006 WL_ERR("error (%d)\n", err);
2014 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2016 const struct cfg80211_bitrate_mask *mask)
2018 struct brcmf_if *ifp = netdev_priv(ndev);
2019 struct brcm_rateset_le rateset_le;
2027 WL_TRACE("Enter\n");
2028 if (!check_vif_up(ifp->vif))
2031 /* addr param is always NULL. ignore it */
2032 /* Get current rateset */
2033 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET,
2034 &rateset_le, sizeof(rateset_le));
2036 WL_ERR("could not get current rateset (%d)\n", err);
2040 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2042 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2045 val = wl_g_rates[legacy - 1].bitrate * 100000;
2047 if (val < le32_to_cpu(rateset_le.count))
2048 /* Select rate by rateset index */
2049 rate = rateset_le.rates[val] & 0x7f;
2051 /* Specified rate in bps */
2052 rate = val / 500000;
2054 WL_CONN("rate %d mbps\n", rate / 2);
2058 * Set rate override,
2059 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2061 err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate);
2062 err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate);
2063 if (err_bg && err_a) {
2064 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2065 err = err_bg | err_a;
2073 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2074 struct brcmf_bss_info_le *bi)
2076 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2077 struct ieee80211_channel *notify_channel;
2078 struct cfg80211_bss *bss;
2079 struct ieee80211_supported_band *band;
2083 u16 notify_capability;
2084 u16 notify_interval;
2086 size_t notify_ielen;
2089 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2090 WL_ERR("Bss info is larger than buffer. Discarding\n");
2094 channel = bi->ctl_ch ? bi->ctl_ch :
2095 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2097 if (channel <= CH_MAX_2G_CHANNEL)
2098 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2100 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2102 freq = ieee80211_channel_to_frequency(channel, band->band);
2103 notify_channel = ieee80211_get_channel(wiphy, freq);
2105 notify_capability = le16_to_cpu(bi->capability);
2106 notify_interval = le16_to_cpu(bi->beacon_period);
2107 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2108 notify_ielen = le32_to_cpu(bi->ie_length);
2109 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2111 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2112 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2113 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2114 WL_CONN("Channel: %d(%d)\n", channel, freq);
2115 WL_CONN("Capability: %X\n", notify_capability);
2116 WL_CONN("Beacon interval: %d\n", notify_interval);
2117 WL_CONN("Signal: %d\n", notify_signal);
2119 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2120 0, notify_capability, notify_interval, notify_ie,
2121 notify_ielen, notify_signal, GFP_KERNEL);
2126 cfg80211_put_bss(bss);
2131 static struct brcmf_bss_info_le *
2132 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2135 return list->bss_info_le;
2136 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2137 le32_to_cpu(bss->length));
2140 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2142 struct brcmf_scan_results *bss_list;
2143 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2147 bss_list = cfg->bss_list;
2148 if (bss_list->count != 0 &&
2149 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2150 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2154 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2155 for (i = 0; i < bss_list->count; i++) {
2156 bi = next_bss_le(bss_list, bi);
2157 err = brcmf_inform_single_bss(cfg, bi);
2164 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2165 struct net_device *ndev, const u8 *bssid)
2167 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2168 struct ieee80211_channel *notify_channel;
2169 struct brcmf_bss_info_le *bi = NULL;
2170 struct ieee80211_supported_band *band;
2171 struct cfg80211_bss *bss;
2176 u16 notify_capability;
2177 u16 notify_interval;
2179 size_t notify_ielen;
2182 WL_TRACE("Enter\n");
2184 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2190 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2192 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2193 buf, WL_BSS_INFO_MAX);
2195 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2199 bi = (struct brcmf_bss_info_le *)(buf + 4);
2201 channel = bi->ctl_ch ? bi->ctl_ch :
2202 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2204 if (channel <= CH_MAX_2G_CHANNEL)
2205 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2207 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2209 freq = ieee80211_channel_to_frequency(channel, band->band);
2210 notify_channel = ieee80211_get_channel(wiphy, freq);
2212 notify_capability = le16_to_cpu(bi->capability);
2213 notify_interval = le16_to_cpu(bi->beacon_period);
2214 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2215 notify_ielen = le32_to_cpu(bi->ie_length);
2216 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2218 WL_CONN("channel: %d(%d)\n", channel, freq);
2219 WL_CONN("capability: %X\n", notify_capability);
2220 WL_CONN("beacon interval: %d\n", notify_interval);
2221 WL_CONN("signal: %d\n", notify_signal);
2223 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2224 0, notify_capability, notify_interval,
2225 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2232 cfg80211_put_bss(bss);
2243 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2245 return vif->mode == WL_MODE_IBSS;
2249 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2250 * triples, returning a pointer to the substring whose first element
2253 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2255 struct brcmf_tlv *elt;
2258 elt = (struct brcmf_tlv *) buf;
2261 /* find tagged parameter */
2262 while (totlen >= TLV_HDR_LEN) {
2265 /* validate remaining totlen */
2266 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2269 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2270 totlen -= (len + TLV_HDR_LEN);
2276 /* Is any of the tlvs the expected entry? If
2277 * not update the tlvs buffer pointer/length.
2280 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2281 u8 *oui, u32 oui_len, u8 type)
2283 /* If the contents match the OUI and the type */
2284 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2285 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2286 type == ie[TLV_BODY_OFF + oui_len]) {
2292 /* point to the next ie */
2293 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2294 /* calculate the length of the rest of the buffer */
2295 *tlvs_len -= (int)(ie - *tlvs);
2296 /* update the pointer to the start of the buffer */
2302 static struct brcmf_vs_tlv *
2303 brcmf_find_wpaie(u8 *parse, u32 len)
2305 struct brcmf_tlv *ie;
2307 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
2308 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2309 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2310 return (struct brcmf_vs_tlv *)ie;
2315 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2317 struct net_device *ndev = cfg_to_ndev(cfg);
2318 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2319 struct brcmf_if *ifp = netdev_priv(ndev);
2320 struct brcmf_bss_info_le *bi;
2321 struct brcmf_ssid *ssid;
2322 struct brcmf_tlv *tim;
2323 u16 beacon_interval;
2329 WL_TRACE("Enter\n");
2330 if (brcmf_is_ibssmode(ifp->vif))
2333 ssid = &profile->ssid;
2335 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2336 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2337 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2339 WL_ERR("Could not get bss info %d\n", err);
2340 goto update_bss_info_out;
2343 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2344 err = brcmf_inform_single_bss(cfg, bi);
2346 goto update_bss_info_out;
2348 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2349 ie_len = le32_to_cpu(bi->ie_length);
2350 beacon_interval = le16_to_cpu(bi->beacon_period);
2352 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2354 dtim_period = tim->data[1];
2357 * active scan was done so we could not get dtim
2358 * information out of probe response.
2359 * so we speficially query dtim information to dongle.
2362 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2364 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2365 goto update_bss_info_out;
2367 dtim_period = (u8)var;
2370 update_bss_info_out:
2375 static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2377 struct escan_info *escan = &cfg->escan_info;
2379 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2380 if (cfg->scan_request) {
2381 escan->escan_state = WL_ESCAN_STATE_IDLE;
2382 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2384 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2385 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2388 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2390 struct brcmf_cfg80211_info *cfg =
2391 container_of(work, struct brcmf_cfg80211_info,
2392 escan_timeout_work);
2394 brcmf_notify_escan_complete(cfg,
2395 cfg->escan_info.ndev, true, true);
2398 static void brcmf_escan_timeout(unsigned long data)
2400 struct brcmf_cfg80211_info *cfg =
2401 (struct brcmf_cfg80211_info *)data;
2403 if (cfg->scan_request) {
2404 WL_ERR("timer expired\n");
2405 schedule_work(&cfg->escan_timeout_work);
2410 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2411 struct brcmf_bss_info_le *bss_info_le)
2413 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2414 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2415 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2416 bss_info_le->SSID_len == bss->SSID_len &&
2417 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2418 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2419 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2420 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2421 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2423 /* preserve max RSSI if the measurements are
2424 * both on-channel or both off-channel
2426 if (bss_info_rssi > bss_rssi)
2427 bss->RSSI = bss_info_le->RSSI;
2428 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2429 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2430 /* preserve the on-channel rssi measurement
2431 * if the new measurement is off channel
2433 bss->RSSI = bss_info_le->RSSI;
2434 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2442 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2443 const struct brcmf_event_msg *e, void *data)
2445 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2446 struct net_device *ndev = ifp->ndev;
2449 struct brcmf_escan_result_le *escan_result_le;
2450 struct brcmf_bss_info_le *bss_info_le;
2451 struct brcmf_bss_info_le *bss = NULL;
2453 struct brcmf_scan_results *list;
2459 if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2460 WL_ERR("scan not ready ndev %p drv_status %x\n", ndev,
2461 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2465 if (status == BRCMF_E_STATUS_PARTIAL) {
2466 WL_SCAN("ESCAN Partial result\n");
2467 escan_result_le = (struct brcmf_escan_result_le *) data;
2468 if (!escan_result_le) {
2469 WL_ERR("Invalid escan result (NULL pointer)\n");
2472 if (!cfg->scan_request) {
2473 WL_SCAN("result without cfg80211 request\n");
2477 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2478 WL_ERR("Invalid bss_count %d: ignoring\n",
2479 escan_result_le->bss_count);
2482 bss_info_le = &escan_result_le->bss_info_le;
2484 bi_length = le32_to_cpu(bss_info_le->length);
2485 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2486 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2487 WL_ERR("Invalid bss_info length %d: ignoring\n",
2492 if (!(cfg_to_wiphy(cfg)->interface_modes &
2493 BIT(NL80211_IFTYPE_ADHOC))) {
2494 if (le16_to_cpu(bss_info_le->capability) &
2495 WLAN_CAPABILITY_IBSS) {
2496 WL_ERR("Ignoring IBSS result\n");
2501 list = (struct brcmf_scan_results *)
2502 cfg->escan_info.escan_buf;
2503 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2504 WL_ERR("Buffer is too small: ignoring\n");
2508 for (i = 0; i < list->count; i++) {
2509 bss = bss ? (struct brcmf_bss_info_le *)
2510 ((unsigned char *)bss +
2511 le32_to_cpu(bss->length)) : list->bss_info_le;
2512 if (brcmf_compare_update_same_bss(bss, bss_info_le))
2515 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2516 bss_info_le, bi_length);
2517 list->version = le32_to_cpu(bss_info_le->version);
2518 list->buflen += bi_length;
2521 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2522 if (cfg->scan_request) {
2523 cfg->bss_list = (struct brcmf_scan_results *)
2524 cfg->escan_info.escan_buf;
2525 brcmf_inform_bss(cfg);
2526 aborted = status != BRCMF_E_STATUS_SUCCESS;
2527 brcmf_notify_escan_complete(cfg, ndev, aborted,
2530 WL_ERR("Unexpected scan result 0x%x\n", status);
2536 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2538 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2539 brcmf_cfg80211_escan_handler);
2540 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2541 /* Init scan_timeout timer */
2542 init_timer(&cfg->escan_timeout);
2543 cfg->escan_timeout.data = (unsigned long) cfg;
2544 cfg->escan_timeout.function = brcmf_escan_timeout;
2545 INIT_WORK(&cfg->escan_timeout_work,
2546 brcmf_cfg80211_escan_timeout_worker);
2549 static __always_inline void brcmf_delay(u32 ms)
2551 if (ms < 1000 / HZ) {
2559 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2561 WL_TRACE("Enter\n");
2566 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2567 struct cfg80211_wowlan *wow)
2569 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2570 struct net_device *ndev = cfg_to_ndev(cfg);
2571 struct brcmf_cfg80211_vif *vif;
2573 WL_TRACE("Enter\n");
2576 * if the primary net_device is not READY there is nothing
2577 * we can do but pray resume goes smoothly.
2579 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2580 if (!check_vif_up(vif))
2583 list_for_each_entry(vif, &cfg->vif_list, list) {
2584 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2587 * While going to suspend if associated with AP disassociate
2588 * from AP to save power while system is in suspended state
2590 brcmf_link_down(vif);
2592 /* Make sure WPA_Supplicant receives all the event
2593 * generated due to DISASSOC call to the fw to keep
2594 * the state fw and WPA_Supplicant state consistent
2599 /* end any scanning */
2600 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2601 brcmf_abort_scanning(cfg);
2603 /* Turn off watchdog timer */
2604 brcmf_set_mpc(ndev, 1);
2608 /* clear any scanning activity */
2609 cfg->scan_status = 0;
2614 brcmf_update_pmklist(struct net_device *ndev,
2615 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2620 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2622 WL_CONN("No of elements %d\n", pmkid_len);
2623 for (i = 0; i < pmkid_len; i++) {
2624 WL_CONN("PMKID[%d]: %pM =\n", i,
2625 &pmk_list->pmkids.pmkid[i].BSSID);
2626 for (j = 0; j < WLAN_PMKID_LEN; j++)
2627 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2631 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2632 (char *)pmk_list, sizeof(*pmk_list));
2638 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2639 struct cfg80211_pmksa *pmksa)
2641 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2642 struct brcmf_if *ifp = netdev_priv(ndev);
2643 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2648 WL_TRACE("Enter\n");
2649 if (!check_vif_up(ifp->vif))
2652 pmkid_len = le32_to_cpu(pmkids->npmkid);
2653 for (i = 0; i < pmkid_len; i++)
2654 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2656 if (i < WL_NUM_PMKIDS_MAX) {
2657 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2658 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2659 if (i == pmkid_len) {
2661 pmkids->npmkid = cpu_to_le32(pmkid_len);
2666 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2667 pmkids->pmkid[pmkid_len].BSSID);
2668 for (i = 0; i < WLAN_PMKID_LEN; i++)
2669 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2671 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2678 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2679 struct cfg80211_pmksa *pmksa)
2681 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2682 struct brcmf_if *ifp = netdev_priv(ndev);
2683 struct pmkid_list pmkid;
2687 WL_TRACE("Enter\n");
2688 if (!check_vif_up(ifp->vif))
2691 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2692 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2694 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2695 &pmkid.pmkid[0].BSSID);
2696 for (i = 0; i < WLAN_PMKID_LEN; i++)
2697 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2699 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2700 for (i = 0; i < pmkid_len; i++)
2702 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2707 && (i < pmkid_len)) {
2708 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2709 sizeof(struct pmkid));
2710 for (; i < (pmkid_len - 1); i++) {
2711 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2712 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2714 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2715 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2718 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2722 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2730 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2732 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2733 struct brcmf_if *ifp = netdev_priv(ndev);
2736 WL_TRACE("Enter\n");
2737 if (!check_vif_up(ifp->vif))
2740 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2741 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2749 * PFN result doesn't have all the info which are
2750 * required by the supplicant
2751 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2752 * via wl_inform_single_bss in the required format. Escan does require the
2753 * scan request in the form of cfg80211_scan_request. For timebeing, create
2754 * cfg80211_scan_request one out of the received PNO event.
2757 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2758 const struct brcmf_event_msg *e, void *data)
2760 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2761 struct net_device *ndev = ifp->ndev;
2762 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2763 struct cfg80211_scan_request *request = NULL;
2764 struct cfg80211_ssid *ssid = NULL;
2765 struct ieee80211_channel *channel = NULL;
2766 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2768 int channel_req = 0;
2770 struct brcmf_pno_scanresults_le *pfn_result;
2776 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2777 WL_SCAN("PFN NET LOST event. Do Nothing\n");
2781 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2782 result_count = le32_to_cpu(pfn_result->count);
2783 status = le32_to_cpu(pfn_result->status);
2786 * PFN event is limited to fit 512 bytes so we may get
2787 * multiple NET_FOUND events. For now place a warning here.
2789 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2790 WL_SCAN("PFN NET FOUND event. count: %d\n", result_count);
2791 if (result_count > 0) {
2794 request = kzalloc(sizeof(*request), GFP_KERNEL);
2795 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2796 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2797 if (!request || !ssid || !channel) {
2802 request->wiphy = wiphy;
2803 data += sizeof(struct brcmf_pno_scanresults_le);
2804 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2806 for (i = 0; i < result_count; i++) {
2807 netinfo = &netinfo_start[i];
2809 WL_ERR("Invalid netinfo ptr. index: %d\n", i);
2814 WL_SCAN("SSID:%s Channel:%d\n",
2815 netinfo->SSID, netinfo->channel);
2816 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2817 ssid[i].ssid_len = netinfo->SSID_len;
2820 channel_req = netinfo->channel;
2821 if (channel_req <= CH_MAX_2G_CHANNEL)
2822 band = NL80211_BAND_2GHZ;
2824 band = NL80211_BAND_5GHZ;
2825 channel[i].center_freq =
2826 ieee80211_channel_to_frequency(channel_req,
2828 channel[i].band = band;
2829 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2830 request->channels[i] = &channel[i];
2831 request->n_channels++;
2834 /* assign parsed ssid array */
2835 if (request->n_ssids)
2836 request->ssids = &ssid[0];
2838 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2839 /* Abort any on-going scan */
2840 brcmf_abort_scanning(cfg);
2843 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2844 err = brcmf_do_escan(cfg, wiphy, ndev, request);
2846 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2849 cfg->sched_escan = true;
2850 cfg->scan_request = request;
2852 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
2865 cfg80211_sched_scan_stopped(wiphy);
2869 static int brcmf_dev_pno_clean(struct net_device *ndev)
2874 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
2877 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
2881 WL_ERR("failed code %d\n", ret);
2886 static int brcmf_dev_pno_config(struct net_device *ndev)
2888 struct brcmf_pno_param_le pfn_param;
2890 memset(&pfn_param, 0, sizeof(pfn_param));
2891 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
2893 /* set extra pno params */
2894 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
2895 pfn_param.repeat = BRCMF_PNO_REPEAT;
2896 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
2898 /* set up pno scan fr */
2899 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
2901 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
2902 &pfn_param, sizeof(pfn_param));
2906 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
2907 struct net_device *ndev,
2908 struct cfg80211_sched_scan_request *request)
2910 struct brcmf_if *ifp = netdev_priv(ndev);
2911 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
2912 struct brcmf_pno_net_param_le pfn;
2916 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
2917 request->n_match_sets, request->n_ssids);
2918 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2919 WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
2923 if (!request || !request->n_ssids || !request->n_match_sets) {
2924 WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
2925 request ? request->n_ssids : 0);
2929 if (request->n_ssids > 0) {
2930 for (i = 0; i < request->n_ssids; i++) {
2931 /* Active scan req for ssids */
2932 WL_SCAN(">>> Active scan req for ssid (%s)\n",
2933 request->ssids[i].ssid);
2936 * match_set ssids is a supert set of n_ssid list,
2937 * so we need not add these set seperately.
2942 if (request->n_match_sets > 0) {
2943 /* clean up everything */
2944 ret = brcmf_dev_pno_clean(ndev);
2946 WL_ERR("failed error=%d\n", ret);
2951 ret = brcmf_dev_pno_config(ndev);
2953 WL_ERR("PNO setup failed!! ret=%d\n", ret);
2957 /* configure each match set */
2958 for (i = 0; i < request->n_match_sets; i++) {
2959 struct cfg80211_ssid *ssid;
2962 ssid = &request->match_sets[i].ssid;
2963 ssid_len = ssid->ssid_len;
2966 WL_ERR("skip broadcast ssid\n");
2969 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
2970 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
2971 pfn.wsec = cpu_to_le32(0);
2972 pfn.infra = cpu_to_le32(1);
2973 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
2974 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
2975 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
2976 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
2978 WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
2979 ret == 0 ? "set" : "failed",
2982 /* Enable the PNO */
2983 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
2984 WL_ERR("PNO enable failed!! ret=%d\n", ret);
2994 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
2995 struct net_device *ndev)
2997 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3000 brcmf_dev_pno_clean(ndev);
3001 if (cfg->sched_escan)
3002 brcmf_notify_escan_complete(cfg, ndev, true, true);
3006 #ifdef CONFIG_NL80211_TESTMODE
3007 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3009 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3010 struct net_device *ndev = cfg_to_ndev(cfg);
3011 struct brcmf_dcmd *dcmd = data;
3012 struct sk_buff *reply;
3015 WL_TRACE("cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3016 dcmd->buf, dcmd->len);
3019 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3020 dcmd->buf, dcmd->len);
3022 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3023 dcmd->buf, dcmd->len);
3025 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3026 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3027 ret = cfg80211_testmode_reply(reply);
3033 static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3035 struct brcmf_if *ifp = netdev_priv(ndev);
3039 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3041 WL_ERR("auth error %d\n", err);
3045 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3047 WL_ERR("wsec error %d\n", err);
3050 /* set upper-layer auth */
3051 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3053 WL_ERR("wpa_auth error %d\n", err);
3060 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3063 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3065 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3069 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3072 struct brcmf_if *ifp = netdev_priv(ndev);
3073 u32 auth = 0; /* d11 open authentication */
3085 u32 wme_bss_disable;
3087 WL_TRACE("Enter\n");
3091 len = wpa_ie->len + TLV_HDR_LEN;
3092 data = (u8 *)wpa_ie;
3095 offset += VS_IE_FIXED_HDR_LEN;
3096 offset += WPA_IE_VERSION_LEN;
3098 /* check for multicast cipher suite */
3099 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3101 WL_ERR("no multicast cipher suite\n");
3105 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3107 WL_ERR("ivalid OUI\n");
3110 offset += TLV_OUI_LEN;
3112 /* pick up multicast cipher */
3113 switch (data[offset]) {
3114 case WPA_CIPHER_NONE:
3117 case WPA_CIPHER_WEP_40:
3118 case WPA_CIPHER_WEP_104:
3121 case WPA_CIPHER_TKIP:
3122 gval = TKIP_ENABLED;
3124 case WPA_CIPHER_AES_CCM:
3129 WL_ERR("Invalid multi cast cipher info\n");
3134 /* walk thru unicast cipher list and pick up what we recognize */
3135 count = data[offset] + (data[offset + 1] << 8);
3136 offset += WPA_IE_SUITE_COUNT_LEN;
3137 /* Check for unicast suite(s) */
3138 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3140 WL_ERR("no unicast cipher suite\n");
3143 for (i = 0; i < count; i++) {
3144 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3146 WL_ERR("ivalid OUI\n");
3149 offset += TLV_OUI_LEN;
3150 switch (data[offset]) {
3151 case WPA_CIPHER_NONE:
3153 case WPA_CIPHER_WEP_40:
3154 case WPA_CIPHER_WEP_104:
3155 pval |= WEP_ENABLED;
3157 case WPA_CIPHER_TKIP:
3158 pval |= TKIP_ENABLED;
3160 case WPA_CIPHER_AES_CCM:
3161 pval |= AES_ENABLED;
3164 WL_ERR("Ivalid unicast security info\n");
3168 /* walk thru auth management suite list and pick up what we recognize */
3169 count = data[offset] + (data[offset + 1] << 8);
3170 offset += WPA_IE_SUITE_COUNT_LEN;
3171 /* Check for auth key management suite(s) */
3172 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3174 WL_ERR("no auth key mgmt suite\n");
3177 for (i = 0; i < count; i++) {
3178 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3180 WL_ERR("ivalid OUI\n");
3183 offset += TLV_OUI_LEN;
3184 switch (data[offset]) {
3186 WL_TRACE("RSN_AKM_NONE\n");
3187 wpa_auth |= WPA_AUTH_NONE;
3189 case RSN_AKM_UNSPECIFIED:
3190 WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3191 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3192 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3195 WL_TRACE("RSN_AKM_PSK\n");
3196 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3197 (wpa_auth |= WPA_AUTH_PSK);
3200 WL_ERR("Ivalid key mgmt info\n");
3206 wme_bss_disable = 1;
3207 if ((offset + RSN_CAP_LEN) <= len) {
3208 rsn_cap = data[offset] + (data[offset + 1] << 8);
3209 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3210 wme_bss_disable = 0;
3212 /* set wme_bss_disable to sync RSN Capabilities */
3213 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3216 WL_ERR("wme_bss_disable error %d\n", err);
3220 /* FOR WPS , set SES_OW_ENABLED */
3221 wsec = (pval | gval | SES_OW_ENABLED);
3224 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3226 WL_ERR("auth error %d\n", err);
3230 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3232 WL_ERR("wsec error %d\n", err);
3235 /* set upper-layer auth */
3236 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3238 WL_ERR("wpa_auth error %d\n", err);
3247 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3248 struct parsed_vndr_ies *vndr_ies)
3251 struct brcmf_vs_tlv *vndrie;
3252 struct brcmf_tlv *ie;
3253 struct parsed_vndr_ie_info *parsed_info;
3256 remaining_len = (s32)vndr_ie_len;
3257 memset(vndr_ies, 0, sizeof(*vndr_ies));
3259 ie = (struct brcmf_tlv *)vndr_ie_buf;
3261 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3263 vndrie = (struct brcmf_vs_tlv *)ie;
3264 /* len should be bigger than OUI length + one */
3265 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3266 WL_ERR("invalid vndr ie. length is too small %d\n",
3270 /* if wpa or wme ie, do not add ie */
3271 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3272 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3273 (vndrie->oui_type == WME_OUI_TYPE))) {
3274 WL_TRACE("Found WPA/WME oui. Do not add it\n");
3278 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3280 /* save vndr ie information */
3281 parsed_info->ie_ptr = (char *)vndrie;
3282 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3283 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3287 WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3288 parsed_info->vndrie.oui[0],
3289 parsed_info->vndrie.oui[1],
3290 parsed_info->vndrie.oui[2],
3291 parsed_info->vndrie.oui_type);
3293 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3296 remaining_len -= ie->len;
3297 if (remaining_len <= 2)
3300 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len);
3306 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3312 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3313 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3315 iecount_le = cpu_to_le32(1);
3316 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3318 pktflag_le = cpu_to_le32(pktflag);
3319 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3321 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3323 return ie_len + VNDR_IE_HDR_SIZE;
3327 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3328 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3330 struct brcmf_if *ifp;
3331 struct vif_saved_ie *saved_ie;
3335 u8 *mgmt_ie_buf = NULL;
3336 int mgmt_ie_buf_len;
3338 u32 del_add_ie_buf_len = 0;
3339 u32 total_ie_buf_len = 0;
3340 u32 parsed_ie_buf_len = 0;
3341 struct parsed_vndr_ies old_vndr_ies;
3342 struct parsed_vndr_ies new_vndr_ies;
3343 struct parsed_vndr_ie_info *vndrie_info;
3346 int remained_buf_len;
3351 saved_ie = &vif->saved_ie;
3353 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3354 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3357 curr_ie_buf = iovar_ie_buf;
3358 if (ifp->vif->mode == WL_MODE_AP) {
3360 case VNDR_IE_PRBRSP_FLAG:
3361 mgmt_ie_buf = saved_ie->probe_res_ie;
3362 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3363 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3365 case VNDR_IE_BEACON_FLAG:
3366 mgmt_ie_buf = saved_ie->beacon_ie;
3367 mgmt_ie_len = &saved_ie->beacon_ie_len;
3368 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3372 WL_ERR("not suitable type\n");
3377 WL_ERR("not suitable type\n");
3381 if (vndr_ie_len > mgmt_ie_buf_len) {
3383 WL_ERR("extra IE size too big\n");
3387 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3388 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3390 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3391 for (i = 0; i < new_vndr_ies.count; i++) {
3392 vndrie_info = &new_vndr_ies.ie_info[i];
3393 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3394 vndrie_info->ie_len);
3395 parsed_ie_buf_len += vndrie_info->ie_len;
3399 if (mgmt_ie_buf != NULL) {
3400 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3401 (memcmp(mgmt_ie_buf, curr_ie_buf,
3402 parsed_ie_buf_len) == 0)) {
3403 WL_TRACE("Previous mgmt IE is equals to current IE");
3407 /* parse old vndr_ie */
3408 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3410 /* make a command to delete old ie */
3411 for (i = 0; i < old_vndr_ies.count; i++) {
3412 vndrie_info = &old_vndr_ies.ie_info[i];
3414 WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3415 vndrie_info->vndrie.id,
3416 vndrie_info->vndrie.len,
3417 vndrie_info->vndrie.oui[0],
3418 vndrie_info->vndrie.oui[1],
3419 vndrie_info->vndrie.oui[2]);
3421 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3422 vndrie_info->ie_ptr,
3423 vndrie_info->ie_len,
3425 curr_ie_buf += del_add_ie_buf_len;
3426 total_ie_buf_len += del_add_ie_buf_len;
3431 /* Add if there is any extra IE */
3432 if (mgmt_ie_buf && parsed_ie_buf_len) {
3435 remained_buf_len = mgmt_ie_buf_len;
3437 /* make a command to add new ie */
3438 for (i = 0; i < new_vndr_ies.count; i++) {
3439 vndrie_info = &new_vndr_ies.ie_info[i];
3441 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3442 vndrie_info->vndrie.id,
3443 vndrie_info->vndrie.len,
3444 vndrie_info->vndrie.oui[0],
3445 vndrie_info->vndrie.oui[1],
3446 vndrie_info->vndrie.oui[2]);
3448 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3449 vndrie_info->ie_ptr,
3450 vndrie_info->ie_len,
3452 /* verify remained buf size before copy data */
3453 remained_buf_len -= vndrie_info->ie_len;
3454 if (remained_buf_len < 0) {
3455 WL_ERR("no space in mgmt_ie_buf: len left %d",
3460 /* save the parsed IE in wl struct */
3461 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3462 vndrie_info->ie_len);
3463 *mgmt_ie_len += vndrie_info->ie_len;
3465 curr_ie_buf += del_add_ie_buf_len;
3466 total_ie_buf_len += del_add_ie_buf_len;
3469 if (total_ie_buf_len) {
3470 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3473 WL_ERR("vndr ie set error : %d\n", err);
3477 kfree(iovar_ie_buf);
3482 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3483 struct cfg80211_ap_settings *settings)
3486 struct brcmf_if *ifp = netdev_priv(ndev);
3487 struct brcmf_tlv *ssid_ie;
3488 struct brcmf_ssid_le ssid_le;
3490 struct brcmf_tlv *rsn_ie;
3491 struct brcmf_vs_tlv *wpa_ie;
3492 struct brcmf_join_params join_params;
3495 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3496 cfg80211_get_chandef_type(&settings->chandef),
3497 settings->beacon_interval,
3498 settings->dtim_period);
3499 WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3500 settings->ssid, settings->ssid_len, settings->auth_type,
3501 settings->inactivity_timeout);
3503 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
3504 WL_ERR("Not in AP creation mode\n");
3508 memset(&ssid_le, 0, sizeof(ssid_le));
3509 if (settings->ssid == NULL || settings->ssid_len == 0) {
3510 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3511 ssid_ie = brcmf_parse_tlvs(
3512 (u8 *)&settings->beacon.head[ie_offset],
3513 settings->beacon.head_len - ie_offset,
3518 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3519 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3520 WL_TRACE("SSID is (%s) in Head\n", ssid_le.SSID);
3522 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3523 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3526 brcmf_set_mpc(ndev, 0);
3527 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3529 WL_ERR("BRCMF_C_DOWN error %d\n", err);
3532 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3534 WL_ERR("SET INFRA error %d\n", err);
3537 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3539 WL_ERR("setting AP mode failed %d\n", err);
3543 /* find the RSN_IE */
3544 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3545 settings->beacon.tail_len, WLAN_EID_RSN);
3547 /* find the WPA_IE */
3548 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3549 settings->beacon.tail_len);
3551 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3552 WL_TRACE("WPA(2) IE is found\n");
3553 if (wpa_ie != NULL) {
3555 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3560 err = brcmf_configure_wpaie(ndev,
3561 (struct brcmf_vs_tlv *)rsn_ie, true);
3566 WL_TRACE("No WPA(2) IEs found\n");
3567 brcmf_configure_opensecurity(ndev, bssidx);
3569 /* Set Beacon IEs to FW */
3570 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3571 VNDR_IE_BEACON_FLAG,
3572 settings->beacon.tail,
3573 settings->beacon.tail_len);
3575 WL_ERR("Set Beacon IE Failed\n");
3577 WL_TRACE("Applied Vndr IEs for Beacon\n");
3579 /* Set Probe Response IEs to FW */
3580 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3581 VNDR_IE_PRBRSP_FLAG,
3582 settings->beacon.proberesp_ies,
3583 settings->beacon.proberesp_ies_len);
3585 WL_ERR("Set Probe Resp IE Failed\n");
3587 WL_TRACE("Applied Vndr IEs for Probe Resp\n");
3589 if (settings->beacon_interval) {
3590 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3591 settings->beacon_interval);
3593 WL_ERR("Beacon Interval Set Error, %d\n", err);
3597 if (settings->dtim_period) {
3598 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3599 settings->dtim_period);
3601 WL_ERR("DTIM Interval Set Error, %d\n", err);
3605 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3607 WL_ERR("BRCMF_C_UP error (%d)\n", err);
3611 memset(&join_params, 0, sizeof(join_params));
3612 /* join parameters starts with ssid */
3613 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3615 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3616 &join_params, sizeof(join_params));
3618 WL_ERR("SET SSID error (%d)\n", err);
3621 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3622 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3626 brcmf_set_mpc(ndev, 1);
3630 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3632 struct brcmf_if *ifp = netdev_priv(ndev);
3635 WL_TRACE("Enter\n");
3637 if (ifp->vif->mode == WL_MODE_AP) {
3638 /* Due to most likely deauths outstanding we sleep */
3639 /* first to make sure they get processed by fw. */
3641 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3643 WL_ERR("setting AP mode failed %d\n", err);
3646 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3648 WL_ERR("BRCMF_C_UP error %d\n", err);
3651 brcmf_set_mpc(ndev, 1);
3652 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3653 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3660 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3663 struct brcmf_scb_val_le scbval;
3664 struct brcmf_if *ifp = netdev_priv(ndev);
3670 WL_TRACE("Enter %pM\n", mac);
3672 if (!check_vif_up(ifp->vif))
3675 memcpy(&scbval.ea, mac, ETH_ALEN);
3676 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3677 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3678 &scbval, sizeof(scbval));
3680 WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3686 static struct cfg80211_ops wl_cfg80211_ops = {
3687 .change_virtual_intf = brcmf_cfg80211_change_iface,
3688 .scan = brcmf_cfg80211_scan,
3689 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
3690 .join_ibss = brcmf_cfg80211_join_ibss,
3691 .leave_ibss = brcmf_cfg80211_leave_ibss,
3692 .get_station = brcmf_cfg80211_get_station,
3693 .set_tx_power = brcmf_cfg80211_set_tx_power,
3694 .get_tx_power = brcmf_cfg80211_get_tx_power,
3695 .add_key = brcmf_cfg80211_add_key,
3696 .del_key = brcmf_cfg80211_del_key,
3697 .get_key = brcmf_cfg80211_get_key,
3698 .set_default_key = brcmf_cfg80211_config_default_key,
3699 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
3700 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
3701 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
3702 .connect = brcmf_cfg80211_connect,
3703 .disconnect = brcmf_cfg80211_disconnect,
3704 .suspend = brcmf_cfg80211_suspend,
3705 .resume = brcmf_cfg80211_resume,
3706 .set_pmksa = brcmf_cfg80211_set_pmksa,
3707 .del_pmksa = brcmf_cfg80211_del_pmksa,
3708 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3709 .start_ap = brcmf_cfg80211_start_ap,
3710 .stop_ap = brcmf_cfg80211_stop_ap,
3711 .del_station = brcmf_cfg80211_del_station,
3712 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
3713 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
3714 #ifdef CONFIG_NL80211_TESTMODE
3715 .testmode_cmd = brcmf_cfg80211_testmode
3719 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
3725 return NL80211_IFTYPE_STATION;
3727 return NL80211_IFTYPE_ADHOC;
3729 return NL80211_IFTYPE_UNSPECIFIED;
3735 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3737 /* scheduled scan settings */
3738 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
3739 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
3740 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
3741 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3744 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3746 struct wiphy *wiphy;
3749 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
3751 WL_ERR("Could not allocate wiphy device\n");
3752 return ERR_PTR(-ENOMEM);
3754 set_wiphy_dev(wiphy, phydev);
3755 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3756 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3757 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3758 BIT(NL80211_IFTYPE_ADHOC) |
3759 BIT(NL80211_IFTYPE_AP);
3760 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3761 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
3762 * it as 11a by default.
3763 * This will be updated with
3766 * if phy has 11n capability
3768 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3769 wiphy->cipher_suites = __wl_cipher_suites;
3770 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3771 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
3775 brcmf_wiphy_pno_params(wiphy);
3776 err = wiphy_register(wiphy);
3778 WL_ERR("Could not register wiphy device (%d)\n", err);
3780 return ERR_PTR(err);
3786 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3787 struct net_device *netdev,
3788 s32 mode, bool pm_block)
3790 struct brcmf_cfg80211_vif *vif;
3792 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
3793 return ERR_PTR(-ENOSPC);
3795 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
3797 return ERR_PTR(-ENOMEM);
3799 vif->wdev.wiphy = cfg->wiphy;
3800 vif->wdev.netdev = netdev;
3801 vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
3804 vif->ifp = netdev_priv(netdev);
3805 netdev->ieee80211_ptr = &vif->wdev;
3806 SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
3810 vif->pm_block = pm_block;
3813 brcmf_init_prof(&vif->profile);
3815 list_add_tail(&vif->list, &cfg->vif_list);
3820 static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3822 struct brcmf_cfg80211_info *cfg;
3823 struct wiphy *wiphy;
3825 wiphy = vif->wdev.wiphy;
3826 cfg = wiphy_priv(wiphy);
3827 list_del(&vif->list);
3831 if (!cfg->vif_cnt) {
3832 wiphy_unregister(wiphy);
3837 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
3839 u32 event = e->event_code;
3840 u32 status = e->status;
3842 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3843 WL_CONN("Processing set ssid\n");
3850 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
3852 u32 event = e->event_code;
3853 u16 flags = e->flags;
3855 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
3856 WL_CONN("Processing link down\n");
3862 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
3863 const struct brcmf_event_msg *e)
3865 u32 event = e->event_code;
3866 u32 status = e->status;
3868 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
3869 WL_CONN("Processing Link %s & no network found\n",
3870 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
3874 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
3875 WL_CONN("Processing connecting & no network found\n");
3882 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3884 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3886 kfree(conn_info->req_ie);
3887 conn_info->req_ie = NULL;
3888 conn_info->req_ie_len = 0;
3889 kfree(conn_info->resp_ie);
3890 conn_info->resp_ie = NULL;
3891 conn_info->resp_ie_len = 0;
3894 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
3896 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
3897 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3898 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3903 brcmf_clear_assoc_ies(cfg);
3905 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
3906 cfg->extra_buf, WL_ASSOC_INFO_MAX);
3908 WL_ERR("could not get assoc info (%d)\n", err);
3912 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
3913 req_len = le32_to_cpu(assoc_info->req_len);
3914 resp_len = le32_to_cpu(assoc_info->resp_len);
3916 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
3920 WL_ERR("could not get assoc req (%d)\n", err);
3923 conn_info->req_ie_len = req_len;
3925 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
3928 conn_info->req_ie_len = 0;
3929 conn_info->req_ie = NULL;
3932 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
3936 WL_ERR("could not get assoc resp (%d)\n", err);
3939 conn_info->resp_ie_len = resp_len;
3940 conn_info->resp_ie =
3941 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
3944 conn_info->resp_ie_len = 0;
3945 conn_info->resp_ie = NULL;
3947 WL_CONN("req len (%d) resp len (%d)\n",
3948 conn_info->req_ie_len, conn_info->resp_ie_len);
3954 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3955 struct net_device *ndev,
3956 const struct brcmf_event_msg *e)
3958 struct brcmf_if *ifp = netdev_priv(ndev);
3959 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
3960 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3961 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3962 struct ieee80211_channel *notify_channel = NULL;
3963 struct ieee80211_supported_band *band;
3964 struct brcmf_bss_info_le *bi;
3970 WL_TRACE("Enter\n");
3972 brcmf_get_assoc_ies(cfg);
3973 memcpy(profile->bssid, e->addr, ETH_ALEN);
3974 brcmf_update_bss_info(cfg);
3976 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3982 /* data sent to dongle has to be little endian */
3983 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3984 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3985 buf, WL_BSS_INFO_MAX);
3990 bi = (struct brcmf_bss_info_le *)(buf + 4);
3991 target_channel = bi->ctl_ch ? bi->ctl_ch :
3992 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
3994 if (target_channel <= CH_MAX_2G_CHANNEL)
3995 band = wiphy->bands[IEEE80211_BAND_2GHZ];
3997 band = wiphy->bands[IEEE80211_BAND_5GHZ];
3999 freq = ieee80211_channel_to_frequency(target_channel, band->band);
4000 notify_channel = ieee80211_get_channel(wiphy, freq);
4004 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4005 conn_info->req_ie, conn_info->req_ie_len,
4006 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4007 WL_CONN("Report roaming result\n");
4009 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4015 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4016 struct net_device *ndev, const struct brcmf_event_msg *e,
4019 struct brcmf_if *ifp = netdev_priv(ndev);
4020 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4021 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4024 WL_TRACE("Enter\n");
4026 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4027 &ifp->vif->sme_state)) {
4029 brcmf_get_assoc_ies(cfg);
4030 memcpy(profile->bssid, e->addr, ETH_ALEN);
4031 brcmf_update_bss_info(cfg);
4033 cfg80211_connect_result(ndev,
4034 (u8 *)profile->bssid,
4036 conn_info->req_ie_len,
4038 conn_info->resp_ie_len,
4039 completed ? WLAN_STATUS_SUCCESS :
4040 WLAN_STATUS_AUTH_TIMEOUT,
4043 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4044 &ifp->vif->sme_state);
4045 WL_CONN("Report connect result - connection %s\n",
4046 completed ? "succeeded" : "failed");
4053 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4054 struct net_device *ndev,
4055 const struct brcmf_event_msg *e, void *data)
4058 u32 event = e->event_code;
4059 u32 reason = e->reason;
4060 u32 len = e->datalen;
4061 static int generation;
4063 struct station_info sinfo;
4065 WL_CONN("event %d, reason %d\n", event, reason);
4066 memset(&sinfo, 0, sizeof(sinfo));
4069 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4070 reason == BRCMF_E_STATUS_SUCCESS) {
4071 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4073 WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4076 sinfo.assoc_req_ies = data;
4077 sinfo.assoc_req_ies_len = len;
4079 sinfo.generation = generation;
4080 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4081 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4082 (event == BRCMF_E_DEAUTH_IND) ||
4083 (event == BRCMF_E_DEAUTH)) {
4085 sinfo.generation = generation;
4086 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4092 brcmf_notify_connect_status(struct brcmf_if *ifp,
4093 const struct brcmf_event_msg *e, void *data)
4095 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4096 struct net_device *ndev = ifp->ndev;
4097 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4100 if (ifp->vif->mode == WL_MODE_AP) {
4101 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4102 } else if (brcmf_is_linkup(e)) {
4103 WL_CONN("Linkup\n");
4104 if (brcmf_is_ibssmode(ifp->vif)) {
4105 memcpy(profile->bssid, e->addr, ETH_ALEN);
4106 wl_inform_ibss(cfg, ndev, e->addr);
4107 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4108 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4109 &ifp->vif->sme_state);
4110 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4111 &ifp->vif->sme_state);
4113 brcmf_bss_connect_done(cfg, ndev, e, true);
4114 } else if (brcmf_is_linkdown(e)) {
4115 WL_CONN("Linkdown\n");
4116 if (!brcmf_is_ibssmode(ifp->vif)) {
4117 brcmf_bss_connect_done(cfg, ndev, e, false);
4118 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4119 &ifp->vif->sme_state))
4120 cfg80211_disconnected(ndev, 0, NULL, 0,
4123 brcmf_link_down(ifp->vif);
4124 brcmf_init_prof(ndev_to_prof(ndev));
4125 } else if (brcmf_is_nonetwork(cfg, e)) {
4126 if (brcmf_is_ibssmode(ifp->vif))
4127 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4128 &ifp->vif->sme_state);
4130 brcmf_bss_connect_done(cfg, ndev, e, false);
4137 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4138 const struct brcmf_event_msg *e, void *data)
4140 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4142 u32 event = e->event_code;
4143 u32 status = e->status;
4145 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4146 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4147 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4149 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4156 brcmf_notify_mic_status(struct brcmf_if *ifp,
4157 const struct brcmf_event_msg *e, void *data)
4159 u16 flags = e->flags;
4160 enum nl80211_key_type key_type;
4162 if (flags & BRCMF_EVENT_MSG_GROUP)
4163 key_type = NL80211_KEYTYPE_GROUP;
4165 key_type = NL80211_KEYTYPE_PAIRWISE;
4167 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4173 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4175 conf->frag_threshold = (u32)-1;
4176 conf->rts_threshold = (u32)-1;
4177 conf->retry_short = (u32)-1;
4178 conf->retry_long = (u32)-1;
4179 conf->tx_power = -1;
4182 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4184 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4185 brcmf_notify_connect_status);
4186 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4187 brcmf_notify_connect_status);
4188 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4189 brcmf_notify_connect_status);
4190 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4191 brcmf_notify_connect_status);
4192 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4193 brcmf_notify_connect_status);
4194 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4195 brcmf_notify_connect_status);
4196 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4197 brcmf_notify_roaming_status);
4198 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4199 brcmf_notify_mic_status);
4200 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4201 brcmf_notify_connect_status);
4202 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4203 brcmf_notify_sched_scan_results);
4206 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4210 kfree(cfg->escan_ioctl_buf);
4211 cfg->escan_ioctl_buf = NULL;
4212 kfree(cfg->extra_buf);
4213 cfg->extra_buf = NULL;
4214 kfree(cfg->pmk_list);
4215 cfg->pmk_list = NULL;
4218 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4220 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4222 goto init_priv_mem_out;
4223 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4224 if (!cfg->escan_ioctl_buf)
4225 goto init_priv_mem_out;
4226 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4227 if (!cfg->extra_buf)
4228 goto init_priv_mem_out;
4229 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4231 goto init_priv_mem_out;
4236 brcmf_deinit_priv_mem(cfg);
4241 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4245 cfg->scan_request = NULL;
4246 cfg->pwr_save = true;
4247 cfg->roam_on = true; /* roam on & off switch.
4248 we enable roam per default */
4249 cfg->active_scan = true; /* we do active scan for
4250 specific scan per default */
4251 cfg->dongle_up = false; /* dongle is not up yet */
4252 err = brcmf_init_priv_mem(cfg);
4255 brcmf_register_event_handlers(cfg);
4256 mutex_init(&cfg->usr_sync);
4257 brcmf_init_escan(cfg);
4258 brcmf_init_conf(cfg->conf);
4263 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4265 cfg->dongle_up = false; /* dongle down */
4266 brcmf_abort_scanning(cfg);
4267 brcmf_deinit_priv_mem(cfg);
4270 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr)
4272 struct net_device *ndev = drvr->iflist[0]->ndev;
4273 struct device *busdev = drvr->dev;
4274 struct brcmf_cfg80211_info *cfg;
4275 struct wiphy *wiphy;
4276 struct brcmf_cfg80211_vif *vif;
4277 struct brcmf_if *ifp;
4281 WL_ERR("ndev is invalid\n");
4285 ifp = netdev_priv(ndev);
4286 wiphy = brcmf_setup_wiphy(busdev);
4290 cfg = wiphy_priv(wiphy);
4293 INIT_LIST_HEAD(&cfg->vif_list);
4295 vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false);
4301 err = wl_init_priv(cfg);
4303 WL_ERR("Failed to init iwm_priv (%d)\n", err);
4304 goto cfg80211_attach_out;
4310 cfg80211_attach_out:
4311 brcmf_free_vif(vif);
4315 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4317 struct brcmf_cfg80211_vif *vif;
4318 struct brcmf_cfg80211_vif *tmp;
4320 wl_deinit_priv(cfg);
4321 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4322 brcmf_free_vif(vif);
4327 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
4329 struct brcmf_if *ifp = netdev_priv(ndev);
4331 __le32 roamtrigger[2];
4332 __le32 roam_delta[2];
4335 * Setup timeout if Beacons are lost and roam is
4336 * off to report link down
4339 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4341 WL_ERR("bcn_timeout error (%d)\n", err);
4342 goto dongle_rom_out;
4347 * Enable/Disable built-in roaming to allow supplicant
4348 * to take care of roaming
4350 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
4351 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4353 WL_ERR("roam_off error (%d)\n", err);
4354 goto dongle_rom_out;
4357 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4358 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4359 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4360 (void *)roamtrigger, sizeof(roamtrigger));
4362 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4363 goto dongle_rom_out;
4366 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4367 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4368 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4369 (void *)roam_delta, sizeof(roam_delta));
4371 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
4372 goto dongle_rom_out;
4380 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
4381 s32 scan_unassoc_time, s32 scan_passive_time)
4383 struct brcmf_if *ifp = netdev_priv(ndev);
4386 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4389 if (err == -EOPNOTSUPP)
4390 WL_INFO("Scan assoc time is not supported\n");
4392 WL_ERR("Scan assoc time error (%d)\n", err);
4393 goto dongle_scantime_out;
4395 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4398 if (err == -EOPNOTSUPP)
4399 WL_INFO("Scan unassoc time is not supported\n");
4401 WL_ERR("Scan unassoc time error (%d)\n", err);
4402 goto dongle_scantime_out;
4405 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4408 if (err == -EOPNOTSUPP)
4409 WL_INFO("Scan passive time is not supported\n");
4411 WL_ERR("Scan passive time error (%d)\n", err);
4412 goto dongle_scantime_out;
4415 dongle_scantime_out:
4419 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4421 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4422 struct wiphy *wiphy;
4427 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4428 &phy_list, sizeof(phy_list));
4430 WL_ERR("error (%d)\n", err);
4434 phy = ((char *)&phy_list)[0];
4435 WL_INFO("%c phy\n", phy);
4436 if (phy == 'n' || phy == 'a') {
4437 wiphy = cfg_to_wiphy(cfg);
4438 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4444 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4446 return wl_update_wiphybands(cfg);
4449 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4451 struct net_device *ndev;
4452 struct wireless_dev *wdev;
4459 ndev = cfg_to_ndev(cfg);
4460 wdev = ndev->ieee80211_ptr;
4462 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4463 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4465 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4466 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
4469 goto default_conf_out;
4470 WL_INFO("power save set to %s\n",
4471 (power_mode ? "enabled" : "disabled"));
4473 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
4476 goto default_conf_out;
4477 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4479 if (err && err != -EINPROGRESS)
4480 goto default_conf_out;
4481 err = brcmf_dongle_probecap(cfg);
4483 goto default_conf_out;
4485 /* -EINPROGRESS: Call commit handler */
4489 cfg->dongle_up = true;
4495 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
4497 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4501 return brcmf_config_dongle(ifp->drvr->config);
4504 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
4506 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4509 * While going down, if associated with AP disassociate
4510 * from AP to save power
4512 if (check_vif_up(ifp->vif)) {
4513 brcmf_link_down(ifp->vif);
4515 /* Make sure WPA_Supplicant receives all the event
4516 generated due to DISASSOC call to the fw to keep
4517 the state fw and WPA_Supplicant state consistent
4522 brcmf_abort_scanning(cfg);
4523 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4528 s32 brcmf_cfg80211_up(struct net_device *ndev)
4530 struct brcmf_if *ifp = netdev_priv(ndev);
4531 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4534 mutex_lock(&cfg->usr_sync);
4535 err = __brcmf_cfg80211_up(ifp);
4536 mutex_unlock(&cfg->usr_sync);
4541 s32 brcmf_cfg80211_down(struct net_device *ndev)
4543 struct brcmf_if *ifp = netdev_priv(ndev);
4544 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4547 mutex_lock(&cfg->usr_sync);
4548 err = __brcmf_cfg80211_down(ifp);
4549 mutex_unlock(&cfg->usr_sync);