2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
19 #include <linux/kernel.h>
20 #include <linux/etherdevice.h>
21 #include <net/cfg80211.h>
22 #include <net/netlink.h>
24 #include <brcmu_utils.h>
26 #include <brcmu_wifi.h>
29 #include "wl_cfg80211.h"
32 #define BRCMF_SCAN_IE_LEN_MAX 2048
33 #define BRCMF_PNO_VERSION 2
34 #define BRCMF_PNO_TIME 30
35 #define BRCMF_PNO_REPEAT 4
36 #define BRCMF_PNO_FREQ_EXPO_MAX 3
37 #define BRCMF_PNO_MAX_PFN_COUNT 16
38 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
39 #define BRCMF_PNO_HIDDEN_BIT 2
40 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
41 #define BRCMF_PNO_SCAN_COMPLETE 1
42 #define BRCMF_PNO_SCAN_INCOMPLETE 0
44 #define BRCMF_IFACE_MAX_CNT 2
46 #define TLV_LEN_OFF 1 /* length offset */
47 #define TLV_HDR_LEN 2 /* header length */
48 #define TLV_BODY_OFF 2 /* body offset */
49 #define TLV_OUI_LEN 3 /* oui id length */
50 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
51 #define WPA_OUI_TYPE 1
52 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
53 #define WME_OUI_TYPE 2
55 #define VS_IE_FIXED_HDR_LEN 6
56 #define WPA_IE_VERSION_LEN 2
57 #define WPA_IE_MIN_OUI_LEN 4
58 #define WPA_IE_SUITE_COUNT_LEN 2
60 #define WPA_CIPHER_NONE 0 /* None */
61 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
62 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
63 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
64 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
66 #define RSN_AKM_NONE 0 /* None (IBSS) */
67 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
68 #define RSN_AKM_PSK 2 /* Pre-shared Key */
69 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
70 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
72 #define VNDR_IE_CMD_LEN 4 /* length of the set command
73 * string :"add", "del" (+ NUL)
75 #define VNDR_IE_COUNT_OFFSET 4
76 #define VNDR_IE_PKTFLAG_OFFSET 8
77 #define VNDR_IE_VSIE_OFFSET 12
78 #define VNDR_IE_HDR_SIZE 12
79 #define VNDR_IE_BEACON_FLAG 0x1
80 #define VNDR_IE_PRBRSP_FLAG 0x2
81 #define MAX_VNDR_IE_NUMBER 5
83 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
84 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
86 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
87 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
89 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
91 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
92 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
99 #define CHAN2G(_channel, _freq, _flags) { \
100 .band = IEEE80211_BAND_2GHZ, \
101 .center_freq = (_freq), \
102 .hw_value = (_channel), \
104 .max_antenna_gain = 0, \
108 #define CHAN5G(_channel, _flags) { \
109 .band = IEEE80211_BAND_5GHZ, \
110 .center_freq = 5000 + (5 * (_channel)), \
111 .hw_value = (_channel), \
113 .max_antenna_gain = 0, \
117 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
118 #define RATETAB_ENT(_rateid, _flags) \
120 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
121 .hw_value = (_rateid), \
125 static struct ieee80211_rate __wl_rates[] = {
126 RATETAB_ENT(BRCM_RATE_1M, 0),
127 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
128 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
129 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
130 RATETAB_ENT(BRCM_RATE_6M, 0),
131 RATETAB_ENT(BRCM_RATE_9M, 0),
132 RATETAB_ENT(BRCM_RATE_12M, 0),
133 RATETAB_ENT(BRCM_RATE_18M, 0),
134 RATETAB_ENT(BRCM_RATE_24M, 0),
135 RATETAB_ENT(BRCM_RATE_36M, 0),
136 RATETAB_ENT(BRCM_RATE_48M, 0),
137 RATETAB_ENT(BRCM_RATE_54M, 0),
140 #define wl_a_rates (__wl_rates + 4)
141 #define wl_a_rates_size 8
142 #define wl_g_rates (__wl_rates + 0)
143 #define wl_g_rates_size 12
145 static struct ieee80211_channel __wl_2ghz_channels[] = {
162 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
163 CHAN5G(34, 0), CHAN5G(36, 0),
164 CHAN5G(38, 0), CHAN5G(40, 0),
165 CHAN5G(42, 0), CHAN5G(44, 0),
166 CHAN5G(46, 0), CHAN5G(48, 0),
167 CHAN5G(52, 0), CHAN5G(56, 0),
168 CHAN5G(60, 0), CHAN5G(64, 0),
169 CHAN5G(100, 0), CHAN5G(104, 0),
170 CHAN5G(108, 0), CHAN5G(112, 0),
171 CHAN5G(116, 0), CHAN5G(120, 0),
172 CHAN5G(124, 0), CHAN5G(128, 0),
173 CHAN5G(132, 0), CHAN5G(136, 0),
174 CHAN5G(140, 0), CHAN5G(149, 0),
175 CHAN5G(153, 0), CHAN5G(157, 0),
176 CHAN5G(161, 0), CHAN5G(165, 0),
177 CHAN5G(184, 0), CHAN5G(188, 0),
178 CHAN5G(192, 0), CHAN5G(196, 0),
179 CHAN5G(200, 0), CHAN5G(204, 0),
180 CHAN5G(208, 0), CHAN5G(212, 0),
184 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
185 CHAN5G(32, 0), CHAN5G(34, 0),
186 CHAN5G(36, 0), CHAN5G(38, 0),
187 CHAN5G(40, 0), CHAN5G(42, 0),
188 CHAN5G(44, 0), CHAN5G(46, 0),
189 CHAN5G(48, 0), CHAN5G(50, 0),
190 CHAN5G(52, 0), CHAN5G(54, 0),
191 CHAN5G(56, 0), CHAN5G(58, 0),
192 CHAN5G(60, 0), CHAN5G(62, 0),
193 CHAN5G(64, 0), CHAN5G(66, 0),
194 CHAN5G(68, 0), CHAN5G(70, 0),
195 CHAN5G(72, 0), CHAN5G(74, 0),
196 CHAN5G(76, 0), CHAN5G(78, 0),
197 CHAN5G(80, 0), CHAN5G(82, 0),
198 CHAN5G(84, 0), CHAN5G(86, 0),
199 CHAN5G(88, 0), CHAN5G(90, 0),
200 CHAN5G(92, 0), CHAN5G(94, 0),
201 CHAN5G(96, 0), CHAN5G(98, 0),
202 CHAN5G(100, 0), CHAN5G(102, 0),
203 CHAN5G(104, 0), CHAN5G(106, 0),
204 CHAN5G(108, 0), CHAN5G(110, 0),
205 CHAN5G(112, 0), CHAN5G(114, 0),
206 CHAN5G(116, 0), CHAN5G(118, 0),
207 CHAN5G(120, 0), CHAN5G(122, 0),
208 CHAN5G(124, 0), CHAN5G(126, 0),
209 CHAN5G(128, 0), CHAN5G(130, 0),
210 CHAN5G(132, 0), CHAN5G(134, 0),
211 CHAN5G(136, 0), CHAN5G(138, 0),
212 CHAN5G(140, 0), CHAN5G(142, 0),
213 CHAN5G(144, 0), CHAN5G(145, 0),
214 CHAN5G(146, 0), CHAN5G(147, 0),
215 CHAN5G(148, 0), CHAN5G(149, 0),
216 CHAN5G(150, 0), CHAN5G(151, 0),
217 CHAN5G(152, 0), CHAN5G(153, 0),
218 CHAN5G(154, 0), CHAN5G(155, 0),
219 CHAN5G(156, 0), CHAN5G(157, 0),
220 CHAN5G(158, 0), CHAN5G(159, 0),
221 CHAN5G(160, 0), CHAN5G(161, 0),
222 CHAN5G(162, 0), CHAN5G(163, 0),
223 CHAN5G(164, 0), CHAN5G(165, 0),
224 CHAN5G(166, 0), CHAN5G(168, 0),
225 CHAN5G(170, 0), CHAN5G(172, 0),
226 CHAN5G(174, 0), CHAN5G(176, 0),
227 CHAN5G(178, 0), CHAN5G(180, 0),
228 CHAN5G(182, 0), CHAN5G(184, 0),
229 CHAN5G(186, 0), CHAN5G(188, 0),
230 CHAN5G(190, 0), CHAN5G(192, 0),
231 CHAN5G(194, 0), CHAN5G(196, 0),
232 CHAN5G(198, 0), CHAN5G(200, 0),
233 CHAN5G(202, 0), CHAN5G(204, 0),
234 CHAN5G(206, 0), CHAN5G(208, 0),
235 CHAN5G(210, 0), CHAN5G(212, 0),
236 CHAN5G(214, 0), CHAN5G(216, 0),
237 CHAN5G(218, 0), CHAN5G(220, 0),
238 CHAN5G(222, 0), CHAN5G(224, 0),
239 CHAN5G(226, 0), CHAN5G(228, 0),
242 static struct ieee80211_supported_band __wl_band_2ghz = {
243 .band = IEEE80211_BAND_2GHZ,
244 .channels = __wl_2ghz_channels,
245 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
246 .bitrates = wl_g_rates,
247 .n_bitrates = wl_g_rates_size,
250 static struct ieee80211_supported_band __wl_band_5ghz_a = {
251 .band = IEEE80211_BAND_5GHZ,
252 .channels = __wl_5ghz_a_channels,
253 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
254 .bitrates = wl_a_rates,
255 .n_bitrates = wl_a_rates_size,
258 static struct ieee80211_supported_band __wl_band_5ghz_n = {
259 .band = IEEE80211_BAND_5GHZ,
260 .channels = __wl_5ghz_n_channels,
261 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
262 .bitrates = wl_a_rates,
263 .n_bitrates = wl_a_rates_size,
266 static const u32 __wl_cipher_suites[] = {
267 WLAN_CIPHER_SUITE_WEP40,
268 WLAN_CIPHER_SUITE_WEP104,
269 WLAN_CIPHER_SUITE_TKIP,
270 WLAN_CIPHER_SUITE_CCMP,
271 WLAN_CIPHER_SUITE_AES_CMAC,
274 /* tag_ID/length/value_buffer tuple */
281 /* Vendor specific ie. id = 221, oui and type defines exact ie */
282 struct brcmf_vs_tlv {
289 struct parsed_vndr_ie_info {
291 u32 ie_len; /* total length including id & length field */
292 struct brcmf_vs_tlv vndrie;
295 struct parsed_vndr_ies {
297 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
300 /* Quarter dBm units to mW
301 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
302 * Table is offset so the last entry is largest mW value that fits in
306 #define QDBM_OFFSET 153 /* Offset for first entry */
307 #define QDBM_TABLE_LEN 40 /* Table size */
309 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
310 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
312 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
314 /* Largest mW value that will round down to the last table entry,
315 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
316 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
317 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
319 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
321 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
322 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
323 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
324 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
325 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
326 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
327 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
330 static u16 brcmf_qdbm_to_mw(u8 qdbm)
333 int idx = qdbm - QDBM_OFFSET;
335 if (idx >= QDBM_TABLE_LEN)
336 /* clamp to max u16 mW value */
339 /* scale the qdBm index up to the range of the table 0-40
340 * where an offset of 40 qdBm equals a factor of 10 mW.
347 /* return the mW value scaled down to the correct factor of 10,
348 * adding in factor/2 to get proper rounding.
350 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
353 static u8 brcmf_mw_to_qdbm(u16 mw)
360 /* handle boundary case */
364 offset = QDBM_OFFSET;
366 /* move mw into the range of the table */
367 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
372 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
373 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
374 nqdBm_to_mW_map[qdbm]) / 2;
375 if (mw_uint < boundary)
384 static u16 channel_to_chanspec(struct ieee80211_channel *ch)
388 chanspec = ieee80211_frequency_to_channel(ch->center_freq);
389 chanspec &= WL_CHANSPEC_CHAN_MASK;
391 if (ch->band == IEEE80211_BAND_2GHZ)
392 chanspec |= WL_CHANSPEC_BAND_2G;
394 chanspec |= WL_CHANSPEC_BAND_5G;
396 chanspec |= WL_CHANSPEC_BW_20;
397 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
402 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
403 struct brcmf_wsec_key_le *key_le)
405 key_le->index = cpu_to_le32(key->index);
406 key_le->len = cpu_to_le32(key->len);
407 key_le->algo = cpu_to_le32(key->algo);
408 key_le->flags = cpu_to_le32(key->flags);
409 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
410 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
411 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
412 memcpy(key_le->data, key->data, sizeof(key->data));
413 memcpy(key_le->ea, key->ea, sizeof(key->ea));
417 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
420 struct brcmf_wsec_key_le key_le;
422 convert_key_from_CPU(key, &key_le);
424 brcmf_netdev_wait_pend8021x(ndev);
426 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
430 brcmf_err("wsec_key error (%d)\n", err);
435 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
436 enum nl80211_iftype type, u32 *flags,
437 struct vif_params *params)
439 struct brcmf_if *ifp = netdev_priv(ndev);
440 struct brcmf_cfg80211_vif *vif = ifp->vif;
445 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
448 case NL80211_IFTYPE_MONITOR:
449 case NL80211_IFTYPE_WDS:
450 brcmf_err("type (%d) : currently we do not support this type\n",
453 case NL80211_IFTYPE_ADHOC:
454 vif->mode = WL_MODE_IBSS;
457 case NL80211_IFTYPE_STATION:
458 vif->mode = WL_MODE_BSS;
461 case NL80211_IFTYPE_AP:
462 vif->mode = WL_MODE_AP;
471 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
472 brcmf_dbg(INFO, "IF Type = AP\n");
474 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
476 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
480 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
483 ndev->ieee80211_ptr->iftype = type;
486 brcmf_dbg(TRACE, "Exit\n");
491 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
493 struct brcmf_if *ifp = netdev_priv(ndev);
496 if (check_vif_up(ifp->vif)) {
497 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
499 brcmf_err("fail to set mpc\n");
502 brcmf_dbg(INFO, "MPC : %d\n", mpc);
506 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
507 struct cfg80211_scan_request *request)
515 struct brcmf_ssid_le ssid_le;
517 memset(params_le->bssid, 0xFF, ETH_ALEN);
518 params_le->bss_type = DOT11_BSSTYPE_ANY;
519 params_le->scan_type = 0;
520 params_le->channel_num = 0;
521 params_le->nprobes = cpu_to_le32(-1);
522 params_le->active_time = cpu_to_le32(-1);
523 params_le->passive_time = cpu_to_le32(-1);
524 params_le->home_time = cpu_to_le32(-1);
525 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
527 /* if request is null exit so it will be all channel broadcast scan */
531 n_ssids = request->n_ssids;
532 n_channels = request->n_channels;
533 /* Copy channel array if applicable */
534 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
536 if (n_channels > 0) {
537 for (i = 0; i < n_channels; i++) {
538 chanspec = channel_to_chanspec(request->channels[i]);
539 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
540 request->channels[i]->hw_value, chanspec);
541 params_le->channel_list[i] = cpu_to_le16(chanspec);
544 brcmf_dbg(SCAN, "Scanning all channels\n");
546 /* Copy ssid array if applicable */
547 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
549 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
550 n_channels * sizeof(u16);
551 offset = roundup(offset, sizeof(u32));
552 ptr = (char *)params_le + offset;
553 for (i = 0; i < n_ssids; i++) {
554 memset(&ssid_le, 0, sizeof(ssid_le));
556 cpu_to_le32(request->ssids[i].ssid_len);
557 memcpy(ssid_le.SSID, request->ssids[i].ssid,
558 request->ssids[i].ssid_len);
559 if (!ssid_le.SSID_len)
560 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
562 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
563 i, ssid_le.SSID, ssid_le.SSID_len);
564 memcpy(ptr, &ssid_le, sizeof(ssid_le));
565 ptr += sizeof(ssid_le);
568 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
569 if ((request->ssids) && request->ssids->ssid_len) {
570 brcmf_dbg(SCAN, "SSID %s len=%d\n",
571 params_le->ssid_le.SSID,
572 request->ssids->ssid_len);
573 params_le->ssid_le.SSID_len =
574 cpu_to_le32(request->ssids->ssid_len);
575 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
576 request->ssids->ssid_len);
579 /* Adding mask to channel numbers */
580 params_le->channel_num =
581 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
582 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
586 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
587 struct net_device *ndev,
588 bool aborted, bool fw_abort)
590 struct brcmf_scan_params_le params_le;
591 struct cfg80211_scan_request *scan_request;
594 brcmf_dbg(SCAN, "Enter\n");
596 /* clear scan request, because the FW abort can cause a second call */
597 /* to this functon and might cause a double cfg80211_scan_done */
598 scan_request = cfg->scan_request;
599 cfg->scan_request = NULL;
601 if (timer_pending(&cfg->escan_timeout))
602 del_timer_sync(&cfg->escan_timeout);
605 /* Do a scan abort to stop the driver's scan engine */
606 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
607 memset(¶ms_le, 0, sizeof(params_le));
608 memset(params_le.bssid, 0xFF, ETH_ALEN);
609 params_le.bss_type = DOT11_BSSTYPE_ANY;
610 params_le.scan_type = 0;
611 params_le.channel_num = cpu_to_le32(1);
612 params_le.nprobes = cpu_to_le32(1);
613 params_le.active_time = cpu_to_le32(-1);
614 params_le.passive_time = cpu_to_le32(-1);
615 params_le.home_time = cpu_to_le32(-1);
616 /* Scan is aborted by setting channel_list[0] to -1 */
617 params_le.channel_list[0] = cpu_to_le16(-1);
618 /* E-Scan (or anyother type) can be aborted by SCAN */
619 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
620 ¶ms_le, sizeof(params_le));
622 brcmf_err("Scan abort failed\n");
625 * e-scan can be initiated by scheduled scan
626 * which takes precedence.
628 if (cfg->sched_escan) {
629 brcmf_dbg(SCAN, "scheduled scan completed\n");
630 cfg->sched_escan = false;
632 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
633 brcmf_set_mpc(ndev, 1);
634 } else if (scan_request) {
635 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
636 aborted ? "Aborted" : "Done");
637 cfg80211_scan_done(scan_request, aborted);
638 brcmf_set_mpc(ndev, 1);
640 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
641 brcmf_err("Scan complete while device not scanning\n");
649 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
650 struct cfg80211_scan_request *request, u16 action)
652 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
653 offsetof(struct brcmf_escan_params_le, params_le);
654 struct brcmf_escan_params_le *params;
657 brcmf_dbg(SCAN, "E-SCAN START\n");
659 if (request != NULL) {
660 /* Allocate space for populating ssids in struct */
661 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
663 /* Allocate space for populating ssids in struct */
664 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
667 params = kzalloc(params_size, GFP_KERNEL);
672 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
673 brcmf_escan_prep(¶ms->params_le, request);
674 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
675 params->action = cpu_to_le16(action);
676 params->sync_id = cpu_to_le16(0x1234);
678 err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan",
679 params, params_size);
682 brcmf_dbg(INFO, "system busy : escan canceled\n");
684 brcmf_err("error (%d)\n", err);
693 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
694 struct net_device *ndev, struct cfg80211_scan_request *request)
698 struct brcmf_scan_results *results;
700 brcmf_dbg(SCAN, "Enter\n");
701 cfg->escan_info.ndev = ndev;
702 cfg->escan_info.wiphy = wiphy;
703 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
704 passive_scan = cfg->active_scan ? 0 : 1;
705 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
708 brcmf_err("error (%d)\n", err);
711 brcmf_set_mpc(ndev, 0);
712 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
713 results->version = 0;
715 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
717 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
719 brcmf_set_mpc(ndev, 1);
724 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
725 struct cfg80211_scan_request *request,
726 struct cfg80211_ssid *this_ssid)
728 struct brcmf_if *ifp = netdev_priv(ndev);
729 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
730 struct cfg80211_ssid *ssids;
731 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
738 brcmf_dbg(SCAN, "START ESCAN\n");
740 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
741 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
744 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
745 brcmf_err("Scanning being aborted: status (%lu)\n",
749 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
750 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
754 /* Arm scan timeout timer */
755 mod_timer(&cfg->escan_timeout, jiffies +
756 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
761 ssids = request->ssids;
765 /* we don't do escan in ibss */
769 cfg->scan_request = request;
770 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
772 err = brcmf_do_escan(cfg, wiphy, ndev, request);
776 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
777 ssids->ssid, ssids->ssid_len);
778 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
779 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
780 sr->ssid_le.SSID_len = cpu_to_le32(0);
783 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
784 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
787 brcmf_dbg(SCAN, "Broadcast scan\n");
789 passive_scan = cfg->active_scan ? 0 : 1;
790 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
793 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
796 brcmf_set_mpc(ndev, 0);
797 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
798 &sr->ssid_le, sizeof(sr->ssid_le));
801 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
804 brcmf_err("WLC_SCAN error (%d)\n", err);
806 brcmf_set_mpc(ndev, 1);
814 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
815 if (timer_pending(&cfg->escan_timeout))
816 del_timer_sync(&cfg->escan_timeout);
817 cfg->scan_request = NULL;
822 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
824 struct net_device *ndev = request->wdev->netdev;
827 brcmf_dbg(TRACE, "Enter\n");
829 if (!check_vif_up(container_of(request->wdev,
830 struct brcmf_cfg80211_vif, wdev)))
833 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
836 brcmf_err("scan error (%d)\n", err);
838 brcmf_dbg(TRACE, "Exit\n");
842 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
846 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
849 brcmf_err("Error (%d)\n", err);
854 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
858 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
861 brcmf_err("Error (%d)\n", err);
866 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
869 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
871 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
873 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
879 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
881 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
882 struct net_device *ndev = cfg_to_ndev(cfg);
883 struct brcmf_if *ifp = netdev_priv(ndev);
886 brcmf_dbg(TRACE, "Enter\n");
887 if (!check_vif_up(ifp->vif))
890 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
891 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
892 cfg->conf->rts_threshold = wiphy->rts_threshold;
893 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
897 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
898 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
899 cfg->conf->frag_threshold = wiphy->frag_threshold;
900 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
904 if (changed & WIPHY_PARAM_RETRY_LONG
905 && (cfg->conf->retry_long != wiphy->retry_long)) {
906 cfg->conf->retry_long = wiphy->retry_long;
907 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
911 if (changed & WIPHY_PARAM_RETRY_SHORT
912 && (cfg->conf->retry_short != wiphy->retry_short)) {
913 cfg->conf->retry_short = wiphy->retry_short;
914 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
920 brcmf_dbg(TRACE, "Exit\n");
924 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
926 memset(prof, 0, sizeof(*prof));
929 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
933 brcmf_dbg(TRACE, "Enter\n");
935 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
936 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
937 err = brcmf_fil_cmd_data_set(vif->ifp,
938 BRCMF_C_DISASSOC, NULL, 0);
940 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
941 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
943 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
944 brcmf_dbg(TRACE, "Exit\n");
948 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
949 struct cfg80211_ibss_params *params)
951 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
952 struct brcmf_if *ifp = netdev_priv(ndev);
953 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
954 struct brcmf_join_params join_params;
955 size_t join_params_size = 0;
961 brcmf_dbg(TRACE, "Enter\n");
962 if (!check_vif_up(ifp->vif))
966 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
968 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
972 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
975 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
977 brcmf_dbg(CONN, "No BSSID specified\n");
979 if (params->chandef.chan)
980 brcmf_dbg(CONN, "channel: %d\n",
981 params->chandef.chan->center_freq);
983 brcmf_dbg(CONN, "no channel specified\n");
985 if (params->channel_fixed)
986 brcmf_dbg(CONN, "fixed channel required\n");
988 brcmf_dbg(CONN, "no fixed channel required\n");
990 if (params->ie && params->ie_len)
991 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
993 brcmf_dbg(CONN, "no ie specified\n");
995 if (params->beacon_interval)
996 brcmf_dbg(CONN, "beacon interval: %d\n",
997 params->beacon_interval);
999 brcmf_dbg(CONN, "no beacon interval specified\n");
1001 if (params->basic_rates)
1002 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1004 brcmf_dbg(CONN, "no basic rates specified\n");
1006 if (params->privacy)
1007 brcmf_dbg(CONN, "privacy required\n");
1009 brcmf_dbg(CONN, "no privacy required\n");
1011 /* Configure Privacy for starter */
1012 if (params->privacy)
1013 wsec |= WEP_ENABLED;
1015 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1017 brcmf_err("wsec failed (%d)\n", err);
1021 /* Configure Beacon Interval for starter */
1022 if (params->beacon_interval)
1023 bcnprd = params->beacon_interval;
1027 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1029 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1033 /* Configure required join parameter */
1034 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1037 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1038 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1039 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1040 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1041 join_params_size = sizeof(join_params.ssid_le);
1044 if (params->bssid) {
1045 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1046 join_params_size = sizeof(join_params.ssid_le) +
1047 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1048 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1050 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1051 memset(profile->bssid, 0, ETH_ALEN);
1055 if (params->chandef.chan) {
1059 ieee80211_frequency_to_channel(
1060 params->chandef.chan->center_freq);
1061 if (params->channel_fixed) {
1062 /* adding chanspec */
1063 chanspec = channel_to_chanspec(params->chandef.chan);
1064 join_params.params_le.chanspec_list[0] =
1065 cpu_to_le16(chanspec);
1066 join_params.params_le.chanspec_num = cpu_to_le32(1);
1067 join_params_size += sizeof(join_params.params_le);
1070 /* set channel for starter */
1071 target_channel = cfg->channel;
1072 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1075 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1081 cfg->ibss_starter = false;
1084 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1085 &join_params, join_params_size);
1087 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1093 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1094 brcmf_dbg(TRACE, "Exit\n");
1099 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1101 struct brcmf_if *ifp = netdev_priv(ndev);
1104 brcmf_dbg(TRACE, "Enter\n");
1105 if (!check_vif_up(ifp->vif))
1108 brcmf_link_down(ifp->vif);
1110 brcmf_dbg(TRACE, "Exit\n");
1115 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1116 struct cfg80211_connect_params *sme)
1118 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1119 struct brcmf_cfg80211_security *sec;
1123 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1124 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1125 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1126 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1128 val = WPA_AUTH_DISABLED;
1129 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1130 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val);
1132 brcmf_err("set wpa_auth failed (%d)\n", err);
1135 sec = &profile->sec;
1136 sec->wpa_versions = sme->crypto.wpa_versions;
1140 static s32 brcmf_set_auth_type(struct net_device *ndev,
1141 struct cfg80211_connect_params *sme)
1143 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1144 struct brcmf_cfg80211_security *sec;
1148 switch (sme->auth_type) {
1149 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1151 brcmf_dbg(CONN, "open system\n");
1153 case NL80211_AUTHTYPE_SHARED_KEY:
1155 brcmf_dbg(CONN, "shared key\n");
1157 case NL80211_AUTHTYPE_AUTOMATIC:
1159 brcmf_dbg(CONN, "automatic\n");
1161 case NL80211_AUTHTYPE_NETWORK_EAP:
1162 brcmf_dbg(CONN, "network eap\n");
1165 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1169 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val);
1171 brcmf_err("set auth failed (%d)\n", err);
1174 sec = &profile->sec;
1175 sec->auth_type = sme->auth_type;
1180 brcmf_set_set_cipher(struct net_device *ndev,
1181 struct cfg80211_connect_params *sme)
1183 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1184 struct brcmf_cfg80211_security *sec;
1189 if (sme->crypto.n_ciphers_pairwise) {
1190 switch (sme->crypto.ciphers_pairwise[0]) {
1191 case WLAN_CIPHER_SUITE_WEP40:
1192 case WLAN_CIPHER_SUITE_WEP104:
1195 case WLAN_CIPHER_SUITE_TKIP:
1196 pval = TKIP_ENABLED;
1198 case WLAN_CIPHER_SUITE_CCMP:
1201 case WLAN_CIPHER_SUITE_AES_CMAC:
1205 brcmf_err("invalid cipher pairwise (%d)\n",
1206 sme->crypto.ciphers_pairwise[0]);
1210 if (sme->crypto.cipher_group) {
1211 switch (sme->crypto.cipher_group) {
1212 case WLAN_CIPHER_SUITE_WEP40:
1213 case WLAN_CIPHER_SUITE_WEP104:
1216 case WLAN_CIPHER_SUITE_TKIP:
1217 gval = TKIP_ENABLED;
1219 case WLAN_CIPHER_SUITE_CCMP:
1222 case WLAN_CIPHER_SUITE_AES_CMAC:
1226 brcmf_err("invalid cipher group (%d)\n",
1227 sme->crypto.cipher_group);
1232 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1233 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval);
1235 brcmf_err("error (%d)\n", err);
1239 sec = &profile->sec;
1240 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1241 sec->cipher_group = sme->crypto.cipher_group;
1247 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1249 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1250 struct brcmf_cfg80211_security *sec;
1254 if (sme->crypto.n_akm_suites) {
1255 err = brcmf_fil_iovar_int_get(netdev_priv(ndev),
1258 brcmf_err("could not get wpa_auth (%d)\n", err);
1261 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1262 switch (sme->crypto.akm_suites[0]) {
1263 case WLAN_AKM_SUITE_8021X:
1264 val = WPA_AUTH_UNSPECIFIED;
1266 case WLAN_AKM_SUITE_PSK:
1270 brcmf_err("invalid cipher group (%d)\n",
1271 sme->crypto.cipher_group);
1274 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1275 switch (sme->crypto.akm_suites[0]) {
1276 case WLAN_AKM_SUITE_8021X:
1277 val = WPA2_AUTH_UNSPECIFIED;
1279 case WLAN_AKM_SUITE_PSK:
1280 val = WPA2_AUTH_PSK;
1283 brcmf_err("invalid cipher group (%d)\n",
1284 sme->crypto.cipher_group);
1289 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1290 err = brcmf_fil_iovar_int_set(netdev_priv(ndev),
1293 brcmf_err("could not set wpa_auth (%d)\n", err);
1297 sec = &profile->sec;
1298 sec->wpa_auth = sme->crypto.akm_suites[0];
1304 brcmf_set_sharedkey(struct net_device *ndev,
1305 struct cfg80211_connect_params *sme)
1307 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1308 struct brcmf_cfg80211_security *sec;
1309 struct brcmf_wsec_key key;
1313 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1315 if (sme->key_len == 0)
1318 sec = &profile->sec;
1319 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1320 sec->wpa_versions, sec->cipher_pairwise);
1322 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1325 if (!(sec->cipher_pairwise &
1326 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1329 memset(&key, 0, sizeof(key));
1330 key.len = (u32) sme->key_len;
1331 key.index = (u32) sme->key_idx;
1332 if (key.len > sizeof(key.data)) {
1333 brcmf_err("Too long key length (%u)\n", key.len);
1336 memcpy(key.data, sme->key, key.len);
1337 key.flags = BRCMF_PRIMARY_KEY;
1338 switch (sec->cipher_pairwise) {
1339 case WLAN_CIPHER_SUITE_WEP40:
1340 key.algo = CRYPTO_ALGO_WEP1;
1342 case WLAN_CIPHER_SUITE_WEP104:
1343 key.algo = CRYPTO_ALGO_WEP128;
1346 brcmf_err("Invalid algorithm (%d)\n",
1347 sme->crypto.ciphers_pairwise[0]);
1350 /* Set the new key/index */
1351 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1352 key.len, key.index, key.algo);
1353 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1354 err = send_key_to_dongle(ndev, &key);
1358 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1359 brcmf_dbg(CONN, "set auth_type to shared key\n");
1360 val = WL_AUTH_SHARED_KEY; /* shared key */
1361 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1363 brcmf_err("set auth failed (%d)\n", err);
1369 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1370 enum nl80211_auth_type type)
1373 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1374 /* shift to ignore chip revision */
1375 ci = brcmf_get_chip_info(ifp) >> 4;
1378 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1379 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1388 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1389 struct cfg80211_connect_params *sme)
1391 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1392 struct brcmf_if *ifp = netdev_priv(ndev);
1393 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1394 struct ieee80211_channel *chan = sme->channel;
1395 struct brcmf_join_params join_params;
1396 size_t join_params_size;
1397 struct brcmf_ssid ssid;
1402 brcmf_dbg(TRACE, "Enter\n");
1403 if (!check_vif_up(ifp->vif))
1407 brcmf_err("Invalid ssid\n");
1411 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1415 ieee80211_frequency_to_channel(chan->center_freq);
1416 chanspec = channel_to_chanspec(chan);
1417 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1418 cfg->channel, chan->center_freq, chanspec);
1424 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1426 err = brcmf_set_wpa_version(ndev, sme);
1428 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1432 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1433 err = brcmf_set_auth_type(ndev, sme);
1435 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1439 err = brcmf_set_set_cipher(ndev, sme);
1441 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1445 err = brcmf_set_key_mgmt(ndev, sme);
1447 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1451 err = brcmf_set_sharedkey(ndev, sme);
1453 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1457 memset(&join_params, 0, sizeof(join_params));
1458 join_params_size = sizeof(join_params.ssid_le);
1460 profile->ssid.SSID_len = min_t(u32,
1461 sizeof(ssid.SSID), (u32)sme->ssid_len);
1462 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1463 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1464 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1466 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1468 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1469 brcmf_dbg(CONN, "ssid \"%s\", len (%d)\n",
1470 ssid.SSID, ssid.SSID_len);
1473 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1474 join_params.params_le.chanspec_num = cpu_to_le32(1);
1475 join_params_size += sizeof(join_params.params_le);
1477 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1478 &join_params, join_params_size);
1480 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1484 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1485 brcmf_dbg(TRACE, "Exit\n");
1490 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1493 struct brcmf_if *ifp = netdev_priv(ndev);
1494 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1495 struct brcmf_scb_val_le scbval;
1498 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1499 if (!check_vif_up(ifp->vif))
1502 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1504 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1505 scbval.val = cpu_to_le32(reason_code);
1506 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1507 &scbval, sizeof(scbval));
1509 brcmf_err("error (%d)\n", err);
1511 brcmf_dbg(TRACE, "Exit\n");
1516 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1517 enum nl80211_tx_power_setting type, s32 mbm)
1520 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1521 struct net_device *ndev = cfg_to_ndev(cfg);
1522 struct brcmf_if *ifp = netdev_priv(ndev);
1526 s32 dbm = MBM_TO_DBM(mbm);
1528 brcmf_dbg(TRACE, "Enter\n");
1529 if (!check_vif_up(ifp->vif))
1533 case NL80211_TX_POWER_AUTOMATIC:
1535 case NL80211_TX_POWER_LIMITED:
1536 case NL80211_TX_POWER_FIXED:
1538 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1544 /* Make sure radio is off or on as far as software is concerned */
1545 disable = WL_RADIO_SW_DISABLE << 16;
1546 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1548 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1553 txpwrmw = (u16) dbm;
1554 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1555 (s32)brcmf_mw_to_qdbm(txpwrmw));
1557 brcmf_err("qtxpower error (%d)\n", err);
1558 cfg->conf->tx_power = dbm;
1561 brcmf_dbg(TRACE, "Exit\n");
1565 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1566 struct wireless_dev *wdev,
1569 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1570 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1575 brcmf_dbg(TRACE, "Enter\n");
1576 if (!check_vif_up(ifp->vif))
1579 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1581 brcmf_err("error (%d)\n", err);
1585 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1586 *dbm = (s32) brcmf_qdbm_to_mw(result);
1589 brcmf_dbg(TRACE, "Exit\n");
1594 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1595 u8 key_idx, bool unicast, bool multicast)
1597 struct brcmf_if *ifp = netdev_priv(ndev);
1602 brcmf_dbg(TRACE, "Enter\n");
1603 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1604 if (!check_vif_up(ifp->vif))
1607 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1609 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1613 if (wsec & WEP_ENABLED) {
1614 /* Just select a new current key */
1616 err = brcmf_fil_cmd_int_set(ifp,
1617 BRCMF_C_SET_KEY_PRIMARY, index);
1619 brcmf_err("error (%d)\n", err);
1622 brcmf_dbg(TRACE, "Exit\n");
1627 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1628 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1630 struct brcmf_wsec_key key;
1633 memset(&key, 0, sizeof(key));
1634 key.index = (u32) key_idx;
1635 /* Instead of bcast for ea address for default wep keys,
1636 driver needs it to be Null */
1637 if (!is_multicast_ether_addr(mac_addr))
1638 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1639 key.len = (u32) params->key_len;
1640 /* check for key index change */
1643 err = send_key_to_dongle(ndev, &key);
1645 brcmf_err("key delete error (%d)\n", err);
1647 if (key.len > sizeof(key.data)) {
1648 brcmf_err("Invalid key length (%d)\n", key.len);
1652 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1653 memcpy(key.data, params->key, key.len);
1655 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1657 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1658 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1659 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1662 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1663 if (params->seq && params->seq_len == 6) {
1666 ivptr = (u8 *) params->seq;
1667 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1668 (ivptr[3] << 8) | ivptr[2];
1669 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1670 key.iv_initialized = true;
1673 switch (params->cipher) {
1674 case WLAN_CIPHER_SUITE_WEP40:
1675 key.algo = CRYPTO_ALGO_WEP1;
1676 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1678 case WLAN_CIPHER_SUITE_WEP104:
1679 key.algo = CRYPTO_ALGO_WEP128;
1680 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1682 case WLAN_CIPHER_SUITE_TKIP:
1683 key.algo = CRYPTO_ALGO_TKIP;
1684 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1686 case WLAN_CIPHER_SUITE_AES_CMAC:
1687 key.algo = CRYPTO_ALGO_AES_CCM;
1688 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1690 case WLAN_CIPHER_SUITE_CCMP:
1691 key.algo = CRYPTO_ALGO_AES_CCM;
1692 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1695 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1698 err = send_key_to_dongle(ndev, &key);
1700 brcmf_err("wsec_key error (%d)\n", err);
1706 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1707 u8 key_idx, bool pairwise, const u8 *mac_addr,
1708 struct key_params *params)
1710 struct brcmf_if *ifp = netdev_priv(ndev);
1711 struct brcmf_wsec_key key;
1717 brcmf_dbg(TRACE, "Enter\n");
1718 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1719 if (!check_vif_up(ifp->vif))
1723 brcmf_dbg(TRACE, "Exit");
1724 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1726 memset(&key, 0, sizeof(key));
1728 key.len = (u32) params->key_len;
1729 key.index = (u32) key_idx;
1731 if (key.len > sizeof(key.data)) {
1732 brcmf_err("Too long key length (%u)\n", key.len);
1736 memcpy(key.data, params->key, key.len);
1738 key.flags = BRCMF_PRIMARY_KEY;
1739 switch (params->cipher) {
1740 case WLAN_CIPHER_SUITE_WEP40:
1741 key.algo = CRYPTO_ALGO_WEP1;
1743 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1745 case WLAN_CIPHER_SUITE_WEP104:
1746 key.algo = CRYPTO_ALGO_WEP128;
1748 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1750 case WLAN_CIPHER_SUITE_TKIP:
1751 if (ifp->vif->mode != WL_MODE_AP) {
1752 brcmf_dbg(CONN, "Swapping key\n");
1753 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1754 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1755 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1757 key.algo = CRYPTO_ALGO_TKIP;
1759 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1761 case WLAN_CIPHER_SUITE_AES_CMAC:
1762 key.algo = CRYPTO_ALGO_AES_CCM;
1764 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1766 case WLAN_CIPHER_SUITE_CCMP:
1767 key.algo = CRYPTO_ALGO_AES_CCM;
1769 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1772 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1777 err = send_key_to_dongle(ndev, &key);
1781 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1783 brcmf_err("get wsec error (%d)\n", err);
1787 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1789 brcmf_err("set wsec error (%d)\n", err);
1794 brcmf_dbg(TRACE, "Exit\n");
1799 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1800 u8 key_idx, bool pairwise, const u8 *mac_addr)
1802 struct brcmf_if *ifp = netdev_priv(ndev);
1803 struct brcmf_wsec_key key;
1806 brcmf_dbg(TRACE, "Enter\n");
1807 if (!check_vif_up(ifp->vif))
1810 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
1811 /* we ignore this key index in this case */
1812 brcmf_err("invalid key index (%d)\n", key_idx);
1816 memset(&key, 0, sizeof(key));
1818 key.index = (u32) key_idx;
1819 key.flags = BRCMF_PRIMARY_KEY;
1820 key.algo = CRYPTO_ALGO_OFF;
1822 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1824 /* Set the new key/index */
1825 err = send_key_to_dongle(ndev, &key);
1827 brcmf_dbg(TRACE, "Exit\n");
1832 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1833 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1834 void (*callback) (void *cookie, struct key_params * params))
1836 struct key_params params;
1837 struct brcmf_if *ifp = netdev_priv(ndev);
1838 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1839 struct brcmf_cfg80211_security *sec;
1843 brcmf_dbg(TRACE, "Enter\n");
1844 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1845 if (!check_vif_up(ifp->vif))
1848 memset(¶ms, 0, sizeof(params));
1850 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1852 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1853 /* Ignore this error, may happen during DISASSOC */
1857 switch (wsec & ~SES_OW_ENABLED) {
1859 sec = &profile->sec;
1860 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1861 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1862 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1863 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1864 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1865 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1869 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1870 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1873 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1874 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1877 brcmf_err("Invalid algo (0x%x)\n", wsec);
1881 callback(cookie, ¶ms);
1884 brcmf_dbg(TRACE, "Exit\n");
1889 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1890 struct net_device *ndev, u8 key_idx)
1892 brcmf_dbg(INFO, "Not supported\n");
1898 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1899 u8 *mac, struct station_info *sinfo)
1901 struct brcmf_if *ifp = netdev_priv(ndev);
1902 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1903 struct brcmf_scb_val_le scb_val;
1907 u8 *bssid = profile->bssid;
1908 struct brcmf_sta_info_le sta_info_le;
1910 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
1911 if (!check_vif_up(ifp->vif))
1914 if (ifp->vif->mode == WL_MODE_AP) {
1915 memcpy(&sta_info_le, mac, ETH_ALEN);
1916 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
1918 sizeof(sta_info_le));
1920 brcmf_err("GET STA INFO failed, %d\n", err);
1923 sinfo->filled = STATION_INFO_INACTIVE_TIME;
1924 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
1925 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
1926 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
1927 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
1929 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
1930 sinfo->inactive_time, sinfo->connected_time);
1931 } else if (ifp->vif->mode == WL_MODE_BSS) {
1932 if (memcmp(mac, bssid, ETH_ALEN)) {
1933 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1938 /* Report the current tx rate */
1939 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
1941 brcmf_err("Could not get rate (%d)\n", err);
1944 sinfo->filled |= STATION_INFO_TX_BITRATE;
1945 sinfo->txrate.legacy = rate * 5;
1946 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
1949 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
1950 &ifp->vif->sme_state)) {
1951 memset(&scb_val, 0, sizeof(scb_val));
1952 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
1953 &scb_val, sizeof(scb_val));
1955 brcmf_err("Could not get rssi (%d)\n", err);
1958 rssi = le32_to_cpu(scb_val.val);
1959 sinfo->filled |= STATION_INFO_SIGNAL;
1960 sinfo->signal = rssi;
1961 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
1967 brcmf_dbg(TRACE, "Exit\n");
1972 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1973 bool enabled, s32 timeout)
1977 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1978 struct brcmf_if *ifp = netdev_priv(ndev);
1980 brcmf_dbg(TRACE, "Enter\n");
1983 * Powersave enable/disable request is coming from the
1984 * cfg80211 even before the interface is up. In that
1985 * scenario, driver will be storing the power save
1986 * preference in cfg struct to apply this to
1987 * FW later while initializing the dongle
1989 cfg->pwr_save = enabled;
1990 if (!check_vif_up(ifp->vif)) {
1992 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
1996 pm = enabled ? PM_FAST : PM_OFF;
1997 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
1999 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2002 brcmf_err("net_device is not ready yet\n");
2004 brcmf_err("error (%d)\n", err);
2007 brcmf_dbg(TRACE, "Exit\n");
2011 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2012 struct brcmf_bss_info_le *bi)
2014 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2015 struct ieee80211_channel *notify_channel;
2016 struct cfg80211_bss *bss;
2017 struct ieee80211_supported_band *band;
2021 u16 notify_capability;
2022 u16 notify_interval;
2024 size_t notify_ielen;
2027 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2028 brcmf_err("Bss info is larger than buffer. Discarding\n");
2032 channel = bi->ctl_ch ? bi->ctl_ch :
2033 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2035 if (channel <= CH_MAX_2G_CHANNEL)
2036 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2038 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2040 freq = ieee80211_channel_to_frequency(channel, band->band);
2041 notify_channel = ieee80211_get_channel(wiphy, freq);
2043 notify_capability = le16_to_cpu(bi->capability);
2044 notify_interval = le16_to_cpu(bi->beacon_period);
2045 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2046 notify_ielen = le32_to_cpu(bi->ie_length);
2047 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2049 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2050 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2051 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2052 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2053 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2055 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2056 0, notify_capability, notify_interval, notify_ie,
2057 notify_ielen, notify_signal, GFP_KERNEL);
2062 cfg80211_put_bss(bss);
2067 static struct brcmf_bss_info_le *
2068 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2071 return list->bss_info_le;
2072 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2073 le32_to_cpu(bss->length));
2076 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2078 struct brcmf_scan_results *bss_list;
2079 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2083 bss_list = cfg->bss_list;
2084 if (bss_list->count != 0 &&
2085 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2086 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2090 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2091 for (i = 0; i < bss_list->count; i++) {
2092 bi = next_bss_le(bss_list, bi);
2093 err = brcmf_inform_single_bss(cfg, bi);
2100 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2101 struct net_device *ndev, const u8 *bssid)
2103 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2104 struct ieee80211_channel *notify_channel;
2105 struct brcmf_bss_info_le *bi = NULL;
2106 struct ieee80211_supported_band *band;
2107 struct cfg80211_bss *bss;
2112 u16 notify_capability;
2113 u16 notify_interval;
2115 size_t notify_ielen;
2118 brcmf_dbg(TRACE, "Enter\n");
2120 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2126 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2128 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2129 buf, WL_BSS_INFO_MAX);
2131 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2135 bi = (struct brcmf_bss_info_le *)(buf + 4);
2137 channel = bi->ctl_ch ? bi->ctl_ch :
2138 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2140 if (channel <= CH_MAX_2G_CHANNEL)
2141 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2143 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2145 freq = ieee80211_channel_to_frequency(channel, band->band);
2146 notify_channel = ieee80211_get_channel(wiphy, freq);
2148 notify_capability = le16_to_cpu(bi->capability);
2149 notify_interval = le16_to_cpu(bi->beacon_period);
2150 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2151 notify_ielen = le32_to_cpu(bi->ie_length);
2152 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2154 brcmf_dbg(CONN, "channel: %d(%d)\n", channel, freq);
2155 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2156 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2157 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2159 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2160 0, notify_capability, notify_interval,
2161 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2168 cfg80211_put_bss(bss);
2174 brcmf_dbg(TRACE, "Exit\n");
2179 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2181 return vif->mode == WL_MODE_IBSS;
2185 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2186 * triples, returning a pointer to the substring whose first element
2189 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2191 struct brcmf_tlv *elt;
2194 elt = (struct brcmf_tlv *) buf;
2197 /* find tagged parameter */
2198 while (totlen >= TLV_HDR_LEN) {
2201 /* validate remaining totlen */
2202 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2205 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2206 totlen -= (len + TLV_HDR_LEN);
2212 /* Is any of the tlvs the expected entry? If
2213 * not update the tlvs buffer pointer/length.
2216 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2217 u8 *oui, u32 oui_len, u8 type)
2219 /* If the contents match the OUI and the type */
2220 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2221 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2222 type == ie[TLV_BODY_OFF + oui_len]) {
2228 /* point to the next ie */
2229 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2230 /* calculate the length of the rest of the buffer */
2231 *tlvs_len -= (int)(ie - *tlvs);
2232 /* update the pointer to the start of the buffer */
2238 static struct brcmf_vs_tlv *
2239 brcmf_find_wpaie(u8 *parse, u32 len)
2241 struct brcmf_tlv *ie;
2243 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
2244 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2245 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2246 return (struct brcmf_vs_tlv *)ie;
2251 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2253 struct net_device *ndev = cfg_to_ndev(cfg);
2254 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2255 struct brcmf_if *ifp = netdev_priv(ndev);
2256 struct brcmf_bss_info_le *bi;
2257 struct brcmf_ssid *ssid;
2258 struct brcmf_tlv *tim;
2259 u16 beacon_interval;
2265 brcmf_dbg(TRACE, "Enter\n");
2266 if (brcmf_is_ibssmode(ifp->vif))
2269 ssid = &profile->ssid;
2271 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2272 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2273 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2275 brcmf_err("Could not get bss info %d\n", err);
2276 goto update_bss_info_out;
2279 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2280 err = brcmf_inform_single_bss(cfg, bi);
2282 goto update_bss_info_out;
2284 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2285 ie_len = le32_to_cpu(bi->ie_length);
2286 beacon_interval = le16_to_cpu(bi->beacon_period);
2288 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2290 dtim_period = tim->data[1];
2293 * active scan was done so we could not get dtim
2294 * information out of probe response.
2295 * so we speficially query dtim information to dongle.
2298 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2300 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2301 goto update_bss_info_out;
2303 dtim_period = (u8)var;
2306 update_bss_info_out:
2307 brcmf_dbg(TRACE, "Exit");
2311 static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2313 struct escan_info *escan = &cfg->escan_info;
2315 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2316 if (cfg->scan_request) {
2317 escan->escan_state = WL_ESCAN_STATE_IDLE;
2318 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2320 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2321 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2324 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2326 struct brcmf_cfg80211_info *cfg =
2327 container_of(work, struct brcmf_cfg80211_info,
2328 escan_timeout_work);
2330 brcmf_notify_escan_complete(cfg,
2331 cfg->escan_info.ndev, true, true);
2334 static void brcmf_escan_timeout(unsigned long data)
2336 struct brcmf_cfg80211_info *cfg =
2337 (struct brcmf_cfg80211_info *)data;
2339 if (cfg->scan_request) {
2340 brcmf_err("timer expired\n");
2341 schedule_work(&cfg->escan_timeout_work);
2346 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2347 struct brcmf_bss_info_le *bss_info_le)
2349 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2350 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2351 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2352 bss_info_le->SSID_len == bss->SSID_len &&
2353 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2354 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2355 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2356 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2357 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2359 /* preserve max RSSI if the measurements are
2360 * both on-channel or both off-channel
2362 if (bss_info_rssi > bss_rssi)
2363 bss->RSSI = bss_info_le->RSSI;
2364 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2365 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2366 /* preserve the on-channel rssi measurement
2367 * if the new measurement is off channel
2369 bss->RSSI = bss_info_le->RSSI;
2370 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2378 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2379 const struct brcmf_event_msg *e, void *data)
2381 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2382 struct net_device *ndev = ifp->ndev;
2385 struct brcmf_escan_result_le *escan_result_le;
2386 struct brcmf_bss_info_le *bss_info_le;
2387 struct brcmf_bss_info_le *bss = NULL;
2389 struct brcmf_scan_results *list;
2395 if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2396 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev,
2397 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2401 if (status == BRCMF_E_STATUS_PARTIAL) {
2402 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2403 escan_result_le = (struct brcmf_escan_result_le *) data;
2404 if (!escan_result_le) {
2405 brcmf_err("Invalid escan result (NULL pointer)\n");
2408 if (!cfg->scan_request) {
2409 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2413 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2414 brcmf_err("Invalid bss_count %d: ignoring\n",
2415 escan_result_le->bss_count);
2418 bss_info_le = &escan_result_le->bss_info_le;
2420 bi_length = le32_to_cpu(bss_info_le->length);
2421 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2422 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2423 brcmf_err("Invalid bss_info length %d: ignoring\n",
2428 if (!(cfg_to_wiphy(cfg)->interface_modes &
2429 BIT(NL80211_IFTYPE_ADHOC))) {
2430 if (le16_to_cpu(bss_info_le->capability) &
2431 WLAN_CAPABILITY_IBSS) {
2432 brcmf_err("Ignoring IBSS result\n");
2437 list = (struct brcmf_scan_results *)
2438 cfg->escan_info.escan_buf;
2439 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2440 brcmf_err("Buffer is too small: ignoring\n");
2444 for (i = 0; i < list->count; i++) {
2445 bss = bss ? (struct brcmf_bss_info_le *)
2446 ((unsigned char *)bss +
2447 le32_to_cpu(bss->length)) : list->bss_info_le;
2448 if (brcmf_compare_update_same_bss(bss, bss_info_le))
2451 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2452 bss_info_le, bi_length);
2453 list->version = le32_to_cpu(bss_info_le->version);
2454 list->buflen += bi_length;
2457 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2458 if (cfg->scan_request) {
2459 cfg->bss_list = (struct brcmf_scan_results *)
2460 cfg->escan_info.escan_buf;
2461 brcmf_inform_bss(cfg);
2462 aborted = status != BRCMF_E_STATUS_SUCCESS;
2463 brcmf_notify_escan_complete(cfg, ndev, aborted,
2466 brcmf_err("Unexpected scan result 0x%x\n", status);
2472 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2474 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2475 brcmf_cfg80211_escan_handler);
2476 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2477 /* Init scan_timeout timer */
2478 init_timer(&cfg->escan_timeout);
2479 cfg->escan_timeout.data = (unsigned long) cfg;
2480 cfg->escan_timeout.function = brcmf_escan_timeout;
2481 INIT_WORK(&cfg->escan_timeout_work,
2482 brcmf_cfg80211_escan_timeout_worker);
2485 static __always_inline void brcmf_delay(u32 ms)
2487 if (ms < 1000 / HZ) {
2495 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2497 brcmf_dbg(TRACE, "Enter\n");
2502 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2503 struct cfg80211_wowlan *wow)
2505 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2506 struct net_device *ndev = cfg_to_ndev(cfg);
2507 struct brcmf_cfg80211_vif *vif;
2509 brcmf_dbg(TRACE, "Enter\n");
2512 * if the primary net_device is not READY there is nothing
2513 * we can do but pray resume goes smoothly.
2515 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2516 if (!check_vif_up(vif))
2519 list_for_each_entry(vif, &cfg->vif_list, list) {
2520 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2523 * While going to suspend if associated with AP disassociate
2524 * from AP to save power while system is in suspended state
2526 brcmf_link_down(vif);
2528 /* Make sure WPA_Supplicant receives all the event
2529 * generated due to DISASSOC call to the fw to keep
2530 * the state fw and WPA_Supplicant state consistent
2535 /* end any scanning */
2536 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2537 brcmf_abort_scanning(cfg);
2539 /* Turn off watchdog timer */
2540 brcmf_set_mpc(ndev, 1);
2543 brcmf_dbg(TRACE, "Exit\n");
2544 /* clear any scanning activity */
2545 cfg->scan_status = 0;
2550 brcmf_update_pmklist(struct net_device *ndev,
2551 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2556 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2558 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2559 for (i = 0; i < pmkid_len; i++) {
2560 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2561 &pmk_list->pmkids.pmkid[i].BSSID);
2562 for (j = 0; j < WLAN_PMKID_LEN; j++)
2563 brcmf_dbg(CONN, "%02x\n",
2564 pmk_list->pmkids.pmkid[i].PMKID[j]);
2568 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2569 (char *)pmk_list, sizeof(*pmk_list));
2575 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2576 struct cfg80211_pmksa *pmksa)
2578 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2579 struct brcmf_if *ifp = netdev_priv(ndev);
2580 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2585 brcmf_dbg(TRACE, "Enter\n");
2586 if (!check_vif_up(ifp->vif))
2589 pmkid_len = le32_to_cpu(pmkids->npmkid);
2590 for (i = 0; i < pmkid_len; i++)
2591 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2593 if (i < WL_NUM_PMKIDS_MAX) {
2594 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2595 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2596 if (i == pmkid_len) {
2598 pmkids->npmkid = cpu_to_le32(pmkid_len);
2603 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2604 pmkids->pmkid[pmkid_len].BSSID);
2605 for (i = 0; i < WLAN_PMKID_LEN; i++)
2606 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2608 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2610 brcmf_dbg(TRACE, "Exit\n");
2615 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2616 struct cfg80211_pmksa *pmksa)
2618 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2619 struct brcmf_if *ifp = netdev_priv(ndev);
2620 struct pmkid_list pmkid;
2624 brcmf_dbg(TRACE, "Enter\n");
2625 if (!check_vif_up(ifp->vif))
2628 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2629 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2631 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2632 &pmkid.pmkid[0].BSSID);
2633 for (i = 0; i < WLAN_PMKID_LEN; i++)
2634 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2636 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2637 for (i = 0; i < pmkid_len; i++)
2639 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2644 && (i < pmkid_len)) {
2645 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2646 sizeof(struct pmkid));
2647 for (; i < (pmkid_len - 1); i++) {
2648 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2649 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2651 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2652 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2655 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2659 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2661 brcmf_dbg(TRACE, "Exit\n");
2667 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2669 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2670 struct brcmf_if *ifp = netdev_priv(ndev);
2673 brcmf_dbg(TRACE, "Enter\n");
2674 if (!check_vif_up(ifp->vif))
2677 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2678 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2680 brcmf_dbg(TRACE, "Exit\n");
2686 * PFN result doesn't have all the info which are
2687 * required by the supplicant
2688 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2689 * via wl_inform_single_bss in the required format. Escan does require the
2690 * scan request in the form of cfg80211_scan_request. For timebeing, create
2691 * cfg80211_scan_request one out of the received PNO event.
2694 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2695 const struct brcmf_event_msg *e, void *data)
2697 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2698 struct net_device *ndev = ifp->ndev;
2699 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2700 struct cfg80211_scan_request *request = NULL;
2701 struct cfg80211_ssid *ssid = NULL;
2702 struct ieee80211_channel *channel = NULL;
2703 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2705 int channel_req = 0;
2707 struct brcmf_pno_scanresults_le *pfn_result;
2711 brcmf_dbg(SCAN, "Enter\n");
2713 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2714 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2718 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2719 result_count = le32_to_cpu(pfn_result->count);
2720 status = le32_to_cpu(pfn_result->status);
2723 * PFN event is limited to fit 512 bytes so we may get
2724 * multiple NET_FOUND events. For now place a warning here.
2726 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2727 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2728 if (result_count > 0) {
2731 request = kzalloc(sizeof(*request), GFP_KERNEL);
2732 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2733 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2734 if (!request || !ssid || !channel) {
2739 request->wiphy = wiphy;
2740 data += sizeof(struct brcmf_pno_scanresults_le);
2741 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2743 for (i = 0; i < result_count; i++) {
2744 netinfo = &netinfo_start[i];
2746 brcmf_err("Invalid netinfo ptr. index: %d\n",
2752 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2753 netinfo->SSID, netinfo->channel);
2754 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2755 ssid[i].ssid_len = netinfo->SSID_len;
2758 channel_req = netinfo->channel;
2759 if (channel_req <= CH_MAX_2G_CHANNEL)
2760 band = NL80211_BAND_2GHZ;
2762 band = NL80211_BAND_5GHZ;
2763 channel[i].center_freq =
2764 ieee80211_channel_to_frequency(channel_req,
2766 channel[i].band = band;
2767 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2768 request->channels[i] = &channel[i];
2769 request->n_channels++;
2772 /* assign parsed ssid array */
2773 if (request->n_ssids)
2774 request->ssids = &ssid[0];
2776 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2777 /* Abort any on-going scan */
2778 brcmf_abort_scanning(cfg);
2781 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2782 err = brcmf_do_escan(cfg, wiphy, ndev, request);
2784 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2787 cfg->sched_escan = true;
2788 cfg->scan_request = request;
2790 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2803 cfg80211_sched_scan_stopped(wiphy);
2807 static int brcmf_dev_pno_clean(struct net_device *ndev)
2812 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
2815 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
2819 brcmf_err("failed code %d\n", ret);
2824 static int brcmf_dev_pno_config(struct net_device *ndev)
2826 struct brcmf_pno_param_le pfn_param;
2828 memset(&pfn_param, 0, sizeof(pfn_param));
2829 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
2831 /* set extra pno params */
2832 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
2833 pfn_param.repeat = BRCMF_PNO_REPEAT;
2834 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
2836 /* set up pno scan fr */
2837 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
2839 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
2840 &pfn_param, sizeof(pfn_param));
2844 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
2845 struct net_device *ndev,
2846 struct cfg80211_sched_scan_request *request)
2848 struct brcmf_if *ifp = netdev_priv(ndev);
2849 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
2850 struct brcmf_pno_net_param_le pfn;
2854 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
2855 request->n_match_sets, request->n_ssids);
2856 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2857 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
2861 if (!request || !request->n_ssids || !request->n_match_sets) {
2862 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
2863 request ? request->n_ssids : 0);
2867 if (request->n_ssids > 0) {
2868 for (i = 0; i < request->n_ssids; i++) {
2869 /* Active scan req for ssids */
2870 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
2871 request->ssids[i].ssid);
2874 * match_set ssids is a supert set of n_ssid list,
2875 * so we need not add these set seperately.
2880 if (request->n_match_sets > 0) {
2881 /* clean up everything */
2882 ret = brcmf_dev_pno_clean(ndev);
2884 brcmf_err("failed error=%d\n", ret);
2889 ret = brcmf_dev_pno_config(ndev);
2891 brcmf_err("PNO setup failed!! ret=%d\n", ret);
2895 /* configure each match set */
2896 for (i = 0; i < request->n_match_sets; i++) {
2897 struct cfg80211_ssid *ssid;
2900 ssid = &request->match_sets[i].ssid;
2901 ssid_len = ssid->ssid_len;
2904 brcmf_err("skip broadcast ssid\n");
2907 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
2908 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
2909 pfn.wsec = cpu_to_le32(0);
2910 pfn.infra = cpu_to_le32(1);
2911 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
2912 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
2913 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
2914 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
2916 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
2917 ret == 0 ? "set" : "failed", ssid->ssid);
2919 /* Enable the PNO */
2920 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
2921 brcmf_err("PNO enable failed!! ret=%d\n", ret);
2931 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
2932 struct net_device *ndev)
2934 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2936 brcmf_dbg(SCAN, "enter\n");
2937 brcmf_dev_pno_clean(ndev);
2938 if (cfg->sched_escan)
2939 brcmf_notify_escan_complete(cfg, ndev, true, true);
2943 #ifdef CONFIG_NL80211_TESTMODE
2944 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
2946 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2947 struct net_device *ndev = cfg_to_ndev(cfg);
2948 struct brcmf_dcmd *dcmd = data;
2949 struct sk_buff *reply;
2952 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
2953 dcmd->buf, dcmd->len);
2956 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
2957 dcmd->buf, dcmd->len);
2959 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
2960 dcmd->buf, dcmd->len);
2962 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
2963 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
2964 ret = cfg80211_testmode_reply(reply);
2970 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
2975 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
2977 brcmf_err("auth error %d\n", err);
2981 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
2983 brcmf_err("wsec error %d\n", err);
2986 /* set upper-layer auth */
2987 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
2989 brcmf_err("wpa_auth error %d\n", err);
2996 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
2999 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3001 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3005 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3008 struct brcmf_if *ifp = netdev_priv(ndev);
3009 u32 auth = 0; /* d11 open authentication */
3021 u32 wme_bss_disable;
3023 brcmf_dbg(TRACE, "Enter\n");
3027 len = wpa_ie->len + TLV_HDR_LEN;
3028 data = (u8 *)wpa_ie;
3029 offset = TLV_HDR_LEN;
3031 offset += VS_IE_FIXED_HDR_LEN;
3033 offset += WPA_IE_VERSION_LEN;
3035 /* check for multicast cipher suite */
3036 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3038 brcmf_err("no multicast cipher suite\n");
3042 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3044 brcmf_err("ivalid OUI\n");
3047 offset += TLV_OUI_LEN;
3049 /* pick up multicast cipher */
3050 switch (data[offset]) {
3051 case WPA_CIPHER_NONE:
3054 case WPA_CIPHER_WEP_40:
3055 case WPA_CIPHER_WEP_104:
3058 case WPA_CIPHER_TKIP:
3059 gval = TKIP_ENABLED;
3061 case WPA_CIPHER_AES_CCM:
3066 brcmf_err("Invalid multi cast cipher info\n");
3071 /* walk thru unicast cipher list and pick up what we recognize */
3072 count = data[offset] + (data[offset + 1] << 8);
3073 offset += WPA_IE_SUITE_COUNT_LEN;
3074 /* Check for unicast suite(s) */
3075 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3077 brcmf_err("no unicast cipher suite\n");
3080 for (i = 0; i < count; i++) {
3081 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3083 brcmf_err("ivalid OUI\n");
3086 offset += TLV_OUI_LEN;
3087 switch (data[offset]) {
3088 case WPA_CIPHER_NONE:
3090 case WPA_CIPHER_WEP_40:
3091 case WPA_CIPHER_WEP_104:
3092 pval |= WEP_ENABLED;
3094 case WPA_CIPHER_TKIP:
3095 pval |= TKIP_ENABLED;
3097 case WPA_CIPHER_AES_CCM:
3098 pval |= AES_ENABLED;
3101 brcmf_err("Ivalid unicast security info\n");
3105 /* walk thru auth management suite list and pick up what we recognize */
3106 count = data[offset] + (data[offset + 1] << 8);
3107 offset += WPA_IE_SUITE_COUNT_LEN;
3108 /* Check for auth key management suite(s) */
3109 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3111 brcmf_err("no auth key mgmt suite\n");
3114 for (i = 0; i < count; i++) {
3115 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3117 brcmf_err("ivalid OUI\n");
3120 offset += TLV_OUI_LEN;
3121 switch (data[offset]) {
3123 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3124 wpa_auth |= WPA_AUTH_NONE;
3126 case RSN_AKM_UNSPECIFIED:
3127 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3128 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3129 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3132 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3133 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3134 (wpa_auth |= WPA_AUTH_PSK);
3137 brcmf_err("Ivalid key mgmt info\n");
3143 wme_bss_disable = 1;
3144 if ((offset + RSN_CAP_LEN) <= len) {
3145 rsn_cap = data[offset] + (data[offset + 1] << 8);
3146 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3147 wme_bss_disable = 0;
3149 /* set wme_bss_disable to sync RSN Capabilities */
3150 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3153 brcmf_err("wme_bss_disable error %d\n", err);
3157 /* FOR WPS , set SES_OW_ENABLED */
3158 wsec = (pval | gval | SES_OW_ENABLED);
3161 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3163 brcmf_err("auth error %d\n", err);
3167 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3169 brcmf_err("wsec error %d\n", err);
3172 /* set upper-layer auth */
3173 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3175 brcmf_err("wpa_auth error %d\n", err);
3184 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3185 struct parsed_vndr_ies *vndr_ies)
3188 struct brcmf_vs_tlv *vndrie;
3189 struct brcmf_tlv *ie;
3190 struct parsed_vndr_ie_info *parsed_info;
3193 remaining_len = (s32)vndr_ie_len;
3194 memset(vndr_ies, 0, sizeof(*vndr_ies));
3196 ie = (struct brcmf_tlv *)vndr_ie_buf;
3198 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3200 vndrie = (struct brcmf_vs_tlv *)ie;
3201 /* len should be bigger than OUI length + one */
3202 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3203 brcmf_err("invalid vndr ie. length is too small %d\n",
3207 /* if wpa or wme ie, do not add ie */
3208 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3209 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3210 (vndrie->oui_type == WME_OUI_TYPE))) {
3211 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3215 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3217 /* save vndr ie information */
3218 parsed_info->ie_ptr = (char *)vndrie;
3219 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3220 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3224 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3225 parsed_info->vndrie.oui[0],
3226 parsed_info->vndrie.oui[1],
3227 parsed_info->vndrie.oui[2],
3228 parsed_info->vndrie.oui_type);
3230 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3233 remaining_len -= (ie->len + TLV_HDR_LEN);
3234 if (remaining_len <= TLV_HDR_LEN)
3237 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3244 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3250 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3251 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3253 iecount_le = cpu_to_le32(1);
3254 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3256 pktflag_le = cpu_to_le32(pktflag);
3257 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3259 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3261 return ie_len + VNDR_IE_HDR_SIZE;
3265 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3266 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3268 struct brcmf_if *ifp;
3269 struct vif_saved_ie *saved_ie;
3273 u8 *mgmt_ie_buf = NULL;
3274 int mgmt_ie_buf_len;
3276 u32 del_add_ie_buf_len = 0;
3277 u32 total_ie_buf_len = 0;
3278 u32 parsed_ie_buf_len = 0;
3279 struct parsed_vndr_ies old_vndr_ies;
3280 struct parsed_vndr_ies new_vndr_ies;
3281 struct parsed_vndr_ie_info *vndrie_info;
3284 int remained_buf_len;
3289 saved_ie = &vif->saved_ie;
3291 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3292 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3295 curr_ie_buf = iovar_ie_buf;
3296 if (ifp->vif->mode == WL_MODE_AP) {
3298 case VNDR_IE_PRBRSP_FLAG:
3299 mgmt_ie_buf = saved_ie->probe_res_ie;
3300 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3301 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3303 case VNDR_IE_BEACON_FLAG:
3304 mgmt_ie_buf = saved_ie->beacon_ie;
3305 mgmt_ie_len = &saved_ie->beacon_ie_len;
3306 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3310 brcmf_err("not suitable type\n");
3315 brcmf_err("not suitable type\n");
3319 if (vndr_ie_len > mgmt_ie_buf_len) {
3321 brcmf_err("extra IE size too big\n");
3325 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3326 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3328 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3329 for (i = 0; i < new_vndr_ies.count; i++) {
3330 vndrie_info = &new_vndr_ies.ie_info[i];
3331 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3332 vndrie_info->ie_len);
3333 parsed_ie_buf_len += vndrie_info->ie_len;
3337 if (mgmt_ie_buf && *mgmt_ie_len) {
3338 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3339 (memcmp(mgmt_ie_buf, curr_ie_buf,
3340 parsed_ie_buf_len) == 0)) {
3341 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3345 /* parse old vndr_ie */
3346 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3348 /* make a command to delete old ie */
3349 for (i = 0; i < old_vndr_ies.count; i++) {
3350 vndrie_info = &old_vndr_ies.ie_info[i];
3352 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3353 vndrie_info->vndrie.id,
3354 vndrie_info->vndrie.len,
3355 vndrie_info->vndrie.oui[0],
3356 vndrie_info->vndrie.oui[1],
3357 vndrie_info->vndrie.oui[2]);
3359 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3360 vndrie_info->ie_ptr,
3361 vndrie_info->ie_len,
3363 curr_ie_buf += del_add_ie_buf_len;
3364 total_ie_buf_len += del_add_ie_buf_len;
3369 /* Add if there is any extra IE */
3370 if (mgmt_ie_buf && parsed_ie_buf_len) {
3373 remained_buf_len = mgmt_ie_buf_len;
3375 /* make a command to add new ie */
3376 for (i = 0; i < new_vndr_ies.count; i++) {
3377 vndrie_info = &new_vndr_ies.ie_info[i];
3379 /* verify remained buf size before copy data */
3380 if (remained_buf_len < (vndrie_info->vndrie.len +
3381 VNDR_IE_VSIE_OFFSET)) {
3382 brcmf_err("no space in mgmt_ie_buf: len left %d",
3386 remained_buf_len -= (vndrie_info->ie_len +
3387 VNDR_IE_VSIE_OFFSET);
3389 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3390 vndrie_info->vndrie.id,
3391 vndrie_info->vndrie.len,
3392 vndrie_info->vndrie.oui[0],
3393 vndrie_info->vndrie.oui[1],
3394 vndrie_info->vndrie.oui[2]);
3396 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3397 vndrie_info->ie_ptr,
3398 vndrie_info->ie_len,
3401 /* save the parsed IE in wl struct */
3402 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3403 vndrie_info->ie_len);
3404 *mgmt_ie_len += vndrie_info->ie_len;
3406 curr_ie_buf += del_add_ie_buf_len;
3407 total_ie_buf_len += del_add_ie_buf_len;
3410 if (total_ie_buf_len) {
3411 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3414 brcmf_err("vndr ie set error : %d\n", err);
3418 kfree(iovar_ie_buf);
3423 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3424 struct cfg80211_ap_settings *settings)
3427 struct brcmf_if *ifp = netdev_priv(ndev);
3428 struct brcmf_tlv *ssid_ie;
3429 struct brcmf_ssid_le ssid_le;
3431 struct brcmf_tlv *rsn_ie;
3432 struct brcmf_vs_tlv *wpa_ie;
3433 struct brcmf_join_params join_params;
3435 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3436 cfg80211_get_chandef_type(&settings->chandef),
3437 settings->beacon_interval,
3438 settings->dtim_period);
3439 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3440 settings->ssid, settings->ssid_len, settings->auth_type,
3441 settings->inactivity_timeout);
3443 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
3444 brcmf_err("Not in AP creation mode\n");
3448 memset(&ssid_le, 0, sizeof(ssid_le));
3449 if (settings->ssid == NULL || settings->ssid_len == 0) {
3450 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3451 ssid_ie = brcmf_parse_tlvs(
3452 (u8 *)&settings->beacon.head[ie_offset],
3453 settings->beacon.head_len - ie_offset,
3458 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3459 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3460 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3462 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3463 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3466 brcmf_set_mpc(ndev, 0);
3467 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3469 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3472 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3474 brcmf_err("SET INFRA error %d\n", err);
3477 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3479 brcmf_err("setting AP mode failed %d\n", err);
3483 /* find the RSN_IE */
3484 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3485 settings->beacon.tail_len, WLAN_EID_RSN);
3487 /* find the WPA_IE */
3488 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3489 settings->beacon.tail_len);
3491 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3492 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3493 if (wpa_ie != NULL) {
3495 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3500 err = brcmf_configure_wpaie(ndev,
3501 (struct brcmf_vs_tlv *)rsn_ie, true);
3506 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3507 brcmf_configure_opensecurity(ifp);
3509 /* Set Beacon IEs to FW */
3510 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3511 VNDR_IE_BEACON_FLAG,
3512 settings->beacon.tail,
3513 settings->beacon.tail_len);
3515 brcmf_err("Set Beacon IE Failed\n");
3517 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3519 /* Set Probe Response IEs to FW */
3520 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3521 VNDR_IE_PRBRSP_FLAG,
3522 settings->beacon.proberesp_ies,
3523 settings->beacon.proberesp_ies_len);
3525 brcmf_err("Set Probe Resp IE Failed\n");
3527 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3529 if (settings->beacon_interval) {
3530 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3531 settings->beacon_interval);
3533 brcmf_err("Beacon Interval Set Error, %d\n", err);
3537 if (settings->dtim_period) {
3538 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3539 settings->dtim_period);
3541 brcmf_err("DTIM Interval Set Error, %d\n", err);
3545 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3547 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3551 memset(&join_params, 0, sizeof(join_params));
3552 /* join parameters starts with ssid */
3553 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3555 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3556 &join_params, sizeof(join_params));
3558 brcmf_err("SET SSID error (%d)\n", err);
3561 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3562 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3566 brcmf_set_mpc(ndev, 1);
3570 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3572 struct brcmf_if *ifp = netdev_priv(ndev);
3575 brcmf_dbg(TRACE, "Enter\n");
3577 if (ifp->vif->mode == WL_MODE_AP) {
3578 /* Due to most likely deauths outstanding we sleep */
3579 /* first to make sure they get processed by fw. */
3581 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3583 brcmf_err("setting AP mode failed %d\n", err);
3586 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3588 brcmf_err("BRCMF_C_UP error %d\n", err);
3591 brcmf_set_mpc(ndev, 1);
3592 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3593 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3600 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3603 struct brcmf_scb_val_le scbval;
3604 struct brcmf_if *ifp = netdev_priv(ndev);
3610 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3612 if (!check_vif_up(ifp->vif))
3615 memcpy(&scbval.ea, mac, ETH_ALEN);
3616 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3617 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3618 &scbval, sizeof(scbval));
3620 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3622 brcmf_dbg(TRACE, "Exit\n");
3626 static struct cfg80211_ops wl_cfg80211_ops = {
3627 .change_virtual_intf = brcmf_cfg80211_change_iface,
3628 .scan = brcmf_cfg80211_scan,
3629 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
3630 .join_ibss = brcmf_cfg80211_join_ibss,
3631 .leave_ibss = brcmf_cfg80211_leave_ibss,
3632 .get_station = brcmf_cfg80211_get_station,
3633 .set_tx_power = brcmf_cfg80211_set_tx_power,
3634 .get_tx_power = brcmf_cfg80211_get_tx_power,
3635 .add_key = brcmf_cfg80211_add_key,
3636 .del_key = brcmf_cfg80211_del_key,
3637 .get_key = brcmf_cfg80211_get_key,
3638 .set_default_key = brcmf_cfg80211_config_default_key,
3639 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
3640 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
3641 .connect = brcmf_cfg80211_connect,
3642 .disconnect = brcmf_cfg80211_disconnect,
3643 .suspend = brcmf_cfg80211_suspend,
3644 .resume = brcmf_cfg80211_resume,
3645 .set_pmksa = brcmf_cfg80211_set_pmksa,
3646 .del_pmksa = brcmf_cfg80211_del_pmksa,
3647 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3648 .start_ap = brcmf_cfg80211_start_ap,
3649 .stop_ap = brcmf_cfg80211_stop_ap,
3650 .del_station = brcmf_cfg80211_del_station,
3651 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
3652 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
3653 #ifdef CONFIG_NL80211_TESTMODE
3654 .testmode_cmd = brcmf_cfg80211_testmode
3658 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
3664 return NL80211_IFTYPE_STATION;
3666 return NL80211_IFTYPE_ADHOC;
3668 return NL80211_IFTYPE_UNSPECIFIED;
3674 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3676 /* scheduled scan settings */
3677 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
3678 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
3679 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
3680 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3683 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3685 struct wiphy *wiphy;
3688 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
3690 brcmf_err("Could not allocate wiphy device\n");
3691 return ERR_PTR(-ENOMEM);
3693 set_wiphy_dev(wiphy, phydev);
3694 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3695 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3696 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3697 BIT(NL80211_IFTYPE_ADHOC) |
3698 BIT(NL80211_IFTYPE_AP);
3699 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3700 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
3701 * it as 11a by default.
3702 * This will be updated with
3705 * if phy has 11n capability
3707 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3708 wiphy->cipher_suites = __wl_cipher_suites;
3709 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3710 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
3714 brcmf_wiphy_pno_params(wiphy);
3715 err = wiphy_register(wiphy);
3717 brcmf_err("Could not register wiphy device (%d)\n", err);
3719 return ERR_PTR(err);
3725 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3726 struct net_device *netdev,
3727 s32 mode, bool pm_block)
3729 struct brcmf_cfg80211_vif *vif;
3731 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
3732 return ERR_PTR(-ENOSPC);
3734 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
3736 return ERR_PTR(-ENOMEM);
3738 vif->wdev.wiphy = cfg->wiphy;
3739 vif->wdev.netdev = netdev;
3740 vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
3743 vif->ifp = netdev_priv(netdev);
3744 netdev->ieee80211_ptr = &vif->wdev;
3745 SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
3749 vif->pm_block = pm_block;
3752 brcmf_init_prof(&vif->profile);
3754 list_add_tail(&vif->list, &cfg->vif_list);
3759 static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3761 struct brcmf_cfg80211_info *cfg;
3762 struct wiphy *wiphy;
3764 wiphy = vif->wdev.wiphy;
3765 cfg = wiphy_priv(wiphy);
3766 list_del(&vif->list);
3770 if (!cfg->vif_cnt) {
3771 wiphy_unregister(wiphy);
3776 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
3778 u32 event = e->event_code;
3779 u32 status = e->status;
3781 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3782 brcmf_dbg(CONN, "Processing set ssid\n");
3789 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
3791 u32 event = e->event_code;
3792 u16 flags = e->flags;
3794 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
3795 brcmf_dbg(CONN, "Processing link down\n");
3801 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
3802 const struct brcmf_event_msg *e)
3804 u32 event = e->event_code;
3805 u32 status = e->status;
3807 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
3808 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
3809 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
3813 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
3814 brcmf_dbg(CONN, "Processing connecting & no network found\n");
3821 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3823 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3825 kfree(conn_info->req_ie);
3826 conn_info->req_ie = NULL;
3827 conn_info->req_ie_len = 0;
3828 kfree(conn_info->resp_ie);
3829 conn_info->resp_ie = NULL;
3830 conn_info->resp_ie_len = 0;
3833 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
3835 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
3836 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3837 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3842 brcmf_clear_assoc_ies(cfg);
3844 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
3845 cfg->extra_buf, WL_ASSOC_INFO_MAX);
3847 brcmf_err("could not get assoc info (%d)\n", err);
3851 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
3852 req_len = le32_to_cpu(assoc_info->req_len);
3853 resp_len = le32_to_cpu(assoc_info->resp_len);
3855 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
3859 brcmf_err("could not get assoc req (%d)\n", err);
3862 conn_info->req_ie_len = req_len;
3864 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
3867 conn_info->req_ie_len = 0;
3868 conn_info->req_ie = NULL;
3871 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
3875 brcmf_err("could not get assoc resp (%d)\n", err);
3878 conn_info->resp_ie_len = resp_len;
3879 conn_info->resp_ie =
3880 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
3883 conn_info->resp_ie_len = 0;
3884 conn_info->resp_ie = NULL;
3886 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
3887 conn_info->req_ie_len, conn_info->resp_ie_len);
3893 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3894 struct net_device *ndev,
3895 const struct brcmf_event_msg *e)
3897 struct brcmf_if *ifp = netdev_priv(ndev);
3898 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
3899 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3900 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3901 struct ieee80211_channel *notify_channel = NULL;
3902 struct ieee80211_supported_band *band;
3903 struct brcmf_bss_info_le *bi;
3909 brcmf_dbg(TRACE, "Enter\n");
3911 brcmf_get_assoc_ies(cfg);
3912 memcpy(profile->bssid, e->addr, ETH_ALEN);
3913 brcmf_update_bss_info(cfg);
3915 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3921 /* data sent to dongle has to be little endian */
3922 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3923 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3924 buf, WL_BSS_INFO_MAX);
3929 bi = (struct brcmf_bss_info_le *)(buf + 4);
3930 target_channel = bi->ctl_ch ? bi->ctl_ch :
3931 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
3933 if (target_channel <= CH_MAX_2G_CHANNEL)
3934 band = wiphy->bands[IEEE80211_BAND_2GHZ];
3936 band = wiphy->bands[IEEE80211_BAND_5GHZ];
3938 freq = ieee80211_channel_to_frequency(target_channel, band->band);
3939 notify_channel = ieee80211_get_channel(wiphy, freq);
3943 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
3944 conn_info->req_ie, conn_info->req_ie_len,
3945 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
3946 brcmf_dbg(CONN, "Report roaming result\n");
3948 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
3949 brcmf_dbg(TRACE, "Exit\n");
3954 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
3955 struct net_device *ndev, const struct brcmf_event_msg *e,
3958 struct brcmf_if *ifp = netdev_priv(ndev);
3959 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
3960 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3963 brcmf_dbg(TRACE, "Enter\n");
3965 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
3966 &ifp->vif->sme_state)) {
3968 brcmf_get_assoc_ies(cfg);
3969 memcpy(profile->bssid, e->addr, ETH_ALEN);
3970 brcmf_update_bss_info(cfg);
3972 cfg80211_connect_result(ndev,
3973 (u8 *)profile->bssid,
3975 conn_info->req_ie_len,
3977 conn_info->resp_ie_len,
3978 completed ? WLAN_STATUS_SUCCESS :
3979 WLAN_STATUS_AUTH_TIMEOUT,
3982 set_bit(BRCMF_VIF_STATUS_CONNECTED,
3983 &ifp->vif->sme_state);
3984 brcmf_dbg(CONN, "Report connect result - connection %s\n",
3985 completed ? "succeeded" : "failed");
3987 brcmf_dbg(TRACE, "Exit\n");
3992 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
3993 struct net_device *ndev,
3994 const struct brcmf_event_msg *e, void *data)
3996 static int generation;
3997 u32 event = e->event_code;
3998 u32 reason = e->reason;
3999 struct station_info sinfo;
4001 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4003 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4004 (reason == BRCMF_E_STATUS_SUCCESS)) {
4005 memset(&sinfo, 0, sizeof(sinfo));
4006 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4008 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4011 sinfo.assoc_req_ies = data;
4012 sinfo.assoc_req_ies_len = e->datalen;
4014 sinfo.generation = generation;
4015 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4016 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4017 (event == BRCMF_E_DEAUTH_IND) ||
4018 (event == BRCMF_E_DEAUTH)) {
4019 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4025 brcmf_notify_connect_status(struct brcmf_if *ifp,
4026 const struct brcmf_event_msg *e, void *data)
4028 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4029 struct net_device *ndev = ifp->ndev;
4030 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4033 if (ifp->vif->mode == WL_MODE_AP) {
4034 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4035 } else if (brcmf_is_linkup(e)) {
4036 brcmf_dbg(CONN, "Linkup\n");
4037 if (brcmf_is_ibssmode(ifp->vif)) {
4038 memcpy(profile->bssid, e->addr, ETH_ALEN);
4039 wl_inform_ibss(cfg, ndev, e->addr);
4040 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4041 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4042 &ifp->vif->sme_state);
4043 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4044 &ifp->vif->sme_state);
4046 brcmf_bss_connect_done(cfg, ndev, e, true);
4047 } else if (brcmf_is_linkdown(e)) {
4048 brcmf_dbg(CONN, "Linkdown\n");
4049 if (!brcmf_is_ibssmode(ifp->vif)) {
4050 brcmf_bss_connect_done(cfg, ndev, e, false);
4051 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4052 &ifp->vif->sme_state))
4053 cfg80211_disconnected(ndev, 0, NULL, 0,
4056 brcmf_link_down(ifp->vif);
4057 brcmf_init_prof(ndev_to_prof(ndev));
4058 } else if (brcmf_is_nonetwork(cfg, e)) {
4059 if (brcmf_is_ibssmode(ifp->vif))
4060 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4061 &ifp->vif->sme_state);
4063 brcmf_bss_connect_done(cfg, ndev, e, false);
4070 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4071 const struct brcmf_event_msg *e, void *data)
4073 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4075 u32 event = e->event_code;
4076 u32 status = e->status;
4078 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4079 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4080 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4082 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4089 brcmf_notify_mic_status(struct brcmf_if *ifp,
4090 const struct brcmf_event_msg *e, void *data)
4092 u16 flags = e->flags;
4093 enum nl80211_key_type key_type;
4095 if (flags & BRCMF_EVENT_MSG_GROUP)
4096 key_type = NL80211_KEYTYPE_GROUP;
4098 key_type = NL80211_KEYTYPE_PAIRWISE;
4100 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4106 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4108 conf->frag_threshold = (u32)-1;
4109 conf->rts_threshold = (u32)-1;
4110 conf->retry_short = (u32)-1;
4111 conf->retry_long = (u32)-1;
4112 conf->tx_power = -1;
4115 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4117 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4118 brcmf_notify_connect_status);
4119 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4120 brcmf_notify_connect_status);
4121 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4122 brcmf_notify_connect_status);
4123 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4124 brcmf_notify_connect_status);
4125 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4126 brcmf_notify_connect_status);
4127 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4128 brcmf_notify_connect_status);
4129 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4130 brcmf_notify_roaming_status);
4131 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4132 brcmf_notify_mic_status);
4133 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4134 brcmf_notify_connect_status);
4135 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4136 brcmf_notify_sched_scan_results);
4139 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4143 kfree(cfg->escan_ioctl_buf);
4144 cfg->escan_ioctl_buf = NULL;
4145 kfree(cfg->extra_buf);
4146 cfg->extra_buf = NULL;
4147 kfree(cfg->pmk_list);
4148 cfg->pmk_list = NULL;
4151 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4153 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4155 goto init_priv_mem_out;
4156 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4157 if (!cfg->escan_ioctl_buf)
4158 goto init_priv_mem_out;
4159 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4160 if (!cfg->extra_buf)
4161 goto init_priv_mem_out;
4162 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4164 goto init_priv_mem_out;
4169 brcmf_deinit_priv_mem(cfg);
4174 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4178 cfg->scan_request = NULL;
4179 cfg->pwr_save = true;
4180 cfg->roam_on = true; /* roam on & off switch.
4181 we enable roam per default */
4182 cfg->active_scan = true; /* we do active scan for
4183 specific scan per default */
4184 cfg->dongle_up = false; /* dongle is not up yet */
4185 err = brcmf_init_priv_mem(cfg);
4188 brcmf_register_event_handlers(cfg);
4189 mutex_init(&cfg->usr_sync);
4190 brcmf_init_escan(cfg);
4191 brcmf_init_conf(cfg->conf);
4196 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4198 cfg->dongle_up = false; /* dongle down */
4199 brcmf_abort_scanning(cfg);
4200 brcmf_deinit_priv_mem(cfg);
4203 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4204 struct device *busdev)
4206 struct net_device *ndev = drvr->iflist[0]->ndev;
4207 struct brcmf_cfg80211_info *cfg;
4208 struct wiphy *wiphy;
4209 struct brcmf_cfg80211_vif *vif;
4210 struct brcmf_if *ifp;
4214 brcmf_err("ndev is invalid\n");
4218 ifp = netdev_priv(ndev);
4219 wiphy = brcmf_setup_wiphy(busdev);
4223 cfg = wiphy_priv(wiphy);
4226 INIT_LIST_HEAD(&cfg->vif_list);
4228 vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false);
4234 err = wl_init_priv(cfg);
4236 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4237 goto cfg80211_attach_out;
4243 cfg80211_attach_out:
4244 brcmf_free_vif(vif);
4248 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4250 struct brcmf_cfg80211_vif *vif;
4251 struct brcmf_cfg80211_vif *tmp;
4253 wl_deinit_priv(cfg);
4254 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4255 brcmf_free_vif(vif);
4260 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
4263 __le32 roamtrigger[2];
4264 __le32 roam_delta[2];
4267 * Setup timeout if Beacons are lost and roam is
4268 * off to report link down
4271 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4273 brcmf_err("bcn_timeout error (%d)\n", err);
4274 goto dongle_rom_out;
4279 * Enable/Disable built-in roaming to allow supplicant
4280 * to take care of roaming
4282 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4283 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4285 brcmf_err("roam_off error (%d)\n", err);
4286 goto dongle_rom_out;
4289 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4290 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4291 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4292 (void *)roamtrigger, sizeof(roamtrigger));
4294 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4295 goto dongle_rom_out;
4298 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4299 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4300 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4301 (void *)roam_delta, sizeof(roam_delta));
4303 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4304 goto dongle_rom_out;
4312 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
4313 s32 scan_unassoc_time, s32 scan_passive_time)
4317 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4320 if (err == -EOPNOTSUPP)
4321 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4323 brcmf_err("Scan assoc time error (%d)\n", err);
4324 goto dongle_scantime_out;
4326 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4329 if (err == -EOPNOTSUPP)
4330 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4332 brcmf_err("Scan unassoc time error (%d)\n", err);
4333 goto dongle_scantime_out;
4336 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4339 if (err == -EOPNOTSUPP)
4340 brcmf_dbg(INFO, "Scan passive time is not supported\n");
4342 brcmf_err("Scan passive time error (%d)\n", err);
4343 goto dongle_scantime_out;
4346 dongle_scantime_out:
4350 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4352 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4353 struct wiphy *wiphy;
4358 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4359 &phy_list, sizeof(phy_list));
4361 brcmf_err("error (%d)\n", err);
4365 phy = ((char *)&phy_list)[0];
4366 brcmf_dbg(INFO, "%c phy\n", phy);
4367 if (phy == 'n' || phy == 'a') {
4368 wiphy = cfg_to_wiphy(cfg);
4369 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4375 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4377 return wl_update_wiphybands(cfg);
4380 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4382 struct net_device *ndev;
4383 struct wireless_dev *wdev;
4384 struct brcmf_if *ifp;
4391 ndev = cfg_to_ndev(cfg);
4392 wdev = ndev->ieee80211_ptr;
4393 ifp = netdev_priv(ndev);
4395 /* make sure RF is ready for work */
4396 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
4398 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
4399 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4401 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4402 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
4404 goto default_conf_out;
4405 brcmf_dbg(INFO, "power save set to %s\n",
4406 (power_mode ? "enabled" : "disabled"));
4408 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
4410 goto default_conf_out;
4411 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4414 goto default_conf_out;
4415 err = brcmf_dongle_probecap(cfg);
4417 goto default_conf_out;
4419 cfg->dongle_up = true;
4426 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
4428 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4430 return brcmf_config_dongle(ifp->drvr->config);
4433 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
4435 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4438 * While going down, if associated with AP disassociate
4439 * from AP to save power
4441 if (check_vif_up(ifp->vif)) {
4442 brcmf_link_down(ifp->vif);
4444 /* Make sure WPA_Supplicant receives all the event
4445 generated due to DISASSOC call to the fw to keep
4446 the state fw and WPA_Supplicant state consistent
4451 brcmf_abort_scanning(cfg);
4452 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4457 s32 brcmf_cfg80211_up(struct net_device *ndev)
4459 struct brcmf_if *ifp = netdev_priv(ndev);
4460 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4463 mutex_lock(&cfg->usr_sync);
4464 err = __brcmf_cfg80211_up(ifp);
4465 mutex_unlock(&cfg->usr_sync);
4470 s32 brcmf_cfg80211_down(struct net_device *ndev)
4472 struct brcmf_if *ifp = netdev_priv(ndev);
4473 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4476 mutex_lock(&cfg->usr_sync);
4477 err = __brcmf_cfg80211_down(ifp);
4478 mutex_unlock(&cfg->usr_sync);