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;
3096 offset += VS_IE_FIXED_HDR_LEN;
3097 offset += WPA_IE_VERSION_LEN;
3099 /* check for multicast cipher suite */
3100 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3102 brcmf_err("no multicast cipher suite\n");
3106 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3108 brcmf_err("ivalid OUI\n");
3111 offset += TLV_OUI_LEN;
3113 /* pick up multicast cipher */
3114 switch (data[offset]) {
3115 case WPA_CIPHER_NONE:
3118 case WPA_CIPHER_WEP_40:
3119 case WPA_CIPHER_WEP_104:
3122 case WPA_CIPHER_TKIP:
3123 gval = TKIP_ENABLED;
3125 case WPA_CIPHER_AES_CCM:
3130 brcmf_err("Invalid multi cast cipher info\n");
3135 /* walk thru unicast cipher list and pick up what we recognize */
3136 count = data[offset] + (data[offset + 1] << 8);
3137 offset += WPA_IE_SUITE_COUNT_LEN;
3138 /* Check for unicast suite(s) */
3139 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3141 brcmf_err("no unicast cipher suite\n");
3144 for (i = 0; i < count; i++) {
3145 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3147 brcmf_err("ivalid OUI\n");
3150 offset += TLV_OUI_LEN;
3151 switch (data[offset]) {
3152 case WPA_CIPHER_NONE:
3154 case WPA_CIPHER_WEP_40:
3155 case WPA_CIPHER_WEP_104:
3156 pval |= WEP_ENABLED;
3158 case WPA_CIPHER_TKIP:
3159 pval |= TKIP_ENABLED;
3161 case WPA_CIPHER_AES_CCM:
3162 pval |= AES_ENABLED;
3165 brcmf_err("Ivalid unicast security info\n");
3169 /* walk thru auth management suite list and pick up what we recognize */
3170 count = data[offset] + (data[offset + 1] << 8);
3171 offset += WPA_IE_SUITE_COUNT_LEN;
3172 /* Check for auth key management suite(s) */
3173 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3175 brcmf_err("no auth key mgmt suite\n");
3178 for (i = 0; i < count; i++) {
3179 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3181 brcmf_err("ivalid OUI\n");
3184 offset += TLV_OUI_LEN;
3185 switch (data[offset]) {
3187 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3188 wpa_auth |= WPA_AUTH_NONE;
3190 case RSN_AKM_UNSPECIFIED:
3191 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3192 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3193 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3196 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3197 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3198 (wpa_auth |= WPA_AUTH_PSK);
3201 brcmf_err("Ivalid key mgmt info\n");
3207 wme_bss_disable = 1;
3208 if ((offset + RSN_CAP_LEN) <= len) {
3209 rsn_cap = data[offset] + (data[offset + 1] << 8);
3210 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3211 wme_bss_disable = 0;
3213 /* set wme_bss_disable to sync RSN Capabilities */
3214 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3217 brcmf_err("wme_bss_disable error %d\n", err);
3221 /* FOR WPS , set SES_OW_ENABLED */
3222 wsec = (pval | gval | SES_OW_ENABLED);
3225 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3227 brcmf_err("auth error %d\n", err);
3231 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3233 brcmf_err("wsec error %d\n", err);
3236 /* set upper-layer auth */
3237 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3239 brcmf_err("wpa_auth error %d\n", err);
3248 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3249 struct parsed_vndr_ies *vndr_ies)
3252 struct brcmf_vs_tlv *vndrie;
3253 struct brcmf_tlv *ie;
3254 struct parsed_vndr_ie_info *parsed_info;
3257 remaining_len = (s32)vndr_ie_len;
3258 memset(vndr_ies, 0, sizeof(*vndr_ies));
3260 ie = (struct brcmf_tlv *)vndr_ie_buf;
3262 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3264 vndrie = (struct brcmf_vs_tlv *)ie;
3265 /* len should be bigger than OUI length + one */
3266 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3267 brcmf_err("invalid vndr ie. length is too small %d\n",
3271 /* if wpa or wme ie, do not add ie */
3272 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3273 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3274 (vndrie->oui_type == WME_OUI_TYPE))) {
3275 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3279 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3281 /* save vndr ie information */
3282 parsed_info->ie_ptr = (char *)vndrie;
3283 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3284 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3288 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3289 parsed_info->vndrie.oui[0],
3290 parsed_info->vndrie.oui[1],
3291 parsed_info->vndrie.oui[2],
3292 parsed_info->vndrie.oui_type);
3294 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3297 remaining_len -= (ie->len + TLV_HDR_LEN);
3298 if (remaining_len <= TLV_HDR_LEN)
3301 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3308 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3314 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3315 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3317 iecount_le = cpu_to_le32(1);
3318 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3320 pktflag_le = cpu_to_le32(pktflag);
3321 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3323 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3325 return ie_len + VNDR_IE_HDR_SIZE;
3329 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3330 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3332 struct brcmf_if *ifp;
3333 struct vif_saved_ie *saved_ie;
3337 u8 *mgmt_ie_buf = NULL;
3338 int mgmt_ie_buf_len;
3340 u32 del_add_ie_buf_len = 0;
3341 u32 total_ie_buf_len = 0;
3342 u32 parsed_ie_buf_len = 0;
3343 struct parsed_vndr_ies old_vndr_ies;
3344 struct parsed_vndr_ies new_vndr_ies;
3345 struct parsed_vndr_ie_info *vndrie_info;
3348 int remained_buf_len;
3353 saved_ie = &vif->saved_ie;
3355 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3356 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3359 curr_ie_buf = iovar_ie_buf;
3360 if (ifp->vif->mode == WL_MODE_AP) {
3362 case VNDR_IE_PRBRSP_FLAG:
3363 mgmt_ie_buf = saved_ie->probe_res_ie;
3364 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3365 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3367 case VNDR_IE_BEACON_FLAG:
3368 mgmt_ie_buf = saved_ie->beacon_ie;
3369 mgmt_ie_len = &saved_ie->beacon_ie_len;
3370 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3374 brcmf_err("not suitable type\n");
3379 brcmf_err("not suitable type\n");
3383 if (vndr_ie_len > mgmt_ie_buf_len) {
3385 brcmf_err("extra IE size too big\n");
3389 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3390 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3392 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3393 for (i = 0; i < new_vndr_ies.count; i++) {
3394 vndrie_info = &new_vndr_ies.ie_info[i];
3395 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3396 vndrie_info->ie_len);
3397 parsed_ie_buf_len += vndrie_info->ie_len;
3401 if (mgmt_ie_buf && *mgmt_ie_len) {
3402 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3403 (memcmp(mgmt_ie_buf, curr_ie_buf,
3404 parsed_ie_buf_len) == 0)) {
3405 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3409 /* parse old vndr_ie */
3410 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3412 /* make a command to delete old ie */
3413 for (i = 0; i < old_vndr_ies.count; i++) {
3414 vndrie_info = &old_vndr_ies.ie_info[i];
3416 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3417 vndrie_info->vndrie.id,
3418 vndrie_info->vndrie.len,
3419 vndrie_info->vndrie.oui[0],
3420 vndrie_info->vndrie.oui[1],
3421 vndrie_info->vndrie.oui[2]);
3423 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3424 vndrie_info->ie_ptr,
3425 vndrie_info->ie_len,
3427 curr_ie_buf += del_add_ie_buf_len;
3428 total_ie_buf_len += del_add_ie_buf_len;
3433 /* Add if there is any extra IE */
3434 if (mgmt_ie_buf && parsed_ie_buf_len) {
3437 remained_buf_len = mgmt_ie_buf_len;
3439 /* make a command to add new ie */
3440 for (i = 0; i < new_vndr_ies.count; i++) {
3441 vndrie_info = &new_vndr_ies.ie_info[i];
3443 /* verify remained buf size before copy data */
3444 if (remained_buf_len < (vndrie_info->vndrie.len +
3445 VNDR_IE_VSIE_OFFSET)) {
3446 brcmf_err("no space in mgmt_ie_buf: len left %d",
3450 remained_buf_len -= (vndrie_info->ie_len +
3451 VNDR_IE_VSIE_OFFSET);
3453 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3454 vndrie_info->vndrie.id,
3455 vndrie_info->vndrie.len,
3456 vndrie_info->vndrie.oui[0],
3457 vndrie_info->vndrie.oui[1],
3458 vndrie_info->vndrie.oui[2]);
3460 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3461 vndrie_info->ie_ptr,
3462 vndrie_info->ie_len,
3465 /* save the parsed IE in wl struct */
3466 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3467 vndrie_info->ie_len);
3468 *mgmt_ie_len += vndrie_info->ie_len;
3470 curr_ie_buf += del_add_ie_buf_len;
3471 total_ie_buf_len += del_add_ie_buf_len;
3474 if (total_ie_buf_len) {
3475 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3478 brcmf_err("vndr ie set error : %d\n", err);
3482 kfree(iovar_ie_buf);
3487 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3488 struct cfg80211_ap_settings *settings)
3491 struct brcmf_if *ifp = netdev_priv(ndev);
3492 struct brcmf_tlv *ssid_ie;
3493 struct brcmf_ssid_le ssid_le;
3495 struct brcmf_tlv *rsn_ie;
3496 struct brcmf_vs_tlv *wpa_ie;
3497 struct brcmf_join_params join_params;
3500 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3501 cfg80211_get_chandef_type(&settings->chandef),
3502 settings->beacon_interval,
3503 settings->dtim_period);
3504 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3505 settings->ssid, settings->ssid_len, settings->auth_type,
3506 settings->inactivity_timeout);
3508 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
3509 brcmf_err("Not in AP creation mode\n");
3513 memset(&ssid_le, 0, sizeof(ssid_le));
3514 if (settings->ssid == NULL || settings->ssid_len == 0) {
3515 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3516 ssid_ie = brcmf_parse_tlvs(
3517 (u8 *)&settings->beacon.head[ie_offset],
3518 settings->beacon.head_len - ie_offset,
3523 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3524 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3525 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3527 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3528 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3531 brcmf_set_mpc(ndev, 0);
3532 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3534 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3537 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3539 brcmf_err("SET INFRA error %d\n", err);
3542 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3544 brcmf_err("setting AP mode failed %d\n", err);
3548 /* find the RSN_IE */
3549 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3550 settings->beacon.tail_len, WLAN_EID_RSN);
3552 /* find the WPA_IE */
3553 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3554 settings->beacon.tail_len);
3556 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3557 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3558 if (wpa_ie != NULL) {
3560 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3565 err = brcmf_configure_wpaie(ndev,
3566 (struct brcmf_vs_tlv *)rsn_ie, true);
3571 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3572 brcmf_configure_opensecurity(ndev, bssidx);
3574 /* Set Beacon IEs to FW */
3575 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3576 VNDR_IE_BEACON_FLAG,
3577 settings->beacon.tail,
3578 settings->beacon.tail_len);
3580 brcmf_err("Set Beacon IE Failed\n");
3582 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3584 /* Set Probe Response IEs to FW */
3585 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3586 VNDR_IE_PRBRSP_FLAG,
3587 settings->beacon.proberesp_ies,
3588 settings->beacon.proberesp_ies_len);
3590 brcmf_err("Set Probe Resp IE Failed\n");
3592 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3594 if (settings->beacon_interval) {
3595 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3596 settings->beacon_interval);
3598 brcmf_err("Beacon Interval Set Error, %d\n", err);
3602 if (settings->dtim_period) {
3603 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3604 settings->dtim_period);
3606 brcmf_err("DTIM Interval Set Error, %d\n", err);
3610 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3612 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3616 memset(&join_params, 0, sizeof(join_params));
3617 /* join parameters starts with ssid */
3618 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3620 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3621 &join_params, sizeof(join_params));
3623 brcmf_err("SET SSID error (%d)\n", err);
3626 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3627 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3631 brcmf_set_mpc(ndev, 1);
3635 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3637 struct brcmf_if *ifp = netdev_priv(ndev);
3640 brcmf_dbg(TRACE, "Enter\n");
3642 if (ifp->vif->mode == WL_MODE_AP) {
3643 /* Due to most likely deauths outstanding we sleep */
3644 /* first to make sure they get processed by fw. */
3646 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3648 brcmf_err("setting AP mode failed %d\n", err);
3651 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3653 brcmf_err("BRCMF_C_UP error %d\n", err);
3656 brcmf_set_mpc(ndev, 1);
3657 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3658 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3665 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3668 struct brcmf_scb_val_le scbval;
3669 struct brcmf_if *ifp = netdev_priv(ndev);
3675 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3677 if (!check_vif_up(ifp->vif))
3680 memcpy(&scbval.ea, mac, ETH_ALEN);
3681 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3682 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3683 &scbval, sizeof(scbval));
3685 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3687 brcmf_dbg(TRACE, "Exit\n");
3691 static struct cfg80211_ops wl_cfg80211_ops = {
3692 .change_virtual_intf = brcmf_cfg80211_change_iface,
3693 .scan = brcmf_cfg80211_scan,
3694 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
3695 .join_ibss = brcmf_cfg80211_join_ibss,
3696 .leave_ibss = brcmf_cfg80211_leave_ibss,
3697 .get_station = brcmf_cfg80211_get_station,
3698 .set_tx_power = brcmf_cfg80211_set_tx_power,
3699 .get_tx_power = brcmf_cfg80211_get_tx_power,
3700 .add_key = brcmf_cfg80211_add_key,
3701 .del_key = brcmf_cfg80211_del_key,
3702 .get_key = brcmf_cfg80211_get_key,
3703 .set_default_key = brcmf_cfg80211_config_default_key,
3704 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
3705 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
3706 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
3707 .connect = brcmf_cfg80211_connect,
3708 .disconnect = brcmf_cfg80211_disconnect,
3709 .suspend = brcmf_cfg80211_suspend,
3710 .resume = brcmf_cfg80211_resume,
3711 .set_pmksa = brcmf_cfg80211_set_pmksa,
3712 .del_pmksa = brcmf_cfg80211_del_pmksa,
3713 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3714 .start_ap = brcmf_cfg80211_start_ap,
3715 .stop_ap = brcmf_cfg80211_stop_ap,
3716 .del_station = brcmf_cfg80211_del_station,
3717 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
3718 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
3719 #ifdef CONFIG_NL80211_TESTMODE
3720 .testmode_cmd = brcmf_cfg80211_testmode
3724 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
3730 return NL80211_IFTYPE_STATION;
3732 return NL80211_IFTYPE_ADHOC;
3734 return NL80211_IFTYPE_UNSPECIFIED;
3740 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3742 /* scheduled scan settings */
3743 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
3744 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
3745 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
3746 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3749 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3751 struct wiphy *wiphy;
3754 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
3756 brcmf_err("Could not allocate wiphy device\n");
3757 return ERR_PTR(-ENOMEM);
3759 set_wiphy_dev(wiphy, phydev);
3760 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3761 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3762 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3763 BIT(NL80211_IFTYPE_ADHOC) |
3764 BIT(NL80211_IFTYPE_AP);
3765 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3766 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
3767 * it as 11a by default.
3768 * This will be updated with
3771 * if phy has 11n capability
3773 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3774 wiphy->cipher_suites = __wl_cipher_suites;
3775 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3776 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
3780 brcmf_wiphy_pno_params(wiphy);
3781 err = wiphy_register(wiphy);
3783 brcmf_err("Could not register wiphy device (%d)\n", err);
3785 return ERR_PTR(err);
3791 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3792 struct net_device *netdev,
3793 s32 mode, bool pm_block)
3795 struct brcmf_cfg80211_vif *vif;
3797 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
3798 return ERR_PTR(-ENOSPC);
3800 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
3802 return ERR_PTR(-ENOMEM);
3804 vif->wdev.wiphy = cfg->wiphy;
3805 vif->wdev.netdev = netdev;
3806 vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
3809 vif->ifp = netdev_priv(netdev);
3810 netdev->ieee80211_ptr = &vif->wdev;
3811 SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
3815 vif->pm_block = pm_block;
3818 brcmf_init_prof(&vif->profile);
3820 list_add_tail(&vif->list, &cfg->vif_list);
3825 static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3827 struct brcmf_cfg80211_info *cfg;
3828 struct wiphy *wiphy;
3830 wiphy = vif->wdev.wiphy;
3831 cfg = wiphy_priv(wiphy);
3832 list_del(&vif->list);
3836 if (!cfg->vif_cnt) {
3837 wiphy_unregister(wiphy);
3842 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
3844 u32 event = e->event_code;
3845 u32 status = e->status;
3847 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3848 brcmf_dbg(CONN, "Processing set ssid\n");
3855 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
3857 u32 event = e->event_code;
3858 u16 flags = e->flags;
3860 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
3861 brcmf_dbg(CONN, "Processing link down\n");
3867 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
3868 const struct brcmf_event_msg *e)
3870 u32 event = e->event_code;
3871 u32 status = e->status;
3873 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
3874 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
3875 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
3879 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
3880 brcmf_dbg(CONN, "Processing connecting & no network found\n");
3887 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3889 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3891 kfree(conn_info->req_ie);
3892 conn_info->req_ie = NULL;
3893 conn_info->req_ie_len = 0;
3894 kfree(conn_info->resp_ie);
3895 conn_info->resp_ie = NULL;
3896 conn_info->resp_ie_len = 0;
3899 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
3901 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
3902 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3903 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3908 brcmf_clear_assoc_ies(cfg);
3910 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
3911 cfg->extra_buf, WL_ASSOC_INFO_MAX);
3913 brcmf_err("could not get assoc info (%d)\n", err);
3917 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
3918 req_len = le32_to_cpu(assoc_info->req_len);
3919 resp_len = le32_to_cpu(assoc_info->resp_len);
3921 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
3925 brcmf_err("could not get assoc req (%d)\n", err);
3928 conn_info->req_ie_len = req_len;
3930 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
3933 conn_info->req_ie_len = 0;
3934 conn_info->req_ie = NULL;
3937 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
3941 brcmf_err("could not get assoc resp (%d)\n", err);
3944 conn_info->resp_ie_len = resp_len;
3945 conn_info->resp_ie =
3946 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
3949 conn_info->resp_ie_len = 0;
3950 conn_info->resp_ie = NULL;
3952 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
3953 conn_info->req_ie_len, conn_info->resp_ie_len);
3959 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3960 struct net_device *ndev,
3961 const struct brcmf_event_msg *e)
3963 struct brcmf_if *ifp = netdev_priv(ndev);
3964 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
3965 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3966 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3967 struct ieee80211_channel *notify_channel = NULL;
3968 struct ieee80211_supported_band *band;
3969 struct brcmf_bss_info_le *bi;
3975 brcmf_dbg(TRACE, "Enter\n");
3977 brcmf_get_assoc_ies(cfg);
3978 memcpy(profile->bssid, e->addr, ETH_ALEN);
3979 brcmf_update_bss_info(cfg);
3981 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3987 /* data sent to dongle has to be little endian */
3988 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3989 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3990 buf, WL_BSS_INFO_MAX);
3995 bi = (struct brcmf_bss_info_le *)(buf + 4);
3996 target_channel = bi->ctl_ch ? bi->ctl_ch :
3997 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
3999 if (target_channel <= CH_MAX_2G_CHANNEL)
4000 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4002 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4004 freq = ieee80211_channel_to_frequency(target_channel, band->band);
4005 notify_channel = ieee80211_get_channel(wiphy, freq);
4009 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4010 conn_info->req_ie, conn_info->req_ie_len,
4011 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4012 brcmf_dbg(CONN, "Report roaming result\n");
4014 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4015 brcmf_dbg(TRACE, "Exit\n");
4020 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4021 struct net_device *ndev, const struct brcmf_event_msg *e,
4024 struct brcmf_if *ifp = netdev_priv(ndev);
4025 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4026 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4029 brcmf_dbg(TRACE, "Enter\n");
4031 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4032 &ifp->vif->sme_state)) {
4034 brcmf_get_assoc_ies(cfg);
4035 memcpy(profile->bssid, e->addr, ETH_ALEN);
4036 brcmf_update_bss_info(cfg);
4038 cfg80211_connect_result(ndev,
4039 (u8 *)profile->bssid,
4041 conn_info->req_ie_len,
4043 conn_info->resp_ie_len,
4044 completed ? WLAN_STATUS_SUCCESS :
4045 WLAN_STATUS_AUTH_TIMEOUT,
4048 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4049 &ifp->vif->sme_state);
4050 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4051 completed ? "succeeded" : "failed");
4053 brcmf_dbg(TRACE, "Exit\n");
4058 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4059 struct net_device *ndev,
4060 const struct brcmf_event_msg *e, void *data)
4063 u32 event = e->event_code;
4064 u32 reason = e->reason;
4065 u32 len = e->datalen;
4066 static int generation;
4068 struct station_info sinfo;
4070 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4071 memset(&sinfo, 0, sizeof(sinfo));
4074 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4075 reason == BRCMF_E_STATUS_SUCCESS) {
4076 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4078 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4081 sinfo.assoc_req_ies = data;
4082 sinfo.assoc_req_ies_len = len;
4084 sinfo.generation = generation;
4085 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4086 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4087 (event == BRCMF_E_DEAUTH_IND) ||
4088 (event == BRCMF_E_DEAUTH)) {
4090 sinfo.generation = generation;
4091 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4097 brcmf_notify_connect_status(struct brcmf_if *ifp,
4098 const struct brcmf_event_msg *e, void *data)
4100 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4101 struct net_device *ndev = ifp->ndev;
4102 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4105 if (ifp->vif->mode == WL_MODE_AP) {
4106 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4107 } else if (brcmf_is_linkup(e)) {
4108 brcmf_dbg(CONN, "Linkup\n");
4109 if (brcmf_is_ibssmode(ifp->vif)) {
4110 memcpy(profile->bssid, e->addr, ETH_ALEN);
4111 wl_inform_ibss(cfg, ndev, e->addr);
4112 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4113 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4114 &ifp->vif->sme_state);
4115 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4116 &ifp->vif->sme_state);
4118 brcmf_bss_connect_done(cfg, ndev, e, true);
4119 } else if (brcmf_is_linkdown(e)) {
4120 brcmf_dbg(CONN, "Linkdown\n");
4121 if (!brcmf_is_ibssmode(ifp->vif)) {
4122 brcmf_bss_connect_done(cfg, ndev, e, false);
4123 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4124 &ifp->vif->sme_state))
4125 cfg80211_disconnected(ndev, 0, NULL, 0,
4128 brcmf_link_down(ifp->vif);
4129 brcmf_init_prof(ndev_to_prof(ndev));
4130 } else if (brcmf_is_nonetwork(cfg, e)) {
4131 if (brcmf_is_ibssmode(ifp->vif))
4132 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4133 &ifp->vif->sme_state);
4135 brcmf_bss_connect_done(cfg, ndev, e, false);
4142 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4143 const struct brcmf_event_msg *e, void *data)
4145 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4147 u32 event = e->event_code;
4148 u32 status = e->status;
4150 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4151 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4152 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4154 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4161 brcmf_notify_mic_status(struct brcmf_if *ifp,
4162 const struct brcmf_event_msg *e, void *data)
4164 u16 flags = e->flags;
4165 enum nl80211_key_type key_type;
4167 if (flags & BRCMF_EVENT_MSG_GROUP)
4168 key_type = NL80211_KEYTYPE_GROUP;
4170 key_type = NL80211_KEYTYPE_PAIRWISE;
4172 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4178 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4180 conf->frag_threshold = (u32)-1;
4181 conf->rts_threshold = (u32)-1;
4182 conf->retry_short = (u32)-1;
4183 conf->retry_long = (u32)-1;
4184 conf->tx_power = -1;
4187 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4189 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4190 brcmf_notify_connect_status);
4191 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4192 brcmf_notify_connect_status);
4193 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4194 brcmf_notify_connect_status);
4195 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4196 brcmf_notify_connect_status);
4197 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4198 brcmf_notify_connect_status);
4199 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4200 brcmf_notify_connect_status);
4201 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4202 brcmf_notify_roaming_status);
4203 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4204 brcmf_notify_mic_status);
4205 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4206 brcmf_notify_connect_status);
4207 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4208 brcmf_notify_sched_scan_results);
4211 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4215 kfree(cfg->escan_ioctl_buf);
4216 cfg->escan_ioctl_buf = NULL;
4217 kfree(cfg->extra_buf);
4218 cfg->extra_buf = NULL;
4219 kfree(cfg->pmk_list);
4220 cfg->pmk_list = NULL;
4223 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4225 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4227 goto init_priv_mem_out;
4228 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4229 if (!cfg->escan_ioctl_buf)
4230 goto init_priv_mem_out;
4231 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4232 if (!cfg->extra_buf)
4233 goto init_priv_mem_out;
4234 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4236 goto init_priv_mem_out;
4241 brcmf_deinit_priv_mem(cfg);
4246 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4250 cfg->scan_request = NULL;
4251 cfg->pwr_save = true;
4252 cfg->roam_on = true; /* roam on & off switch.
4253 we enable roam per default */
4254 cfg->active_scan = true; /* we do active scan for
4255 specific scan per default */
4256 cfg->dongle_up = false; /* dongle is not up yet */
4257 err = brcmf_init_priv_mem(cfg);
4260 brcmf_register_event_handlers(cfg);
4261 mutex_init(&cfg->usr_sync);
4262 brcmf_init_escan(cfg);
4263 brcmf_init_conf(cfg->conf);
4268 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4270 cfg->dongle_up = false; /* dongle down */
4271 brcmf_abort_scanning(cfg);
4272 brcmf_deinit_priv_mem(cfg);
4275 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4276 struct device *busdev)
4278 struct net_device *ndev = drvr->iflist[0]->ndev;
4279 struct brcmf_cfg80211_info *cfg;
4280 struct wiphy *wiphy;
4281 struct brcmf_cfg80211_vif *vif;
4282 struct brcmf_if *ifp;
4286 brcmf_err("ndev is invalid\n");
4290 ifp = netdev_priv(ndev);
4291 wiphy = brcmf_setup_wiphy(busdev);
4295 cfg = wiphy_priv(wiphy);
4298 INIT_LIST_HEAD(&cfg->vif_list);
4300 vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false);
4306 err = wl_init_priv(cfg);
4308 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4309 goto cfg80211_attach_out;
4315 cfg80211_attach_out:
4316 brcmf_free_vif(vif);
4320 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4322 struct brcmf_cfg80211_vif *vif;
4323 struct brcmf_cfg80211_vif *tmp;
4325 wl_deinit_priv(cfg);
4326 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4327 brcmf_free_vif(vif);
4332 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
4334 struct brcmf_if *ifp = netdev_priv(ndev);
4336 __le32 roamtrigger[2];
4337 __le32 roam_delta[2];
4340 * Setup timeout if Beacons are lost and roam is
4341 * off to report link down
4344 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4346 brcmf_err("bcn_timeout error (%d)\n", err);
4347 goto dongle_rom_out;
4352 * Enable/Disable built-in roaming to allow supplicant
4353 * to take care of roaming
4355 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4356 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4358 brcmf_err("roam_off error (%d)\n", err);
4359 goto dongle_rom_out;
4362 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4363 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4364 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4365 (void *)roamtrigger, sizeof(roamtrigger));
4367 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4368 goto dongle_rom_out;
4371 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4372 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4373 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4374 (void *)roam_delta, sizeof(roam_delta));
4376 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4377 goto dongle_rom_out;
4385 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
4386 s32 scan_unassoc_time, s32 scan_passive_time)
4388 struct brcmf_if *ifp = netdev_priv(ndev);
4391 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4394 if (err == -EOPNOTSUPP)
4395 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4397 brcmf_err("Scan assoc time error (%d)\n", err);
4398 goto dongle_scantime_out;
4400 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4403 if (err == -EOPNOTSUPP)
4404 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4406 brcmf_err("Scan unassoc time error (%d)\n", err);
4407 goto dongle_scantime_out;
4410 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4413 if (err == -EOPNOTSUPP)
4414 brcmf_dbg(INFO, "Scan passive time is not supported\n");
4416 brcmf_err("Scan passive time error (%d)\n", err);
4417 goto dongle_scantime_out;
4420 dongle_scantime_out:
4424 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4426 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4427 struct wiphy *wiphy;
4432 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4433 &phy_list, sizeof(phy_list));
4435 brcmf_err("error (%d)\n", err);
4439 phy = ((char *)&phy_list)[0];
4440 brcmf_dbg(INFO, "%c phy\n", phy);
4441 if (phy == 'n' || phy == 'a') {
4442 wiphy = cfg_to_wiphy(cfg);
4443 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4449 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4451 return wl_update_wiphybands(cfg);
4454 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4456 struct net_device *ndev;
4457 struct wireless_dev *wdev;
4464 ndev = cfg_to_ndev(cfg);
4465 wdev = ndev->ieee80211_ptr;
4467 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4468 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4470 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4471 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
4474 goto default_conf_out;
4475 brcmf_dbg(INFO, "power save set to %s\n",
4476 (power_mode ? "enabled" : "disabled"));
4478 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
4481 goto default_conf_out;
4482 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4484 if (err && err != -EINPROGRESS)
4485 goto default_conf_out;
4486 err = brcmf_dongle_probecap(cfg);
4488 goto default_conf_out;
4490 /* -EINPROGRESS: Call commit handler */
4494 cfg->dongle_up = true;
4500 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
4502 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4506 return brcmf_config_dongle(ifp->drvr->config);
4509 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
4511 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4514 * While going down, if associated with AP disassociate
4515 * from AP to save power
4517 if (check_vif_up(ifp->vif)) {
4518 brcmf_link_down(ifp->vif);
4520 /* Make sure WPA_Supplicant receives all the event
4521 generated due to DISASSOC call to the fw to keep
4522 the state fw and WPA_Supplicant state consistent
4527 brcmf_abort_scanning(cfg);
4528 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4533 s32 brcmf_cfg80211_up(struct net_device *ndev)
4535 struct brcmf_if *ifp = netdev_priv(ndev);
4536 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4539 mutex_lock(&cfg->usr_sync);
4540 err = __brcmf_cfg80211_up(ifp);
4541 mutex_unlock(&cfg->usr_sync);
4546 s32 brcmf_cfg80211_down(struct net_device *ndev)
4548 struct brcmf_if *ifp = netdev_priv(ndev);
4549 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4552 mutex_lock(&cfg->usr_sync);
4553 err = __brcmf_cfg80211_down(ifp);
4554 mutex_unlock(&cfg->usr_sync);