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>
31 #include "wl_cfg80211.h"
34 #define BRCMF_SCAN_IE_LEN_MAX 2048
35 #define BRCMF_PNO_VERSION 2
36 #define BRCMF_PNO_TIME 30
37 #define BRCMF_PNO_REPEAT 4
38 #define BRCMF_PNO_FREQ_EXPO_MAX 3
39 #define BRCMF_PNO_MAX_PFN_COUNT 16
40 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
41 #define BRCMF_PNO_HIDDEN_BIT 2
42 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
43 #define BRCMF_PNO_SCAN_COMPLETE 1
44 #define BRCMF_PNO_SCAN_INCOMPLETE 0
46 #define BRCMF_IFACE_MAX_CNT 2
48 #define TLV_LEN_OFF 1 /* length offset */
49 #define TLV_HDR_LEN 2 /* header length */
50 #define TLV_BODY_OFF 2 /* body offset */
51 #define TLV_OUI_LEN 3 /* oui id length */
52 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
53 #define WPA_OUI_TYPE 1
54 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
55 #define WME_OUI_TYPE 2
57 #define VS_IE_FIXED_HDR_LEN 6
58 #define WPA_IE_VERSION_LEN 2
59 #define WPA_IE_MIN_OUI_LEN 4
60 #define WPA_IE_SUITE_COUNT_LEN 2
62 #define WPA_CIPHER_NONE 0 /* None */
63 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
64 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
65 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
66 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
68 #define RSN_AKM_NONE 0 /* None (IBSS) */
69 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
70 #define RSN_AKM_PSK 2 /* Pre-shared Key */
71 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
72 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
74 #define VNDR_IE_CMD_LEN 4 /* length of the set command
75 * string :"add", "del" (+ NUL)
77 #define VNDR_IE_COUNT_OFFSET 4
78 #define VNDR_IE_PKTFLAG_OFFSET 8
79 #define VNDR_IE_VSIE_OFFSET 12
80 #define VNDR_IE_HDR_SIZE 12
81 #define VNDR_IE_BEACON_FLAG 0x1
82 #define VNDR_IE_PRBRSP_FLAG 0x2
83 #define MAX_VNDR_IE_NUMBER 5
85 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
86 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
88 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
89 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
91 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
93 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
94 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
101 #define CHAN2G(_channel, _freq, _flags) { \
102 .band = IEEE80211_BAND_2GHZ, \
103 .center_freq = (_freq), \
104 .hw_value = (_channel), \
106 .max_antenna_gain = 0, \
110 #define CHAN5G(_channel, _flags) { \
111 .band = IEEE80211_BAND_5GHZ, \
112 .center_freq = 5000 + (5 * (_channel)), \
113 .hw_value = (_channel), \
115 .max_antenna_gain = 0, \
119 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
120 #define RATETAB_ENT(_rateid, _flags) \
122 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
123 .hw_value = (_rateid), \
127 static struct ieee80211_rate __wl_rates[] = {
128 RATETAB_ENT(BRCM_RATE_1M, 0),
129 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
130 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
131 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
132 RATETAB_ENT(BRCM_RATE_6M, 0),
133 RATETAB_ENT(BRCM_RATE_9M, 0),
134 RATETAB_ENT(BRCM_RATE_12M, 0),
135 RATETAB_ENT(BRCM_RATE_18M, 0),
136 RATETAB_ENT(BRCM_RATE_24M, 0),
137 RATETAB_ENT(BRCM_RATE_36M, 0),
138 RATETAB_ENT(BRCM_RATE_48M, 0),
139 RATETAB_ENT(BRCM_RATE_54M, 0),
142 #define wl_a_rates (__wl_rates + 4)
143 #define wl_a_rates_size 8
144 #define wl_g_rates (__wl_rates + 0)
145 #define wl_g_rates_size 12
147 static struct ieee80211_channel __wl_2ghz_channels[] = {
164 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
165 CHAN5G(34, 0), CHAN5G(36, 0),
166 CHAN5G(38, 0), CHAN5G(40, 0),
167 CHAN5G(42, 0), CHAN5G(44, 0),
168 CHAN5G(46, 0), CHAN5G(48, 0),
169 CHAN5G(52, 0), CHAN5G(56, 0),
170 CHAN5G(60, 0), CHAN5G(64, 0),
171 CHAN5G(100, 0), CHAN5G(104, 0),
172 CHAN5G(108, 0), CHAN5G(112, 0),
173 CHAN5G(116, 0), CHAN5G(120, 0),
174 CHAN5G(124, 0), CHAN5G(128, 0),
175 CHAN5G(132, 0), CHAN5G(136, 0),
176 CHAN5G(140, 0), CHAN5G(149, 0),
177 CHAN5G(153, 0), CHAN5G(157, 0),
178 CHAN5G(161, 0), CHAN5G(165, 0),
179 CHAN5G(184, 0), CHAN5G(188, 0),
180 CHAN5G(192, 0), CHAN5G(196, 0),
181 CHAN5G(200, 0), CHAN5G(204, 0),
182 CHAN5G(208, 0), CHAN5G(212, 0),
186 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
187 CHAN5G(32, 0), CHAN5G(34, 0),
188 CHAN5G(36, 0), CHAN5G(38, 0),
189 CHAN5G(40, 0), CHAN5G(42, 0),
190 CHAN5G(44, 0), CHAN5G(46, 0),
191 CHAN5G(48, 0), CHAN5G(50, 0),
192 CHAN5G(52, 0), CHAN5G(54, 0),
193 CHAN5G(56, 0), CHAN5G(58, 0),
194 CHAN5G(60, 0), CHAN5G(62, 0),
195 CHAN5G(64, 0), CHAN5G(66, 0),
196 CHAN5G(68, 0), CHAN5G(70, 0),
197 CHAN5G(72, 0), CHAN5G(74, 0),
198 CHAN5G(76, 0), CHAN5G(78, 0),
199 CHAN5G(80, 0), CHAN5G(82, 0),
200 CHAN5G(84, 0), CHAN5G(86, 0),
201 CHAN5G(88, 0), CHAN5G(90, 0),
202 CHAN5G(92, 0), CHAN5G(94, 0),
203 CHAN5G(96, 0), CHAN5G(98, 0),
204 CHAN5G(100, 0), CHAN5G(102, 0),
205 CHAN5G(104, 0), CHAN5G(106, 0),
206 CHAN5G(108, 0), CHAN5G(110, 0),
207 CHAN5G(112, 0), CHAN5G(114, 0),
208 CHAN5G(116, 0), CHAN5G(118, 0),
209 CHAN5G(120, 0), CHAN5G(122, 0),
210 CHAN5G(124, 0), CHAN5G(126, 0),
211 CHAN5G(128, 0), CHAN5G(130, 0),
212 CHAN5G(132, 0), CHAN5G(134, 0),
213 CHAN5G(136, 0), CHAN5G(138, 0),
214 CHAN5G(140, 0), CHAN5G(142, 0),
215 CHAN5G(144, 0), CHAN5G(145, 0),
216 CHAN5G(146, 0), CHAN5G(147, 0),
217 CHAN5G(148, 0), CHAN5G(149, 0),
218 CHAN5G(150, 0), CHAN5G(151, 0),
219 CHAN5G(152, 0), CHAN5G(153, 0),
220 CHAN5G(154, 0), CHAN5G(155, 0),
221 CHAN5G(156, 0), CHAN5G(157, 0),
222 CHAN5G(158, 0), CHAN5G(159, 0),
223 CHAN5G(160, 0), CHAN5G(161, 0),
224 CHAN5G(162, 0), CHAN5G(163, 0),
225 CHAN5G(164, 0), CHAN5G(165, 0),
226 CHAN5G(166, 0), CHAN5G(168, 0),
227 CHAN5G(170, 0), CHAN5G(172, 0),
228 CHAN5G(174, 0), CHAN5G(176, 0),
229 CHAN5G(178, 0), CHAN5G(180, 0),
230 CHAN5G(182, 0), CHAN5G(184, 0),
231 CHAN5G(186, 0), CHAN5G(188, 0),
232 CHAN5G(190, 0), CHAN5G(192, 0),
233 CHAN5G(194, 0), CHAN5G(196, 0),
234 CHAN5G(198, 0), CHAN5G(200, 0),
235 CHAN5G(202, 0), CHAN5G(204, 0),
236 CHAN5G(206, 0), CHAN5G(208, 0),
237 CHAN5G(210, 0), CHAN5G(212, 0),
238 CHAN5G(214, 0), CHAN5G(216, 0),
239 CHAN5G(218, 0), CHAN5G(220, 0),
240 CHAN5G(222, 0), CHAN5G(224, 0),
241 CHAN5G(226, 0), CHAN5G(228, 0),
244 static struct ieee80211_supported_band __wl_band_2ghz = {
245 .band = IEEE80211_BAND_2GHZ,
246 .channels = __wl_2ghz_channels,
247 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
248 .bitrates = wl_g_rates,
249 .n_bitrates = wl_g_rates_size,
252 static struct ieee80211_supported_band __wl_band_5ghz_a = {
253 .band = IEEE80211_BAND_5GHZ,
254 .channels = __wl_5ghz_a_channels,
255 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
256 .bitrates = wl_a_rates,
257 .n_bitrates = wl_a_rates_size,
260 static struct ieee80211_supported_band __wl_band_5ghz_n = {
261 .band = IEEE80211_BAND_5GHZ,
262 .channels = __wl_5ghz_n_channels,
263 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
264 .bitrates = wl_a_rates,
265 .n_bitrates = wl_a_rates_size,
268 static const u32 __wl_cipher_suites[] = {
269 WLAN_CIPHER_SUITE_WEP40,
270 WLAN_CIPHER_SUITE_WEP104,
271 WLAN_CIPHER_SUITE_TKIP,
272 WLAN_CIPHER_SUITE_CCMP,
273 WLAN_CIPHER_SUITE_AES_CMAC,
276 /* tag_ID/length/value_buffer tuple */
283 /* Vendor specific ie. id = 221, oui and type defines exact ie */
284 struct brcmf_vs_tlv {
291 struct parsed_vndr_ie_info {
293 u32 ie_len; /* total length including id & length field */
294 struct brcmf_vs_tlv vndrie;
297 struct parsed_vndr_ies {
299 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
302 /* Quarter dBm units to mW
303 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
304 * Table is offset so the last entry is largest mW value that fits in
308 #define QDBM_OFFSET 153 /* Offset for first entry */
309 #define QDBM_TABLE_LEN 40 /* Table size */
311 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
312 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
314 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
316 /* Largest mW value that will round down to the last table entry,
317 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
318 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
319 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
321 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
323 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
324 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
325 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
326 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
327 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
328 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
329 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
332 static u16 brcmf_qdbm_to_mw(u8 qdbm)
335 int idx = qdbm - QDBM_OFFSET;
337 if (idx >= QDBM_TABLE_LEN)
338 /* clamp to max u16 mW value */
341 /* scale the qdBm index up to the range of the table 0-40
342 * where an offset of 40 qdBm equals a factor of 10 mW.
349 /* return the mW value scaled down to the correct factor of 10,
350 * adding in factor/2 to get proper rounding.
352 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
355 static u8 brcmf_mw_to_qdbm(u16 mw)
362 /* handle boundary case */
366 offset = QDBM_OFFSET;
368 /* move mw into the range of the table */
369 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
374 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
375 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
376 nqdBm_to_mW_map[qdbm]) / 2;
377 if (mw_uint < boundary)
386 static u16 channel_to_chanspec(struct ieee80211_channel *ch)
390 chanspec = ieee80211_frequency_to_channel(ch->center_freq);
391 chanspec &= WL_CHANSPEC_CHAN_MASK;
393 if (ch->band == IEEE80211_BAND_2GHZ)
394 chanspec |= WL_CHANSPEC_BAND_2G;
396 chanspec |= WL_CHANSPEC_BAND_5G;
398 if (ch->flags & IEEE80211_CHAN_NO_HT40) {
399 chanspec |= WL_CHANSPEC_BW_20;
400 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
402 chanspec |= WL_CHANSPEC_BW_40;
403 if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS)
404 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
406 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
411 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
412 struct brcmf_wsec_key_le *key_le)
414 key_le->index = cpu_to_le32(key->index);
415 key_le->len = cpu_to_le32(key->len);
416 key_le->algo = cpu_to_le32(key->algo);
417 key_le->flags = cpu_to_le32(key->flags);
418 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
419 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
420 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
421 memcpy(key_le->data, key->data, sizeof(key->data));
422 memcpy(key_le->ea, key->ea, sizeof(key->ea));
426 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
429 struct brcmf_wsec_key_le key_le;
431 convert_key_from_CPU(key, &key_le);
433 brcmf_netdev_wait_pend8021x(ndev);
435 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
439 brcmf_err("wsec_key error (%d)\n", err);
444 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
445 enum nl80211_iftype type, u32 *flags,
446 struct vif_params *params)
448 struct brcmf_if *ifp = netdev_priv(ndev);
449 struct brcmf_cfg80211_vif *vif = ifp->vif;
454 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
457 case NL80211_IFTYPE_MONITOR:
458 case NL80211_IFTYPE_WDS:
459 brcmf_err("type (%d) : currently we do not support this type\n",
462 case NL80211_IFTYPE_ADHOC:
463 vif->mode = WL_MODE_IBSS;
466 case NL80211_IFTYPE_STATION:
467 vif->mode = WL_MODE_BSS;
470 case NL80211_IFTYPE_AP:
471 vif->mode = WL_MODE_AP;
480 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
481 brcmf_dbg(INFO, "IF Type = AP\n");
483 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
485 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
489 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
492 ndev->ieee80211_ptr->iftype = type;
495 brcmf_dbg(TRACE, "Exit\n");
500 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
502 struct brcmf_if *ifp = netdev_priv(ndev);
505 if (check_vif_up(ifp->vif)) {
506 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
508 brcmf_err("fail to set mpc\n");
511 brcmf_dbg(INFO, "MPC : %d\n", mpc);
515 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
516 struct cfg80211_scan_request *request)
524 struct brcmf_ssid_le ssid_le;
526 memset(params_le->bssid, 0xFF, ETH_ALEN);
527 params_le->bss_type = DOT11_BSSTYPE_ANY;
528 params_le->scan_type = 0;
529 params_le->channel_num = 0;
530 params_le->nprobes = cpu_to_le32(-1);
531 params_le->active_time = cpu_to_le32(-1);
532 params_le->passive_time = cpu_to_le32(-1);
533 params_le->home_time = cpu_to_le32(-1);
534 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
536 /* if request is null exit so it will be all channel broadcast scan */
540 n_ssids = request->n_ssids;
541 n_channels = request->n_channels;
542 /* Copy channel array if applicable */
543 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
545 if (n_channels > 0) {
546 for (i = 0; i < n_channels; i++) {
547 chanspec = channel_to_chanspec(request->channels[i]);
548 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
549 request->channels[i]->hw_value, chanspec);
550 params_le->channel_list[i] = cpu_to_le16(chanspec);
553 brcmf_dbg(SCAN, "Scanning all channels\n");
555 /* Copy ssid array if applicable */
556 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
558 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
559 n_channels * sizeof(u16);
560 offset = roundup(offset, sizeof(u32));
561 ptr = (char *)params_le + offset;
562 for (i = 0; i < n_ssids; i++) {
563 memset(&ssid_le, 0, sizeof(ssid_le));
565 cpu_to_le32(request->ssids[i].ssid_len);
566 memcpy(ssid_le.SSID, request->ssids[i].ssid,
567 request->ssids[i].ssid_len);
568 if (!ssid_le.SSID_len)
569 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
571 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
572 i, ssid_le.SSID, ssid_le.SSID_len);
573 memcpy(ptr, &ssid_le, sizeof(ssid_le));
574 ptr += sizeof(ssid_le);
577 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
578 if ((request->ssids) && request->ssids->ssid_len) {
579 brcmf_dbg(SCAN, "SSID %s len=%d\n",
580 params_le->ssid_le.SSID,
581 request->ssids->ssid_len);
582 params_le->ssid_le.SSID_len =
583 cpu_to_le32(request->ssids->ssid_len);
584 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
585 request->ssids->ssid_len);
588 /* Adding mask to channel numbers */
589 params_le->channel_num =
590 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
591 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
595 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
596 struct net_device *ndev,
597 bool aborted, bool fw_abort)
599 struct brcmf_scan_params_le params_le;
600 struct cfg80211_scan_request *scan_request;
603 brcmf_dbg(SCAN, "Enter\n");
605 /* clear scan request, because the FW abort can cause a second call */
606 /* to this functon and might cause a double cfg80211_scan_done */
607 scan_request = cfg->scan_request;
608 cfg->scan_request = NULL;
610 if (timer_pending(&cfg->escan_timeout))
611 del_timer_sync(&cfg->escan_timeout);
614 /* Do a scan abort to stop the driver's scan engine */
615 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
616 memset(¶ms_le, 0, sizeof(params_le));
617 memset(params_le.bssid, 0xFF, ETH_ALEN);
618 params_le.bss_type = DOT11_BSSTYPE_ANY;
619 params_le.scan_type = 0;
620 params_le.channel_num = cpu_to_le32(1);
621 params_le.nprobes = cpu_to_le32(1);
622 params_le.active_time = cpu_to_le32(-1);
623 params_le.passive_time = cpu_to_le32(-1);
624 params_le.home_time = cpu_to_le32(-1);
625 /* Scan is aborted by setting channel_list[0] to -1 */
626 params_le.channel_list[0] = cpu_to_le16(-1);
627 /* E-Scan (or anyother type) can be aborted by SCAN */
628 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
629 ¶ms_le, sizeof(params_le));
631 brcmf_err("Scan abort failed\n");
634 * e-scan can be initiated by scheduled scan
635 * which takes precedence.
637 if (cfg->sched_escan) {
638 brcmf_dbg(SCAN, "scheduled scan completed\n");
639 cfg->sched_escan = false;
641 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
642 brcmf_set_mpc(ndev, 1);
643 } else if (scan_request) {
644 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
645 aborted ? "Aborted" : "Done");
646 cfg80211_scan_done(scan_request, aborted);
647 brcmf_set_mpc(ndev, 1);
649 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
650 brcmf_err("Scan complete while device not scanning\n");
658 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
659 struct cfg80211_scan_request *request, u16 action)
661 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
662 offsetof(struct brcmf_escan_params_le, params_le);
663 struct brcmf_escan_params_le *params;
666 brcmf_dbg(SCAN, "E-SCAN START\n");
668 if (request != NULL) {
669 /* Allocate space for populating ssids in struct */
670 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
672 /* Allocate space for populating ssids in struct */
673 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
676 params = kzalloc(params_size, GFP_KERNEL);
681 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
682 brcmf_escan_prep(¶ms->params_le, request);
683 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
684 params->action = cpu_to_le16(action);
685 params->sync_id = cpu_to_le16(0x1234);
687 err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan",
688 params, params_size);
691 brcmf_dbg(INFO, "system busy : escan canceled\n");
693 brcmf_err("error (%d)\n", err);
702 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
703 struct net_device *ndev, struct cfg80211_scan_request *request)
707 struct brcmf_scan_results *results;
709 brcmf_dbg(SCAN, "Enter\n");
710 cfg->escan_info.ndev = ndev;
711 cfg->escan_info.wiphy = wiphy;
712 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
713 passive_scan = cfg->active_scan ? 0 : 1;
714 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
717 brcmf_err("error (%d)\n", err);
720 brcmf_set_mpc(ndev, 0);
721 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
722 results->version = 0;
724 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
726 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
728 brcmf_set_mpc(ndev, 1);
733 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
734 struct cfg80211_scan_request *request,
735 struct cfg80211_ssid *this_ssid)
737 struct brcmf_if *ifp = netdev_priv(ndev);
738 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
739 struct cfg80211_ssid *ssids;
740 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
747 brcmf_dbg(SCAN, "START ESCAN\n");
749 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
750 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
753 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
754 brcmf_err("Scanning being aborted: status (%lu)\n",
758 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
759 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
763 /* Arm scan timeout timer */
764 mod_timer(&cfg->escan_timeout, jiffies +
765 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
770 ssids = request->ssids;
774 /* we don't do escan in ibss */
778 cfg->scan_request = request;
779 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
781 err = brcmf_do_escan(cfg, wiphy, ndev, request);
785 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
786 ssids->ssid, ssids->ssid_len);
787 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
788 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
789 sr->ssid_le.SSID_len = cpu_to_le32(0);
792 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
793 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
796 brcmf_dbg(SCAN, "Broadcast scan\n");
798 passive_scan = cfg->active_scan ? 0 : 1;
799 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
802 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
805 brcmf_set_mpc(ndev, 0);
806 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
807 &sr->ssid_le, sizeof(sr->ssid_le));
810 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
813 brcmf_err("WLC_SCAN error (%d)\n", err);
815 brcmf_set_mpc(ndev, 1);
823 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
824 if (timer_pending(&cfg->escan_timeout))
825 del_timer_sync(&cfg->escan_timeout);
826 cfg->scan_request = NULL;
831 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
833 struct net_device *ndev = request->wdev->netdev;
836 brcmf_dbg(TRACE, "Enter\n");
838 if (!check_vif_up(container_of(request->wdev,
839 struct brcmf_cfg80211_vif, wdev)))
842 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
845 brcmf_err("scan error (%d)\n", err);
847 brcmf_dbg(TRACE, "Exit\n");
851 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
855 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
858 brcmf_err("Error (%d)\n", err);
863 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
867 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
870 brcmf_err("Error (%d)\n", err);
875 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
878 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
880 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
882 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
888 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
890 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
891 struct net_device *ndev = cfg_to_ndev(cfg);
892 struct brcmf_if *ifp = netdev_priv(ndev);
895 brcmf_dbg(TRACE, "Enter\n");
896 if (!check_vif_up(ifp->vif))
899 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
900 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
901 cfg->conf->rts_threshold = wiphy->rts_threshold;
902 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
906 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
907 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
908 cfg->conf->frag_threshold = wiphy->frag_threshold;
909 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
913 if (changed & WIPHY_PARAM_RETRY_LONG
914 && (cfg->conf->retry_long != wiphy->retry_long)) {
915 cfg->conf->retry_long = wiphy->retry_long;
916 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
920 if (changed & WIPHY_PARAM_RETRY_SHORT
921 && (cfg->conf->retry_short != wiphy->retry_short)) {
922 cfg->conf->retry_short = wiphy->retry_short;
923 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
929 brcmf_dbg(TRACE, "Exit\n");
933 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
935 memset(prof, 0, sizeof(*prof));
938 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
939 size_t *join_params_size)
944 if (ch <= CH_MAX_2G_CHANNEL)
945 chanspec |= WL_CHANSPEC_BAND_2G;
947 chanspec |= WL_CHANSPEC_BAND_5G;
949 chanspec |= WL_CHANSPEC_BW_20;
950 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
952 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
955 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
956 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
957 join_params->params_le.chanspec_num = cpu_to_le32(1);
959 brcmf_dbg(CONN, "channel %d, chanspec %#X\n", ch, chanspec);
963 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
967 brcmf_dbg(TRACE, "Enter\n");
969 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
970 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
971 err = brcmf_fil_cmd_data_set(vif->ifp,
972 BRCMF_C_DISASSOC, NULL, 0);
974 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
975 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
977 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
978 brcmf_dbg(TRACE, "Exit\n");
982 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
983 struct cfg80211_ibss_params *params)
985 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
986 struct brcmf_if *ifp = netdev_priv(ndev);
987 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
988 struct brcmf_join_params join_params;
989 size_t join_params_size = 0;
994 brcmf_dbg(TRACE, "Enter\n");
995 if (!check_vif_up(ifp->vif))
999 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1001 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1005 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1008 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1010 brcmf_dbg(CONN, "No BSSID specified\n");
1012 if (params->chandef.chan)
1013 brcmf_dbg(CONN, "channel: %d\n",
1014 params->chandef.chan->center_freq);
1016 brcmf_dbg(CONN, "no channel specified\n");
1018 if (params->channel_fixed)
1019 brcmf_dbg(CONN, "fixed channel required\n");
1021 brcmf_dbg(CONN, "no fixed channel required\n");
1023 if (params->ie && params->ie_len)
1024 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1026 brcmf_dbg(CONN, "no ie specified\n");
1028 if (params->beacon_interval)
1029 brcmf_dbg(CONN, "beacon interval: %d\n",
1030 params->beacon_interval);
1032 brcmf_dbg(CONN, "no beacon interval specified\n");
1034 if (params->basic_rates)
1035 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1037 brcmf_dbg(CONN, "no basic rates specified\n");
1039 if (params->privacy)
1040 brcmf_dbg(CONN, "privacy required\n");
1042 brcmf_dbg(CONN, "no privacy required\n");
1044 /* Configure Privacy for starter */
1045 if (params->privacy)
1046 wsec |= WEP_ENABLED;
1048 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1050 brcmf_err("wsec failed (%d)\n", err);
1054 /* Configure Beacon Interval for starter */
1055 if (params->beacon_interval)
1056 bcnprd = params->beacon_interval;
1060 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1062 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1066 /* Configure required join parameter */
1067 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1070 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1071 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1072 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1073 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1074 join_params_size = sizeof(join_params.ssid_le);
1077 if (params->bssid) {
1078 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1079 join_params_size = sizeof(join_params.ssid_le) +
1080 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1081 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1083 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1084 memset(profile->bssid, 0, ETH_ALEN);
1088 if (params->chandef.chan) {
1092 ieee80211_frequency_to_channel(
1093 params->chandef.chan->center_freq);
1094 if (params->channel_fixed) {
1095 /* adding chanspec */
1096 brcmf_ch_to_chanspec(cfg->channel,
1097 &join_params, &join_params_size);
1100 /* set channel for starter */
1101 target_channel = cfg->channel;
1102 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1105 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1111 cfg->ibss_starter = false;
1114 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1115 &join_params, join_params_size);
1117 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1123 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1124 brcmf_dbg(TRACE, "Exit\n");
1129 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1131 struct brcmf_if *ifp = netdev_priv(ndev);
1134 brcmf_dbg(TRACE, "Enter\n");
1135 if (!check_vif_up(ifp->vif))
1138 brcmf_link_down(ifp->vif);
1140 brcmf_dbg(TRACE, "Exit\n");
1145 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1146 struct cfg80211_connect_params *sme)
1148 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1149 struct brcmf_cfg80211_security *sec;
1153 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1154 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1155 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1156 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1158 val = WPA_AUTH_DISABLED;
1159 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1160 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val);
1162 brcmf_err("set wpa_auth failed (%d)\n", err);
1165 sec = &profile->sec;
1166 sec->wpa_versions = sme->crypto.wpa_versions;
1170 static s32 brcmf_set_auth_type(struct net_device *ndev,
1171 struct cfg80211_connect_params *sme)
1173 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1174 struct brcmf_cfg80211_security *sec;
1178 switch (sme->auth_type) {
1179 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1181 brcmf_dbg(CONN, "open system\n");
1183 case NL80211_AUTHTYPE_SHARED_KEY:
1185 brcmf_dbg(CONN, "shared key\n");
1187 case NL80211_AUTHTYPE_AUTOMATIC:
1189 brcmf_dbg(CONN, "automatic\n");
1191 case NL80211_AUTHTYPE_NETWORK_EAP:
1192 brcmf_dbg(CONN, "network eap\n");
1195 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1199 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val);
1201 brcmf_err("set auth failed (%d)\n", err);
1204 sec = &profile->sec;
1205 sec->auth_type = sme->auth_type;
1210 brcmf_set_set_cipher(struct net_device *ndev,
1211 struct cfg80211_connect_params *sme)
1213 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1214 struct brcmf_cfg80211_security *sec;
1219 if (sme->crypto.n_ciphers_pairwise) {
1220 switch (sme->crypto.ciphers_pairwise[0]) {
1221 case WLAN_CIPHER_SUITE_WEP40:
1222 case WLAN_CIPHER_SUITE_WEP104:
1225 case WLAN_CIPHER_SUITE_TKIP:
1226 pval = TKIP_ENABLED;
1228 case WLAN_CIPHER_SUITE_CCMP:
1231 case WLAN_CIPHER_SUITE_AES_CMAC:
1235 brcmf_err("invalid cipher pairwise (%d)\n",
1236 sme->crypto.ciphers_pairwise[0]);
1240 if (sme->crypto.cipher_group) {
1241 switch (sme->crypto.cipher_group) {
1242 case WLAN_CIPHER_SUITE_WEP40:
1243 case WLAN_CIPHER_SUITE_WEP104:
1246 case WLAN_CIPHER_SUITE_TKIP:
1247 gval = TKIP_ENABLED;
1249 case WLAN_CIPHER_SUITE_CCMP:
1252 case WLAN_CIPHER_SUITE_AES_CMAC:
1256 brcmf_err("invalid cipher group (%d)\n",
1257 sme->crypto.cipher_group);
1262 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1263 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval);
1265 brcmf_err("error (%d)\n", err);
1269 sec = &profile->sec;
1270 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1271 sec->cipher_group = sme->crypto.cipher_group;
1277 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1279 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1280 struct brcmf_cfg80211_security *sec;
1284 if (sme->crypto.n_akm_suites) {
1285 err = brcmf_fil_iovar_int_get(netdev_priv(ndev),
1288 brcmf_err("could not get wpa_auth (%d)\n", err);
1291 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1292 switch (sme->crypto.akm_suites[0]) {
1293 case WLAN_AKM_SUITE_8021X:
1294 val = WPA_AUTH_UNSPECIFIED;
1296 case WLAN_AKM_SUITE_PSK:
1300 brcmf_err("invalid cipher group (%d)\n",
1301 sme->crypto.cipher_group);
1304 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1305 switch (sme->crypto.akm_suites[0]) {
1306 case WLAN_AKM_SUITE_8021X:
1307 val = WPA2_AUTH_UNSPECIFIED;
1309 case WLAN_AKM_SUITE_PSK:
1310 val = WPA2_AUTH_PSK;
1313 brcmf_err("invalid cipher group (%d)\n",
1314 sme->crypto.cipher_group);
1319 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1320 err = brcmf_fil_iovar_int_set(netdev_priv(ndev),
1323 brcmf_err("could not set wpa_auth (%d)\n", err);
1327 sec = &profile->sec;
1328 sec->wpa_auth = sme->crypto.akm_suites[0];
1334 brcmf_set_sharedkey(struct net_device *ndev,
1335 struct cfg80211_connect_params *sme)
1337 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1338 struct brcmf_cfg80211_security *sec;
1339 struct brcmf_wsec_key key;
1343 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1345 if (sme->key_len == 0)
1348 sec = &profile->sec;
1349 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1350 sec->wpa_versions, sec->cipher_pairwise);
1352 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1355 if (!(sec->cipher_pairwise &
1356 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1359 memset(&key, 0, sizeof(key));
1360 key.len = (u32) sme->key_len;
1361 key.index = (u32) sme->key_idx;
1362 if (key.len > sizeof(key.data)) {
1363 brcmf_err("Too long key length (%u)\n", key.len);
1366 memcpy(key.data, sme->key, key.len);
1367 key.flags = BRCMF_PRIMARY_KEY;
1368 switch (sec->cipher_pairwise) {
1369 case WLAN_CIPHER_SUITE_WEP40:
1370 key.algo = CRYPTO_ALGO_WEP1;
1372 case WLAN_CIPHER_SUITE_WEP104:
1373 key.algo = CRYPTO_ALGO_WEP128;
1376 brcmf_err("Invalid algorithm (%d)\n",
1377 sme->crypto.ciphers_pairwise[0]);
1380 /* Set the new key/index */
1381 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1382 key.len, key.index, key.algo);
1383 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1384 err = send_key_to_dongle(ndev, &key);
1388 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1389 brcmf_dbg(CONN, "set auth_type to shared key\n");
1390 val = WL_AUTH_SHARED_KEY; /* shared key */
1391 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1393 brcmf_err("set auth failed (%d)\n", err);
1399 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1400 struct cfg80211_connect_params *sme)
1402 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1403 struct brcmf_if *ifp = netdev_priv(ndev);
1404 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1405 struct ieee80211_channel *chan = sme->channel;
1406 struct brcmf_join_params join_params;
1407 size_t join_params_size;
1408 struct brcmf_ssid ssid;
1412 brcmf_dbg(TRACE, "Enter\n");
1413 if (!check_vif_up(ifp->vif))
1417 brcmf_err("Invalid ssid\n");
1421 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1425 ieee80211_frequency_to_channel(chan->center_freq);
1426 brcmf_dbg(CONN, "channel (%d), center_req (%d)\n",
1427 cfg->channel, chan->center_freq);
1431 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1433 err = brcmf_set_wpa_version(ndev, sme);
1435 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1439 err = brcmf_set_auth_type(ndev, sme);
1441 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1445 err = brcmf_set_set_cipher(ndev, sme);
1447 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1451 err = brcmf_set_key_mgmt(ndev, sme);
1453 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1457 err = brcmf_set_sharedkey(ndev, sme);
1459 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1463 memset(&join_params, 0, sizeof(join_params));
1464 join_params_size = sizeof(join_params.ssid_le);
1466 profile->ssid.SSID_len = min_t(u32,
1467 sizeof(ssid.SSID), (u32)sme->ssid_len);
1468 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1469 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1470 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1472 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1474 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1475 brcmf_dbg(CONN, "ssid \"%s\", len (%d)\n",
1476 ssid.SSID, ssid.SSID_len);
1478 brcmf_ch_to_chanspec(cfg->channel,
1479 &join_params, &join_params_size);
1480 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1481 &join_params, join_params_size);
1483 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1487 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1488 brcmf_dbg(TRACE, "Exit\n");
1493 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1496 struct brcmf_if *ifp = netdev_priv(ndev);
1497 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1498 struct brcmf_scb_val_le scbval;
1501 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1502 if (!check_vif_up(ifp->vif))
1505 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1507 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1508 scbval.val = cpu_to_le32(reason_code);
1509 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1510 &scbval, sizeof(scbval));
1512 brcmf_err("error (%d)\n", err);
1514 brcmf_dbg(TRACE, "Exit\n");
1519 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1520 enum nl80211_tx_power_setting type, s32 mbm)
1523 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1524 struct net_device *ndev = cfg_to_ndev(cfg);
1525 struct brcmf_if *ifp = netdev_priv(ndev);
1529 s32 dbm = MBM_TO_DBM(mbm);
1531 brcmf_dbg(TRACE, "Enter\n");
1532 if (!check_vif_up(ifp->vif))
1536 case NL80211_TX_POWER_AUTOMATIC:
1538 case NL80211_TX_POWER_LIMITED:
1539 case NL80211_TX_POWER_FIXED:
1541 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1547 /* Make sure radio is off or on as far as software is concerned */
1548 disable = WL_RADIO_SW_DISABLE << 16;
1549 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1551 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1556 txpwrmw = (u16) dbm;
1557 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1558 (s32)brcmf_mw_to_qdbm(txpwrmw));
1560 brcmf_err("qtxpower error (%d)\n", err);
1561 cfg->conf->tx_power = dbm;
1564 brcmf_dbg(TRACE, "Exit\n");
1568 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1569 struct wireless_dev *wdev,
1572 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1573 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1578 brcmf_dbg(TRACE, "Enter\n");
1579 if (!check_vif_up(ifp->vif))
1582 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1584 brcmf_err("error (%d)\n", err);
1588 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1589 *dbm = (s32) brcmf_qdbm_to_mw(result);
1592 brcmf_dbg(TRACE, "Exit\n");
1597 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1598 u8 key_idx, bool unicast, bool multicast)
1600 struct brcmf_if *ifp = netdev_priv(ndev);
1605 brcmf_dbg(TRACE, "Enter\n");
1606 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1607 if (!check_vif_up(ifp->vif))
1610 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1612 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1616 if (wsec & WEP_ENABLED) {
1617 /* Just select a new current key */
1619 err = brcmf_fil_cmd_int_set(ifp,
1620 BRCMF_C_SET_KEY_PRIMARY, index);
1622 brcmf_err("error (%d)\n", err);
1625 brcmf_dbg(TRACE, "Exit\n");
1630 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1631 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1633 struct brcmf_wsec_key key;
1636 memset(&key, 0, sizeof(key));
1637 key.index = (u32) key_idx;
1638 /* Instead of bcast for ea address for default wep keys,
1639 driver needs it to be Null */
1640 if (!is_multicast_ether_addr(mac_addr))
1641 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1642 key.len = (u32) params->key_len;
1643 /* check for key index change */
1646 err = send_key_to_dongle(ndev, &key);
1648 brcmf_err("key delete error (%d)\n", err);
1650 if (key.len > sizeof(key.data)) {
1651 brcmf_err("Invalid key length (%d)\n", key.len);
1655 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1656 memcpy(key.data, params->key, key.len);
1658 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1660 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1661 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1662 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1665 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1666 if (params->seq && params->seq_len == 6) {
1669 ivptr = (u8 *) params->seq;
1670 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1671 (ivptr[3] << 8) | ivptr[2];
1672 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1673 key.iv_initialized = true;
1676 switch (params->cipher) {
1677 case WLAN_CIPHER_SUITE_WEP40:
1678 key.algo = CRYPTO_ALGO_WEP1;
1679 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1681 case WLAN_CIPHER_SUITE_WEP104:
1682 key.algo = CRYPTO_ALGO_WEP128;
1683 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1685 case WLAN_CIPHER_SUITE_TKIP:
1686 key.algo = CRYPTO_ALGO_TKIP;
1687 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1689 case WLAN_CIPHER_SUITE_AES_CMAC:
1690 key.algo = CRYPTO_ALGO_AES_CCM;
1691 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1693 case WLAN_CIPHER_SUITE_CCMP:
1694 key.algo = CRYPTO_ALGO_AES_CCM;
1695 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1698 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1701 err = send_key_to_dongle(ndev, &key);
1703 brcmf_err("wsec_key error (%d)\n", err);
1709 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1710 u8 key_idx, bool pairwise, const u8 *mac_addr,
1711 struct key_params *params)
1713 struct brcmf_if *ifp = netdev_priv(ndev);
1714 struct brcmf_wsec_key key;
1720 brcmf_dbg(TRACE, "Enter\n");
1721 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1722 if (!check_vif_up(ifp->vif))
1726 brcmf_dbg(TRACE, "Exit");
1727 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1729 memset(&key, 0, sizeof(key));
1731 key.len = (u32) params->key_len;
1732 key.index = (u32) key_idx;
1734 if (key.len > sizeof(key.data)) {
1735 brcmf_err("Too long key length (%u)\n", key.len);
1739 memcpy(key.data, params->key, key.len);
1741 key.flags = BRCMF_PRIMARY_KEY;
1742 switch (params->cipher) {
1743 case WLAN_CIPHER_SUITE_WEP40:
1744 key.algo = CRYPTO_ALGO_WEP1;
1746 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1748 case WLAN_CIPHER_SUITE_WEP104:
1749 key.algo = CRYPTO_ALGO_WEP128;
1751 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1753 case WLAN_CIPHER_SUITE_TKIP:
1754 if (ifp->vif->mode != WL_MODE_AP) {
1755 brcmf_dbg(CONN, "Swapping key\n");
1756 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1757 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1758 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1760 key.algo = CRYPTO_ALGO_TKIP;
1762 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1764 case WLAN_CIPHER_SUITE_AES_CMAC:
1765 key.algo = CRYPTO_ALGO_AES_CCM;
1767 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1769 case WLAN_CIPHER_SUITE_CCMP:
1770 key.algo = CRYPTO_ALGO_AES_CCM;
1772 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1775 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1780 err = send_key_to_dongle(ndev, &key);
1784 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1786 brcmf_err("get wsec error (%d)\n", err);
1790 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1792 brcmf_err("set wsec error (%d)\n", err);
1797 brcmf_dbg(TRACE, "Exit\n");
1802 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1803 u8 key_idx, bool pairwise, const u8 *mac_addr)
1805 struct brcmf_if *ifp = netdev_priv(ndev);
1806 struct brcmf_wsec_key key;
1809 brcmf_dbg(TRACE, "Enter\n");
1810 if (!check_vif_up(ifp->vif))
1813 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
1814 /* we ignore this key index in this case */
1815 brcmf_err("invalid key index (%d)\n", key_idx);
1819 memset(&key, 0, sizeof(key));
1821 key.index = (u32) key_idx;
1822 key.flags = BRCMF_PRIMARY_KEY;
1823 key.algo = CRYPTO_ALGO_OFF;
1825 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1827 /* Set the new key/index */
1828 err = send_key_to_dongle(ndev, &key);
1830 brcmf_dbg(TRACE, "Exit\n");
1835 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1836 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1837 void (*callback) (void *cookie, struct key_params * params))
1839 struct key_params params;
1840 struct brcmf_if *ifp = netdev_priv(ndev);
1841 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1842 struct brcmf_cfg80211_security *sec;
1846 brcmf_dbg(TRACE, "Enter\n");
1847 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1848 if (!check_vif_up(ifp->vif))
1851 memset(¶ms, 0, sizeof(params));
1853 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1855 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1856 /* Ignore this error, may happen during DISASSOC */
1860 switch (wsec & ~SES_OW_ENABLED) {
1862 sec = &profile->sec;
1863 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1864 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1865 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1866 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1867 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1868 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1872 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1873 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1876 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1877 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1880 brcmf_err("Invalid algo (0x%x)\n", wsec);
1884 callback(cookie, ¶ms);
1887 brcmf_dbg(TRACE, "Exit\n");
1892 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1893 struct net_device *ndev, u8 key_idx)
1895 brcmf_dbg(INFO, "Not supported\n");
1901 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1902 u8 *mac, struct station_info *sinfo)
1904 struct brcmf_if *ifp = netdev_priv(ndev);
1905 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1906 struct brcmf_scb_val_le scb_val;
1910 u8 *bssid = profile->bssid;
1911 struct brcmf_sta_info_le sta_info_le;
1913 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
1914 if (!check_vif_up(ifp->vif))
1917 if (ifp->vif->mode == WL_MODE_AP) {
1918 memcpy(&sta_info_le, mac, ETH_ALEN);
1919 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
1921 sizeof(sta_info_le));
1923 brcmf_err("GET STA INFO failed, %d\n", err);
1926 sinfo->filled = STATION_INFO_INACTIVE_TIME;
1927 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
1928 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
1929 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
1930 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
1932 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
1933 sinfo->inactive_time, sinfo->connected_time);
1934 } else if (ifp->vif->mode == WL_MODE_BSS) {
1935 if (memcmp(mac, bssid, ETH_ALEN)) {
1936 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1941 /* Report the current tx rate */
1942 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
1944 brcmf_err("Could not get rate (%d)\n", err);
1947 sinfo->filled |= STATION_INFO_TX_BITRATE;
1948 sinfo->txrate.legacy = rate * 5;
1949 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
1952 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
1953 &ifp->vif->sme_state)) {
1954 memset(&scb_val, 0, sizeof(scb_val));
1955 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
1956 &scb_val, sizeof(scb_val));
1958 brcmf_err("Could not get rssi (%d)\n", err);
1961 rssi = le32_to_cpu(scb_val.val);
1962 sinfo->filled |= STATION_INFO_SIGNAL;
1963 sinfo->signal = rssi;
1964 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
1970 brcmf_dbg(TRACE, "Exit\n");
1975 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1976 bool enabled, s32 timeout)
1980 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1981 struct brcmf_if *ifp = netdev_priv(ndev);
1983 brcmf_dbg(TRACE, "Enter\n");
1986 * Powersave enable/disable request is coming from the
1987 * cfg80211 even before the interface is up. In that
1988 * scenario, driver will be storing the power save
1989 * preference in cfg struct to apply this to
1990 * FW later while initializing the dongle
1992 cfg->pwr_save = enabled;
1993 if (!check_vif_up(ifp->vif)) {
1995 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
1999 pm = enabled ? PM_FAST : PM_OFF;
2000 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2002 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2005 brcmf_err("net_device is not ready yet\n");
2007 brcmf_err("error (%d)\n", err);
2010 brcmf_dbg(TRACE, "Exit\n");
2015 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2017 const struct cfg80211_bitrate_mask *mask)
2019 struct brcmf_if *ifp = netdev_priv(ndev);
2020 struct brcm_rateset_le rateset_le;
2028 brcmf_dbg(TRACE, "Enter\n");
2029 if (!check_vif_up(ifp->vif))
2032 /* addr param is always NULL. ignore it */
2033 /* Get current rateset */
2034 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET,
2035 &rateset_le, sizeof(rateset_le));
2037 brcmf_err("could not get current rateset (%d)\n", err);
2041 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2043 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2046 val = wl_g_rates[legacy - 1].bitrate * 100000;
2048 if (val < le32_to_cpu(rateset_le.count))
2049 /* Select rate by rateset index */
2050 rate = rateset_le.rates[val] & 0x7f;
2052 /* Specified rate in bps */
2053 rate = val / 500000;
2055 brcmf_dbg(CONN, "rate %d mbps\n", rate / 2);
2059 * Set rate override,
2060 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2062 err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate);
2063 err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate);
2064 if (err_bg && err_a) {
2065 brcmf_err("could not set fixed rate (%d) (%d)\n", err_bg,
2067 err = err_bg | err_a;
2071 brcmf_dbg(TRACE, "Exit\n");
2075 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2076 struct brcmf_bss_info_le *bi)
2078 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2079 struct ieee80211_channel *notify_channel;
2080 struct cfg80211_bss *bss;
2081 struct ieee80211_supported_band *band;
2085 u16 notify_capability;
2086 u16 notify_interval;
2088 size_t notify_ielen;
2091 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2092 brcmf_err("Bss info is larger than buffer. Discarding\n");
2096 channel = bi->ctl_ch ? bi->ctl_ch :
2097 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2099 if (channel <= CH_MAX_2G_CHANNEL)
2100 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2102 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2104 freq = ieee80211_channel_to_frequency(channel, band->band);
2105 notify_channel = ieee80211_get_channel(wiphy, freq);
2107 notify_capability = le16_to_cpu(bi->capability);
2108 notify_interval = le16_to_cpu(bi->beacon_period);
2109 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2110 notify_ielen = le32_to_cpu(bi->ie_length);
2111 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2113 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2114 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2115 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2116 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2117 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2119 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2120 0, notify_capability, notify_interval, notify_ie,
2121 notify_ielen, notify_signal, GFP_KERNEL);
2126 cfg80211_put_bss(bss);
2131 static struct brcmf_bss_info_le *
2132 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2135 return list->bss_info_le;
2136 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2137 le32_to_cpu(bss->length));
2140 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2142 struct brcmf_scan_results *bss_list;
2143 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2147 bss_list = cfg->bss_list;
2148 if (bss_list->count != 0 &&
2149 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2150 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2154 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2155 for (i = 0; i < bss_list->count; i++) {
2156 bi = next_bss_le(bss_list, bi);
2157 err = brcmf_inform_single_bss(cfg, bi);
2164 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2165 struct net_device *ndev, const u8 *bssid)
2167 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2168 struct ieee80211_channel *notify_channel;
2169 struct brcmf_bss_info_le *bi = NULL;
2170 struct ieee80211_supported_band *band;
2171 struct cfg80211_bss *bss;
2176 u16 notify_capability;
2177 u16 notify_interval;
2179 size_t notify_ielen;
2182 brcmf_dbg(TRACE, "Enter\n");
2184 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2190 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2192 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2193 buf, WL_BSS_INFO_MAX);
2195 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2199 bi = (struct brcmf_bss_info_le *)(buf + 4);
2201 channel = bi->ctl_ch ? bi->ctl_ch :
2202 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2204 if (channel <= CH_MAX_2G_CHANNEL)
2205 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2207 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2209 freq = ieee80211_channel_to_frequency(channel, band->band);
2210 notify_channel = ieee80211_get_channel(wiphy, freq);
2212 notify_capability = le16_to_cpu(bi->capability);
2213 notify_interval = le16_to_cpu(bi->beacon_period);
2214 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2215 notify_ielen = le32_to_cpu(bi->ie_length);
2216 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2218 brcmf_dbg(CONN, "channel: %d(%d)\n", channel, freq);
2219 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2220 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2221 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2223 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2224 0, notify_capability, notify_interval,
2225 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2232 cfg80211_put_bss(bss);
2238 brcmf_dbg(TRACE, "Exit\n");
2243 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2245 return vif->mode == WL_MODE_IBSS;
2249 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2250 * triples, returning a pointer to the substring whose first element
2253 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2255 struct brcmf_tlv *elt;
2258 elt = (struct brcmf_tlv *) buf;
2261 /* find tagged parameter */
2262 while (totlen >= TLV_HDR_LEN) {
2265 /* validate remaining totlen */
2266 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2269 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2270 totlen -= (len + TLV_HDR_LEN);
2276 /* Is any of the tlvs the expected entry? If
2277 * not update the tlvs buffer pointer/length.
2280 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2281 u8 *oui, u32 oui_len, u8 type)
2283 /* If the contents match the OUI and the type */
2284 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2285 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2286 type == ie[TLV_BODY_OFF + oui_len]) {
2292 /* point to the next ie */
2293 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2294 /* calculate the length of the rest of the buffer */
2295 *tlvs_len -= (int)(ie - *tlvs);
2296 /* update the pointer to the start of the buffer */
2302 static struct brcmf_vs_tlv *
2303 brcmf_find_wpaie(u8 *parse, u32 len)
2305 struct brcmf_tlv *ie;
2307 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
2308 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2309 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2310 return (struct brcmf_vs_tlv *)ie;
2315 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2317 struct net_device *ndev = cfg_to_ndev(cfg);
2318 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2319 struct brcmf_if *ifp = netdev_priv(ndev);
2320 struct brcmf_bss_info_le *bi;
2321 struct brcmf_ssid *ssid;
2322 struct brcmf_tlv *tim;
2323 u16 beacon_interval;
2329 brcmf_dbg(TRACE, "Enter\n");
2330 if (brcmf_is_ibssmode(ifp->vif))
2333 ssid = &profile->ssid;
2335 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2336 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2337 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2339 brcmf_err("Could not get bss info %d\n", err);
2340 goto update_bss_info_out;
2343 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2344 err = brcmf_inform_single_bss(cfg, bi);
2346 goto update_bss_info_out;
2348 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2349 ie_len = le32_to_cpu(bi->ie_length);
2350 beacon_interval = le16_to_cpu(bi->beacon_period);
2352 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2354 dtim_period = tim->data[1];
2357 * active scan was done so we could not get dtim
2358 * information out of probe response.
2359 * so we speficially query dtim information to dongle.
2362 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2364 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2365 goto update_bss_info_out;
2367 dtim_period = (u8)var;
2370 update_bss_info_out:
2371 brcmf_dbg(TRACE, "Exit");
2375 static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2377 struct escan_info *escan = &cfg->escan_info;
2379 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2380 if (cfg->scan_request) {
2381 escan->escan_state = WL_ESCAN_STATE_IDLE;
2382 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2384 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2385 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2388 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2390 struct brcmf_cfg80211_info *cfg =
2391 container_of(work, struct brcmf_cfg80211_info,
2392 escan_timeout_work);
2394 brcmf_notify_escan_complete(cfg,
2395 cfg->escan_info.ndev, true, true);
2398 static void brcmf_escan_timeout(unsigned long data)
2400 struct brcmf_cfg80211_info *cfg =
2401 (struct brcmf_cfg80211_info *)data;
2403 if (cfg->scan_request) {
2404 brcmf_err("timer expired\n");
2405 schedule_work(&cfg->escan_timeout_work);
2410 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2411 struct brcmf_bss_info_le *bss_info_le)
2413 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2414 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2415 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2416 bss_info_le->SSID_len == bss->SSID_len &&
2417 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2418 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2419 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2420 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2421 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2423 /* preserve max RSSI if the measurements are
2424 * both on-channel or both off-channel
2426 if (bss_info_rssi > bss_rssi)
2427 bss->RSSI = bss_info_le->RSSI;
2428 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2429 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2430 /* preserve the on-channel rssi measurement
2431 * if the new measurement is off channel
2433 bss->RSSI = bss_info_le->RSSI;
2434 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2442 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2443 const struct brcmf_event_msg *e, void *data)
2445 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2446 struct net_device *ndev = ifp->ndev;
2449 struct brcmf_escan_result_le *escan_result_le;
2450 struct brcmf_bss_info_le *bss_info_le;
2451 struct brcmf_bss_info_le *bss = NULL;
2453 struct brcmf_scan_results *list;
2459 if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2460 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev,
2461 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2465 if (status == BRCMF_E_STATUS_PARTIAL) {
2466 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2467 escan_result_le = (struct brcmf_escan_result_le *) data;
2468 if (!escan_result_le) {
2469 brcmf_err("Invalid escan result (NULL pointer)\n");
2472 if (!cfg->scan_request) {
2473 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2477 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2478 brcmf_err("Invalid bss_count %d: ignoring\n",
2479 escan_result_le->bss_count);
2482 bss_info_le = &escan_result_le->bss_info_le;
2484 bi_length = le32_to_cpu(bss_info_le->length);
2485 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2486 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2487 brcmf_err("Invalid bss_info length %d: ignoring\n",
2492 if (!(cfg_to_wiphy(cfg)->interface_modes &
2493 BIT(NL80211_IFTYPE_ADHOC))) {
2494 if (le16_to_cpu(bss_info_le->capability) &
2495 WLAN_CAPABILITY_IBSS) {
2496 brcmf_err("Ignoring IBSS result\n");
2501 list = (struct brcmf_scan_results *)
2502 cfg->escan_info.escan_buf;
2503 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2504 brcmf_err("Buffer is too small: ignoring\n");
2508 for (i = 0; i < list->count; i++) {
2509 bss = bss ? (struct brcmf_bss_info_le *)
2510 ((unsigned char *)bss +
2511 le32_to_cpu(bss->length)) : list->bss_info_le;
2512 if (brcmf_compare_update_same_bss(bss, bss_info_le))
2515 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2516 bss_info_le, bi_length);
2517 list->version = le32_to_cpu(bss_info_le->version);
2518 list->buflen += bi_length;
2521 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2522 if (cfg->scan_request) {
2523 cfg->bss_list = (struct brcmf_scan_results *)
2524 cfg->escan_info.escan_buf;
2525 brcmf_inform_bss(cfg);
2526 aborted = status != BRCMF_E_STATUS_SUCCESS;
2527 brcmf_notify_escan_complete(cfg, ndev, aborted,
2530 brcmf_err("Unexpected scan result 0x%x\n", status);
2536 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2538 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2539 brcmf_cfg80211_escan_handler);
2540 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2541 /* Init scan_timeout timer */
2542 init_timer(&cfg->escan_timeout);
2543 cfg->escan_timeout.data = (unsigned long) cfg;
2544 cfg->escan_timeout.function = brcmf_escan_timeout;
2545 INIT_WORK(&cfg->escan_timeout_work,
2546 brcmf_cfg80211_escan_timeout_worker);
2549 static __always_inline void brcmf_delay(u32 ms)
2551 if (ms < 1000 / HZ) {
2559 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2561 brcmf_dbg(TRACE, "Enter\n");
2566 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2567 struct cfg80211_wowlan *wow)
2569 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2570 struct net_device *ndev = cfg_to_ndev(cfg);
2571 struct brcmf_cfg80211_vif *vif;
2573 brcmf_dbg(TRACE, "Enter\n");
2576 * if the primary net_device is not READY there is nothing
2577 * we can do but pray resume goes smoothly.
2579 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2580 if (!check_vif_up(vif))
2583 list_for_each_entry(vif, &cfg->vif_list, list) {
2584 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2587 * While going to suspend if associated with AP disassociate
2588 * from AP to save power while system is in suspended state
2590 brcmf_link_down(vif);
2592 /* Make sure WPA_Supplicant receives all the event
2593 * generated due to DISASSOC call to the fw to keep
2594 * the state fw and WPA_Supplicant state consistent
2599 /* end any scanning */
2600 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2601 brcmf_abort_scanning(cfg);
2603 /* Turn off watchdog timer */
2604 brcmf_set_mpc(ndev, 1);
2607 brcmf_dbg(TRACE, "Exit\n");
2608 /* clear any scanning activity */
2609 cfg->scan_status = 0;
2614 brcmf_update_pmklist(struct net_device *ndev,
2615 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2620 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2622 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2623 for (i = 0; i < pmkid_len; i++) {
2624 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2625 &pmk_list->pmkids.pmkid[i].BSSID);
2626 for (j = 0; j < WLAN_PMKID_LEN; j++)
2627 brcmf_dbg(CONN, "%02x\n",
2628 pmk_list->pmkids.pmkid[i].PMKID[j]);
2632 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2633 (char *)pmk_list, sizeof(*pmk_list));
2639 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2640 struct cfg80211_pmksa *pmksa)
2642 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2643 struct brcmf_if *ifp = netdev_priv(ndev);
2644 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2649 brcmf_dbg(TRACE, "Enter\n");
2650 if (!check_vif_up(ifp->vif))
2653 pmkid_len = le32_to_cpu(pmkids->npmkid);
2654 for (i = 0; i < pmkid_len; i++)
2655 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2657 if (i < WL_NUM_PMKIDS_MAX) {
2658 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2659 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2660 if (i == pmkid_len) {
2662 pmkids->npmkid = cpu_to_le32(pmkid_len);
2667 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2668 pmkids->pmkid[pmkid_len].BSSID);
2669 for (i = 0; i < WLAN_PMKID_LEN; i++)
2670 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2672 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2674 brcmf_dbg(TRACE, "Exit\n");
2679 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2680 struct cfg80211_pmksa *pmksa)
2682 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2683 struct brcmf_if *ifp = netdev_priv(ndev);
2684 struct pmkid_list pmkid;
2688 brcmf_dbg(TRACE, "Enter\n");
2689 if (!check_vif_up(ifp->vif))
2692 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2693 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2695 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2696 &pmkid.pmkid[0].BSSID);
2697 for (i = 0; i < WLAN_PMKID_LEN; i++)
2698 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2700 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2701 for (i = 0; i < pmkid_len; i++)
2703 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2708 && (i < pmkid_len)) {
2709 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2710 sizeof(struct pmkid));
2711 for (; i < (pmkid_len - 1); i++) {
2712 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2713 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2715 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2716 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2719 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2723 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2725 brcmf_dbg(TRACE, "Exit\n");
2731 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2733 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2734 struct brcmf_if *ifp = netdev_priv(ndev);
2737 brcmf_dbg(TRACE, "Enter\n");
2738 if (!check_vif_up(ifp->vif))
2741 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2742 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2744 brcmf_dbg(TRACE, "Exit\n");
2750 * PFN result doesn't have all the info which are
2751 * required by the supplicant
2752 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2753 * via wl_inform_single_bss in the required format. Escan does require the
2754 * scan request in the form of cfg80211_scan_request. For timebeing, create
2755 * cfg80211_scan_request one out of the received PNO event.
2758 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2759 const struct brcmf_event_msg *e, void *data)
2761 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2762 struct net_device *ndev = ifp->ndev;
2763 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2764 struct cfg80211_scan_request *request = NULL;
2765 struct cfg80211_ssid *ssid = NULL;
2766 struct ieee80211_channel *channel = NULL;
2767 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2769 int channel_req = 0;
2771 struct brcmf_pno_scanresults_le *pfn_result;
2775 brcmf_dbg(SCAN, "Enter\n");
2777 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2778 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2782 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2783 result_count = le32_to_cpu(pfn_result->count);
2784 status = le32_to_cpu(pfn_result->status);
2787 * PFN event is limited to fit 512 bytes so we may get
2788 * multiple NET_FOUND events. For now place a warning here.
2790 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2791 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2792 if (result_count > 0) {
2795 request = kzalloc(sizeof(*request), GFP_KERNEL);
2796 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2797 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2798 if (!request || !ssid || !channel) {
2803 request->wiphy = wiphy;
2804 data += sizeof(struct brcmf_pno_scanresults_le);
2805 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2807 for (i = 0; i < result_count; i++) {
2808 netinfo = &netinfo_start[i];
2810 brcmf_err("Invalid netinfo ptr. index: %d\n",
2816 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2817 netinfo->SSID, netinfo->channel);
2818 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2819 ssid[i].ssid_len = netinfo->SSID_len;
2822 channel_req = netinfo->channel;
2823 if (channel_req <= CH_MAX_2G_CHANNEL)
2824 band = NL80211_BAND_2GHZ;
2826 band = NL80211_BAND_5GHZ;
2827 channel[i].center_freq =
2828 ieee80211_channel_to_frequency(channel_req,
2830 channel[i].band = band;
2831 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2832 request->channels[i] = &channel[i];
2833 request->n_channels++;
2836 /* assign parsed ssid array */
2837 if (request->n_ssids)
2838 request->ssids = &ssid[0];
2840 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2841 /* Abort any on-going scan */
2842 brcmf_abort_scanning(cfg);
2845 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2846 err = brcmf_do_escan(cfg, wiphy, ndev, request);
2848 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2851 cfg->sched_escan = true;
2852 cfg->scan_request = request;
2854 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2867 cfg80211_sched_scan_stopped(wiphy);
2871 static int brcmf_dev_pno_clean(struct net_device *ndev)
2876 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
2879 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
2883 brcmf_err("failed code %d\n", ret);
2888 static int brcmf_dev_pno_config(struct net_device *ndev)
2890 struct brcmf_pno_param_le pfn_param;
2892 memset(&pfn_param, 0, sizeof(pfn_param));
2893 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
2895 /* set extra pno params */
2896 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
2897 pfn_param.repeat = BRCMF_PNO_REPEAT;
2898 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
2900 /* set up pno scan fr */
2901 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
2903 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
2904 &pfn_param, sizeof(pfn_param));
2908 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
2909 struct net_device *ndev,
2910 struct cfg80211_sched_scan_request *request)
2912 struct brcmf_if *ifp = netdev_priv(ndev);
2913 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
2914 struct brcmf_pno_net_param_le pfn;
2918 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
2919 request->n_match_sets, request->n_ssids);
2920 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2921 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
2925 if (!request || !request->n_ssids || !request->n_match_sets) {
2926 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
2927 request ? request->n_ssids : 0);
2931 if (request->n_ssids > 0) {
2932 for (i = 0; i < request->n_ssids; i++) {
2933 /* Active scan req for ssids */
2934 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
2935 request->ssids[i].ssid);
2938 * match_set ssids is a supert set of n_ssid list,
2939 * so we need not add these set seperately.
2944 if (request->n_match_sets > 0) {
2945 /* clean up everything */
2946 ret = brcmf_dev_pno_clean(ndev);
2948 brcmf_err("failed error=%d\n", ret);
2953 ret = brcmf_dev_pno_config(ndev);
2955 brcmf_err("PNO setup failed!! ret=%d\n", ret);
2959 /* configure each match set */
2960 for (i = 0; i < request->n_match_sets; i++) {
2961 struct cfg80211_ssid *ssid;
2964 ssid = &request->match_sets[i].ssid;
2965 ssid_len = ssid->ssid_len;
2968 brcmf_err("skip broadcast ssid\n");
2971 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
2972 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
2973 pfn.wsec = cpu_to_le32(0);
2974 pfn.infra = cpu_to_le32(1);
2975 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
2976 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
2977 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
2978 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
2980 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
2981 ret == 0 ? "set" : "failed", ssid->ssid);
2983 /* Enable the PNO */
2984 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
2985 brcmf_err("PNO enable failed!! ret=%d\n", ret);
2995 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
2996 struct net_device *ndev)
2998 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3000 brcmf_dbg(SCAN, "enter\n");
3001 brcmf_dev_pno_clean(ndev);
3002 if (cfg->sched_escan)
3003 brcmf_notify_escan_complete(cfg, ndev, true, true);
3007 #ifdef CONFIG_NL80211_TESTMODE
3008 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3010 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3011 struct net_device *ndev = cfg_to_ndev(cfg);
3012 struct brcmf_dcmd *dcmd = data;
3013 struct sk_buff *reply;
3016 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3017 dcmd->buf, dcmd->len);
3020 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3021 dcmd->buf, dcmd->len);
3023 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3024 dcmd->buf, dcmd->len);
3026 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3027 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3028 ret = cfg80211_testmode_reply(reply);
3034 static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3036 struct brcmf_if *ifp = netdev_priv(ndev);
3040 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3042 brcmf_err("auth error %d\n", err);
3046 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3048 brcmf_err("wsec error %d\n", err);
3051 /* set upper-layer auth */
3052 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3054 brcmf_err("wpa_auth error %d\n", err);
3061 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3064 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3066 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3070 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3073 struct brcmf_if *ifp = netdev_priv(ndev);
3074 u32 auth = 0; /* d11 open authentication */
3086 u32 wme_bss_disable;
3088 brcmf_dbg(TRACE, "Enter\n");
3092 len = wpa_ie->len + TLV_HDR_LEN;
3093 data = (u8 *)wpa_ie;
3094 offset = TLV_HDR_LEN;
3096 offset += VS_IE_FIXED_HDR_LEN;
3098 offset += WPA_IE_VERSION_LEN;
3100 /* check for multicast cipher suite */
3101 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3103 brcmf_err("no multicast cipher suite\n");
3107 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3109 brcmf_err("ivalid OUI\n");
3112 offset += TLV_OUI_LEN;
3114 /* pick up multicast cipher */
3115 switch (data[offset]) {
3116 case WPA_CIPHER_NONE:
3119 case WPA_CIPHER_WEP_40:
3120 case WPA_CIPHER_WEP_104:
3123 case WPA_CIPHER_TKIP:
3124 gval = TKIP_ENABLED;
3126 case WPA_CIPHER_AES_CCM:
3131 brcmf_err("Invalid multi cast cipher info\n");
3136 /* walk thru unicast cipher list and pick up what we recognize */
3137 count = data[offset] + (data[offset + 1] << 8);
3138 offset += WPA_IE_SUITE_COUNT_LEN;
3139 /* Check for unicast suite(s) */
3140 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3142 brcmf_err("no unicast cipher suite\n");
3145 for (i = 0; i < count; i++) {
3146 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3148 brcmf_err("ivalid OUI\n");
3151 offset += TLV_OUI_LEN;
3152 switch (data[offset]) {
3153 case WPA_CIPHER_NONE:
3155 case WPA_CIPHER_WEP_40:
3156 case WPA_CIPHER_WEP_104:
3157 pval |= WEP_ENABLED;
3159 case WPA_CIPHER_TKIP:
3160 pval |= TKIP_ENABLED;
3162 case WPA_CIPHER_AES_CCM:
3163 pval |= AES_ENABLED;
3166 brcmf_err("Ivalid unicast security info\n");
3170 /* walk thru auth management suite list and pick up what we recognize */
3171 count = data[offset] + (data[offset + 1] << 8);
3172 offset += WPA_IE_SUITE_COUNT_LEN;
3173 /* Check for auth key management suite(s) */
3174 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3176 brcmf_err("no auth key mgmt suite\n");
3179 for (i = 0; i < count; i++) {
3180 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3182 brcmf_err("ivalid OUI\n");
3185 offset += TLV_OUI_LEN;
3186 switch (data[offset]) {
3188 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3189 wpa_auth |= WPA_AUTH_NONE;
3191 case RSN_AKM_UNSPECIFIED:
3192 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3193 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3194 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3197 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3198 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3199 (wpa_auth |= WPA_AUTH_PSK);
3202 brcmf_err("Ivalid key mgmt info\n");
3208 wme_bss_disable = 1;
3209 if ((offset + RSN_CAP_LEN) <= len) {
3210 rsn_cap = data[offset] + (data[offset + 1] << 8);
3211 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3212 wme_bss_disable = 0;
3214 /* set wme_bss_disable to sync RSN Capabilities */
3215 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3218 brcmf_err("wme_bss_disable error %d\n", err);
3222 /* FOR WPS , set SES_OW_ENABLED */
3223 wsec = (pval | gval | SES_OW_ENABLED);
3226 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3228 brcmf_err("auth error %d\n", err);
3232 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3234 brcmf_err("wsec error %d\n", err);
3237 /* set upper-layer auth */
3238 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3240 brcmf_err("wpa_auth error %d\n", err);
3249 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3250 struct parsed_vndr_ies *vndr_ies)
3253 struct brcmf_vs_tlv *vndrie;
3254 struct brcmf_tlv *ie;
3255 struct parsed_vndr_ie_info *parsed_info;
3258 remaining_len = (s32)vndr_ie_len;
3259 memset(vndr_ies, 0, sizeof(*vndr_ies));
3261 ie = (struct brcmf_tlv *)vndr_ie_buf;
3263 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3265 vndrie = (struct brcmf_vs_tlv *)ie;
3266 /* len should be bigger than OUI length + one */
3267 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3268 brcmf_err("invalid vndr ie. length is too small %d\n",
3272 /* if wpa or wme ie, do not add ie */
3273 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3274 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3275 (vndrie->oui_type == WME_OUI_TYPE))) {
3276 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3280 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3282 /* save vndr ie information */
3283 parsed_info->ie_ptr = (char *)vndrie;
3284 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3285 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3289 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3290 parsed_info->vndrie.oui[0],
3291 parsed_info->vndrie.oui[1],
3292 parsed_info->vndrie.oui[2],
3293 parsed_info->vndrie.oui_type);
3295 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3298 remaining_len -= (ie->len + TLV_HDR_LEN);
3299 if (remaining_len <= TLV_HDR_LEN)
3302 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3309 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3315 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3316 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3318 iecount_le = cpu_to_le32(1);
3319 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3321 pktflag_le = cpu_to_le32(pktflag);
3322 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3324 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3326 return ie_len + VNDR_IE_HDR_SIZE;
3330 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3331 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3333 struct brcmf_if *ifp;
3334 struct vif_saved_ie *saved_ie;
3338 u8 *mgmt_ie_buf = NULL;
3339 int mgmt_ie_buf_len;
3341 u32 del_add_ie_buf_len = 0;
3342 u32 total_ie_buf_len = 0;
3343 u32 parsed_ie_buf_len = 0;
3344 struct parsed_vndr_ies old_vndr_ies;
3345 struct parsed_vndr_ies new_vndr_ies;
3346 struct parsed_vndr_ie_info *vndrie_info;
3349 int remained_buf_len;
3354 saved_ie = &vif->saved_ie;
3356 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3357 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3360 curr_ie_buf = iovar_ie_buf;
3361 if (ifp->vif->mode == WL_MODE_AP) {
3363 case VNDR_IE_PRBRSP_FLAG:
3364 mgmt_ie_buf = saved_ie->probe_res_ie;
3365 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3366 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3368 case VNDR_IE_BEACON_FLAG:
3369 mgmt_ie_buf = saved_ie->beacon_ie;
3370 mgmt_ie_len = &saved_ie->beacon_ie_len;
3371 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3375 brcmf_err("not suitable type\n");
3380 brcmf_err("not suitable type\n");
3384 if (vndr_ie_len > mgmt_ie_buf_len) {
3386 brcmf_err("extra IE size too big\n");
3390 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3391 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3393 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3394 for (i = 0; i < new_vndr_ies.count; i++) {
3395 vndrie_info = &new_vndr_ies.ie_info[i];
3396 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3397 vndrie_info->ie_len);
3398 parsed_ie_buf_len += vndrie_info->ie_len;
3402 if (mgmt_ie_buf && *mgmt_ie_len) {
3403 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3404 (memcmp(mgmt_ie_buf, curr_ie_buf,
3405 parsed_ie_buf_len) == 0)) {
3406 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3410 /* parse old vndr_ie */
3411 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3413 /* make a command to delete old ie */
3414 for (i = 0; i < old_vndr_ies.count; i++) {
3415 vndrie_info = &old_vndr_ies.ie_info[i];
3417 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3418 vndrie_info->vndrie.id,
3419 vndrie_info->vndrie.len,
3420 vndrie_info->vndrie.oui[0],
3421 vndrie_info->vndrie.oui[1],
3422 vndrie_info->vndrie.oui[2]);
3424 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3425 vndrie_info->ie_ptr,
3426 vndrie_info->ie_len,
3428 curr_ie_buf += del_add_ie_buf_len;
3429 total_ie_buf_len += del_add_ie_buf_len;
3434 /* Add if there is any extra IE */
3435 if (mgmt_ie_buf && parsed_ie_buf_len) {
3438 remained_buf_len = mgmt_ie_buf_len;
3440 /* make a command to add new ie */
3441 for (i = 0; i < new_vndr_ies.count; i++) {
3442 vndrie_info = &new_vndr_ies.ie_info[i];
3444 /* verify remained buf size before copy data */
3445 if (remained_buf_len < (vndrie_info->vndrie.len +
3446 VNDR_IE_VSIE_OFFSET)) {
3447 brcmf_err("no space in mgmt_ie_buf: len left %d",
3451 remained_buf_len -= (vndrie_info->ie_len +
3452 VNDR_IE_VSIE_OFFSET);
3454 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3455 vndrie_info->vndrie.id,
3456 vndrie_info->vndrie.len,
3457 vndrie_info->vndrie.oui[0],
3458 vndrie_info->vndrie.oui[1],
3459 vndrie_info->vndrie.oui[2]);
3461 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3462 vndrie_info->ie_ptr,
3463 vndrie_info->ie_len,
3466 /* save the parsed IE in wl struct */
3467 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3468 vndrie_info->ie_len);
3469 *mgmt_ie_len += vndrie_info->ie_len;
3471 curr_ie_buf += del_add_ie_buf_len;
3472 total_ie_buf_len += del_add_ie_buf_len;
3475 if (total_ie_buf_len) {
3476 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3479 brcmf_err("vndr ie set error : %d\n", err);
3483 kfree(iovar_ie_buf);
3488 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3489 struct cfg80211_ap_settings *settings)
3492 struct brcmf_if *ifp = netdev_priv(ndev);
3493 struct brcmf_tlv *ssid_ie;
3494 struct brcmf_ssid_le ssid_le;
3496 struct brcmf_tlv *rsn_ie;
3497 struct brcmf_vs_tlv *wpa_ie;
3498 struct brcmf_join_params join_params;
3501 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3502 cfg80211_get_chandef_type(&settings->chandef),
3503 settings->beacon_interval,
3504 settings->dtim_period);
3505 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3506 settings->ssid, settings->ssid_len, settings->auth_type,
3507 settings->inactivity_timeout);
3509 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
3510 brcmf_err("Not in AP creation mode\n");
3514 memset(&ssid_le, 0, sizeof(ssid_le));
3515 if (settings->ssid == NULL || settings->ssid_len == 0) {
3516 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3517 ssid_ie = brcmf_parse_tlvs(
3518 (u8 *)&settings->beacon.head[ie_offset],
3519 settings->beacon.head_len - ie_offset,
3524 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3525 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3526 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3528 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3529 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3532 brcmf_set_mpc(ndev, 0);
3533 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3535 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3538 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3540 brcmf_err("SET INFRA error %d\n", err);
3543 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3545 brcmf_err("setting AP mode failed %d\n", err);
3549 /* find the RSN_IE */
3550 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3551 settings->beacon.tail_len, WLAN_EID_RSN);
3553 /* find the WPA_IE */
3554 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3555 settings->beacon.tail_len);
3557 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3558 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3559 if (wpa_ie != NULL) {
3561 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3566 err = brcmf_configure_wpaie(ndev,
3567 (struct brcmf_vs_tlv *)rsn_ie, true);
3572 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3573 brcmf_configure_opensecurity(ndev, bssidx);
3575 /* Set Beacon IEs to FW */
3576 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3577 VNDR_IE_BEACON_FLAG,
3578 settings->beacon.tail,
3579 settings->beacon.tail_len);
3581 brcmf_err("Set Beacon IE Failed\n");
3583 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3585 /* Set Probe Response IEs to FW */
3586 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3587 VNDR_IE_PRBRSP_FLAG,
3588 settings->beacon.proberesp_ies,
3589 settings->beacon.proberesp_ies_len);
3591 brcmf_err("Set Probe Resp IE Failed\n");
3593 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3595 if (settings->beacon_interval) {
3596 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3597 settings->beacon_interval);
3599 brcmf_err("Beacon Interval Set Error, %d\n", err);
3603 if (settings->dtim_period) {
3604 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3605 settings->dtim_period);
3607 brcmf_err("DTIM Interval Set Error, %d\n", err);
3611 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3613 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3617 memset(&join_params, 0, sizeof(join_params));
3618 /* join parameters starts with ssid */
3619 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3621 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3622 &join_params, sizeof(join_params));
3624 brcmf_err("SET SSID error (%d)\n", err);
3627 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3628 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3632 brcmf_set_mpc(ndev, 1);
3636 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3638 struct brcmf_if *ifp = netdev_priv(ndev);
3641 brcmf_dbg(TRACE, "Enter\n");
3643 if (ifp->vif->mode == WL_MODE_AP) {
3644 /* Due to most likely deauths outstanding we sleep */
3645 /* first to make sure they get processed by fw. */
3647 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3649 brcmf_err("setting AP mode failed %d\n", err);
3652 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3654 brcmf_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 brcmf_dbg(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 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3688 brcmf_dbg(TRACE, "Exit\n");
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 brcmf_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 brcmf_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 brcmf_dbg(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 brcmf_dbg(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 brcmf_dbg(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 brcmf_dbg(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 brcmf_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 brcmf_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 brcmf_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 brcmf_dbg(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 brcmf_dbg(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 brcmf_dbg(CONN, "Report roaming result\n");
4015 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4016 brcmf_dbg(TRACE, "Exit\n");
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 brcmf_dbg(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 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4052 completed ? "succeeded" : "failed");
4054 brcmf_dbg(TRACE, "Exit\n");
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 brcmf_dbg(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 brcmf_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 (ifp->vif->mode == WL_MODE_AP) {
4107 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4108 } else if (brcmf_is_linkup(e)) {
4109 brcmf_dbg(CONN, "Linkup\n");
4110 if (brcmf_is_ibssmode(ifp->vif)) {
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 brcmf_dbg(CONN, "Linkdown\n");
4122 if (!brcmf_is_ibssmode(ifp->vif)) {
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(ifp->vif))
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->frag_threshold = (u32)-1;
4182 conf->rts_threshold = (u32)-1;
4183 conf->retry_short = (u32)-1;
4184 conf->retry_long = (u32)-1;
4185 conf->tx_power = -1;
4188 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4190 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4191 brcmf_notify_connect_status);
4192 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4193 brcmf_notify_connect_status);
4194 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4195 brcmf_notify_connect_status);
4196 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4197 brcmf_notify_connect_status);
4198 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4199 brcmf_notify_connect_status);
4200 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4201 brcmf_notify_connect_status);
4202 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4203 brcmf_notify_roaming_status);
4204 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4205 brcmf_notify_mic_status);
4206 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4207 brcmf_notify_connect_status);
4208 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4209 brcmf_notify_sched_scan_results);
4212 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4216 kfree(cfg->escan_ioctl_buf);
4217 cfg->escan_ioctl_buf = NULL;
4218 kfree(cfg->extra_buf);
4219 cfg->extra_buf = NULL;
4220 kfree(cfg->pmk_list);
4221 cfg->pmk_list = NULL;
4224 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4226 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4228 goto init_priv_mem_out;
4229 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4230 if (!cfg->escan_ioctl_buf)
4231 goto init_priv_mem_out;
4232 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4233 if (!cfg->extra_buf)
4234 goto init_priv_mem_out;
4235 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4237 goto init_priv_mem_out;
4242 brcmf_deinit_priv_mem(cfg);
4247 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4251 cfg->scan_request = NULL;
4252 cfg->pwr_save = true;
4253 cfg->roam_on = true; /* roam on & off switch.
4254 we enable roam per default */
4255 cfg->active_scan = true; /* we do active scan for
4256 specific scan per default */
4257 cfg->dongle_up = false; /* dongle is not up yet */
4258 err = brcmf_init_priv_mem(cfg);
4261 brcmf_register_event_handlers(cfg);
4262 mutex_init(&cfg->usr_sync);
4263 brcmf_init_escan(cfg);
4264 brcmf_init_conf(cfg->conf);
4269 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4271 cfg->dongle_up = false; /* dongle down */
4272 brcmf_abort_scanning(cfg);
4273 brcmf_deinit_priv_mem(cfg);
4276 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4277 struct device *busdev)
4279 struct net_device *ndev = drvr->iflist[0]->ndev;
4280 struct brcmf_cfg80211_info *cfg;
4281 struct wiphy *wiphy;
4282 struct brcmf_cfg80211_vif *vif;
4283 struct brcmf_if *ifp;
4287 brcmf_err("ndev is invalid\n");
4291 ifp = netdev_priv(ndev);
4292 wiphy = brcmf_setup_wiphy(busdev);
4296 cfg = wiphy_priv(wiphy);
4299 INIT_LIST_HEAD(&cfg->vif_list);
4301 vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false);
4307 err = wl_init_priv(cfg);
4309 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4310 goto cfg80211_attach_out;
4316 cfg80211_attach_out:
4317 brcmf_free_vif(vif);
4321 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4323 struct brcmf_cfg80211_vif *vif;
4324 struct brcmf_cfg80211_vif *tmp;
4326 wl_deinit_priv(cfg);
4327 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4328 brcmf_free_vif(vif);
4333 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
4335 struct brcmf_if *ifp = netdev_priv(ndev);
4337 __le32 roamtrigger[2];
4338 __le32 roam_delta[2];
4341 * Setup timeout if Beacons are lost and roam is
4342 * off to report link down
4345 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4347 brcmf_err("bcn_timeout error (%d)\n", err);
4348 goto dongle_rom_out;
4353 * Enable/Disable built-in roaming to allow supplicant
4354 * to take care of roaming
4356 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4357 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4359 brcmf_err("roam_off error (%d)\n", err);
4360 goto dongle_rom_out;
4363 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4364 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4365 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4366 (void *)roamtrigger, sizeof(roamtrigger));
4368 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4369 goto dongle_rom_out;
4372 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4373 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4374 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4375 (void *)roam_delta, sizeof(roam_delta));
4377 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4378 goto dongle_rom_out;
4386 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
4387 s32 scan_unassoc_time, s32 scan_passive_time)
4389 struct brcmf_if *ifp = netdev_priv(ndev);
4392 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4395 if (err == -EOPNOTSUPP)
4396 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4398 brcmf_err("Scan assoc time error (%d)\n", err);
4399 goto dongle_scantime_out;
4401 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4404 if (err == -EOPNOTSUPP)
4405 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4407 brcmf_err("Scan unassoc time error (%d)\n", err);
4408 goto dongle_scantime_out;
4411 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4414 if (err == -EOPNOTSUPP)
4415 brcmf_dbg(INFO, "Scan passive time is not supported\n");
4417 brcmf_err("Scan passive time error (%d)\n", err);
4418 goto dongle_scantime_out;
4421 dongle_scantime_out:
4425 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4427 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4428 struct wiphy *wiphy;
4433 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4434 &phy_list, sizeof(phy_list));
4436 brcmf_err("error (%d)\n", err);
4440 phy = ((char *)&phy_list)[0];
4441 brcmf_dbg(INFO, "%c phy\n", phy);
4442 if (phy == 'n' || phy == 'a') {
4443 wiphy = cfg_to_wiphy(cfg);
4444 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4450 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4452 return wl_update_wiphybands(cfg);
4455 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4457 struct net_device *ndev;
4458 struct wireless_dev *wdev;
4465 ndev = cfg_to_ndev(cfg);
4466 wdev = ndev->ieee80211_ptr;
4468 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4469 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4471 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4472 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
4475 goto default_conf_out;
4476 brcmf_dbg(INFO, "power save set to %s\n",
4477 (power_mode ? "enabled" : "disabled"));
4479 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
4482 goto default_conf_out;
4483 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4485 if (err && err != -EINPROGRESS)
4486 goto default_conf_out;
4487 err = brcmf_dongle_probecap(cfg);
4489 goto default_conf_out;
4491 /* -EINPROGRESS: Call commit handler */
4495 cfg->dongle_up = true;
4501 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
4503 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4507 return brcmf_config_dongle(ifp->drvr->config);
4510 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
4512 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4515 * While going down, if associated with AP disassociate
4516 * from AP to save power
4518 if (check_vif_up(ifp->vif)) {
4519 brcmf_link_down(ifp->vif);
4521 /* Make sure WPA_Supplicant receives all the event
4522 generated due to DISASSOC call to the fw to keep
4523 the state fw and WPA_Supplicant state consistent
4528 brcmf_abort_scanning(cfg);
4529 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4534 s32 brcmf_cfg80211_up(struct net_device *ndev)
4536 struct brcmf_if *ifp = netdev_priv(ndev);
4537 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4540 mutex_lock(&cfg->usr_sync);
4541 err = __brcmf_cfg80211_up(ifp);
4542 mutex_unlock(&cfg->usr_sync);
4547 s32 brcmf_cfg80211_down(struct net_device *ndev)
4549 struct brcmf_if *ifp = netdev_priv(ndev);
4550 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4553 mutex_lock(&cfg->usr_sync);
4554 err = __brcmf_cfg80211_down(ifp);
4555 mutex_unlock(&cfg->usr_sync);