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 if (ch
->flags
& IEEE80211_CHAN_NO_HT40
) {
397 chanspec
|= WL_CHANSPEC_BW_20
;
398 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
400 chanspec
|= WL_CHANSPEC_BW_40
;
401 if (ch
->flags
& IEEE80211_CHAN_NO_HT40PLUS
)
402 chanspec
|= WL_CHANSPEC_CTL_SB_LOWER
;
404 chanspec
|= WL_CHANSPEC_CTL_SB_UPPER
;
409 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
410 struct brcmf_wsec_key_le
*key_le
)
412 key_le
->index
= cpu_to_le32(key
->index
);
413 key_le
->len
= cpu_to_le32(key
->len
);
414 key_le
->algo
= cpu_to_le32(key
->algo
);
415 key_le
->flags
= cpu_to_le32(key
->flags
);
416 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
417 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
418 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
419 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
420 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
424 send_key_to_dongle(struct net_device
*ndev
, struct brcmf_wsec_key
*key
)
427 struct brcmf_wsec_key_le key_le
;
429 convert_key_from_CPU(key
, &key_le
);
431 brcmf_netdev_wait_pend8021x(ndev
);
433 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "wsec_key", &key_le
,
437 brcmf_err("wsec_key error (%d)\n", err
);
442 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
443 enum nl80211_iftype type
, u32
*flags
,
444 struct vif_params
*params
)
446 struct brcmf_if
*ifp
= netdev_priv(ndev
);
447 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
452 brcmf_dbg(TRACE
, "Enter, ndev=%p, type=%d\n", ndev
, type
);
455 case NL80211_IFTYPE_MONITOR
:
456 case NL80211_IFTYPE_WDS
:
457 brcmf_err("type (%d) : currently we do not support this type\n",
460 case NL80211_IFTYPE_ADHOC
:
461 vif
->mode
= WL_MODE_IBSS
;
464 case NL80211_IFTYPE_STATION
:
465 vif
->mode
= WL_MODE_BSS
;
468 case NL80211_IFTYPE_AP
:
469 vif
->mode
= WL_MODE_AP
;
478 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &vif
->sme_state
);
479 brcmf_dbg(INFO
, "IF Type = AP\n");
481 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, infra
);
483 brcmf_err("WLC_SET_INFRA error (%d)\n", err
);
487 brcmf_dbg(INFO
, "IF Type = %s\n", (vif
->mode
== WL_MODE_IBSS
) ?
490 ndev
->ieee80211_ptr
->iftype
= type
;
493 brcmf_dbg(TRACE
, "Exit\n");
498 static void brcmf_set_mpc(struct net_device
*ndev
, int mpc
)
500 struct brcmf_if
*ifp
= netdev_priv(ndev
);
503 if (check_vif_up(ifp
->vif
)) {
504 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
506 brcmf_err("fail to set mpc\n");
509 brcmf_dbg(INFO
, "MPC : %d\n", mpc
);
513 static void brcmf_escan_prep(struct brcmf_scan_params_le
*params_le
,
514 struct cfg80211_scan_request
*request
)
522 struct brcmf_ssid_le ssid_le
;
524 memset(params_le
->bssid
, 0xFF, ETH_ALEN
);
525 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
526 params_le
->scan_type
= 0;
527 params_le
->channel_num
= 0;
528 params_le
->nprobes
= cpu_to_le32(-1);
529 params_le
->active_time
= cpu_to_le32(-1);
530 params_le
->passive_time
= cpu_to_le32(-1);
531 params_le
->home_time
= cpu_to_le32(-1);
532 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
534 /* if request is null exit so it will be all channel broadcast scan */
538 n_ssids
= request
->n_ssids
;
539 n_channels
= request
->n_channels
;
540 /* Copy channel array if applicable */
541 brcmf_dbg(SCAN
, "### List of channelspecs to scan ### %d\n",
543 if (n_channels
> 0) {
544 for (i
= 0; i
< n_channels
; i
++) {
545 chanspec
= channel_to_chanspec(request
->channels
[i
]);
546 brcmf_dbg(SCAN
, "Chan : %d, Channel spec: %x\n",
547 request
->channels
[i
]->hw_value
, chanspec
);
548 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
551 brcmf_dbg(SCAN
, "Scanning all channels\n");
553 /* Copy ssid array if applicable */
554 brcmf_dbg(SCAN
, "### List of SSIDs to scan ### %d\n", n_ssids
);
556 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
557 n_channels
* sizeof(u16
);
558 offset
= roundup(offset
, sizeof(u32
));
559 ptr
= (char *)params_le
+ offset
;
560 for (i
= 0; i
< n_ssids
; i
++) {
561 memset(&ssid_le
, 0, sizeof(ssid_le
));
563 cpu_to_le32(request
->ssids
[i
].ssid_len
);
564 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
565 request
->ssids
[i
].ssid_len
);
566 if (!ssid_le
.SSID_len
)
567 brcmf_dbg(SCAN
, "%d: Broadcast scan\n", i
);
569 brcmf_dbg(SCAN
, "%d: scan for %s size =%d\n",
570 i
, ssid_le
.SSID
, ssid_le
.SSID_len
);
571 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
572 ptr
+= sizeof(ssid_le
);
575 brcmf_dbg(SCAN
, "Broadcast scan %p\n", request
->ssids
);
576 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
577 brcmf_dbg(SCAN
, "SSID %s len=%d\n",
578 params_le
->ssid_le
.SSID
,
579 request
->ssids
->ssid_len
);
580 params_le
->ssid_le
.SSID_len
=
581 cpu_to_le32(request
->ssids
->ssid_len
);
582 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
583 request
->ssids
->ssid_len
);
586 /* Adding mask to channel numbers */
587 params_le
->channel_num
=
588 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
589 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
593 brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
594 struct net_device
*ndev
,
595 bool aborted
, bool fw_abort
)
597 struct brcmf_scan_params_le params_le
;
598 struct cfg80211_scan_request
*scan_request
;
601 brcmf_dbg(SCAN
, "Enter\n");
603 /* clear scan request, because the FW abort can cause a second call */
604 /* to this functon and might cause a double cfg80211_scan_done */
605 scan_request
= cfg
->scan_request
;
606 cfg
->scan_request
= NULL
;
608 if (timer_pending(&cfg
->escan_timeout
))
609 del_timer_sync(&cfg
->escan_timeout
);
612 /* Do a scan abort to stop the driver's scan engine */
613 brcmf_dbg(SCAN
, "ABORT scan in firmware\n");
614 memset(¶ms_le
, 0, sizeof(params_le
));
615 memset(params_le
.bssid
, 0xFF, ETH_ALEN
);
616 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
617 params_le
.scan_type
= 0;
618 params_le
.channel_num
= cpu_to_le32(1);
619 params_le
.nprobes
= cpu_to_le32(1);
620 params_le
.active_time
= cpu_to_le32(-1);
621 params_le
.passive_time
= cpu_to_le32(-1);
622 params_le
.home_time
= cpu_to_le32(-1);
623 /* Scan is aborted by setting channel_list[0] to -1 */
624 params_le
.channel_list
[0] = cpu_to_le16(-1);
625 /* E-Scan (or anyother type) can be aborted by SCAN */
626 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SCAN
,
627 ¶ms_le
, sizeof(params_le
));
629 brcmf_err("Scan abort failed\n");
632 * e-scan can be initiated by scheduled scan
633 * which takes precedence.
635 if (cfg
->sched_escan
) {
636 brcmf_dbg(SCAN
, "scheduled scan completed\n");
637 cfg
->sched_escan
= false;
639 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
640 brcmf_set_mpc(ndev
, 1);
641 } else if (scan_request
) {
642 brcmf_dbg(SCAN
, "ESCAN Completed scan: %s\n",
643 aborted
? "Aborted" : "Done");
644 cfg80211_scan_done(scan_request
, aborted
);
645 brcmf_set_mpc(ndev
, 1);
647 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
648 brcmf_err("Scan complete while device not scanning\n");
656 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct net_device
*ndev
,
657 struct cfg80211_scan_request
*request
, u16 action
)
659 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
660 offsetof(struct brcmf_escan_params_le
, params_le
);
661 struct brcmf_escan_params_le
*params
;
664 brcmf_dbg(SCAN
, "E-SCAN START\n");
666 if (request
!= NULL
) {
667 /* Allocate space for populating ssids in struct */
668 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
670 /* Allocate space for populating ssids in struct */
671 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
674 params
= kzalloc(params_size
, GFP_KERNEL
);
679 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
680 brcmf_escan_prep(¶ms
->params_le
, request
);
681 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
682 params
->action
= cpu_to_le16(action
);
683 params
->sync_id
= cpu_to_le16(0x1234);
685 err
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "escan",
686 params
, params_size
);
689 brcmf_dbg(INFO
, "system busy : escan canceled\n");
691 brcmf_err("error (%d)\n", err
);
700 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
701 struct net_device
*ndev
, struct cfg80211_scan_request
*request
)
705 struct brcmf_scan_results
*results
;
707 brcmf_dbg(SCAN
, "Enter\n");
708 cfg
->escan_info
.ndev
= ndev
;
709 cfg
->escan_info
.wiphy
= wiphy
;
710 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_SCANNING
;
711 passive_scan
= cfg
->active_scan
? 0 : 1;
712 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_SET_PASSIVE_SCAN
,
715 brcmf_err("error (%d)\n", err
);
718 brcmf_set_mpc(ndev
, 0);
719 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
720 results
->version
= 0;
722 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
724 err
= brcmf_run_escan(cfg
, ndev
, request
, WL_ESCAN_ACTION_START
);
726 brcmf_set_mpc(ndev
, 1);
731 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct net_device
*ndev
,
732 struct cfg80211_scan_request
*request
,
733 struct cfg80211_ssid
*this_ssid
)
735 struct brcmf_if
*ifp
= netdev_priv(ndev
);
736 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
737 struct cfg80211_ssid
*ssids
;
738 struct brcmf_cfg80211_scan_req
*sr
= &cfg
->scan_req_int
;
745 brcmf_dbg(SCAN
, "START ESCAN\n");
747 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
748 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
751 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
752 brcmf_err("Scanning being aborted: status (%lu)\n",
756 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
757 brcmf_err("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
761 /* Arm scan timeout timer */
762 mod_timer(&cfg
->escan_timeout
, jiffies
+
763 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
768 ssids
= request
->ssids
;
772 /* we don't do escan in ibss */
776 cfg
->scan_request
= request
;
777 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
779 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
783 brcmf_dbg(SCAN
, "ssid \"%s\", ssid_len (%d)\n",
784 ssids
->ssid
, ssids
->ssid_len
);
785 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
786 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
787 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
790 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
791 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
794 brcmf_dbg(SCAN
, "Broadcast scan\n");
796 passive_scan
= cfg
->active_scan
? 0 : 1;
797 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
800 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
803 brcmf_set_mpc(ndev
, 0);
804 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
805 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
808 brcmf_dbg(INFO
, "BUSY: scan for \"%s\" canceled\n",
811 brcmf_err("WLC_SCAN error (%d)\n", err
);
813 brcmf_set_mpc(ndev
, 1);
821 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
822 if (timer_pending(&cfg
->escan_timeout
))
823 del_timer_sync(&cfg
->escan_timeout
);
824 cfg
->scan_request
= NULL
;
829 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
831 struct net_device
*ndev
= request
->wdev
->netdev
;
834 brcmf_dbg(TRACE
, "Enter\n");
836 if (!check_vif_up(container_of(request
->wdev
,
837 struct brcmf_cfg80211_vif
, wdev
)))
840 err
= brcmf_cfg80211_escan(wiphy
, ndev
, request
, NULL
);
843 brcmf_err("scan error (%d)\n", err
);
845 brcmf_dbg(TRACE
, "Exit\n");
849 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
853 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
856 brcmf_err("Error (%d)\n", err
);
861 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
865 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
868 brcmf_err("Error (%d)\n", err
);
873 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
876 u32 cmd
= (l
? BRCMF_C_SET_LRL
: BRCMF_C_SET_SRL
);
878 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
880 brcmf_err("cmd (%d) , error (%d)\n", cmd
, err
);
886 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
888 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
889 struct net_device
*ndev
= cfg_to_ndev(cfg
);
890 struct brcmf_if
*ifp
= netdev_priv(ndev
);
893 brcmf_dbg(TRACE
, "Enter\n");
894 if (!check_vif_up(ifp
->vif
))
897 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
898 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
899 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
900 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
904 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
905 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
906 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
907 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
911 if (changed
& WIPHY_PARAM_RETRY_LONG
912 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
913 cfg
->conf
->retry_long
= wiphy
->retry_long
;
914 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
918 if (changed
& WIPHY_PARAM_RETRY_SHORT
919 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
920 cfg
->conf
->retry_short
= wiphy
->retry_short
;
921 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
927 brcmf_dbg(TRACE
, "Exit\n");
931 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
933 memset(prof
, 0, sizeof(*prof
));
936 static void brcmf_ch_to_chanspec(int ch
, struct brcmf_join_params
*join_params
,
937 size_t *join_params_size
)
942 if (ch
<= CH_MAX_2G_CHANNEL
)
943 chanspec
|= WL_CHANSPEC_BAND_2G
;
945 chanspec
|= WL_CHANSPEC_BAND_5G
;
947 chanspec
|= WL_CHANSPEC_BW_20
;
948 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
950 *join_params_size
+= BRCMF_ASSOC_PARAMS_FIXED_SIZE
+
953 chanspec
|= (ch
& WL_CHANSPEC_CHAN_MASK
);
954 join_params
->params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
955 join_params
->params_le
.chanspec_num
= cpu_to_le32(1);
957 brcmf_dbg(CONN
, "channel %d, chanspec %#X\n", ch
, chanspec
);
961 static void brcmf_link_down(struct brcmf_cfg80211_vif
*vif
)
965 brcmf_dbg(TRACE
, "Enter\n");
967 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
)) {
968 brcmf_dbg(INFO
, "Call WLC_DISASSOC to stop excess roaming\n ");
969 err
= brcmf_fil_cmd_data_set(vif
->ifp
,
970 BRCMF_C_DISASSOC
, NULL
, 0);
972 brcmf_err("WLC_DISASSOC failed (%d)\n", err
);
973 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
);
975 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
);
976 brcmf_dbg(TRACE
, "Exit\n");
980 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
981 struct cfg80211_ibss_params
*params
)
983 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
984 struct brcmf_if
*ifp
= netdev_priv(ndev
);
985 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
986 struct brcmf_join_params join_params
;
987 size_t join_params_size
= 0;
992 brcmf_dbg(TRACE
, "Enter\n");
993 if (!check_vif_up(ifp
->vif
))
997 brcmf_dbg(CONN
, "SSID: %s\n", params
->ssid
);
999 brcmf_dbg(CONN
, "SSID: NULL, Not supported\n");
1003 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1006 brcmf_dbg(CONN
, "BSSID: %pM\n", params
->bssid
);
1008 brcmf_dbg(CONN
, "No BSSID specified\n");
1010 if (params
->chandef
.chan
)
1011 brcmf_dbg(CONN
, "channel: %d\n",
1012 params
->chandef
.chan
->center_freq
);
1014 brcmf_dbg(CONN
, "no channel specified\n");
1016 if (params
->channel_fixed
)
1017 brcmf_dbg(CONN
, "fixed channel required\n");
1019 brcmf_dbg(CONN
, "no fixed channel required\n");
1021 if (params
->ie
&& params
->ie_len
)
1022 brcmf_dbg(CONN
, "ie len: %d\n", params
->ie_len
);
1024 brcmf_dbg(CONN
, "no ie specified\n");
1026 if (params
->beacon_interval
)
1027 brcmf_dbg(CONN
, "beacon interval: %d\n",
1028 params
->beacon_interval
);
1030 brcmf_dbg(CONN
, "no beacon interval specified\n");
1032 if (params
->basic_rates
)
1033 brcmf_dbg(CONN
, "basic rates: %08X\n", params
->basic_rates
);
1035 brcmf_dbg(CONN
, "no basic rates specified\n");
1037 if (params
->privacy
)
1038 brcmf_dbg(CONN
, "privacy required\n");
1040 brcmf_dbg(CONN
, "no privacy required\n");
1042 /* Configure Privacy for starter */
1043 if (params
->privacy
)
1044 wsec
|= WEP_ENABLED
;
1046 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1048 brcmf_err("wsec failed (%d)\n", err
);
1052 /* Configure Beacon Interval for starter */
1053 if (params
->beacon_interval
)
1054 bcnprd
= params
->beacon_interval
;
1058 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
, bcnprd
);
1060 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err
);
1064 /* Configure required join parameter */
1065 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1068 profile
->ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1069 memcpy(profile
->ssid
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1070 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1071 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1072 join_params_size
= sizeof(join_params
.ssid_le
);
1075 if (params
->bssid
) {
1076 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1077 join_params_size
= sizeof(join_params
.ssid_le
) +
1078 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1079 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1081 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1082 memset(profile
->bssid
, 0, ETH_ALEN
);
1086 if (params
->chandef
.chan
) {
1090 ieee80211_frequency_to_channel(
1091 params
->chandef
.chan
->center_freq
);
1092 if (params
->channel_fixed
) {
1093 /* adding chanspec */
1094 brcmf_ch_to_chanspec(cfg
->channel
,
1095 &join_params
, &join_params_size
);
1098 /* set channel for starter */
1099 target_channel
= cfg
->channel
;
1100 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_CHANNEL
,
1103 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err
);
1109 cfg
->ibss_starter
= false;
1112 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1113 &join_params
, join_params_size
);
1115 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1121 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1122 brcmf_dbg(TRACE
, "Exit\n");
1127 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1129 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1132 brcmf_dbg(TRACE
, "Enter\n");
1133 if (!check_vif_up(ifp
->vif
))
1136 brcmf_link_down(ifp
->vif
);
1138 brcmf_dbg(TRACE
, "Exit\n");
1143 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1144 struct cfg80211_connect_params
*sme
)
1146 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1147 struct brcmf_cfg80211_security
*sec
;
1151 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1152 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1153 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1154 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1156 val
= WPA_AUTH_DISABLED
;
1157 brcmf_dbg(CONN
, "setting wpa_auth to 0x%0x\n", val
);
1158 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1160 brcmf_err("set wpa_auth failed (%d)\n", err
);
1163 sec
= &profile
->sec
;
1164 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1168 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1169 struct cfg80211_connect_params
*sme
)
1171 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1172 struct brcmf_cfg80211_security
*sec
;
1176 switch (sme
->auth_type
) {
1177 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1179 brcmf_dbg(CONN
, "open system\n");
1181 case NL80211_AUTHTYPE_SHARED_KEY
:
1183 brcmf_dbg(CONN
, "shared key\n");
1185 case NL80211_AUTHTYPE_AUTOMATIC
:
1187 brcmf_dbg(CONN
, "automatic\n");
1189 case NL80211_AUTHTYPE_NETWORK_EAP
:
1190 brcmf_dbg(CONN
, "network eap\n");
1193 brcmf_err("invalid auth type (%d)\n", sme
->auth_type
);
1197 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "auth", val
);
1199 brcmf_err("set auth failed (%d)\n", err
);
1202 sec
= &profile
->sec
;
1203 sec
->auth_type
= sme
->auth_type
;
1208 brcmf_set_set_cipher(struct net_device
*ndev
,
1209 struct cfg80211_connect_params
*sme
)
1211 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1212 struct brcmf_cfg80211_security
*sec
;
1217 if (sme
->crypto
.n_ciphers_pairwise
) {
1218 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1219 case WLAN_CIPHER_SUITE_WEP40
:
1220 case WLAN_CIPHER_SUITE_WEP104
:
1223 case WLAN_CIPHER_SUITE_TKIP
:
1224 pval
= TKIP_ENABLED
;
1226 case WLAN_CIPHER_SUITE_CCMP
:
1229 case WLAN_CIPHER_SUITE_AES_CMAC
:
1233 brcmf_err("invalid cipher pairwise (%d)\n",
1234 sme
->crypto
.ciphers_pairwise
[0]);
1238 if (sme
->crypto
.cipher_group
) {
1239 switch (sme
->crypto
.cipher_group
) {
1240 case WLAN_CIPHER_SUITE_WEP40
:
1241 case WLAN_CIPHER_SUITE_WEP104
:
1244 case WLAN_CIPHER_SUITE_TKIP
:
1245 gval
= TKIP_ENABLED
;
1247 case WLAN_CIPHER_SUITE_CCMP
:
1250 case WLAN_CIPHER_SUITE_AES_CMAC
:
1254 brcmf_err("invalid cipher group (%d)\n",
1255 sme
->crypto
.cipher_group
);
1260 brcmf_dbg(CONN
, "pval (%d) gval (%d)\n", pval
, gval
);
1261 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wsec", pval
| gval
);
1263 brcmf_err("error (%d)\n", err
);
1267 sec
= &profile
->sec
;
1268 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1269 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1275 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1277 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1278 struct brcmf_cfg80211_security
*sec
;
1282 if (sme
->crypto
.n_akm_suites
) {
1283 err
= brcmf_fil_iovar_int_get(netdev_priv(ndev
),
1286 brcmf_err("could not get wpa_auth (%d)\n", err
);
1289 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1290 switch (sme
->crypto
.akm_suites
[0]) {
1291 case WLAN_AKM_SUITE_8021X
:
1292 val
= WPA_AUTH_UNSPECIFIED
;
1294 case WLAN_AKM_SUITE_PSK
:
1298 brcmf_err("invalid cipher group (%d)\n",
1299 sme
->crypto
.cipher_group
);
1302 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1303 switch (sme
->crypto
.akm_suites
[0]) {
1304 case WLAN_AKM_SUITE_8021X
:
1305 val
= WPA2_AUTH_UNSPECIFIED
;
1307 case WLAN_AKM_SUITE_PSK
:
1308 val
= WPA2_AUTH_PSK
;
1311 brcmf_err("invalid cipher group (%d)\n",
1312 sme
->crypto
.cipher_group
);
1317 brcmf_dbg(CONN
, "setting wpa_auth to %d\n", val
);
1318 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
),
1321 brcmf_err("could not set wpa_auth (%d)\n", err
);
1325 sec
= &profile
->sec
;
1326 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1332 brcmf_set_sharedkey(struct net_device
*ndev
,
1333 struct cfg80211_connect_params
*sme
)
1335 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1336 struct brcmf_cfg80211_security
*sec
;
1337 struct brcmf_wsec_key key
;
1341 brcmf_dbg(CONN
, "key len (%d)\n", sme
->key_len
);
1343 if (sme
->key_len
== 0)
1346 sec
= &profile
->sec
;
1347 brcmf_dbg(CONN
, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1348 sec
->wpa_versions
, sec
->cipher_pairwise
);
1350 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1353 if (!(sec
->cipher_pairwise
&
1354 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1357 memset(&key
, 0, sizeof(key
));
1358 key
.len
= (u32
) sme
->key_len
;
1359 key
.index
= (u32
) sme
->key_idx
;
1360 if (key
.len
> sizeof(key
.data
)) {
1361 brcmf_err("Too long key length (%u)\n", key
.len
);
1364 memcpy(key
.data
, sme
->key
, key
.len
);
1365 key
.flags
= BRCMF_PRIMARY_KEY
;
1366 switch (sec
->cipher_pairwise
) {
1367 case WLAN_CIPHER_SUITE_WEP40
:
1368 key
.algo
= CRYPTO_ALGO_WEP1
;
1370 case WLAN_CIPHER_SUITE_WEP104
:
1371 key
.algo
= CRYPTO_ALGO_WEP128
;
1374 brcmf_err("Invalid algorithm (%d)\n",
1375 sme
->crypto
.ciphers_pairwise
[0]);
1378 /* Set the new key/index */
1379 brcmf_dbg(CONN
, "key length (%d) key index (%d) algo (%d)\n",
1380 key
.len
, key
.index
, key
.algo
);
1381 brcmf_dbg(CONN
, "key \"%s\"\n", key
.data
);
1382 err
= send_key_to_dongle(ndev
, &key
);
1386 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1387 brcmf_dbg(CONN
, "set auth_type to shared key\n");
1388 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1389 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1391 brcmf_err("set auth failed (%d)\n", err
);
1397 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1398 struct cfg80211_connect_params
*sme
)
1400 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1401 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1402 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1403 struct ieee80211_channel
*chan
= sme
->channel
;
1404 struct brcmf_join_params join_params
;
1405 size_t join_params_size
;
1406 struct brcmf_ssid ssid
;
1410 brcmf_dbg(TRACE
, "Enter\n");
1411 if (!check_vif_up(ifp
->vif
))
1415 brcmf_err("Invalid ssid\n");
1419 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1423 ieee80211_frequency_to_channel(chan
->center_freq
);
1424 brcmf_dbg(CONN
, "channel (%d), center_req (%d)\n",
1425 cfg
->channel
, chan
->center_freq
);
1429 brcmf_dbg(INFO
, "ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1431 err
= brcmf_set_wpa_version(ndev
, sme
);
1433 brcmf_err("wl_set_wpa_version failed (%d)\n", err
);
1437 err
= brcmf_set_auth_type(ndev
, sme
);
1439 brcmf_err("wl_set_auth_type failed (%d)\n", err
);
1443 err
= brcmf_set_set_cipher(ndev
, sme
);
1445 brcmf_err("wl_set_set_cipher failed (%d)\n", err
);
1449 err
= brcmf_set_key_mgmt(ndev
, sme
);
1451 brcmf_err("wl_set_key_mgmt failed (%d)\n", err
);
1455 err
= brcmf_set_sharedkey(ndev
, sme
);
1457 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err
);
1461 memset(&join_params
, 0, sizeof(join_params
));
1462 join_params_size
= sizeof(join_params
.ssid_le
);
1464 profile
->ssid
.SSID_len
= min_t(u32
,
1465 sizeof(ssid
.SSID
), (u32
)sme
->ssid_len
);
1466 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1467 memcpy(&profile
->ssid
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1468 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1470 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1472 if (ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
)
1473 brcmf_dbg(CONN
, "ssid \"%s\", len (%d)\n",
1474 ssid
.SSID
, ssid
.SSID_len
);
1476 brcmf_ch_to_chanspec(cfg
->channel
,
1477 &join_params
, &join_params_size
);
1478 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1479 &join_params
, join_params_size
);
1481 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1485 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1486 brcmf_dbg(TRACE
, "Exit\n");
1491 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1494 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1495 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1496 struct brcmf_scb_val_le scbval
;
1499 brcmf_dbg(TRACE
, "Enter. Reason code = %d\n", reason_code
);
1500 if (!check_vif_up(ifp
->vif
))
1503 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
1505 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1506 scbval
.val
= cpu_to_le32(reason_code
);
1507 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1508 &scbval
, sizeof(scbval
));
1510 brcmf_err("error (%d)\n", err
);
1512 brcmf_dbg(TRACE
, "Exit\n");
1517 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1518 enum nl80211_tx_power_setting type
, s32 mbm
)
1521 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1522 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1523 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1527 s32 dbm
= MBM_TO_DBM(mbm
);
1529 brcmf_dbg(TRACE
, "Enter\n");
1530 if (!check_vif_up(ifp
->vif
))
1534 case NL80211_TX_POWER_AUTOMATIC
:
1536 case NL80211_TX_POWER_LIMITED
:
1537 case NL80211_TX_POWER_FIXED
:
1539 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1545 /* Make sure radio is off or on as far as software is concerned */
1546 disable
= WL_RADIO_SW_DISABLE
<< 16;
1547 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1549 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
1554 txpwrmw
= (u16
) dbm
;
1555 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1556 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1558 brcmf_err("qtxpower error (%d)\n", err
);
1559 cfg
->conf
->tx_power
= dbm
;
1562 brcmf_dbg(TRACE
, "Exit\n");
1566 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
,
1567 struct wireless_dev
*wdev
,
1570 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1571 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1576 brcmf_dbg(TRACE
, "Enter\n");
1577 if (!check_vif_up(ifp
->vif
))
1580 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &txpwrdbm
);
1582 brcmf_err("error (%d)\n", err
);
1586 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1587 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1590 brcmf_dbg(TRACE
, "Exit\n");
1595 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1596 u8 key_idx
, bool unicast
, bool multicast
)
1598 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1603 brcmf_dbg(TRACE
, "Enter\n");
1604 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1605 if (!check_vif_up(ifp
->vif
))
1608 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1610 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1614 if (wsec
& WEP_ENABLED
) {
1615 /* Just select a new current key */
1617 err
= brcmf_fil_cmd_int_set(ifp
,
1618 BRCMF_C_SET_KEY_PRIMARY
, index
);
1620 brcmf_err("error (%d)\n", err
);
1623 brcmf_dbg(TRACE
, "Exit\n");
1628 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1629 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1631 struct brcmf_wsec_key key
;
1634 memset(&key
, 0, sizeof(key
));
1635 key
.index
= (u32
) key_idx
;
1636 /* Instead of bcast for ea address for default wep keys,
1637 driver needs it to be Null */
1638 if (!is_multicast_ether_addr(mac_addr
))
1639 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1640 key
.len
= (u32
) params
->key_len
;
1641 /* check for key index change */
1644 err
= send_key_to_dongle(ndev
, &key
);
1646 brcmf_err("key delete error (%d)\n", err
);
1648 if (key
.len
> sizeof(key
.data
)) {
1649 brcmf_err("Invalid key length (%d)\n", key
.len
);
1653 brcmf_dbg(CONN
, "Setting the key index %d\n", key
.index
);
1654 memcpy(key
.data
, params
->key
, key
.len
);
1656 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1658 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1659 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1660 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1663 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1664 if (params
->seq
&& params
->seq_len
== 6) {
1667 ivptr
= (u8
*) params
->seq
;
1668 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1669 (ivptr
[3] << 8) | ivptr
[2];
1670 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1671 key
.iv_initialized
= true;
1674 switch (params
->cipher
) {
1675 case WLAN_CIPHER_SUITE_WEP40
:
1676 key
.algo
= CRYPTO_ALGO_WEP1
;
1677 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1679 case WLAN_CIPHER_SUITE_WEP104
:
1680 key
.algo
= CRYPTO_ALGO_WEP128
;
1681 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1683 case WLAN_CIPHER_SUITE_TKIP
:
1684 key
.algo
= CRYPTO_ALGO_TKIP
;
1685 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1687 case WLAN_CIPHER_SUITE_AES_CMAC
:
1688 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1689 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1691 case WLAN_CIPHER_SUITE_CCMP
:
1692 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1693 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1696 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1699 err
= send_key_to_dongle(ndev
, &key
);
1701 brcmf_err("wsec_key error (%d)\n", err
);
1707 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1708 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1709 struct key_params
*params
)
1711 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1712 struct brcmf_wsec_key key
;
1718 brcmf_dbg(TRACE
, "Enter\n");
1719 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1720 if (!check_vif_up(ifp
->vif
))
1724 brcmf_dbg(TRACE
, "Exit");
1725 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1727 memset(&key
, 0, sizeof(key
));
1729 key
.len
= (u32
) params
->key_len
;
1730 key
.index
= (u32
) key_idx
;
1732 if (key
.len
> sizeof(key
.data
)) {
1733 brcmf_err("Too long key length (%u)\n", key
.len
);
1737 memcpy(key
.data
, params
->key
, key
.len
);
1739 key
.flags
= BRCMF_PRIMARY_KEY
;
1740 switch (params
->cipher
) {
1741 case WLAN_CIPHER_SUITE_WEP40
:
1742 key
.algo
= CRYPTO_ALGO_WEP1
;
1744 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1746 case WLAN_CIPHER_SUITE_WEP104
:
1747 key
.algo
= CRYPTO_ALGO_WEP128
;
1749 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1751 case WLAN_CIPHER_SUITE_TKIP
:
1752 if (ifp
->vif
->mode
!= WL_MODE_AP
) {
1753 brcmf_dbg(CONN
, "Swapping key\n");
1754 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1755 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1756 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1758 key
.algo
= CRYPTO_ALGO_TKIP
;
1760 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1762 case WLAN_CIPHER_SUITE_AES_CMAC
:
1763 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1765 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1767 case WLAN_CIPHER_SUITE_CCMP
:
1768 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1770 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1773 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1778 err
= send_key_to_dongle(ndev
, &key
);
1782 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1784 brcmf_err("get wsec error (%d)\n", err
);
1788 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
1790 brcmf_err("set wsec error (%d)\n", err
);
1795 brcmf_dbg(TRACE
, "Exit\n");
1800 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1801 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
1803 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1804 struct brcmf_wsec_key key
;
1807 brcmf_dbg(TRACE
, "Enter\n");
1808 if (!check_vif_up(ifp
->vif
))
1811 if (key_idx
>= DOT11_MAX_DEFAULT_KEYS
) {
1812 /* we ignore this key index in this case */
1813 brcmf_err("invalid key index (%d)\n", key_idx
);
1817 memset(&key
, 0, sizeof(key
));
1819 key
.index
= (u32
) key_idx
;
1820 key
.flags
= BRCMF_PRIMARY_KEY
;
1821 key
.algo
= CRYPTO_ALGO_OFF
;
1823 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1825 /* Set the new key/index */
1826 err
= send_key_to_dongle(ndev
, &key
);
1828 brcmf_dbg(TRACE
, "Exit\n");
1833 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1834 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
1835 void (*callback
) (void *cookie
, struct key_params
* params
))
1837 struct key_params params
;
1838 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1839 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1840 struct brcmf_cfg80211_security
*sec
;
1844 brcmf_dbg(TRACE
, "Enter\n");
1845 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1846 if (!check_vif_up(ifp
->vif
))
1849 memset(¶ms
, 0, sizeof(params
));
1851 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1853 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1854 /* Ignore this error, may happen during DISASSOC */
1858 switch (wsec
& ~SES_OW_ENABLED
) {
1860 sec
= &profile
->sec
;
1861 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
1862 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
1863 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1864 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
1865 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
1866 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1870 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
1871 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1874 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
1875 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1878 brcmf_err("Invalid algo (0x%x)\n", wsec
);
1882 callback(cookie
, ¶ms
);
1885 brcmf_dbg(TRACE
, "Exit\n");
1890 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
1891 struct net_device
*ndev
, u8 key_idx
)
1893 brcmf_dbg(INFO
, "Not supported\n");
1899 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
1900 u8
*mac
, struct station_info
*sinfo
)
1902 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1903 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1904 struct brcmf_scb_val_le scb_val
;
1908 u8
*bssid
= profile
->bssid
;
1909 struct brcmf_sta_info_le sta_info_le
;
1911 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
1912 if (!check_vif_up(ifp
->vif
))
1915 if (ifp
->vif
->mode
== WL_MODE_AP
) {
1916 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
1917 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
1919 sizeof(sta_info_le
));
1921 brcmf_err("GET STA INFO failed, %d\n", err
);
1924 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
1925 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
1926 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
1927 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
1928 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
1930 brcmf_dbg(TRACE
, "STA idle time : %d ms, connected time :%d sec\n",
1931 sinfo
->inactive_time
, sinfo
->connected_time
);
1932 } else if (ifp
->vif
->mode
== WL_MODE_BSS
) {
1933 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
1934 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1939 /* Report the current tx rate */
1940 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
1942 brcmf_err("Could not get rate (%d)\n", err
);
1945 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1946 sinfo
->txrate
.legacy
= rate
* 5;
1947 brcmf_dbg(CONN
, "Rate %d Mbps\n", rate
/ 2);
1950 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
1951 &ifp
->vif
->sme_state
)) {
1952 memset(&scb_val
, 0, sizeof(scb_val
));
1953 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
1954 &scb_val
, sizeof(scb_val
));
1956 brcmf_err("Could not get rssi (%d)\n", err
);
1959 rssi
= le32_to_cpu(scb_val
.val
);
1960 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1961 sinfo
->signal
= rssi
;
1962 brcmf_dbg(CONN
, "RSSI %d dBm\n", rssi
);
1968 brcmf_dbg(TRACE
, "Exit\n");
1973 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
1974 bool enabled
, s32 timeout
)
1978 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1979 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1981 brcmf_dbg(TRACE
, "Enter\n");
1984 * Powersave enable/disable request is coming from the
1985 * cfg80211 even before the interface is up. In that
1986 * scenario, driver will be storing the power save
1987 * preference in cfg struct to apply this to
1988 * FW later while initializing the dongle
1990 cfg
->pwr_save
= enabled
;
1991 if (!check_vif_up(ifp
->vif
)) {
1993 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
1997 pm
= enabled
? PM_FAST
: PM_OFF
;
1998 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2000 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2003 brcmf_err("net_device is not ready yet\n");
2005 brcmf_err("error (%d)\n", err
);
2008 brcmf_dbg(TRACE
, "Exit\n");
2012 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2013 struct brcmf_bss_info_le
*bi
)
2015 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2016 struct ieee80211_channel
*notify_channel
;
2017 struct cfg80211_bss
*bss
;
2018 struct ieee80211_supported_band
*band
;
2022 u16 notify_capability
;
2023 u16 notify_interval
;
2025 size_t notify_ielen
;
2028 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2029 brcmf_err("Bss info is larger than buffer. Discarding\n");
2033 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2034 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2036 if (channel
<= CH_MAX_2G_CHANNEL
)
2037 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2039 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2041 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2042 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2044 notify_capability
= le16_to_cpu(bi
->capability
);
2045 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2046 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2047 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2048 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2050 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2051 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2052 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2053 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2054 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2056 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2057 0, notify_capability
, notify_interval
, notify_ie
,
2058 notify_ielen
, notify_signal
, GFP_KERNEL
);
2063 cfg80211_put_bss(bss
);
2068 static struct brcmf_bss_info_le
*
2069 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2072 return list
->bss_info_le
;
2073 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2074 le32_to_cpu(bss
->length
));
2077 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2079 struct brcmf_scan_results
*bss_list
;
2080 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2084 bss_list
= cfg
->bss_list
;
2085 if (bss_list
->count
!= 0 &&
2086 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2087 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2091 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2092 for (i
= 0; i
< bss_list
->count
; i
++) {
2093 bi
= next_bss_le(bss_list
, bi
);
2094 err
= brcmf_inform_single_bss(cfg
, bi
);
2101 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2102 struct net_device
*ndev
, const u8
*bssid
)
2104 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2105 struct ieee80211_channel
*notify_channel
;
2106 struct brcmf_bss_info_le
*bi
= NULL
;
2107 struct ieee80211_supported_band
*band
;
2108 struct cfg80211_bss
*bss
;
2113 u16 notify_capability
;
2114 u16 notify_interval
;
2116 size_t notify_ielen
;
2119 brcmf_dbg(TRACE
, "Enter\n");
2121 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2127 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2129 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2130 buf
, WL_BSS_INFO_MAX
);
2132 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2136 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2138 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2139 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2141 if (channel
<= CH_MAX_2G_CHANNEL
)
2142 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2144 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2146 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2147 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2149 notify_capability
= le16_to_cpu(bi
->capability
);
2150 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2151 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2152 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2153 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2155 brcmf_dbg(CONN
, "channel: %d(%d)\n", channel
, freq
);
2156 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2157 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2158 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2160 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2161 0, notify_capability
, notify_interval
,
2162 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2169 cfg80211_put_bss(bss
);
2175 brcmf_dbg(TRACE
, "Exit\n");
2180 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
2182 return vif
->mode
== WL_MODE_IBSS
;
2186 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2187 * triples, returning a pointer to the substring whose first element
2190 static struct brcmf_tlv
*brcmf_parse_tlvs(void *buf
, int buflen
, uint key
)
2192 struct brcmf_tlv
*elt
;
2195 elt
= (struct brcmf_tlv
*) buf
;
2198 /* find tagged parameter */
2199 while (totlen
>= TLV_HDR_LEN
) {
2202 /* validate remaining totlen */
2203 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
2206 elt
= (struct brcmf_tlv
*) ((u8
*) elt
+ (len
+ TLV_HDR_LEN
));
2207 totlen
-= (len
+ TLV_HDR_LEN
);
2213 /* Is any of the tlvs the expected entry? If
2214 * not update the tlvs buffer pointer/length.
2217 brcmf_tlv_has_ie(u8
*ie
, u8
**tlvs
, u32
*tlvs_len
,
2218 u8
*oui
, u32 oui_len
, u8 type
)
2220 /* If the contents match the OUI and the type */
2221 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
2222 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
2223 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
2229 /* point to the next ie */
2230 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
2231 /* calculate the length of the rest of the buffer */
2232 *tlvs_len
-= (int)(ie
- *tlvs
);
2233 /* update the pointer to the start of the buffer */
2239 static struct brcmf_vs_tlv
*
2240 brcmf_find_wpaie(u8
*parse
, u32 len
)
2242 struct brcmf_tlv
*ie
;
2244 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
2245 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
2246 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
2247 return (struct brcmf_vs_tlv
*)ie
;
2252 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
)
2254 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2255 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
2256 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2257 struct brcmf_bss_info_le
*bi
;
2258 struct brcmf_ssid
*ssid
;
2259 struct brcmf_tlv
*tim
;
2260 u16 beacon_interval
;
2266 brcmf_dbg(TRACE
, "Enter\n");
2267 if (brcmf_is_ibssmode(ifp
->vif
))
2270 ssid
= &profile
->ssid
;
2272 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2273 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2274 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2276 brcmf_err("Could not get bss info %d\n", err
);
2277 goto update_bss_info_out
;
2280 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2281 err
= brcmf_inform_single_bss(cfg
, bi
);
2283 goto update_bss_info_out
;
2285 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2286 ie_len
= le32_to_cpu(bi
->ie_length
);
2287 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2289 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2291 dtim_period
= tim
->data
[1];
2294 * active scan was done so we could not get dtim
2295 * information out of probe response.
2296 * so we speficially query dtim information to dongle.
2299 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2301 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2302 goto update_bss_info_out
;
2304 dtim_period
= (u8
)var
;
2307 update_bss_info_out
:
2308 brcmf_dbg(TRACE
, "Exit");
2312 static void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2314 struct escan_info
*escan
= &cfg
->escan_info
;
2316 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2317 if (cfg
->scan_request
) {
2318 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2319 brcmf_notify_escan_complete(cfg
, escan
->ndev
, true, true);
2321 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2322 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2325 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2327 struct brcmf_cfg80211_info
*cfg
=
2328 container_of(work
, struct brcmf_cfg80211_info
,
2329 escan_timeout_work
);
2331 brcmf_notify_escan_complete(cfg
,
2332 cfg
->escan_info
.ndev
, true, true);
2335 static void brcmf_escan_timeout(unsigned long data
)
2337 struct brcmf_cfg80211_info
*cfg
=
2338 (struct brcmf_cfg80211_info
*)data
;
2340 if (cfg
->scan_request
) {
2341 brcmf_err("timer expired\n");
2342 schedule_work(&cfg
->escan_timeout_work
);
2347 brcmf_compare_update_same_bss(struct brcmf_bss_info_le
*bss
,
2348 struct brcmf_bss_info_le
*bss_info_le
)
2350 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2351 (CHSPEC_BAND(le16_to_cpu(bss_info_le
->chanspec
)) ==
2352 CHSPEC_BAND(le16_to_cpu(bss
->chanspec
))) &&
2353 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2354 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2355 if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) ==
2356 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
)) {
2357 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2358 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2360 /* preserve max RSSI if the measurements are
2361 * both on-channel or both off-channel
2363 if (bss_info_rssi
> bss_rssi
)
2364 bss
->RSSI
= bss_info_le
->RSSI
;
2365 } else if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) &&
2366 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) == 0) {
2367 /* preserve the on-channel rssi measurement
2368 * if the new measurement is off channel
2370 bss
->RSSI
= bss_info_le
->RSSI
;
2371 bss
->flags
|= WLC_BSS_RSSI_ON_CHANNEL
;
2379 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
2380 const struct brcmf_event_msg
*e
, void *data
)
2382 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2383 struct net_device
*ndev
= ifp
->ndev
;
2386 struct brcmf_escan_result_le
*escan_result_le
;
2387 struct brcmf_bss_info_le
*bss_info_le
;
2388 struct brcmf_bss_info_le
*bss
= NULL
;
2390 struct brcmf_scan_results
*list
;
2396 if (!ndev
|| !test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2397 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev
,
2398 !test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
));
2402 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2403 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
2404 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2405 if (!escan_result_le
) {
2406 brcmf_err("Invalid escan result (NULL pointer)\n");
2409 if (!cfg
->scan_request
) {
2410 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
2414 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2415 brcmf_err("Invalid bss_count %d: ignoring\n",
2416 escan_result_le
->bss_count
);
2419 bss_info_le
= &escan_result_le
->bss_info_le
;
2421 bi_length
= le32_to_cpu(bss_info_le
->length
);
2422 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2423 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2424 brcmf_err("Invalid bss_info length %d: ignoring\n",
2429 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
2430 BIT(NL80211_IFTYPE_ADHOC
))) {
2431 if (le16_to_cpu(bss_info_le
->capability
) &
2432 WLAN_CAPABILITY_IBSS
) {
2433 brcmf_err("Ignoring IBSS result\n");
2438 list
= (struct brcmf_scan_results
*)
2439 cfg
->escan_info
.escan_buf
;
2440 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2441 brcmf_err("Buffer is too small: ignoring\n");
2445 for (i
= 0; i
< list
->count
; i
++) {
2446 bss
= bss
? (struct brcmf_bss_info_le
*)
2447 ((unsigned char *)bss
+
2448 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2449 if (brcmf_compare_update_same_bss(bss
, bss_info_le
))
2452 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
2453 bss_info_le
, bi_length
);
2454 list
->version
= le32_to_cpu(bss_info_le
->version
);
2455 list
->buflen
+= bi_length
;
2458 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2459 if (cfg
->scan_request
) {
2460 cfg
->bss_list
= (struct brcmf_scan_results
*)
2461 cfg
->escan_info
.escan_buf
;
2462 brcmf_inform_bss(cfg
);
2463 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2464 brcmf_notify_escan_complete(cfg
, ndev
, aborted
,
2467 brcmf_err("Unexpected scan result 0x%x\n", status
);
2473 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2475 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
2476 brcmf_cfg80211_escan_handler
);
2477 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2478 /* Init scan_timeout timer */
2479 init_timer(&cfg
->escan_timeout
);
2480 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2481 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2482 INIT_WORK(&cfg
->escan_timeout_work
,
2483 brcmf_cfg80211_escan_timeout_worker
);
2486 static __always_inline
void brcmf_delay(u32 ms
)
2488 if (ms
< 1000 / HZ
) {
2496 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2498 brcmf_dbg(TRACE
, "Enter\n");
2503 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2504 struct cfg80211_wowlan
*wow
)
2506 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2507 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2508 struct brcmf_cfg80211_vif
*vif
;
2510 brcmf_dbg(TRACE
, "Enter\n");
2513 * if the primary net_device is not READY there is nothing
2514 * we can do but pray resume goes smoothly.
2516 vif
= ((struct brcmf_if
*)netdev_priv(ndev
))->vif
;
2517 if (!check_vif_up(vif
))
2520 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
2521 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
2524 * While going to suspend if associated with AP disassociate
2525 * from AP to save power while system is in suspended state
2527 brcmf_link_down(vif
);
2529 /* Make sure WPA_Supplicant receives all the event
2530 * generated due to DISASSOC call to the fw to keep
2531 * the state fw and WPA_Supplicant state consistent
2536 /* end any scanning */
2537 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
2538 brcmf_abort_scanning(cfg
);
2540 /* Turn off watchdog timer */
2541 brcmf_set_mpc(ndev
, 1);
2544 brcmf_dbg(TRACE
, "Exit\n");
2545 /* clear any scanning activity */
2546 cfg
->scan_status
= 0;
2551 brcmf_update_pmklist(struct net_device
*ndev
,
2552 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2557 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
2559 brcmf_dbg(CONN
, "No of elements %d\n", pmkid_len
);
2560 for (i
= 0; i
< pmkid_len
; i
++) {
2561 brcmf_dbg(CONN
, "PMKID[%d]: %pM =\n", i
,
2562 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2563 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2564 brcmf_dbg(CONN
, "%02x\n",
2565 pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2569 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
2570 (char *)pmk_list
, sizeof(*pmk_list
));
2576 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2577 struct cfg80211_pmksa
*pmksa
)
2579 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2580 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2581 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
2586 brcmf_dbg(TRACE
, "Enter\n");
2587 if (!check_vif_up(ifp
->vif
))
2590 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
2591 for (i
= 0; i
< pmkid_len
; i
++)
2592 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2594 if (i
< WL_NUM_PMKIDS_MAX
) {
2595 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2596 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2597 if (i
== pmkid_len
) {
2599 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
2604 brcmf_dbg(CONN
, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2605 pmkids
->pmkid
[pmkid_len
].BSSID
);
2606 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2607 brcmf_dbg(CONN
, "%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
2609 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2611 brcmf_dbg(TRACE
, "Exit\n");
2616 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2617 struct cfg80211_pmksa
*pmksa
)
2619 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2620 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2621 struct pmkid_list pmkid
;
2625 brcmf_dbg(TRACE
, "Enter\n");
2626 if (!check_vif_up(ifp
->vif
))
2629 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2630 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2632 brcmf_dbg(CONN
, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2633 &pmkid
.pmkid
[0].BSSID
);
2634 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2635 brcmf_dbg(CONN
, "%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2637 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
2638 for (i
= 0; i
< pmkid_len
; i
++)
2640 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2645 && (i
< pmkid_len
)) {
2646 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
2647 sizeof(struct pmkid
));
2648 for (; i
< (pmkid_len
- 1); i
++) {
2649 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2650 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2652 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2653 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2656 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
2660 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2662 brcmf_dbg(TRACE
, "Exit\n");
2668 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
2670 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2671 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2674 brcmf_dbg(TRACE
, "Enter\n");
2675 if (!check_vif_up(ifp
->vif
))
2678 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
2679 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2681 brcmf_dbg(TRACE
, "Exit\n");
2687 * PFN result doesn't have all the info which are
2688 * required by the supplicant
2689 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2690 * via wl_inform_single_bss in the required format. Escan does require the
2691 * scan request in the form of cfg80211_scan_request. For timebeing, create
2692 * cfg80211_scan_request one out of the received PNO event.
2695 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
2696 const struct brcmf_event_msg
*e
, void *data
)
2698 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2699 struct net_device
*ndev
= ifp
->ndev
;
2700 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
2701 struct cfg80211_scan_request
*request
= NULL
;
2702 struct cfg80211_ssid
*ssid
= NULL
;
2703 struct ieee80211_channel
*channel
= NULL
;
2704 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2706 int channel_req
= 0;
2708 struct brcmf_pno_scanresults_le
*pfn_result
;
2712 brcmf_dbg(SCAN
, "Enter\n");
2714 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
2715 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
2719 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
2720 result_count
= le32_to_cpu(pfn_result
->count
);
2721 status
= le32_to_cpu(pfn_result
->status
);
2724 * PFN event is limited to fit 512 bytes so we may get
2725 * multiple NET_FOUND events. For now place a warning here.
2727 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
2728 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
2729 if (result_count
> 0) {
2732 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
2733 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
2734 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
2735 if (!request
|| !ssid
|| !channel
) {
2740 request
->wiphy
= wiphy
;
2741 data
+= sizeof(struct brcmf_pno_scanresults_le
);
2742 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
2744 for (i
= 0; i
< result_count
; i
++) {
2745 netinfo
= &netinfo_start
[i
];
2747 brcmf_err("Invalid netinfo ptr. index: %d\n",
2753 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
2754 netinfo
->SSID
, netinfo
->channel
);
2755 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
2756 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
2759 channel_req
= netinfo
->channel
;
2760 if (channel_req
<= CH_MAX_2G_CHANNEL
)
2761 band
= NL80211_BAND_2GHZ
;
2763 band
= NL80211_BAND_5GHZ
;
2764 channel
[i
].center_freq
=
2765 ieee80211_channel_to_frequency(channel_req
,
2767 channel
[i
].band
= band
;
2768 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
2769 request
->channels
[i
] = &channel
[i
];
2770 request
->n_channels
++;
2773 /* assign parsed ssid array */
2774 if (request
->n_ssids
)
2775 request
->ssids
= &ssid
[0];
2777 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2778 /* Abort any on-going scan */
2779 brcmf_abort_scanning(cfg
);
2782 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2783 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
2785 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2788 cfg
->sched_escan
= true;
2789 cfg
->scan_request
= request
;
2791 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2804 cfg80211_sched_scan_stopped(wiphy
);
2808 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
2813 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
2816 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
2820 brcmf_err("failed code %d\n", ret
);
2825 static int brcmf_dev_pno_config(struct net_device
*ndev
)
2827 struct brcmf_pno_param_le pfn_param
;
2829 memset(&pfn_param
, 0, sizeof(pfn_param
));
2830 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
2832 /* set extra pno params */
2833 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
2834 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
2835 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
2837 /* set up pno scan fr */
2838 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
2840 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
2841 &pfn_param
, sizeof(pfn_param
));
2845 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
2846 struct net_device
*ndev
,
2847 struct cfg80211_sched_scan_request
*request
)
2849 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2850 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
2851 struct brcmf_pno_net_param_le pfn
;
2855 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
2856 request
->n_match_sets
, request
->n_ssids
);
2857 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2858 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
2862 if (!request
|| !request
->n_ssids
|| !request
->n_match_sets
) {
2863 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
2864 request
? request
->n_ssids
: 0);
2868 if (request
->n_ssids
> 0) {
2869 for (i
= 0; i
< request
->n_ssids
; i
++) {
2870 /* Active scan req for ssids */
2871 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
2872 request
->ssids
[i
].ssid
);
2875 * match_set ssids is a supert set of n_ssid list,
2876 * so we need not add these set seperately.
2881 if (request
->n_match_sets
> 0) {
2882 /* clean up everything */
2883 ret
= brcmf_dev_pno_clean(ndev
);
2885 brcmf_err("failed error=%d\n", ret
);
2890 ret
= brcmf_dev_pno_config(ndev
);
2892 brcmf_err("PNO setup failed!! ret=%d\n", ret
);
2896 /* configure each match set */
2897 for (i
= 0; i
< request
->n_match_sets
; i
++) {
2898 struct cfg80211_ssid
*ssid
;
2901 ssid
= &request
->match_sets
[i
].ssid
;
2902 ssid_len
= ssid
->ssid_len
;
2905 brcmf_err("skip broadcast ssid\n");
2908 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
2909 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
2910 pfn
.wsec
= cpu_to_le32(0);
2911 pfn
.infra
= cpu_to_le32(1);
2912 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
2913 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
2914 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
2915 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
2917 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
2918 ret
== 0 ? "set" : "failed", ssid
->ssid
);
2920 /* Enable the PNO */
2921 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
2922 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
2932 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
2933 struct net_device
*ndev
)
2935 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2937 brcmf_dbg(SCAN
, "enter\n");
2938 brcmf_dev_pno_clean(ndev
);
2939 if (cfg
->sched_escan
)
2940 brcmf_notify_escan_complete(cfg
, ndev
, true, true);
2944 #ifdef CONFIG_NL80211_TESTMODE
2945 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
, void *data
, int len
)
2947 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2948 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2949 struct brcmf_dcmd
*dcmd
= data
;
2950 struct sk_buff
*reply
;
2953 brcmf_dbg(TRACE
, "cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
2954 dcmd
->buf
, dcmd
->len
);
2957 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
2958 dcmd
->buf
, dcmd
->len
);
2960 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
2961 dcmd
->buf
, dcmd
->len
);
2963 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
2964 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
2965 ret
= cfg80211_testmode_reply(reply
);
2971 static s32
brcmf_configure_opensecurity(struct net_device
*ndev
, s32 bssidx
)
2973 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2977 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
2979 brcmf_err("auth error %d\n", err
);
2983 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
2985 brcmf_err("wsec error %d\n", err
);
2988 /* set upper-layer auth */
2989 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
2991 brcmf_err("wpa_auth error %d\n", err
);
2998 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3001 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3003 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3007 brcmf_configure_wpaie(struct net_device
*ndev
, struct brcmf_vs_tlv
*wpa_ie
,
3010 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3011 u32 auth
= 0; /* d11 open authentication */
3023 u32 wme_bss_disable
;
3025 brcmf_dbg(TRACE
, "Enter\n");
3029 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3030 data
= (u8
*)wpa_ie
;
3033 offset
+= VS_IE_FIXED_HDR_LEN
;
3034 offset
+= WPA_IE_VERSION_LEN
;
3036 /* check for multicast cipher suite */
3037 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3039 brcmf_err("no multicast cipher suite\n");
3043 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3045 brcmf_err("ivalid OUI\n");
3048 offset
+= TLV_OUI_LEN
;
3050 /* pick up multicast cipher */
3051 switch (data
[offset
]) {
3052 case WPA_CIPHER_NONE
:
3055 case WPA_CIPHER_WEP_40
:
3056 case WPA_CIPHER_WEP_104
:
3059 case WPA_CIPHER_TKIP
:
3060 gval
= TKIP_ENABLED
;
3062 case WPA_CIPHER_AES_CCM
:
3067 brcmf_err("Invalid multi cast cipher info\n");
3072 /* walk thru unicast cipher list and pick up what we recognize */
3073 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3074 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3075 /* Check for unicast suite(s) */
3076 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3078 brcmf_err("no unicast cipher suite\n");
3081 for (i
= 0; i
< count
; i
++) {
3082 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3084 brcmf_err("ivalid OUI\n");
3087 offset
+= TLV_OUI_LEN
;
3088 switch (data
[offset
]) {
3089 case WPA_CIPHER_NONE
:
3091 case WPA_CIPHER_WEP_40
:
3092 case WPA_CIPHER_WEP_104
:
3093 pval
|= WEP_ENABLED
;
3095 case WPA_CIPHER_TKIP
:
3096 pval
|= TKIP_ENABLED
;
3098 case WPA_CIPHER_AES_CCM
:
3099 pval
|= AES_ENABLED
;
3102 brcmf_err("Ivalid unicast security info\n");
3106 /* walk thru auth management suite list and pick up what we recognize */
3107 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3108 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3109 /* Check for auth key management suite(s) */
3110 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3112 brcmf_err("no auth key mgmt suite\n");
3115 for (i
= 0; i
< count
; i
++) {
3116 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3118 brcmf_err("ivalid OUI\n");
3121 offset
+= TLV_OUI_LEN
;
3122 switch (data
[offset
]) {
3124 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
3125 wpa_auth
|= WPA_AUTH_NONE
;
3127 case RSN_AKM_UNSPECIFIED
:
3128 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
3129 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3130 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3133 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
3134 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3135 (wpa_auth
|= WPA_AUTH_PSK
);
3138 brcmf_err("Ivalid key mgmt info\n");
3144 wme_bss_disable
= 1;
3145 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3146 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3147 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3148 wme_bss_disable
= 0;
3150 /* set wme_bss_disable to sync RSN Capabilities */
3151 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3154 brcmf_err("wme_bss_disable error %d\n", err
);
3158 /* FOR WPS , set SES_OW_ENABLED */
3159 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3162 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3164 brcmf_err("auth error %d\n", err
);
3168 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3170 brcmf_err("wsec error %d\n", err
);
3173 /* set upper-layer auth */
3174 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3176 brcmf_err("wpa_auth error %d\n", err
);
3185 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3186 struct parsed_vndr_ies
*vndr_ies
)
3189 struct brcmf_vs_tlv
*vndrie
;
3190 struct brcmf_tlv
*ie
;
3191 struct parsed_vndr_ie_info
*parsed_info
;
3194 remaining_len
= (s32
)vndr_ie_len
;
3195 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3197 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3199 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3201 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3202 /* len should be bigger than OUI length + one */
3203 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3204 brcmf_err("invalid vndr ie. length is too small %d\n",
3208 /* if wpa or wme ie, do not add ie */
3209 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3210 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3211 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3212 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
3216 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3218 /* save vndr ie information */
3219 parsed_info
->ie_ptr
= (char *)vndrie
;
3220 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3221 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3225 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
3226 parsed_info
->vndrie
.oui
[0],
3227 parsed_info
->vndrie
.oui
[1],
3228 parsed_info
->vndrie
.oui
[2],
3229 parsed_info
->vndrie
.oui_type
);
3231 if (vndr_ies
->count
>= MAX_VNDR_IE_NUMBER
)
3234 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
3235 if (remaining_len
<= TLV_HDR_LEN
)
3238 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
3245 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3251 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3252 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3254 iecount_le
= cpu_to_le32(1);
3255 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3257 pktflag_le
= cpu_to_le32(pktflag
);
3258 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3260 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3262 return ie_len
+ VNDR_IE_HDR_SIZE
;
3266 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
3267 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3269 struct brcmf_if
*ifp
;
3270 struct vif_saved_ie
*saved_ie
;
3274 u8
*mgmt_ie_buf
= NULL
;
3275 int mgmt_ie_buf_len
;
3277 u32 del_add_ie_buf_len
= 0;
3278 u32 total_ie_buf_len
= 0;
3279 u32 parsed_ie_buf_len
= 0;
3280 struct parsed_vndr_ies old_vndr_ies
;
3281 struct parsed_vndr_ies new_vndr_ies
;
3282 struct parsed_vndr_ie_info
*vndrie_info
;
3285 int remained_buf_len
;
3290 saved_ie
= &vif
->saved_ie
;
3292 brcmf_dbg(TRACE
, "bssidx %d, pktflag : 0x%02X\n", ifp
->bssidx
, pktflag
);
3293 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3296 curr_ie_buf
= iovar_ie_buf
;
3297 if (ifp
->vif
->mode
== WL_MODE_AP
) {
3299 case VNDR_IE_PRBRSP_FLAG
:
3300 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
3301 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
3302 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
3304 case VNDR_IE_BEACON_FLAG
:
3305 mgmt_ie_buf
= saved_ie
->beacon_ie
;
3306 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
3307 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
3311 brcmf_err("not suitable type\n");
3316 brcmf_err("not suitable type\n");
3320 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3322 brcmf_err("extra IE size too big\n");
3326 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3327 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3329 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3330 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3331 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3332 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3333 vndrie_info
->ie_len
);
3334 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3338 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
3339 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3340 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3341 parsed_ie_buf_len
) == 0)) {
3342 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
3346 /* parse old vndr_ie */
3347 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3349 /* make a command to delete old ie */
3350 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3351 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3353 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3354 vndrie_info
->vndrie
.id
,
3355 vndrie_info
->vndrie
.len
,
3356 vndrie_info
->vndrie
.oui
[0],
3357 vndrie_info
->vndrie
.oui
[1],
3358 vndrie_info
->vndrie
.oui
[2]);
3360 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3361 vndrie_info
->ie_ptr
,
3362 vndrie_info
->ie_len
,
3364 curr_ie_buf
+= del_add_ie_buf_len
;
3365 total_ie_buf_len
+= del_add_ie_buf_len
;
3370 /* Add if there is any extra IE */
3371 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3374 remained_buf_len
= mgmt_ie_buf_len
;
3376 /* make a command to add new ie */
3377 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3378 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3380 /* verify remained buf size before copy data */
3381 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
3382 VNDR_IE_VSIE_OFFSET
)) {
3383 brcmf_err("no space in mgmt_ie_buf: len left %d",
3387 remained_buf_len
-= (vndrie_info
->ie_len
+
3388 VNDR_IE_VSIE_OFFSET
);
3390 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3391 vndrie_info
->vndrie
.id
,
3392 vndrie_info
->vndrie
.len
,
3393 vndrie_info
->vndrie
.oui
[0],
3394 vndrie_info
->vndrie
.oui
[1],
3395 vndrie_info
->vndrie
.oui
[2]);
3397 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3398 vndrie_info
->ie_ptr
,
3399 vndrie_info
->ie_len
,
3402 /* save the parsed IE in wl struct */
3403 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3404 vndrie_info
->ie_len
);
3405 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3407 curr_ie_buf
+= del_add_ie_buf_len
;
3408 total_ie_buf_len
+= del_add_ie_buf_len
;
3411 if (total_ie_buf_len
) {
3412 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
3415 brcmf_err("vndr ie set error : %d\n", err
);
3419 kfree(iovar_ie_buf
);
3424 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3425 struct cfg80211_ap_settings
*settings
)
3428 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3429 struct brcmf_tlv
*ssid_ie
;
3430 struct brcmf_ssid_le ssid_le
;
3432 struct brcmf_tlv
*rsn_ie
;
3433 struct brcmf_vs_tlv
*wpa_ie
;
3434 struct brcmf_join_params join_params
;
3437 brcmf_dbg(TRACE
, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3438 cfg80211_get_chandef_type(&settings
->chandef
),
3439 settings
->beacon_interval
,
3440 settings
->dtim_period
);
3441 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3442 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3443 settings
->inactivity_timeout
);
3445 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
)) {
3446 brcmf_err("Not in AP creation mode\n");
3450 memset(&ssid_le
, 0, sizeof(ssid_le
));
3451 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3452 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3453 ssid_ie
= brcmf_parse_tlvs(
3454 (u8
*)&settings
->beacon
.head
[ie_offset
],
3455 settings
->beacon
.head_len
- ie_offset
,
3460 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3461 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3462 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
3464 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3465 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3468 brcmf_set_mpc(ndev
, 0);
3469 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3471 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
3474 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3476 brcmf_err("SET INFRA error %d\n", err
);
3479 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3481 brcmf_err("setting AP mode failed %d\n", err
);
3485 /* find the RSN_IE */
3486 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3487 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3489 /* find the WPA_IE */
3490 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3491 settings
->beacon
.tail_len
);
3493 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3494 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
3495 if (wpa_ie
!= NULL
) {
3497 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false);
3502 err
= brcmf_configure_wpaie(ndev
,
3503 (struct brcmf_vs_tlv
*)rsn_ie
, true);
3508 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
3509 brcmf_configure_opensecurity(ndev
, bssidx
);
3511 /* Set Beacon IEs to FW */
3512 err
= brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev
),
3513 VNDR_IE_BEACON_FLAG
,
3514 settings
->beacon
.tail
,
3515 settings
->beacon
.tail_len
);
3517 brcmf_err("Set Beacon IE Failed\n");
3519 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
3521 /* Set Probe Response IEs to FW */
3522 err
= brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev
),
3523 VNDR_IE_PRBRSP_FLAG
,
3524 settings
->beacon
.proberesp_ies
,
3525 settings
->beacon
.proberesp_ies_len
);
3527 brcmf_err("Set Probe Resp IE Failed\n");
3529 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
3531 if (settings
->beacon_interval
) {
3532 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
3533 settings
->beacon_interval
);
3535 brcmf_err("Beacon Interval Set Error, %d\n", err
);
3539 if (settings
->dtim_period
) {
3540 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
3541 settings
->dtim_period
);
3543 brcmf_err("DTIM Interval Set Error, %d\n", err
);
3547 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
3549 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
3553 memset(&join_params
, 0, sizeof(join_params
));
3554 /* join parameters starts with ssid */
3555 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
3557 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3558 &join_params
, sizeof(join_params
));
3560 brcmf_err("SET SSID error (%d)\n", err
);
3563 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3564 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3568 brcmf_set_mpc(ndev
, 1);
3572 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3574 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3577 brcmf_dbg(TRACE
, "Enter\n");
3579 if (ifp
->vif
->mode
== WL_MODE_AP
) {
3580 /* Due to most likely deauths outstanding we sleep */
3581 /* first to make sure they get processed by fw. */
3583 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
3585 brcmf_err("setting AP mode failed %d\n", err
);
3588 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
3590 brcmf_err("BRCMF_C_UP error %d\n", err
);
3593 brcmf_set_mpc(ndev
, 1);
3594 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3595 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3602 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3605 struct brcmf_scb_val_le scbval
;
3606 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3612 brcmf_dbg(TRACE
, "Enter %pM\n", mac
);
3614 if (!check_vif_up(ifp
->vif
))
3617 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
3618 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
3619 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
3620 &scbval
, sizeof(scbval
));
3622 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
3624 brcmf_dbg(TRACE
, "Exit\n");
3628 static struct cfg80211_ops wl_cfg80211_ops
= {
3629 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
3630 .scan
= brcmf_cfg80211_scan
,
3631 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
3632 .join_ibss
= brcmf_cfg80211_join_ibss
,
3633 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
3634 .get_station
= brcmf_cfg80211_get_station
,
3635 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
3636 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
3637 .add_key
= brcmf_cfg80211_add_key
,
3638 .del_key
= brcmf_cfg80211_del_key
,
3639 .get_key
= brcmf_cfg80211_get_key
,
3640 .set_default_key
= brcmf_cfg80211_config_default_key
,
3641 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
3642 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
3643 .connect
= brcmf_cfg80211_connect
,
3644 .disconnect
= brcmf_cfg80211_disconnect
,
3645 .suspend
= brcmf_cfg80211_suspend
,
3646 .resume
= brcmf_cfg80211_resume
,
3647 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
3648 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
3649 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
3650 .start_ap
= brcmf_cfg80211_start_ap
,
3651 .stop_ap
= brcmf_cfg80211_stop_ap
,
3652 .del_station
= brcmf_cfg80211_del_station
,
3653 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
3654 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
3655 #ifdef CONFIG_NL80211_TESTMODE
3656 .testmode_cmd
= brcmf_cfg80211_testmode
3660 static s32
brcmf_mode_to_nl80211_iftype(s32 mode
)
3666 return NL80211_IFTYPE_STATION
;
3668 return NL80211_IFTYPE_ADHOC
;
3670 return NL80211_IFTYPE_UNSPECIFIED
;
3676 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
3678 /* scheduled scan settings */
3679 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
3680 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
3681 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
3682 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
3685 static struct wiphy
*brcmf_setup_wiphy(struct device
*phydev
)
3687 struct wiphy
*wiphy
;
3690 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
3692 brcmf_err("Could not allocate wiphy device\n");
3693 return ERR_PTR(-ENOMEM
);
3695 set_wiphy_dev(wiphy
, phydev
);
3696 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
3697 wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
3698 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
3699 BIT(NL80211_IFTYPE_ADHOC
) |
3700 BIT(NL80211_IFTYPE_AP
);
3701 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
3702 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
3703 * it as 11a by default.
3704 * This will be updated with
3707 * if phy has 11n capability
3709 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
3710 wiphy
->cipher_suites
= __wl_cipher_suites
;
3711 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
3712 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
3716 brcmf_wiphy_pno_params(wiphy
);
3717 err
= wiphy_register(wiphy
);
3719 brcmf_err("Could not register wiphy device (%d)\n", err
);
3721 return ERR_PTR(err
);
3727 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
3728 struct net_device
*netdev
,
3729 s32 mode
, bool pm_block
)
3731 struct brcmf_cfg80211_vif
*vif
;
3733 if (cfg
->vif_cnt
== BRCMF_IFACE_MAX_CNT
)
3734 return ERR_PTR(-ENOSPC
);
3736 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
3738 return ERR_PTR(-ENOMEM
);
3740 vif
->wdev
.wiphy
= cfg
->wiphy
;
3741 vif
->wdev
.netdev
= netdev
;
3742 vif
->wdev
.iftype
= brcmf_mode_to_nl80211_iftype(mode
);
3745 vif
->ifp
= netdev_priv(netdev
);
3746 netdev
->ieee80211_ptr
= &vif
->wdev
;
3747 SET_NETDEV_DEV(netdev
, wiphy_dev(cfg
->wiphy
));
3751 vif
->pm_block
= pm_block
;
3754 brcmf_init_prof(&vif
->profile
);
3756 list_add_tail(&vif
->list
, &cfg
->vif_list
);
3761 static void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
3763 struct brcmf_cfg80211_info
*cfg
;
3764 struct wiphy
*wiphy
;
3766 wiphy
= vif
->wdev
.wiphy
;
3767 cfg
= wiphy_priv(wiphy
);
3768 list_del(&vif
->list
);
3772 if (!cfg
->vif_cnt
) {
3773 wiphy_unregister(wiphy
);
3778 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
3780 u32 event
= e
->event_code
;
3781 u32 status
= e
->status
;
3783 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
3784 brcmf_dbg(CONN
, "Processing set ssid\n");
3791 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
3793 u32 event
= e
->event_code
;
3794 u16 flags
= e
->flags
;
3796 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
3797 brcmf_dbg(CONN
, "Processing link down\n");
3803 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
3804 const struct brcmf_event_msg
*e
)
3806 u32 event
= e
->event_code
;
3807 u32 status
= e
->status
;
3809 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
3810 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
3811 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
3815 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
3816 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
3823 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
3825 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3827 kfree(conn_info
->req_ie
);
3828 conn_info
->req_ie
= NULL
;
3829 conn_info
->req_ie_len
= 0;
3830 kfree(conn_info
->resp_ie
);
3831 conn_info
->resp_ie
= NULL
;
3832 conn_info
->resp_ie_len
= 0;
3835 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
3837 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
3838 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
3839 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3844 brcmf_clear_assoc_ies(cfg
);
3846 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
3847 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
3849 brcmf_err("could not get assoc info (%d)\n", err
);
3853 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
3854 req_len
= le32_to_cpu(assoc_info
->req_len
);
3855 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
3857 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
3861 brcmf_err("could not get assoc req (%d)\n", err
);
3864 conn_info
->req_ie_len
= req_len
;
3866 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
3869 conn_info
->req_ie_len
= 0;
3870 conn_info
->req_ie
= NULL
;
3873 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
3877 brcmf_err("could not get assoc resp (%d)\n", err
);
3880 conn_info
->resp_ie_len
= resp_len
;
3881 conn_info
->resp_ie
=
3882 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
3885 conn_info
->resp_ie_len
= 0;
3886 conn_info
->resp_ie
= NULL
;
3888 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
3889 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
3895 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
3896 struct net_device
*ndev
,
3897 const struct brcmf_event_msg
*e
)
3899 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3900 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
3901 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3902 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
3903 struct ieee80211_channel
*notify_channel
= NULL
;
3904 struct ieee80211_supported_band
*band
;
3905 struct brcmf_bss_info_le
*bi
;
3911 brcmf_dbg(TRACE
, "Enter\n");
3913 brcmf_get_assoc_ies(cfg
);
3914 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
3915 brcmf_update_bss_info(cfg
);
3917 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
3923 /* data sent to dongle has to be little endian */
3924 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
3925 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
3926 buf
, WL_BSS_INFO_MAX
);
3931 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
3932 target_channel
= bi
->ctl_ch
? bi
->ctl_ch
:
3933 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
3935 if (target_channel
<= CH_MAX_2G_CHANNEL
)
3936 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
3938 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
3940 freq
= ieee80211_channel_to_frequency(target_channel
, band
->band
);
3941 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
3945 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
3946 conn_info
->req_ie
, conn_info
->req_ie_len
,
3947 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
3948 brcmf_dbg(CONN
, "Report roaming result\n");
3950 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
3951 brcmf_dbg(TRACE
, "Exit\n");
3956 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
3957 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
3960 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3961 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
3962 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3965 brcmf_dbg(TRACE
, "Enter\n");
3967 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
3968 &ifp
->vif
->sme_state
)) {
3970 brcmf_get_assoc_ies(cfg
);
3971 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
3972 brcmf_update_bss_info(cfg
);
3974 cfg80211_connect_result(ndev
,
3975 (u8
*)profile
->bssid
,
3977 conn_info
->req_ie_len
,
3979 conn_info
->resp_ie_len
,
3980 completed
? WLAN_STATUS_SUCCESS
:
3981 WLAN_STATUS_AUTH_TIMEOUT
,
3984 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
3985 &ifp
->vif
->sme_state
);
3986 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
3987 completed
? "succeeded" : "failed");
3989 brcmf_dbg(TRACE
, "Exit\n");
3994 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
3995 struct net_device
*ndev
,
3996 const struct brcmf_event_msg
*e
, void *data
)
3999 u32 event
= e
->event_code
;
4000 u32 reason
= e
->reason
;
4001 u32 len
= e
->datalen
;
4002 static int generation
;
4004 struct station_info sinfo
;
4006 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
4007 memset(&sinfo
, 0, sizeof(sinfo
));
4010 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4011 reason
== BRCMF_E_STATUS_SUCCESS
) {
4012 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4014 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4017 sinfo
.assoc_req_ies
= data
;
4018 sinfo
.assoc_req_ies_len
= len
;
4020 sinfo
.generation
= generation
;
4021 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_ATOMIC
);
4022 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4023 (event
== BRCMF_E_DEAUTH_IND
) ||
4024 (event
== BRCMF_E_DEAUTH
)) {
4026 sinfo
.generation
= generation
;
4027 cfg80211_del_sta(ndev
, e
->addr
, GFP_ATOMIC
);
4033 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
4034 const struct brcmf_event_msg
*e
, void *data
)
4036 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4037 struct net_device
*ndev
= ifp
->ndev
;
4038 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4041 if (ifp
->vif
->mode
== WL_MODE_AP
) {
4042 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4043 } else if (brcmf_is_linkup(e
)) {
4044 brcmf_dbg(CONN
, "Linkup\n");
4045 if (brcmf_is_ibssmode(ifp
->vif
)) {
4046 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4047 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4048 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
4049 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4050 &ifp
->vif
->sme_state
);
4051 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4052 &ifp
->vif
->sme_state
);
4054 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4055 } else if (brcmf_is_linkdown(e
)) {
4056 brcmf_dbg(CONN
, "Linkdown\n");
4057 if (!brcmf_is_ibssmode(ifp
->vif
)) {
4058 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4059 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
,
4060 &ifp
->vif
->sme_state
))
4061 cfg80211_disconnected(ndev
, 0, NULL
, 0,
4064 brcmf_link_down(ifp
->vif
);
4065 brcmf_init_prof(ndev_to_prof(ndev
));
4066 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4067 if (brcmf_is_ibssmode(ifp
->vif
))
4068 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4069 &ifp
->vif
->sme_state
);
4071 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4078 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
4079 const struct brcmf_event_msg
*e
, void *data
)
4081 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4083 u32 event
= e
->event_code
;
4084 u32 status
= e
->status
;
4086 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4087 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
4088 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
4090 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
4097 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
4098 const struct brcmf_event_msg
*e
, void *data
)
4100 u16 flags
= e
->flags
;
4101 enum nl80211_key_type key_type
;
4103 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4104 key_type
= NL80211_KEYTYPE_GROUP
;
4106 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4108 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
4114 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4116 conf
->frag_threshold
= (u32
)-1;
4117 conf
->rts_threshold
= (u32
)-1;
4118 conf
->retry_short
= (u32
)-1;
4119 conf
->retry_long
= (u32
)-1;
4120 conf
->tx_power
= -1;
4123 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
4125 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
4126 brcmf_notify_connect_status
);
4127 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
4128 brcmf_notify_connect_status
);
4129 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
4130 brcmf_notify_connect_status
);
4131 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
4132 brcmf_notify_connect_status
);
4133 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
4134 brcmf_notify_connect_status
);
4135 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
4136 brcmf_notify_connect_status
);
4137 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
4138 brcmf_notify_roaming_status
);
4139 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
4140 brcmf_notify_mic_status
);
4141 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
4142 brcmf_notify_connect_status
);
4143 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
4144 brcmf_notify_sched_scan_results
);
4147 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4151 kfree(cfg
->escan_ioctl_buf
);
4152 cfg
->escan_ioctl_buf
= NULL
;
4153 kfree(cfg
->extra_buf
);
4154 cfg
->extra_buf
= NULL
;
4155 kfree(cfg
->pmk_list
);
4156 cfg
->pmk_list
= NULL
;
4159 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4161 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4163 goto init_priv_mem_out
;
4164 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4165 if (!cfg
->escan_ioctl_buf
)
4166 goto init_priv_mem_out
;
4167 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4168 if (!cfg
->extra_buf
)
4169 goto init_priv_mem_out
;
4170 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4172 goto init_priv_mem_out
;
4177 brcmf_deinit_priv_mem(cfg
);
4182 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4186 cfg
->scan_request
= NULL
;
4187 cfg
->pwr_save
= true;
4188 cfg
->roam_on
= true; /* roam on & off switch.
4189 we enable roam per default */
4190 cfg
->active_scan
= true; /* we do active scan for
4191 specific scan per default */
4192 cfg
->dongle_up
= false; /* dongle is not up yet */
4193 err
= brcmf_init_priv_mem(cfg
);
4196 brcmf_register_event_handlers(cfg
);
4197 mutex_init(&cfg
->usr_sync
);
4198 brcmf_init_escan(cfg
);
4199 brcmf_init_conf(cfg
->conf
);
4204 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4206 cfg
->dongle_up
= false; /* dongle down */
4207 brcmf_abort_scanning(cfg
);
4208 brcmf_deinit_priv_mem(cfg
);
4211 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
4212 struct device
*busdev
)
4214 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4215 struct brcmf_cfg80211_info
*cfg
;
4216 struct wiphy
*wiphy
;
4217 struct brcmf_cfg80211_vif
*vif
;
4218 struct brcmf_if
*ifp
;
4222 brcmf_err("ndev is invalid\n");
4226 ifp
= netdev_priv(ndev
);
4227 wiphy
= brcmf_setup_wiphy(busdev
);
4231 cfg
= wiphy_priv(wiphy
);
4234 INIT_LIST_HEAD(&cfg
->vif_list
);
4236 vif
= brcmf_alloc_vif(cfg
, ndev
, WL_MODE_BSS
, false);
4242 err
= wl_init_priv(cfg
);
4244 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
4245 goto cfg80211_attach_out
;
4251 cfg80211_attach_out
:
4252 brcmf_free_vif(vif
);
4256 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
4258 struct brcmf_cfg80211_vif
*vif
;
4259 struct brcmf_cfg80211_vif
*tmp
;
4261 wl_deinit_priv(cfg
);
4262 list_for_each_entry_safe(vif
, tmp
, &cfg
->vif_list
, list
) {
4263 brcmf_free_vif(vif
);
4268 brcmf_dongle_roam(struct brcmf_if
*ifp
, u32 roamvar
, u32 bcn_timeout
)
4271 __le32 roamtrigger
[2];
4272 __le32 roam_delta
[2];
4275 * Setup timeout if Beacons are lost and roam is
4276 * off to report link down
4279 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
4281 brcmf_err("bcn_timeout error (%d)\n", err
);
4282 goto dongle_rom_out
;
4287 * Enable/Disable built-in roaming to allow supplicant
4288 * to take care of roaming
4290 brcmf_dbg(INFO
, "Internal Roaming = %s\n", roamvar
? "Off" : "On");
4291 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", roamvar
);
4293 brcmf_err("roam_off error (%d)\n", err
);
4294 goto dongle_rom_out
;
4297 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
4298 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4299 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
4300 (void *)roamtrigger
, sizeof(roamtrigger
));
4302 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
4303 goto dongle_rom_out
;
4306 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
4307 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4308 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
4309 (void *)roam_delta
, sizeof(roam_delta
));
4311 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
4312 goto dongle_rom_out
;
4320 brcmf_dongle_scantime(struct brcmf_if
*ifp
, s32 scan_assoc_time
,
4321 s32 scan_unassoc_time
, s32 scan_passive_time
)
4325 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
4328 if (err
== -EOPNOTSUPP
)
4329 brcmf_dbg(INFO
, "Scan assoc time is not supported\n");
4331 brcmf_err("Scan assoc time error (%d)\n", err
);
4332 goto dongle_scantime_out
;
4334 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
4337 if (err
== -EOPNOTSUPP
)
4338 brcmf_dbg(INFO
, "Scan unassoc time is not supported\n");
4340 brcmf_err("Scan unassoc time error (%d)\n", err
);
4341 goto dongle_scantime_out
;
4344 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
4347 if (err
== -EOPNOTSUPP
)
4348 brcmf_dbg(INFO
, "Scan passive time is not supported\n");
4350 brcmf_err("Scan passive time error (%d)\n", err
);
4351 goto dongle_scantime_out
;
4354 dongle_scantime_out
:
4358 static s32
wl_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
4360 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
4361 struct wiphy
*wiphy
;
4366 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_PHYLIST
,
4367 &phy_list
, sizeof(phy_list
));
4369 brcmf_err("error (%d)\n", err
);
4373 phy
= ((char *)&phy_list
)[0];
4374 brcmf_dbg(INFO
, "%c phy\n", phy
);
4375 if (phy
== 'n' || phy
== 'a') {
4376 wiphy
= cfg_to_wiphy(cfg
);
4377 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
4383 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
4385 return wl_update_wiphybands(cfg
);
4388 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
4390 struct net_device
*ndev
;
4391 struct wireless_dev
*wdev
;
4392 struct brcmf_if
*ifp
;
4399 ndev
= cfg_to_ndev(cfg
);
4400 wdev
= ndev
->ieee80211_ptr
;
4401 ifp
= netdev_priv(ndev
);
4403 /* make sure RF is ready for work */
4404 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
4406 brcmf_dongle_scantime(ifp
, WL_SCAN_CHANNEL_TIME
,
4407 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
4409 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
4410 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
4412 goto default_conf_out
;
4413 brcmf_dbg(INFO
, "power save set to %s\n",
4414 (power_mode
? "enabled" : "disabled"));
4416 err
= brcmf_dongle_roam(ifp
, (cfg
->roam_on
? 0 : 1), WL_BEACON_TIMEOUT
);
4418 goto default_conf_out
;
4419 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
4422 goto default_conf_out
;
4423 err
= brcmf_dongle_probecap(cfg
);
4425 goto default_conf_out
;
4427 cfg
->dongle_up
= true;
4434 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
4436 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
4438 return brcmf_config_dongle(ifp
->drvr
->config
);
4441 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
4443 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4446 * While going down, if associated with AP disassociate
4447 * from AP to save power
4449 if (check_vif_up(ifp
->vif
)) {
4450 brcmf_link_down(ifp
->vif
);
4452 /* Make sure WPA_Supplicant receives all the event
4453 generated due to DISASSOC call to the fw to keep
4454 the state fw and WPA_Supplicant state consistent
4459 brcmf_abort_scanning(cfg
);
4460 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
4465 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
4467 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4468 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4471 mutex_lock(&cfg
->usr_sync
);
4472 err
= __brcmf_cfg80211_up(ifp
);
4473 mutex_unlock(&cfg
->usr_sync
);
4478 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
4480 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4481 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4484 mutex_lock(&cfg
->usr_sync
);
4485 err
= __brcmf_cfg80211_down(ifp
);
4486 mutex_unlock(&cfg
->usr_sync
);