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_info *cfg = wiphy_to_cfg(wiphy);
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 cfg->conf->mode = WL_MODE_IBSS;
467 case NL80211_IFTYPE_STATION:
468 cfg->conf->mode = WL_MODE_BSS;
471 case NL80211_IFTYPE_AP:
472 cfg->conf->mode = WL_MODE_AP;
481 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
482 WL_INFO("IF Type = AP\n");
484 err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
485 BRCMF_C_SET_INFRA, infra);
487 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
491 WL_INFO("IF Type = %s\n",
492 (cfg->conf->mode == WL_MODE_IBSS) ?
495 ndev->ieee80211_ptr->iftype = type;
503 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
505 struct brcmf_if *ifp = netdev_priv(ndev);
508 if (check_vif_up(ifp->vif)) {
509 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
511 WL_ERR("fail to set mpc\n");
514 WL_INFO("MPC : %d\n", mpc);
518 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
519 struct cfg80211_scan_request *request)
527 struct brcmf_ssid_le ssid_le;
529 memset(params_le->bssid, 0xFF, ETH_ALEN);
530 params_le->bss_type = DOT11_BSSTYPE_ANY;
531 params_le->scan_type = 0;
532 params_le->channel_num = 0;
533 params_le->nprobes = cpu_to_le32(-1);
534 params_le->active_time = cpu_to_le32(-1);
535 params_le->passive_time = cpu_to_le32(-1);
536 params_le->home_time = cpu_to_le32(-1);
537 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
539 /* if request is null exit so it will be all channel broadcast scan */
543 n_ssids = request->n_ssids;
544 n_channels = request->n_channels;
545 /* Copy channel array if applicable */
546 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
547 if (n_channels > 0) {
548 for (i = 0; i < n_channels; i++) {
549 chanspec = channel_to_chanspec(request->channels[i]);
550 WL_SCAN("Chan : %d, Channel spec: %x\n",
551 request->channels[i]->hw_value, chanspec);
552 params_le->channel_list[i] = cpu_to_le16(chanspec);
555 WL_SCAN("Scanning all channels\n");
557 /* Copy ssid array if applicable */
558 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
560 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
561 n_channels * sizeof(u16);
562 offset = roundup(offset, sizeof(u32));
563 ptr = (char *)params_le + offset;
564 for (i = 0; i < n_ssids; i++) {
565 memset(&ssid_le, 0, sizeof(ssid_le));
567 cpu_to_le32(request->ssids[i].ssid_len);
568 memcpy(ssid_le.SSID, request->ssids[i].ssid,
569 request->ssids[i].ssid_len);
570 if (!ssid_le.SSID_len)
571 WL_SCAN("%d: Broadcast scan\n", i);
573 WL_SCAN("%d: scan for %s size =%d\n", i,
574 ssid_le.SSID, ssid_le.SSID_len);
575 memcpy(ptr, &ssid_le, sizeof(ssid_le));
576 ptr += sizeof(ssid_le);
579 WL_SCAN("Broadcast scan %p\n", request->ssids);
580 if ((request->ssids) && request->ssids->ssid_len) {
581 WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
582 request->ssids->ssid_len);
583 params_le->ssid_le.SSID_len =
584 cpu_to_le32(request->ssids->ssid_len);
585 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
586 request->ssids->ssid_len);
589 /* Adding mask to channel numbers */
590 params_le->channel_num =
591 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
592 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
596 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
597 struct net_device *ndev,
598 bool aborted, bool fw_abort)
600 struct brcmf_scan_params_le params_le;
601 struct cfg80211_scan_request *scan_request;
606 /* clear scan request, because the FW abort can cause a second call */
607 /* to this functon and might cause a double cfg80211_scan_done */
608 scan_request = cfg->scan_request;
609 cfg->scan_request = NULL;
611 if (timer_pending(&cfg->escan_timeout))
612 del_timer_sync(&cfg->escan_timeout);
615 /* Do a scan abort to stop the driver's scan engine */
616 WL_SCAN("ABORT scan in firmware\n");
617 memset(¶ms_le, 0, sizeof(params_le));
618 memset(params_le.bssid, 0xFF, ETH_ALEN);
619 params_le.bss_type = DOT11_BSSTYPE_ANY;
620 params_le.scan_type = 0;
621 params_le.channel_num = cpu_to_le32(1);
622 params_le.nprobes = cpu_to_le32(1);
623 params_le.active_time = cpu_to_le32(-1);
624 params_le.passive_time = cpu_to_le32(-1);
625 params_le.home_time = cpu_to_le32(-1);
626 /* Scan is aborted by setting channel_list[0] to -1 */
627 params_le.channel_list[0] = cpu_to_le16(-1);
628 /* E-Scan (or anyother type) can be aborted by SCAN */
629 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
630 ¶ms_le, sizeof(params_le));
632 WL_ERR("Scan abort failed\n");
635 * e-scan can be initiated by scheduled scan
636 * which takes precedence.
638 if (cfg->sched_escan) {
639 WL_SCAN("scheduled scan completed\n");
640 cfg->sched_escan = false;
642 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
643 brcmf_set_mpc(ndev, 1);
644 } else if (scan_request) {
645 WL_SCAN("ESCAN Completed scan: %s\n",
646 aborted ? "Aborted" : "Done");
647 cfg80211_scan_done(scan_request, aborted);
648 brcmf_set_mpc(ndev, 1);
650 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
651 WL_ERR("Scan complete while device not scanning\n");
659 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
660 struct cfg80211_scan_request *request, u16 action)
662 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
663 offsetof(struct brcmf_escan_params_le, params_le);
664 struct brcmf_escan_params_le *params;
667 WL_SCAN("E-SCAN START\n");
669 if (request != NULL) {
670 /* Allocate space for populating ssids in struct */
671 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
673 /* Allocate space for populating ssids in struct */
674 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
677 params = kzalloc(params_size, GFP_KERNEL);
682 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
683 brcmf_escan_prep(¶ms->params_le, request);
684 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
685 params->action = cpu_to_le16(action);
686 params->sync_id = cpu_to_le16(0x1234);
688 err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan",
689 params, params_size);
692 WL_INFO("system busy : escan canceled\n");
694 WL_ERR("error (%d)\n", err);
703 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
704 struct net_device *ndev, struct cfg80211_scan_request *request)
708 struct brcmf_scan_results *results;
711 cfg->escan_info.ndev = ndev;
712 cfg->escan_info.wiphy = wiphy;
713 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
714 passive_scan = cfg->active_scan ? 0 : 1;
715 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
718 WL_ERR("error (%d)\n", err);
721 brcmf_set_mpc(ndev, 0);
722 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
723 results->version = 0;
725 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
727 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
729 brcmf_set_mpc(ndev, 1);
734 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
735 struct cfg80211_scan_request *request,
736 struct cfg80211_ssid *this_ssid)
738 struct brcmf_if *ifp = netdev_priv(ndev);
739 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
740 struct cfg80211_ssid *ssids;
741 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
748 WL_SCAN("START ESCAN\n");
750 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
751 WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
754 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
755 WL_ERR("Scanning being aborted: status (%lu)\n",
759 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
760 WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state);
764 /* Arm scan timeout timer */
765 mod_timer(&cfg->escan_timeout, jiffies +
766 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
771 ssids = request->ssids;
775 /* we don't do escan in ibss */
779 cfg->scan_request = request;
780 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
782 err = brcmf_do_escan(cfg, wiphy, ndev, request);
786 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
787 ssids->ssid, ssids->ssid_len);
788 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
789 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
790 sr->ssid_le.SSID_len = cpu_to_le32(0);
793 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
794 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
797 WL_SCAN("Broadcast scan\n");
799 passive_scan = cfg->active_scan ? 0 : 1;
800 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
803 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
806 brcmf_set_mpc(ndev, 0);
807 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
808 &sr->ssid_le, sizeof(sr->ssid_le));
811 WL_INFO("BUSY: scan for \"%s\" canceled\n",
814 WL_ERR("WLC_SCAN error (%d)\n", err);
816 brcmf_set_mpc(ndev, 1);
824 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
825 if (timer_pending(&cfg->escan_timeout))
826 del_timer_sync(&cfg->escan_timeout);
827 cfg->scan_request = NULL;
832 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
834 struct net_device *ndev = request->wdev->netdev;
839 if (!check_vif_up(container_of(request->wdev,
840 struct brcmf_cfg80211_vif, wdev)))
843 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
846 WL_ERR("scan error (%d)\n", err);
852 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
856 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
859 WL_ERR("Error (%d)\n", err);
864 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
868 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
871 WL_ERR("Error (%d)\n", err);
876 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
879 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
881 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
883 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
889 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
891 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
892 struct net_device *ndev = cfg_to_ndev(cfg);
893 struct brcmf_if *ifp = netdev_priv(ndev);
897 if (!check_vif_up(ifp->vif))
900 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
901 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
902 cfg->conf->rts_threshold = wiphy->rts_threshold;
903 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
907 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
908 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
909 cfg->conf->frag_threshold = wiphy->frag_threshold;
910 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
914 if (changed & WIPHY_PARAM_RETRY_LONG
915 && (cfg->conf->retry_long != wiphy->retry_long)) {
916 cfg->conf->retry_long = wiphy->retry_long;
917 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
921 if (changed & WIPHY_PARAM_RETRY_SHORT
922 && (cfg->conf->retry_short != wiphy->retry_short)) {
923 cfg->conf->retry_short = wiphy->retry_short;
924 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
934 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
936 memset(prof, 0, sizeof(*prof));
939 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
940 size_t *join_params_size)
945 if (ch <= CH_MAX_2G_CHANNEL)
946 chanspec |= WL_CHANSPEC_BAND_2G;
948 chanspec |= WL_CHANSPEC_BAND_5G;
950 chanspec |= WL_CHANSPEC_BW_20;
951 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
953 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
956 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
957 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
958 join_params->params_le.chanspec_num = cpu_to_le32(1);
960 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
961 "channel %d, chanspec %#X\n",
962 chanspec, ch, chanspec);
966 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
972 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
973 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
974 err = brcmf_fil_cmd_data_set(vif->ifp,
975 BRCMF_C_DISASSOC, NULL, 0);
977 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
978 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
980 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
985 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
986 struct cfg80211_ibss_params *params)
988 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
989 struct brcmf_if *ifp = netdev_priv(ndev);
990 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
991 struct brcmf_join_params join_params;
992 size_t join_params_size = 0;
998 if (!check_vif_up(ifp->vif))
1002 WL_CONN("SSID: %s\n", params->ssid);
1004 WL_CONN("SSID: NULL, Not supported\n");
1008 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1011 WL_CONN("BSSID: %pM\n", params->bssid);
1013 WL_CONN("No BSSID specified\n");
1015 if (params->chandef.chan)
1016 WL_CONN("channel: %d\n", params->chandef.chan->center_freq);
1018 WL_CONN("no channel specified\n");
1020 if (params->channel_fixed)
1021 WL_CONN("fixed channel required\n");
1023 WL_CONN("no fixed channel required\n");
1025 if (params->ie && params->ie_len)
1026 WL_CONN("ie len: %d\n", params->ie_len);
1028 WL_CONN("no ie specified\n");
1030 if (params->beacon_interval)
1031 WL_CONN("beacon interval: %d\n", params->beacon_interval);
1033 WL_CONN("no beacon interval specified\n");
1035 if (params->basic_rates)
1036 WL_CONN("basic rates: %08X\n", params->basic_rates);
1038 WL_CONN("no basic rates specified\n");
1040 if (params->privacy)
1041 WL_CONN("privacy required\n");
1043 WL_CONN("no privacy required\n");
1045 /* Configure Privacy for starter */
1046 if (params->privacy)
1047 wsec |= WEP_ENABLED;
1049 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1051 WL_ERR("wsec failed (%d)\n", err);
1055 /* Configure Beacon Interval for starter */
1056 if (params->beacon_interval)
1057 bcnprd = params->beacon_interval;
1061 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1063 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1067 /* Configure required join parameter */
1068 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1071 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1072 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1073 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1074 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1075 join_params_size = sizeof(join_params.ssid_le);
1078 if (params->bssid) {
1079 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1080 join_params_size = sizeof(join_params.ssid_le) +
1081 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1082 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1084 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1085 memset(profile->bssid, 0, ETH_ALEN);
1089 if (params->chandef.chan) {
1093 ieee80211_frequency_to_channel(
1094 params->chandef.chan->center_freq);
1095 if (params->channel_fixed) {
1096 /* adding chanspec */
1097 brcmf_ch_to_chanspec(cfg->channel,
1098 &join_params, &join_params_size);
1101 /* set channel for starter */
1102 target_channel = cfg->channel;
1103 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1106 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1112 cfg->ibss_starter = false;
1115 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1116 &join_params, join_params_size);
1118 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1124 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1130 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1132 struct brcmf_if *ifp = netdev_priv(ndev);
1135 WL_TRACE("Enter\n");
1136 if (!check_vif_up(ifp->vif))
1139 brcmf_link_down(ifp->vif);
1146 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1147 struct cfg80211_connect_params *sme)
1149 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1150 struct brcmf_cfg80211_security *sec;
1154 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1155 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1156 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1157 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1159 val = WPA_AUTH_DISABLED;
1160 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1161 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val);
1163 WL_ERR("set wpa_auth failed (%d)\n", err);
1166 sec = &profile->sec;
1167 sec->wpa_versions = sme->crypto.wpa_versions;
1171 static s32 brcmf_set_auth_type(struct net_device *ndev,
1172 struct cfg80211_connect_params *sme)
1174 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1175 struct brcmf_cfg80211_security *sec;
1179 switch (sme->auth_type) {
1180 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1182 WL_CONN("open system\n");
1184 case NL80211_AUTHTYPE_SHARED_KEY:
1186 WL_CONN("shared key\n");
1188 case NL80211_AUTHTYPE_AUTOMATIC:
1190 WL_CONN("automatic\n");
1192 case NL80211_AUTHTYPE_NETWORK_EAP:
1193 WL_CONN("network eap\n");
1196 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1200 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val);
1202 WL_ERR("set auth failed (%d)\n", err);
1205 sec = &profile->sec;
1206 sec->auth_type = sme->auth_type;
1211 brcmf_set_set_cipher(struct net_device *ndev,
1212 struct cfg80211_connect_params *sme)
1214 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1215 struct brcmf_cfg80211_security *sec;
1220 if (sme->crypto.n_ciphers_pairwise) {
1221 switch (sme->crypto.ciphers_pairwise[0]) {
1222 case WLAN_CIPHER_SUITE_WEP40:
1223 case WLAN_CIPHER_SUITE_WEP104:
1226 case WLAN_CIPHER_SUITE_TKIP:
1227 pval = TKIP_ENABLED;
1229 case WLAN_CIPHER_SUITE_CCMP:
1232 case WLAN_CIPHER_SUITE_AES_CMAC:
1236 WL_ERR("invalid cipher pairwise (%d)\n",
1237 sme->crypto.ciphers_pairwise[0]);
1241 if (sme->crypto.cipher_group) {
1242 switch (sme->crypto.cipher_group) {
1243 case WLAN_CIPHER_SUITE_WEP40:
1244 case WLAN_CIPHER_SUITE_WEP104:
1247 case WLAN_CIPHER_SUITE_TKIP:
1248 gval = TKIP_ENABLED;
1250 case WLAN_CIPHER_SUITE_CCMP:
1253 case WLAN_CIPHER_SUITE_AES_CMAC:
1257 WL_ERR("invalid cipher group (%d)\n",
1258 sme->crypto.cipher_group);
1263 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1264 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval);
1266 WL_ERR("error (%d)\n", err);
1270 sec = &profile->sec;
1271 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1272 sec->cipher_group = sme->crypto.cipher_group;
1278 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1280 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1281 struct brcmf_cfg80211_security *sec;
1285 if (sme->crypto.n_akm_suites) {
1286 err = brcmf_fil_iovar_int_get(netdev_priv(ndev),
1289 WL_ERR("could not get wpa_auth (%d)\n", err);
1292 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1293 switch (sme->crypto.akm_suites[0]) {
1294 case WLAN_AKM_SUITE_8021X:
1295 val = WPA_AUTH_UNSPECIFIED;
1297 case WLAN_AKM_SUITE_PSK:
1301 WL_ERR("invalid cipher group (%d)\n",
1302 sme->crypto.cipher_group);
1305 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1306 switch (sme->crypto.akm_suites[0]) {
1307 case WLAN_AKM_SUITE_8021X:
1308 val = WPA2_AUTH_UNSPECIFIED;
1310 case WLAN_AKM_SUITE_PSK:
1311 val = WPA2_AUTH_PSK;
1314 WL_ERR("invalid cipher group (%d)\n",
1315 sme->crypto.cipher_group);
1320 WL_CONN("setting wpa_auth to %d\n", val);
1321 err = brcmf_fil_iovar_int_set(netdev_priv(ndev),
1324 WL_ERR("could not set wpa_auth (%d)\n", err);
1328 sec = &profile->sec;
1329 sec->wpa_auth = sme->crypto.akm_suites[0];
1335 brcmf_set_sharedkey(struct net_device *ndev,
1336 struct cfg80211_connect_params *sme)
1338 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1339 struct brcmf_cfg80211_security *sec;
1340 struct brcmf_wsec_key key;
1344 WL_CONN("key len (%d)\n", sme->key_len);
1346 if (sme->key_len == 0)
1349 sec = &profile->sec;
1350 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1351 sec->wpa_versions, sec->cipher_pairwise);
1353 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1356 if (!(sec->cipher_pairwise &
1357 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1360 memset(&key, 0, sizeof(key));
1361 key.len = (u32) sme->key_len;
1362 key.index = (u32) sme->key_idx;
1363 if (key.len > sizeof(key.data)) {
1364 WL_ERR("Too long key length (%u)\n", key.len);
1367 memcpy(key.data, sme->key, key.len);
1368 key.flags = BRCMF_PRIMARY_KEY;
1369 switch (sec->cipher_pairwise) {
1370 case WLAN_CIPHER_SUITE_WEP40:
1371 key.algo = CRYPTO_ALGO_WEP1;
1373 case WLAN_CIPHER_SUITE_WEP104:
1374 key.algo = CRYPTO_ALGO_WEP128;
1377 WL_ERR("Invalid algorithm (%d)\n",
1378 sme->crypto.ciphers_pairwise[0]);
1381 /* Set the new key/index */
1382 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1383 key.len, key.index, key.algo);
1384 WL_CONN("key \"%s\"\n", key.data);
1385 err = send_key_to_dongle(ndev, &key);
1389 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1390 WL_CONN("set auth_type to shared key\n");
1391 val = WL_AUTH_SHARED_KEY; /* shared key */
1392 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1394 WL_ERR("set auth failed (%d)\n", err);
1400 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1401 struct cfg80211_connect_params *sme)
1403 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1404 struct brcmf_if *ifp = netdev_priv(ndev);
1405 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1406 struct ieee80211_channel *chan = sme->channel;
1407 struct brcmf_join_params join_params;
1408 size_t join_params_size;
1409 struct brcmf_ssid ssid;
1413 WL_TRACE("Enter\n");
1414 if (!check_vif_up(ifp->vif))
1418 WL_ERR("Invalid ssid\n");
1422 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1426 ieee80211_frequency_to_channel(chan->center_freq);
1427 WL_CONN("channel (%d), center_req (%d)\n",
1428 cfg->channel, chan->center_freq);
1432 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1434 err = brcmf_set_wpa_version(ndev, sme);
1436 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1440 err = brcmf_set_auth_type(ndev, sme);
1442 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1446 err = brcmf_set_set_cipher(ndev, sme);
1448 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1452 err = brcmf_set_key_mgmt(ndev, sme);
1454 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1458 err = brcmf_set_sharedkey(ndev, sme);
1460 WL_ERR("brcmf_set_sharedkey failed (%d)\n", err);
1464 memset(&join_params, 0, sizeof(join_params));
1465 join_params_size = sizeof(join_params.ssid_le);
1467 profile->ssid.SSID_len = min_t(u32,
1468 sizeof(ssid.SSID), (u32)sme->ssid_len);
1469 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1470 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1471 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1473 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1475 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1476 WL_CONN("ssid \"%s\", len (%d)\n",
1477 ssid.SSID, ssid.SSID_len);
1479 brcmf_ch_to_chanspec(cfg->channel,
1480 &join_params, &join_params_size);
1481 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1482 &join_params, join_params_size);
1484 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1488 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1494 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1497 struct brcmf_if *ifp = netdev_priv(ndev);
1498 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1499 struct brcmf_scb_val_le scbval;
1502 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1503 if (!check_vif_up(ifp->vif))
1506 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1508 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1509 scbval.val = cpu_to_le32(reason_code);
1510 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1511 &scbval, sizeof(scbval));
1513 WL_ERR("error (%d)\n", err);
1520 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1521 enum nl80211_tx_power_setting type, s32 mbm)
1524 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1525 struct net_device *ndev = cfg_to_ndev(cfg);
1526 struct brcmf_if *ifp = netdev_priv(ndev);
1530 s32 dbm = MBM_TO_DBM(mbm);
1532 WL_TRACE("Enter\n");
1533 if (!check_vif_up(ifp->vif))
1537 case NL80211_TX_POWER_AUTOMATIC:
1539 case NL80211_TX_POWER_LIMITED:
1540 case NL80211_TX_POWER_FIXED:
1542 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1548 /* Make sure radio is off or on as far as software is concerned */
1549 disable = WL_RADIO_SW_DISABLE << 16;
1550 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1552 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1557 txpwrmw = (u16) dbm;
1558 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1559 (s32)brcmf_mw_to_qdbm(txpwrmw));
1561 WL_ERR("qtxpower error (%d)\n", err);
1562 cfg->conf->tx_power = dbm;
1569 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1570 struct wireless_dev *wdev,
1573 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1574 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1579 WL_TRACE("Enter\n");
1580 if (!check_vif_up(ifp->vif))
1583 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1585 WL_ERR("error (%d)\n", err);
1589 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1590 *dbm = (s32) brcmf_qdbm_to_mw(result);
1598 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1599 u8 key_idx, bool unicast, bool multicast)
1601 struct brcmf_if *ifp = netdev_priv(ndev);
1606 WL_TRACE("Enter\n");
1607 WL_CONN("key index (%d)\n", key_idx);
1608 if (!check_vif_up(ifp->vif))
1611 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1613 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1617 if (wsec & WEP_ENABLED) {
1618 /* Just select a new current key */
1620 err = brcmf_fil_cmd_int_set(ifp,
1621 BRCMF_C_SET_KEY_PRIMARY, index);
1623 WL_ERR("error (%d)\n", err);
1631 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1632 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1634 struct brcmf_wsec_key key;
1637 memset(&key, 0, sizeof(key));
1638 key.index = (u32) key_idx;
1639 /* Instead of bcast for ea address for default wep keys,
1640 driver needs it to be Null */
1641 if (!is_multicast_ether_addr(mac_addr))
1642 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1643 key.len = (u32) params->key_len;
1644 /* check for key index change */
1647 err = send_key_to_dongle(ndev, &key);
1649 WL_ERR("key delete error (%d)\n", err);
1651 if (key.len > sizeof(key.data)) {
1652 WL_ERR("Invalid key length (%d)\n", key.len);
1656 WL_CONN("Setting the key index %d\n", key.index);
1657 memcpy(key.data, params->key, key.len);
1659 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1661 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1662 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1663 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1666 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1667 if (params->seq && params->seq_len == 6) {
1670 ivptr = (u8 *) params->seq;
1671 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1672 (ivptr[3] << 8) | ivptr[2];
1673 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1674 key.iv_initialized = true;
1677 switch (params->cipher) {
1678 case WLAN_CIPHER_SUITE_WEP40:
1679 key.algo = CRYPTO_ALGO_WEP1;
1680 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1682 case WLAN_CIPHER_SUITE_WEP104:
1683 key.algo = CRYPTO_ALGO_WEP128;
1684 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1686 case WLAN_CIPHER_SUITE_TKIP:
1687 key.algo = CRYPTO_ALGO_TKIP;
1688 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1690 case WLAN_CIPHER_SUITE_AES_CMAC:
1691 key.algo = CRYPTO_ALGO_AES_CCM;
1692 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1694 case WLAN_CIPHER_SUITE_CCMP:
1695 key.algo = CRYPTO_ALGO_AES_CCM;
1696 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1699 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1702 err = send_key_to_dongle(ndev, &key);
1704 WL_ERR("wsec_key error (%d)\n", err);
1710 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1711 u8 key_idx, bool pairwise, const u8 *mac_addr,
1712 struct key_params *params)
1714 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1715 struct brcmf_if *ifp = netdev_priv(ndev);
1716 struct brcmf_wsec_key key;
1722 WL_TRACE("Enter\n");
1723 WL_CONN("key index (%d)\n", key_idx);
1724 if (!check_vif_up(ifp->vif))
1729 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1731 memset(&key, 0, sizeof(key));
1733 key.len = (u32) params->key_len;
1734 key.index = (u32) key_idx;
1736 if (key.len > sizeof(key.data)) {
1737 WL_ERR("Too long key length (%u)\n", key.len);
1741 memcpy(key.data, params->key, key.len);
1743 key.flags = BRCMF_PRIMARY_KEY;
1744 switch (params->cipher) {
1745 case WLAN_CIPHER_SUITE_WEP40:
1746 key.algo = CRYPTO_ALGO_WEP1;
1748 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1750 case WLAN_CIPHER_SUITE_WEP104:
1751 key.algo = CRYPTO_ALGO_WEP128;
1753 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1755 case WLAN_CIPHER_SUITE_TKIP:
1756 if (cfg->conf->mode != WL_MODE_AP) {
1757 WL_CONN("Swapping key\n");
1758 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1759 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1760 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1762 key.algo = CRYPTO_ALGO_TKIP;
1764 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1766 case WLAN_CIPHER_SUITE_AES_CMAC:
1767 key.algo = CRYPTO_ALGO_AES_CCM;
1769 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1771 case WLAN_CIPHER_SUITE_CCMP:
1772 key.algo = CRYPTO_ALGO_AES_CCM;
1774 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1777 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1782 err = send_key_to_dongle(ndev, &key);
1786 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1788 WL_ERR("get wsec error (%d)\n", err);
1792 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1794 WL_ERR("set wsec error (%d)\n", err);
1804 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1805 u8 key_idx, bool pairwise, const u8 *mac_addr)
1807 struct brcmf_if *ifp = netdev_priv(ndev);
1808 struct brcmf_wsec_key key;
1811 WL_TRACE("Enter\n");
1812 if (!check_vif_up(ifp->vif))
1815 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
1816 /* we ignore this key index in this case */
1817 WL_ERR("invalid key index (%d)\n", key_idx);
1821 memset(&key, 0, sizeof(key));
1823 key.index = (u32) key_idx;
1824 key.flags = BRCMF_PRIMARY_KEY;
1825 key.algo = CRYPTO_ALGO_OFF;
1827 WL_CONN("key index (%d)\n", key_idx);
1829 /* Set the new key/index */
1830 err = send_key_to_dongle(ndev, &key);
1837 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1838 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1839 void (*callback) (void *cookie, struct key_params * params))
1841 struct key_params params;
1842 struct brcmf_if *ifp = netdev_priv(ndev);
1843 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1844 struct brcmf_cfg80211_security *sec;
1848 WL_TRACE("Enter\n");
1849 WL_CONN("key index (%d)\n", key_idx);
1850 if (!check_vif_up(ifp->vif))
1853 memset(¶ms, 0, sizeof(params));
1855 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1857 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1858 /* Ignore this error, may happen during DISASSOC */
1862 switch (wsec & ~SES_OW_ENABLED) {
1864 sec = &profile->sec;
1865 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1866 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1867 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1868 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1869 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1870 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1874 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1875 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1878 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1879 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1882 WL_ERR("Invalid algo (0x%x)\n", wsec);
1886 callback(cookie, ¶ms);
1894 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1895 struct net_device *ndev, u8 key_idx)
1897 WL_INFO("Not supported\n");
1903 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1904 u8 *mac, struct station_info *sinfo)
1906 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1907 struct brcmf_if *ifp = netdev_priv(ndev);
1908 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1909 struct brcmf_scb_val_le scb_val;
1913 u8 *bssid = profile->bssid;
1914 struct brcmf_sta_info_le sta_info_le;
1916 WL_TRACE("Enter, MAC %pM\n", mac);
1917 if (!check_vif_up(ifp->vif))
1920 if (cfg->conf->mode == WL_MODE_AP) {
1921 memcpy(&sta_info_le, mac, ETH_ALEN);
1922 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
1924 sizeof(sta_info_le));
1926 WL_ERR("GET STA INFO failed, %d\n", err);
1929 sinfo->filled = STATION_INFO_INACTIVE_TIME;
1930 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
1931 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
1932 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
1933 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
1935 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
1936 sinfo->inactive_time, sinfo->connected_time);
1937 } else if (cfg->conf->mode == WL_MODE_BSS) {
1938 if (memcmp(mac, bssid, ETH_ALEN)) {
1939 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1944 /* Report the current tx rate */
1945 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
1947 WL_ERR("Could not get rate (%d)\n", err);
1950 sinfo->filled |= STATION_INFO_TX_BITRATE;
1951 sinfo->txrate.legacy = rate * 5;
1952 WL_CONN("Rate %d Mbps\n", rate / 2);
1955 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
1956 &ifp->vif->sme_state)) {
1957 memset(&scb_val, 0, sizeof(scb_val));
1958 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
1959 &scb_val, sizeof(scb_val));
1961 WL_ERR("Could not get rssi (%d)\n", err);
1964 rssi = le32_to_cpu(scb_val.val);
1965 sinfo->filled |= STATION_INFO_SIGNAL;
1966 sinfo->signal = rssi;
1967 WL_CONN("RSSI %d dBm\n", rssi);
1978 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1979 bool enabled, s32 timeout)
1983 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1984 struct brcmf_if *ifp = netdev_priv(ndev);
1986 WL_TRACE("Enter\n");
1989 * Powersave enable/disable request is coming from the
1990 * cfg80211 even before the interface is up. In that
1991 * scenario, driver will be storing the power save
1992 * preference in cfg struct to apply this to
1993 * FW later while initializing the dongle
1995 cfg->pwr_save = enabled;
1996 if (!check_vif_up(ifp->vif)) {
1998 WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
2002 pm = enabled ? PM_FAST : PM_OFF;
2003 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
2005 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2008 WL_ERR("net_device is not ready yet\n");
2010 WL_ERR("error (%d)\n", err);
2018 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2020 const struct cfg80211_bitrate_mask *mask)
2022 struct brcmf_if *ifp = netdev_priv(ndev);
2023 struct brcm_rateset_le rateset_le;
2031 WL_TRACE("Enter\n");
2032 if (!check_vif_up(ifp->vif))
2035 /* addr param is always NULL. ignore it */
2036 /* Get current rateset */
2037 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET,
2038 &rateset_le, sizeof(rateset_le));
2040 WL_ERR("could not get current rateset (%d)\n", err);
2044 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2046 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2049 val = wl_g_rates[legacy - 1].bitrate * 100000;
2051 if (val < le32_to_cpu(rateset_le.count))
2052 /* Select rate by rateset index */
2053 rate = rateset_le.rates[val] & 0x7f;
2055 /* Specified rate in bps */
2056 rate = val / 500000;
2058 WL_CONN("rate %d mbps\n", rate / 2);
2062 * Set rate override,
2063 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2065 err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate);
2066 err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate);
2067 if (err_bg && err_a) {
2068 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2069 err = err_bg | err_a;
2077 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2078 struct brcmf_bss_info_le *bi)
2080 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2081 struct ieee80211_channel *notify_channel;
2082 struct cfg80211_bss *bss;
2083 struct ieee80211_supported_band *band;
2087 u16 notify_capability;
2088 u16 notify_interval;
2090 size_t notify_ielen;
2093 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2094 WL_ERR("Bss info is larger than buffer. Discarding\n");
2098 channel = bi->ctl_ch ? bi->ctl_ch :
2099 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2101 if (channel <= CH_MAX_2G_CHANNEL)
2102 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2104 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2106 freq = ieee80211_channel_to_frequency(channel, band->band);
2107 notify_channel = ieee80211_get_channel(wiphy, freq);
2109 notify_capability = le16_to_cpu(bi->capability);
2110 notify_interval = le16_to_cpu(bi->beacon_period);
2111 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2112 notify_ielen = le32_to_cpu(bi->ie_length);
2113 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2115 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2116 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2117 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2118 WL_CONN("Channel: %d(%d)\n", channel, freq);
2119 WL_CONN("Capability: %X\n", notify_capability);
2120 WL_CONN("Beacon interval: %d\n", notify_interval);
2121 WL_CONN("Signal: %d\n", notify_signal);
2123 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2124 0, notify_capability, notify_interval, notify_ie,
2125 notify_ielen, notify_signal, GFP_KERNEL);
2130 cfg80211_put_bss(bss);
2135 static struct brcmf_bss_info_le *
2136 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2139 return list->bss_info_le;
2140 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2141 le32_to_cpu(bss->length));
2144 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2146 struct brcmf_scan_results *bss_list;
2147 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2151 bss_list = cfg->bss_list;
2152 if (bss_list->count != 0 &&
2153 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2154 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2158 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2159 for (i = 0; i < bss_list->count; i++) {
2160 bi = next_bss_le(bss_list, bi);
2161 err = brcmf_inform_single_bss(cfg, bi);
2168 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2169 struct net_device *ndev, const u8 *bssid)
2171 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2172 struct ieee80211_channel *notify_channel;
2173 struct brcmf_bss_info_le *bi = NULL;
2174 struct ieee80211_supported_band *band;
2175 struct cfg80211_bss *bss;
2180 u16 notify_capability;
2181 u16 notify_interval;
2183 size_t notify_ielen;
2186 WL_TRACE("Enter\n");
2188 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2194 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2196 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2197 buf, WL_BSS_INFO_MAX);
2199 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2203 bi = (struct brcmf_bss_info_le *)(buf + 4);
2205 channel = bi->ctl_ch ? bi->ctl_ch :
2206 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2208 if (channel <= CH_MAX_2G_CHANNEL)
2209 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2211 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2213 freq = ieee80211_channel_to_frequency(channel, band->band);
2214 notify_channel = ieee80211_get_channel(wiphy, freq);
2216 notify_capability = le16_to_cpu(bi->capability);
2217 notify_interval = le16_to_cpu(bi->beacon_period);
2218 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2219 notify_ielen = le32_to_cpu(bi->ie_length);
2220 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2222 WL_CONN("channel: %d(%d)\n", channel, freq);
2223 WL_CONN("capability: %X\n", notify_capability);
2224 WL_CONN("beacon interval: %d\n", notify_interval);
2225 WL_CONN("signal: %d\n", notify_signal);
2227 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2228 0, notify_capability, notify_interval,
2229 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2236 cfg80211_put_bss(bss);
2247 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg)
2249 return cfg->conf->mode == WL_MODE_IBSS;
2253 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2254 * triples, returning a pointer to the substring whose first element
2257 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2259 struct brcmf_tlv *elt;
2262 elt = (struct brcmf_tlv *) buf;
2265 /* find tagged parameter */
2266 while (totlen >= TLV_HDR_LEN) {
2269 /* validate remaining totlen */
2270 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2273 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2274 totlen -= (len + TLV_HDR_LEN);
2280 /* Is any of the tlvs the expected entry? If
2281 * not update the tlvs buffer pointer/length.
2284 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2285 u8 *oui, u32 oui_len, u8 type)
2287 /* If the contents match the OUI and the type */
2288 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2289 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2290 type == ie[TLV_BODY_OFF + oui_len]) {
2296 /* point to the next ie */
2297 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2298 /* calculate the length of the rest of the buffer */
2299 *tlvs_len -= (int)(ie - *tlvs);
2300 /* update the pointer to the start of the buffer */
2306 static struct brcmf_vs_tlv *
2307 brcmf_find_wpaie(u8 *parse, u32 len)
2309 struct brcmf_tlv *ie;
2311 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
2312 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2313 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2314 return (struct brcmf_vs_tlv *)ie;
2319 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2321 struct net_device *ndev = cfg_to_ndev(cfg);
2322 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2323 struct brcmf_if *ifp = netdev_priv(ndev);
2324 struct brcmf_bss_info_le *bi;
2325 struct brcmf_ssid *ssid;
2326 struct brcmf_tlv *tim;
2327 u16 beacon_interval;
2333 WL_TRACE("Enter\n");
2334 if (brcmf_is_ibssmode(cfg))
2337 ssid = &profile->ssid;
2339 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2340 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2341 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2343 WL_ERR("Could not get bss info %d\n", err);
2344 goto update_bss_info_out;
2347 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2348 err = brcmf_inform_single_bss(cfg, bi);
2350 goto update_bss_info_out;
2352 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2353 ie_len = le32_to_cpu(bi->ie_length);
2354 beacon_interval = le16_to_cpu(bi->beacon_period);
2356 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2358 dtim_period = tim->data[1];
2361 * active scan was done so we could not get dtim
2362 * information out of probe response.
2363 * so we speficially query dtim information to dongle.
2366 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2368 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2369 goto update_bss_info_out;
2371 dtim_period = (u8)var;
2374 update_bss_info_out:
2379 static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2381 struct escan_info *escan = &cfg->escan_info;
2383 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2384 if (cfg->scan_request) {
2385 escan->escan_state = WL_ESCAN_STATE_IDLE;
2386 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2388 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2389 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2392 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2394 struct brcmf_cfg80211_info *cfg =
2395 container_of(work, struct brcmf_cfg80211_info,
2396 escan_timeout_work);
2398 brcmf_notify_escan_complete(cfg,
2399 cfg->escan_info.ndev, true, true);
2402 static void brcmf_escan_timeout(unsigned long data)
2404 struct brcmf_cfg80211_info *cfg =
2405 (struct brcmf_cfg80211_info *)data;
2407 if (cfg->scan_request) {
2408 WL_ERR("timer expired\n");
2409 schedule_work(&cfg->escan_timeout_work);
2414 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2415 struct brcmf_bss_info_le *bss_info_le)
2417 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2418 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2419 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2420 bss_info_le->SSID_len == bss->SSID_len &&
2421 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2422 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2423 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2424 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2425 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2427 /* preserve max RSSI if the measurements are
2428 * both on-channel or both off-channel
2430 if (bss_info_rssi > bss_rssi)
2431 bss->RSSI = bss_info_le->RSSI;
2432 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2433 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2434 /* preserve the on-channel rssi measurement
2435 * if the new measurement is off channel
2437 bss->RSSI = bss_info_le->RSSI;
2438 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2446 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2447 const struct brcmf_event_msg *e, void *data)
2449 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2450 struct net_device *ndev = ifp->ndev;
2453 struct brcmf_escan_result_le *escan_result_le;
2454 struct brcmf_bss_info_le *bss_info_le;
2455 struct brcmf_bss_info_le *bss = NULL;
2457 struct brcmf_scan_results *list;
2463 if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2464 WL_ERR("scan not ready ndev %p drv_status %x\n", ndev,
2465 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2469 if (status == BRCMF_E_STATUS_PARTIAL) {
2470 WL_SCAN("ESCAN Partial result\n");
2471 escan_result_le = (struct brcmf_escan_result_le *) data;
2472 if (!escan_result_le) {
2473 WL_ERR("Invalid escan result (NULL pointer)\n");
2476 if (!cfg->scan_request) {
2477 WL_SCAN("result without cfg80211 request\n");
2481 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2482 WL_ERR("Invalid bss_count %d: ignoring\n",
2483 escan_result_le->bss_count);
2486 bss_info_le = &escan_result_le->bss_info_le;
2488 bi_length = le32_to_cpu(bss_info_le->length);
2489 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2490 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2491 WL_ERR("Invalid bss_info length %d: ignoring\n",
2496 if (!(cfg_to_wiphy(cfg)->interface_modes &
2497 BIT(NL80211_IFTYPE_ADHOC))) {
2498 if (le16_to_cpu(bss_info_le->capability) &
2499 WLAN_CAPABILITY_IBSS) {
2500 WL_ERR("Ignoring IBSS result\n");
2505 list = (struct brcmf_scan_results *)
2506 cfg->escan_info.escan_buf;
2507 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2508 WL_ERR("Buffer is too small: ignoring\n");
2512 for (i = 0; i < list->count; i++) {
2513 bss = bss ? (struct brcmf_bss_info_le *)
2514 ((unsigned char *)bss +
2515 le32_to_cpu(bss->length)) : list->bss_info_le;
2516 if (brcmf_compare_update_same_bss(bss, bss_info_le))
2519 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2520 bss_info_le, bi_length);
2521 list->version = le32_to_cpu(bss_info_le->version);
2522 list->buflen += bi_length;
2525 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2526 if (cfg->scan_request) {
2527 cfg->bss_list = (struct brcmf_scan_results *)
2528 cfg->escan_info.escan_buf;
2529 brcmf_inform_bss(cfg);
2530 aborted = status != BRCMF_E_STATUS_SUCCESS;
2531 brcmf_notify_escan_complete(cfg, ndev, aborted,
2534 WL_ERR("Unexpected scan result 0x%x\n", status);
2540 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2542 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2543 brcmf_cfg80211_escan_handler);
2544 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2545 /* Init scan_timeout timer */
2546 init_timer(&cfg->escan_timeout);
2547 cfg->escan_timeout.data = (unsigned long) cfg;
2548 cfg->escan_timeout.function = brcmf_escan_timeout;
2549 INIT_WORK(&cfg->escan_timeout_work,
2550 brcmf_cfg80211_escan_timeout_worker);
2553 static __always_inline void brcmf_delay(u32 ms)
2555 if (ms < 1000 / HZ) {
2563 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2565 WL_TRACE("Enter\n");
2570 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2571 struct cfg80211_wowlan *wow)
2573 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2574 struct net_device *ndev = cfg_to_ndev(cfg);
2575 struct brcmf_cfg80211_vif *vif;
2577 WL_TRACE("Enter\n");
2580 * if the primary net_device is not READY there is nothing
2581 * we can do but pray resume goes smoothly.
2583 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2584 if (!check_vif_up(vif))
2587 list_for_each_entry(vif, &cfg->vif_list, list) {
2588 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2591 * While going to suspend if associated with AP disassociate
2592 * from AP to save power while system is in suspended state
2594 brcmf_link_down(vif);
2596 /* Make sure WPA_Supplicant receives all the event
2597 * generated due to DISASSOC call to the fw to keep
2598 * the state fw and WPA_Supplicant state consistent
2603 /* end any scanning */
2604 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2605 brcmf_abort_scanning(cfg);
2607 /* Turn off watchdog timer */
2608 brcmf_set_mpc(ndev, 1);
2612 /* clear any scanning activity */
2613 cfg->scan_status = 0;
2618 brcmf_update_pmklist(struct net_device *ndev,
2619 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2624 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2626 WL_CONN("No of elements %d\n", pmkid_len);
2627 for (i = 0; i < pmkid_len; i++) {
2628 WL_CONN("PMKID[%d]: %pM =\n", i,
2629 &pmk_list->pmkids.pmkid[i].BSSID);
2630 for (j = 0; j < WLAN_PMKID_LEN; j++)
2631 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2635 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2636 (char *)pmk_list, sizeof(*pmk_list));
2642 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2643 struct cfg80211_pmksa *pmksa)
2645 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2646 struct brcmf_if *ifp = netdev_priv(ndev);
2647 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2652 WL_TRACE("Enter\n");
2653 if (!check_vif_up(ifp->vif))
2656 pmkid_len = le32_to_cpu(pmkids->npmkid);
2657 for (i = 0; i < pmkid_len; i++)
2658 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2660 if (i < WL_NUM_PMKIDS_MAX) {
2661 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2662 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2663 if (i == pmkid_len) {
2665 pmkids->npmkid = cpu_to_le32(pmkid_len);
2670 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2671 pmkids->pmkid[pmkid_len].BSSID);
2672 for (i = 0; i < WLAN_PMKID_LEN; i++)
2673 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2675 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2682 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2683 struct cfg80211_pmksa *pmksa)
2685 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2686 struct brcmf_if *ifp = netdev_priv(ndev);
2687 struct pmkid_list pmkid;
2691 WL_TRACE("Enter\n");
2692 if (!check_vif_up(ifp->vif))
2695 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2696 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2698 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2699 &pmkid.pmkid[0].BSSID);
2700 for (i = 0; i < WLAN_PMKID_LEN; i++)
2701 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2703 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2704 for (i = 0; i < pmkid_len; i++)
2706 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2711 && (i < pmkid_len)) {
2712 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2713 sizeof(struct pmkid));
2714 for (; i < (pmkid_len - 1); i++) {
2715 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2716 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2718 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2719 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2722 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2726 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2734 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2736 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2737 struct brcmf_if *ifp = netdev_priv(ndev);
2740 WL_TRACE("Enter\n");
2741 if (!check_vif_up(ifp->vif))
2744 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2745 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2753 * PFN result doesn't have all the info which are
2754 * required by the supplicant
2755 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2756 * via wl_inform_single_bss in the required format. Escan does require the
2757 * scan request in the form of cfg80211_scan_request. For timebeing, create
2758 * cfg80211_scan_request one out of the received PNO event.
2761 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2762 const struct brcmf_event_msg *e, void *data)
2764 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2765 struct net_device *ndev = ifp->ndev;
2766 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2767 struct cfg80211_scan_request *request = NULL;
2768 struct cfg80211_ssid *ssid = NULL;
2769 struct ieee80211_channel *channel = NULL;
2770 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2772 int channel_req = 0;
2774 struct brcmf_pno_scanresults_le *pfn_result;
2780 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2781 WL_SCAN("PFN NET LOST event. Do Nothing\n");
2785 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2786 result_count = le32_to_cpu(pfn_result->count);
2787 status = le32_to_cpu(pfn_result->status);
2790 * PFN event is limited to fit 512 bytes so we may get
2791 * multiple NET_FOUND events. For now place a warning here.
2793 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2794 WL_SCAN("PFN NET FOUND event. count: %d\n", result_count);
2795 if (result_count > 0) {
2798 request = kzalloc(sizeof(*request), GFP_KERNEL);
2799 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2800 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2801 if (!request || !ssid || !channel) {
2806 request->wiphy = wiphy;
2807 data += sizeof(struct brcmf_pno_scanresults_le);
2808 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2810 for (i = 0; i < result_count; i++) {
2811 netinfo = &netinfo_start[i];
2813 WL_ERR("Invalid netinfo ptr. index: %d\n", i);
2818 WL_SCAN("SSID:%s Channel:%d\n",
2819 netinfo->SSID, netinfo->channel);
2820 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2821 ssid[i].ssid_len = netinfo->SSID_len;
2824 channel_req = netinfo->channel;
2825 if (channel_req <= CH_MAX_2G_CHANNEL)
2826 band = NL80211_BAND_2GHZ;
2828 band = NL80211_BAND_5GHZ;
2829 channel[i].center_freq =
2830 ieee80211_channel_to_frequency(channel_req,
2832 channel[i].band = band;
2833 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2834 request->channels[i] = &channel[i];
2835 request->n_channels++;
2838 /* assign parsed ssid array */
2839 if (request->n_ssids)
2840 request->ssids = &ssid[0];
2842 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2843 /* Abort any on-going scan */
2844 brcmf_abort_scanning(cfg);
2847 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2848 err = brcmf_do_escan(cfg, wiphy, ndev, request);
2850 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2853 cfg->sched_escan = true;
2854 cfg->scan_request = request;
2856 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
2869 cfg80211_sched_scan_stopped(wiphy);
2873 static int brcmf_dev_pno_clean(struct net_device *ndev)
2878 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
2881 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
2885 WL_ERR("failed code %d\n", ret);
2890 static int brcmf_dev_pno_config(struct net_device *ndev)
2892 struct brcmf_pno_param_le pfn_param;
2894 memset(&pfn_param, 0, sizeof(pfn_param));
2895 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
2897 /* set extra pno params */
2898 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
2899 pfn_param.repeat = BRCMF_PNO_REPEAT;
2900 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
2902 /* set up pno scan fr */
2903 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
2905 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
2906 &pfn_param, sizeof(pfn_param));
2910 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
2911 struct net_device *ndev,
2912 struct cfg80211_sched_scan_request *request)
2914 struct brcmf_if *ifp = netdev_priv(ndev);
2915 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
2916 struct brcmf_pno_net_param_le pfn;
2920 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
2921 request->n_match_sets, request->n_ssids);
2922 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2923 WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
2927 if (!request || !request->n_ssids || !request->n_match_sets) {
2928 WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
2929 request ? request->n_ssids : 0);
2933 if (request->n_ssids > 0) {
2934 for (i = 0; i < request->n_ssids; i++) {
2935 /* Active scan req for ssids */
2936 WL_SCAN(">>> Active scan req for ssid (%s)\n",
2937 request->ssids[i].ssid);
2940 * match_set ssids is a supert set of n_ssid list,
2941 * so we need not add these set seperately.
2946 if (request->n_match_sets > 0) {
2947 /* clean up everything */
2948 ret = brcmf_dev_pno_clean(ndev);
2950 WL_ERR("failed error=%d\n", ret);
2955 ret = brcmf_dev_pno_config(ndev);
2957 WL_ERR("PNO setup failed!! ret=%d\n", ret);
2961 /* configure each match set */
2962 for (i = 0; i < request->n_match_sets; i++) {
2963 struct cfg80211_ssid *ssid;
2966 ssid = &request->match_sets[i].ssid;
2967 ssid_len = ssid->ssid_len;
2970 WL_ERR("skip broadcast ssid\n");
2973 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
2974 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
2975 pfn.wsec = cpu_to_le32(0);
2976 pfn.infra = cpu_to_le32(1);
2977 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
2978 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
2979 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
2980 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
2982 WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
2983 ret == 0 ? "set" : "failed",
2986 /* Enable the PNO */
2987 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
2988 WL_ERR("PNO enable failed!! ret=%d\n", ret);
2998 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
2999 struct net_device *ndev)
3001 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3004 brcmf_dev_pno_clean(ndev);
3005 if (cfg->sched_escan)
3006 brcmf_notify_escan_complete(cfg, ndev, true, true);
3010 #ifdef CONFIG_NL80211_TESTMODE
3011 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3013 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3014 struct net_device *ndev = cfg_to_ndev(cfg);
3015 struct brcmf_dcmd *dcmd = data;
3016 struct sk_buff *reply;
3019 WL_TRACE("cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3020 dcmd->buf, dcmd->len);
3023 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3024 dcmd->buf, dcmd->len);
3026 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3027 dcmd->buf, dcmd->len);
3029 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3030 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3031 ret = cfg80211_testmode_reply(reply);
3037 static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3039 struct brcmf_if *ifp = netdev_priv(ndev);
3043 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3045 WL_ERR("auth error %d\n", err);
3049 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3051 WL_ERR("wsec error %d\n", err);
3054 /* set upper-layer auth */
3055 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3057 WL_ERR("wpa_auth error %d\n", err);
3064 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3067 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3069 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3073 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3076 struct brcmf_if *ifp = netdev_priv(ndev);
3077 u32 auth = 0; /* d11 open authentication */
3089 u32 wme_bss_disable;
3091 WL_TRACE("Enter\n");
3095 len = wpa_ie->len + TLV_HDR_LEN;
3096 data = (u8 *)wpa_ie;
3099 offset += VS_IE_FIXED_HDR_LEN;
3100 offset += WPA_IE_VERSION_LEN;
3102 /* check for multicast cipher suite */
3103 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3105 WL_ERR("no multicast cipher suite\n");
3109 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3111 WL_ERR("ivalid OUI\n");
3114 offset += TLV_OUI_LEN;
3116 /* pick up multicast cipher */
3117 switch (data[offset]) {
3118 case WPA_CIPHER_NONE:
3121 case WPA_CIPHER_WEP_40:
3122 case WPA_CIPHER_WEP_104:
3125 case WPA_CIPHER_TKIP:
3126 gval = TKIP_ENABLED;
3128 case WPA_CIPHER_AES_CCM:
3133 WL_ERR("Invalid multi cast cipher info\n");
3138 /* walk thru unicast cipher list and pick up what we recognize */
3139 count = data[offset] + (data[offset + 1] << 8);
3140 offset += WPA_IE_SUITE_COUNT_LEN;
3141 /* Check for unicast suite(s) */
3142 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3144 WL_ERR("no unicast cipher suite\n");
3147 for (i = 0; i < count; i++) {
3148 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3150 WL_ERR("ivalid OUI\n");
3153 offset += TLV_OUI_LEN;
3154 switch (data[offset]) {
3155 case WPA_CIPHER_NONE:
3157 case WPA_CIPHER_WEP_40:
3158 case WPA_CIPHER_WEP_104:
3159 pval |= WEP_ENABLED;
3161 case WPA_CIPHER_TKIP:
3162 pval |= TKIP_ENABLED;
3164 case WPA_CIPHER_AES_CCM:
3165 pval |= AES_ENABLED;
3168 WL_ERR("Ivalid unicast security info\n");
3172 /* walk thru auth management suite list and pick up what we recognize */
3173 count = data[offset] + (data[offset + 1] << 8);
3174 offset += WPA_IE_SUITE_COUNT_LEN;
3175 /* Check for auth key management suite(s) */
3176 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3178 WL_ERR("no auth key mgmt suite\n");
3181 for (i = 0; i < count; i++) {
3182 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3184 WL_ERR("ivalid OUI\n");
3187 offset += TLV_OUI_LEN;
3188 switch (data[offset]) {
3190 WL_TRACE("RSN_AKM_NONE\n");
3191 wpa_auth |= WPA_AUTH_NONE;
3193 case RSN_AKM_UNSPECIFIED:
3194 WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3195 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3196 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3199 WL_TRACE("RSN_AKM_PSK\n");
3200 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3201 (wpa_auth |= WPA_AUTH_PSK);
3204 WL_ERR("Ivalid key mgmt info\n");
3210 wme_bss_disable = 1;
3211 if ((offset + RSN_CAP_LEN) <= len) {
3212 rsn_cap = data[offset] + (data[offset + 1] << 8);
3213 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3214 wme_bss_disable = 0;
3216 /* set wme_bss_disable to sync RSN Capabilities */
3217 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3220 WL_ERR("wme_bss_disable error %d\n", err);
3224 /* FOR WPS , set SES_OW_ENABLED */
3225 wsec = (pval | gval | SES_OW_ENABLED);
3228 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3230 WL_ERR("auth error %d\n", err);
3234 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3236 WL_ERR("wsec error %d\n", err);
3239 /* set upper-layer auth */
3240 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3242 WL_ERR("wpa_auth error %d\n", err);
3251 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3252 struct parsed_vndr_ies *vndr_ies)
3255 struct brcmf_vs_tlv *vndrie;
3256 struct brcmf_tlv *ie;
3257 struct parsed_vndr_ie_info *parsed_info;
3260 remaining_len = (s32)vndr_ie_len;
3261 memset(vndr_ies, 0, sizeof(*vndr_ies));
3263 ie = (struct brcmf_tlv *)vndr_ie_buf;
3265 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3267 vndrie = (struct brcmf_vs_tlv *)ie;
3268 /* len should be bigger than OUI length + one */
3269 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3270 WL_ERR("invalid vndr ie. length is too small %d\n",
3274 /* if wpa or wme ie, do not add ie */
3275 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3276 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3277 (vndrie->oui_type == WME_OUI_TYPE))) {
3278 WL_TRACE("Found WPA/WME oui. Do not add it\n");
3282 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3284 /* save vndr ie information */
3285 parsed_info->ie_ptr = (char *)vndrie;
3286 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3287 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3291 WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3292 parsed_info->vndrie.oui[0],
3293 parsed_info->vndrie.oui[1],
3294 parsed_info->vndrie.oui[2],
3295 parsed_info->vndrie.oui_type);
3297 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3300 remaining_len -= ie->len;
3301 if (remaining_len <= 2)
3304 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len);
3310 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3316 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3317 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3319 iecount_le = cpu_to_le32(1);
3320 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3322 pktflag_le = cpu_to_le32(pktflag);
3323 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3325 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3327 return ie_len + VNDR_IE_HDR_SIZE;
3331 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3332 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3334 struct brcmf_if *ifp;
3335 struct vif_saved_ie *saved_ie;
3339 u8 *mgmt_ie_buf = NULL;
3340 int mgmt_ie_buf_len;
3342 u32 del_add_ie_buf_len = 0;
3343 u32 total_ie_buf_len = 0;
3344 u32 parsed_ie_buf_len = 0;
3345 struct parsed_vndr_ies old_vndr_ies;
3346 struct parsed_vndr_ies new_vndr_ies;
3347 struct parsed_vndr_ie_info *vndrie_info;
3350 int remained_buf_len;
3355 saved_ie = &vif->saved_ie;
3357 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3358 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3361 curr_ie_buf = iovar_ie_buf;
3362 if (ifp->vif->mode == WL_MODE_AP) {
3364 case VNDR_IE_PRBRSP_FLAG:
3365 mgmt_ie_buf = saved_ie->probe_res_ie;
3366 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3367 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3369 case VNDR_IE_BEACON_FLAG:
3370 mgmt_ie_buf = saved_ie->beacon_ie;
3371 mgmt_ie_len = &saved_ie->beacon_ie_len;
3372 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3376 WL_ERR("not suitable type\n");
3381 WL_ERR("not suitable type\n");
3385 if (vndr_ie_len > mgmt_ie_buf_len) {
3387 WL_ERR("extra IE size too big\n");
3391 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3392 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3394 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3395 for (i = 0; i < new_vndr_ies.count; i++) {
3396 vndrie_info = &new_vndr_ies.ie_info[i];
3397 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3398 vndrie_info->ie_len);
3399 parsed_ie_buf_len += vndrie_info->ie_len;
3403 if (mgmt_ie_buf != NULL) {
3404 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3405 (memcmp(mgmt_ie_buf, curr_ie_buf,
3406 parsed_ie_buf_len) == 0)) {
3407 WL_TRACE("Previous mgmt IE is equals to current IE");
3411 /* parse old vndr_ie */
3412 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3414 /* make a command to delete old ie */
3415 for (i = 0; i < old_vndr_ies.count; i++) {
3416 vndrie_info = &old_vndr_ies.ie_info[i];
3418 WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3419 vndrie_info->vndrie.id,
3420 vndrie_info->vndrie.len,
3421 vndrie_info->vndrie.oui[0],
3422 vndrie_info->vndrie.oui[1],
3423 vndrie_info->vndrie.oui[2]);
3425 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3426 vndrie_info->ie_ptr,
3427 vndrie_info->ie_len,
3429 curr_ie_buf += del_add_ie_buf_len;
3430 total_ie_buf_len += del_add_ie_buf_len;
3435 /* Add if there is any extra IE */
3436 if (mgmt_ie_buf && parsed_ie_buf_len) {
3439 remained_buf_len = mgmt_ie_buf_len;
3441 /* make a command to add new ie */
3442 for (i = 0; i < new_vndr_ies.count; i++) {
3443 vndrie_info = &new_vndr_ies.ie_info[i];
3445 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3446 vndrie_info->vndrie.id,
3447 vndrie_info->vndrie.len,
3448 vndrie_info->vndrie.oui[0],
3449 vndrie_info->vndrie.oui[1],
3450 vndrie_info->vndrie.oui[2]);
3452 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3453 vndrie_info->ie_ptr,
3454 vndrie_info->ie_len,
3456 /* verify remained buf size before copy data */
3457 remained_buf_len -= vndrie_info->ie_len;
3458 if (remained_buf_len < 0) {
3459 WL_ERR("no space in mgmt_ie_buf: len left %d",
3464 /* save the parsed IE in wl struct */
3465 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3466 vndrie_info->ie_len);
3467 *mgmt_ie_len += vndrie_info->ie_len;
3469 curr_ie_buf += del_add_ie_buf_len;
3470 total_ie_buf_len += del_add_ie_buf_len;
3473 if (total_ie_buf_len) {
3474 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3477 WL_ERR("vndr ie set error : %d\n", err);
3481 kfree(iovar_ie_buf);
3486 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3487 struct cfg80211_ap_settings *settings)
3490 struct brcmf_if *ifp = netdev_priv(ndev);
3491 struct brcmf_tlv *ssid_ie;
3492 struct brcmf_ssid_le ssid_le;
3494 struct brcmf_tlv *rsn_ie;
3495 struct brcmf_vs_tlv *wpa_ie;
3496 struct brcmf_join_params join_params;
3499 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3500 cfg80211_get_chandef_type(&settings->chandef),
3501 settings->beacon_interval,
3502 settings->dtim_period);
3503 WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3504 settings->ssid, settings->ssid_len, settings->auth_type,
3505 settings->inactivity_timeout);
3507 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
3508 WL_ERR("Not in AP creation mode\n");
3512 memset(&ssid_le, 0, sizeof(ssid_le));
3513 if (settings->ssid == NULL || settings->ssid_len == 0) {
3514 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3515 ssid_ie = brcmf_parse_tlvs(
3516 (u8 *)&settings->beacon.head[ie_offset],
3517 settings->beacon.head_len - ie_offset,
3522 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3523 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3524 WL_TRACE("SSID is (%s) in Head\n", ssid_le.SSID);
3526 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3527 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3530 brcmf_set_mpc(ndev, 0);
3531 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3533 WL_ERR("BRCMF_C_DOWN error %d\n", err);
3536 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3538 WL_ERR("SET INFRA error %d\n", err);
3541 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3543 WL_ERR("setting AP mode failed %d\n", err);
3547 /* find the RSN_IE */
3548 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3549 settings->beacon.tail_len, WLAN_EID_RSN);
3551 /* find the WPA_IE */
3552 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3553 settings->beacon.tail_len);
3555 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3556 WL_TRACE("WPA(2) IE is found\n");
3557 if (wpa_ie != NULL) {
3559 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3564 err = brcmf_configure_wpaie(ndev,
3565 (struct brcmf_vs_tlv *)rsn_ie, true);
3570 WL_TRACE("No WPA(2) IEs found\n");
3571 brcmf_configure_opensecurity(ndev, bssidx);
3573 /* Set Beacon IEs to FW */
3574 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3575 VNDR_IE_BEACON_FLAG,
3576 settings->beacon.tail,
3577 settings->beacon.tail_len);
3579 WL_ERR("Set Beacon IE Failed\n");
3581 WL_TRACE("Applied Vndr IEs for Beacon\n");
3583 /* Set Probe Response IEs to FW */
3584 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3585 VNDR_IE_PRBRSP_FLAG,
3586 settings->beacon.proberesp_ies,
3587 settings->beacon.proberesp_ies_len);
3589 WL_ERR("Set Probe Resp IE Failed\n");
3591 WL_TRACE("Applied Vndr IEs for Probe Resp\n");
3593 if (settings->beacon_interval) {
3594 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3595 settings->beacon_interval);
3597 WL_ERR("Beacon Interval Set Error, %d\n", err);
3601 if (settings->dtim_period) {
3602 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3603 settings->dtim_period);
3605 WL_ERR("DTIM Interval Set Error, %d\n", err);
3609 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3611 WL_ERR("BRCMF_C_UP error (%d)\n", err);
3615 memset(&join_params, 0, sizeof(join_params));
3616 /* join parameters starts with ssid */
3617 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3619 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3620 &join_params, sizeof(join_params));
3622 WL_ERR("SET SSID error (%d)\n", err);
3625 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3626 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3630 brcmf_set_mpc(ndev, 1);
3634 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3636 struct brcmf_if *ifp = netdev_priv(ndev);
3637 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3640 WL_TRACE("Enter\n");
3642 if (cfg->conf->mode == WL_MODE_AP) {
3643 /* Due to most likely deauths outstanding we sleep */
3644 /* first to make sure they get processed by fw. */
3646 err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
3649 WL_ERR("setting AP mode failed %d\n", err);
3652 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_UP, 0);
3654 WL_ERR("BRCMF_C_UP error %d\n", err);
3657 brcmf_set_mpc(ndev, 1);
3658 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3659 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3666 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3669 struct brcmf_scb_val_le scbval;
3670 struct brcmf_if *ifp = netdev_priv(ndev);
3676 WL_TRACE("Enter %pM\n", mac);
3678 if (!check_vif_up(ifp->vif))
3681 memcpy(&scbval.ea, mac, ETH_ALEN);
3682 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3683 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3684 &scbval, sizeof(scbval));
3686 WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3692 static struct cfg80211_ops wl_cfg80211_ops = {
3693 .change_virtual_intf = brcmf_cfg80211_change_iface,
3694 .scan = brcmf_cfg80211_scan,
3695 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
3696 .join_ibss = brcmf_cfg80211_join_ibss,
3697 .leave_ibss = brcmf_cfg80211_leave_ibss,
3698 .get_station = brcmf_cfg80211_get_station,
3699 .set_tx_power = brcmf_cfg80211_set_tx_power,
3700 .get_tx_power = brcmf_cfg80211_get_tx_power,
3701 .add_key = brcmf_cfg80211_add_key,
3702 .del_key = brcmf_cfg80211_del_key,
3703 .get_key = brcmf_cfg80211_get_key,
3704 .set_default_key = brcmf_cfg80211_config_default_key,
3705 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
3706 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
3707 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
3708 .connect = brcmf_cfg80211_connect,
3709 .disconnect = brcmf_cfg80211_disconnect,
3710 .suspend = brcmf_cfg80211_suspend,
3711 .resume = brcmf_cfg80211_resume,
3712 .set_pmksa = brcmf_cfg80211_set_pmksa,
3713 .del_pmksa = brcmf_cfg80211_del_pmksa,
3714 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3715 .start_ap = brcmf_cfg80211_start_ap,
3716 .stop_ap = brcmf_cfg80211_stop_ap,
3717 .del_station = brcmf_cfg80211_del_station,
3718 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
3719 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
3720 #ifdef CONFIG_NL80211_TESTMODE
3721 .testmode_cmd = brcmf_cfg80211_testmode
3725 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
3731 return NL80211_IFTYPE_STATION;
3733 return NL80211_IFTYPE_ADHOC;
3735 return NL80211_IFTYPE_UNSPECIFIED;
3741 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3743 /* scheduled scan settings */
3744 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
3745 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
3746 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
3747 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3750 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3752 struct wiphy *wiphy;
3755 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
3757 WL_ERR("Could not allocate wiphy device\n");
3758 return ERR_PTR(-ENOMEM);
3760 set_wiphy_dev(wiphy, phydev);
3761 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3762 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3763 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3764 BIT(NL80211_IFTYPE_ADHOC) |
3765 BIT(NL80211_IFTYPE_AP);
3766 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3767 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
3768 * it as 11a by default.
3769 * This will be updated with
3772 * if phy has 11n capability
3774 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3775 wiphy->cipher_suites = __wl_cipher_suites;
3776 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3777 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
3781 brcmf_wiphy_pno_params(wiphy);
3782 err = wiphy_register(wiphy);
3784 WL_ERR("Could not register wiphy device (%d)\n", err);
3786 return ERR_PTR(err);
3792 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3793 struct net_device *netdev,
3794 s32 mode, bool pm_block)
3796 struct brcmf_cfg80211_vif *vif;
3798 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
3799 return ERR_PTR(-ENOSPC);
3801 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
3803 return ERR_PTR(-ENOMEM);
3805 vif->wdev.wiphy = cfg->wiphy;
3806 vif->wdev.netdev = netdev;
3807 vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
3810 vif->ifp = netdev_priv(netdev);
3811 netdev->ieee80211_ptr = &vif->wdev;
3812 SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
3816 vif->pm_block = pm_block;
3819 brcmf_init_prof(&vif->profile);
3821 list_add_tail(&vif->list, &cfg->vif_list);
3826 static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3828 struct brcmf_cfg80211_info *cfg;
3829 struct wiphy *wiphy;
3831 wiphy = vif->wdev.wiphy;
3832 cfg = wiphy_priv(wiphy);
3833 list_del(&vif->list);
3837 if (!cfg->vif_cnt) {
3838 wiphy_unregister(wiphy);
3843 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
3845 u32 event = e->event_code;
3846 u32 status = e->status;
3848 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3849 WL_CONN("Processing set ssid\n");
3856 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
3858 u32 event = e->event_code;
3859 u16 flags = e->flags;
3861 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
3862 WL_CONN("Processing link down\n");
3868 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
3869 const struct brcmf_event_msg *e)
3871 u32 event = e->event_code;
3872 u32 status = e->status;
3874 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
3875 WL_CONN("Processing Link %s & no network found\n",
3876 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
3880 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
3881 WL_CONN("Processing connecting & no network found\n");
3888 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3890 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3892 kfree(conn_info->req_ie);
3893 conn_info->req_ie = NULL;
3894 conn_info->req_ie_len = 0;
3895 kfree(conn_info->resp_ie);
3896 conn_info->resp_ie = NULL;
3897 conn_info->resp_ie_len = 0;
3900 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
3902 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
3903 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3904 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3909 brcmf_clear_assoc_ies(cfg);
3911 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
3912 cfg->extra_buf, WL_ASSOC_INFO_MAX);
3914 WL_ERR("could not get assoc info (%d)\n", err);
3918 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
3919 req_len = le32_to_cpu(assoc_info->req_len);
3920 resp_len = le32_to_cpu(assoc_info->resp_len);
3922 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
3926 WL_ERR("could not get assoc req (%d)\n", err);
3929 conn_info->req_ie_len = req_len;
3931 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
3934 conn_info->req_ie_len = 0;
3935 conn_info->req_ie = NULL;
3938 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
3942 WL_ERR("could not get assoc resp (%d)\n", err);
3945 conn_info->resp_ie_len = resp_len;
3946 conn_info->resp_ie =
3947 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
3950 conn_info->resp_ie_len = 0;
3951 conn_info->resp_ie = NULL;
3953 WL_CONN("req len (%d) resp len (%d)\n",
3954 conn_info->req_ie_len, conn_info->resp_ie_len);
3960 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3961 struct net_device *ndev,
3962 const struct brcmf_event_msg *e)
3964 struct brcmf_if *ifp = netdev_priv(ndev);
3965 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
3966 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3967 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3968 struct ieee80211_channel *notify_channel = NULL;
3969 struct ieee80211_supported_band *band;
3970 struct brcmf_bss_info_le *bi;
3976 WL_TRACE("Enter\n");
3978 brcmf_get_assoc_ies(cfg);
3979 memcpy(profile->bssid, e->addr, ETH_ALEN);
3980 brcmf_update_bss_info(cfg);
3982 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3988 /* data sent to dongle has to be little endian */
3989 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3990 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3991 buf, WL_BSS_INFO_MAX);
3996 bi = (struct brcmf_bss_info_le *)(buf + 4);
3997 target_channel = bi->ctl_ch ? bi->ctl_ch :
3998 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
4000 if (target_channel <= CH_MAX_2G_CHANNEL)
4001 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4003 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4005 freq = ieee80211_channel_to_frequency(target_channel, band->band);
4006 notify_channel = ieee80211_get_channel(wiphy, freq);
4010 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4011 conn_info->req_ie, conn_info->req_ie_len,
4012 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4013 WL_CONN("Report roaming result\n");
4015 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4021 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4022 struct net_device *ndev, const struct brcmf_event_msg *e,
4025 struct brcmf_if *ifp = netdev_priv(ndev);
4026 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4027 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4030 WL_TRACE("Enter\n");
4032 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4033 &ifp->vif->sme_state)) {
4035 brcmf_get_assoc_ies(cfg);
4036 memcpy(profile->bssid, e->addr, ETH_ALEN);
4037 brcmf_update_bss_info(cfg);
4039 cfg80211_connect_result(ndev,
4040 (u8 *)profile->bssid,
4042 conn_info->req_ie_len,
4044 conn_info->resp_ie_len,
4045 completed ? WLAN_STATUS_SUCCESS :
4046 WLAN_STATUS_AUTH_TIMEOUT,
4049 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4050 &ifp->vif->sme_state);
4051 WL_CONN("Report connect result - connection %s\n",
4052 completed ? "succeeded" : "failed");
4059 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4060 struct net_device *ndev,
4061 const struct brcmf_event_msg *e, void *data)
4064 u32 event = e->event_code;
4065 u32 reason = e->reason;
4066 u32 len = e->datalen;
4067 static int generation;
4069 struct station_info sinfo;
4071 WL_CONN("event %d, reason %d\n", event, reason);
4072 memset(&sinfo, 0, sizeof(sinfo));
4075 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4076 reason == BRCMF_E_STATUS_SUCCESS) {
4077 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4079 WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4082 sinfo.assoc_req_ies = data;
4083 sinfo.assoc_req_ies_len = len;
4085 sinfo.generation = generation;
4086 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4087 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4088 (event == BRCMF_E_DEAUTH_IND) ||
4089 (event == BRCMF_E_DEAUTH)) {
4091 sinfo.generation = generation;
4092 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4098 brcmf_notify_connect_status(struct brcmf_if *ifp,
4099 const struct brcmf_event_msg *e, void *data)
4101 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4102 struct net_device *ndev = ifp->ndev;
4103 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4106 if (cfg->conf->mode == WL_MODE_AP) {
4107 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4108 } else if (brcmf_is_linkup(e)) {
4109 WL_CONN("Linkup\n");
4110 if (brcmf_is_ibssmode(cfg)) {
4111 memcpy(profile->bssid, e->addr, ETH_ALEN);
4112 wl_inform_ibss(cfg, ndev, e->addr);
4113 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4114 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4115 &ifp->vif->sme_state);
4116 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4117 &ifp->vif->sme_state);
4119 brcmf_bss_connect_done(cfg, ndev, e, true);
4120 } else if (brcmf_is_linkdown(e)) {
4121 WL_CONN("Linkdown\n");
4122 if (!brcmf_is_ibssmode(cfg)) {
4123 brcmf_bss_connect_done(cfg, ndev, e, false);
4124 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4125 &ifp->vif->sme_state))
4126 cfg80211_disconnected(ndev, 0, NULL, 0,
4129 brcmf_link_down(ifp->vif);
4130 brcmf_init_prof(ndev_to_prof(ndev));
4131 } else if (brcmf_is_nonetwork(cfg, e)) {
4132 if (brcmf_is_ibssmode(cfg))
4133 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4134 &ifp->vif->sme_state);
4136 brcmf_bss_connect_done(cfg, ndev, e, false);
4143 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4144 const struct brcmf_event_msg *e, void *data)
4146 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4148 u32 event = e->event_code;
4149 u32 status = e->status;
4151 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4152 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4153 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4155 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4162 brcmf_notify_mic_status(struct brcmf_if *ifp,
4163 const struct brcmf_event_msg *e, void *data)
4165 u16 flags = e->flags;
4166 enum nl80211_key_type key_type;
4168 if (flags & BRCMF_EVENT_MSG_GROUP)
4169 key_type = NL80211_KEYTYPE_GROUP;
4171 key_type = NL80211_KEYTYPE_PAIRWISE;
4173 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4179 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4181 conf->mode = (u32)-1;
4182 conf->frag_threshold = (u32)-1;
4183 conf->rts_threshold = (u32)-1;
4184 conf->retry_short = (u32)-1;
4185 conf->retry_long = (u32)-1;
4186 conf->tx_power = -1;
4189 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4191 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4192 brcmf_notify_connect_status);
4193 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4194 brcmf_notify_connect_status);
4195 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4196 brcmf_notify_connect_status);
4197 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4198 brcmf_notify_connect_status);
4199 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4200 brcmf_notify_connect_status);
4201 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4202 brcmf_notify_connect_status);
4203 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4204 brcmf_notify_roaming_status);
4205 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4206 brcmf_notify_mic_status);
4207 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4208 brcmf_notify_connect_status);
4209 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4210 brcmf_notify_sched_scan_results);
4213 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4217 kfree(cfg->escan_ioctl_buf);
4218 cfg->escan_ioctl_buf = NULL;
4219 kfree(cfg->extra_buf);
4220 cfg->extra_buf = NULL;
4221 kfree(cfg->pmk_list);
4222 cfg->pmk_list = NULL;
4225 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4227 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4229 goto init_priv_mem_out;
4230 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4231 if (!cfg->escan_ioctl_buf)
4232 goto init_priv_mem_out;
4233 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4234 if (!cfg->extra_buf)
4235 goto init_priv_mem_out;
4236 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4238 goto init_priv_mem_out;
4243 brcmf_deinit_priv_mem(cfg);
4248 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4252 cfg->scan_request = NULL;
4253 cfg->pwr_save = true;
4254 cfg->roam_on = true; /* roam on & off switch.
4255 we enable roam per default */
4256 cfg->active_scan = true; /* we do active scan for
4257 specific scan per default */
4258 cfg->dongle_up = false; /* dongle is not up yet */
4259 err = brcmf_init_priv_mem(cfg);
4262 brcmf_register_event_handlers(cfg);
4263 mutex_init(&cfg->usr_sync);
4264 brcmf_init_escan(cfg);
4265 brcmf_init_conf(cfg->conf);
4270 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4272 cfg->dongle_up = false; /* dongle down */
4273 brcmf_abort_scanning(cfg);
4274 brcmf_deinit_priv_mem(cfg);
4277 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr)
4279 struct net_device *ndev = drvr->iflist[0]->ndev;
4280 struct device *busdev = drvr->dev;
4281 struct brcmf_cfg80211_info *cfg;
4282 struct wiphy *wiphy;
4283 struct brcmf_cfg80211_vif *vif;
4284 struct brcmf_if *ifp;
4288 WL_ERR("ndev is invalid\n");
4292 ifp = netdev_priv(ndev);
4293 wiphy = brcmf_setup_wiphy(busdev);
4297 cfg = wiphy_priv(wiphy);
4300 INIT_LIST_HEAD(&cfg->vif_list);
4302 vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false);
4308 err = wl_init_priv(cfg);
4310 WL_ERR("Failed to init iwm_priv (%d)\n", err);
4311 goto cfg80211_attach_out;
4317 cfg80211_attach_out:
4318 brcmf_free_vif(vif);
4322 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4324 struct brcmf_cfg80211_vif *vif;
4325 struct brcmf_cfg80211_vif *tmp;
4327 wl_deinit_priv(cfg);
4328 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4329 brcmf_free_vif(vif);
4334 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
4336 struct brcmf_if *ifp = netdev_priv(ndev);
4338 __le32 roamtrigger[2];
4339 __le32 roam_delta[2];
4342 * Setup timeout if Beacons are lost and roam is
4343 * off to report link down
4346 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4348 WL_ERR("bcn_timeout error (%d)\n", err);
4349 goto dongle_rom_out;
4354 * Enable/Disable built-in roaming to allow supplicant
4355 * to take care of roaming
4357 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
4358 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4360 WL_ERR("roam_off error (%d)\n", err);
4361 goto dongle_rom_out;
4364 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4365 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4366 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4367 (void *)roamtrigger, sizeof(roamtrigger));
4369 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4370 goto dongle_rom_out;
4373 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4374 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4375 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4376 (void *)roam_delta, sizeof(roam_delta));
4378 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
4379 goto dongle_rom_out;
4387 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
4388 s32 scan_unassoc_time, s32 scan_passive_time)
4390 struct brcmf_if *ifp = netdev_priv(ndev);
4393 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4396 if (err == -EOPNOTSUPP)
4397 WL_INFO("Scan assoc time is not supported\n");
4399 WL_ERR("Scan assoc time error (%d)\n", err);
4400 goto dongle_scantime_out;
4402 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4405 if (err == -EOPNOTSUPP)
4406 WL_INFO("Scan unassoc time is not supported\n");
4408 WL_ERR("Scan unassoc time error (%d)\n", err);
4409 goto dongle_scantime_out;
4412 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4415 if (err == -EOPNOTSUPP)
4416 WL_INFO("Scan passive time is not supported\n");
4418 WL_ERR("Scan passive time error (%d)\n", err);
4419 goto dongle_scantime_out;
4422 dongle_scantime_out:
4426 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4428 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4429 struct wiphy *wiphy;
4434 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4435 &phy_list, sizeof(phy_list));
4437 WL_ERR("error (%d)\n", err);
4441 phy = ((char *)&phy_list)[0];
4442 WL_INFO("%c phy\n", phy);
4443 if (phy == 'n' || phy == 'a') {
4444 wiphy = cfg_to_wiphy(cfg);
4445 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4451 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4453 return wl_update_wiphybands(cfg);
4456 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4458 struct net_device *ndev;
4459 struct wireless_dev *wdev;
4466 ndev = cfg_to_ndev(cfg);
4467 wdev = ndev->ieee80211_ptr;
4469 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4470 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4472 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4473 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
4476 goto default_conf_out;
4477 WL_INFO("power save set to %s\n",
4478 (power_mode ? "enabled" : "disabled"));
4480 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
4483 goto default_conf_out;
4484 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4486 if (err && err != -EINPROGRESS)
4487 goto default_conf_out;
4488 err = brcmf_dongle_probecap(cfg);
4490 goto default_conf_out;
4492 /* -EINPROGRESS: Call commit handler */
4496 cfg->dongle_up = true;
4502 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
4504 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4508 return brcmf_config_dongle(ifp->drvr->config);
4511 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
4513 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4516 * While going down, if associated with AP disassociate
4517 * from AP to save power
4519 if (check_vif_up(ifp->vif)) {
4520 brcmf_link_down(ifp->vif);
4522 /* Make sure WPA_Supplicant receives all the event
4523 generated due to DISASSOC call to the fw to keep
4524 the state fw and WPA_Supplicant state consistent
4529 brcmf_abort_scanning(cfg);
4530 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4535 s32 brcmf_cfg80211_up(struct net_device *ndev)
4537 struct brcmf_if *ifp = netdev_priv(ndev);
4538 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4541 mutex_lock(&cfg->usr_sync);
4542 err = __brcmf_cfg80211_up(ifp);
4543 mutex_unlock(&cfg->usr_sync);
4548 s32 brcmf_cfg80211_down(struct net_device *ndev)
4550 struct brcmf_if *ifp = netdev_priv(ndev);
4551 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4554 mutex_lock(&cfg->usr_sync);
4555 err = __brcmf_cfg80211_down(ifp);
4556 mutex_unlock(&cfg->usr_sync);