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>
30 #include "wl_cfg80211.h"
33 #define BRCMF_SCAN_IE_LEN_MAX 2048
34 #define BRCMF_PNO_VERSION 2
35 #define BRCMF_PNO_TIME 30
36 #define BRCMF_PNO_REPEAT 4
37 #define BRCMF_PNO_FREQ_EXPO_MAX 3
38 #define BRCMF_PNO_MAX_PFN_COUNT 16
39 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
40 #define BRCMF_PNO_HIDDEN_BIT 2
41 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
42 #define BRCMF_PNO_SCAN_COMPLETE 1
43 #define BRCMF_PNO_SCAN_INCOMPLETE 0
45 #define BRCMF_IFACE_MAX_CNT 3
47 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
48 #define WPA_OUI_TYPE 1
49 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
50 #define WME_OUI_TYPE 2
52 #define VS_IE_FIXED_HDR_LEN 6
53 #define WPA_IE_VERSION_LEN 2
54 #define WPA_IE_MIN_OUI_LEN 4
55 #define WPA_IE_SUITE_COUNT_LEN 2
57 #define WPA_CIPHER_NONE 0 /* None */
58 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
59 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
60 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
61 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
63 #define RSN_AKM_NONE 0 /* None (IBSS) */
64 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
65 #define RSN_AKM_PSK 2 /* Pre-shared Key */
66 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
67 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
69 #define VNDR_IE_CMD_LEN 4 /* length of the set command
70 * string :"add", "del" (+ NUL)
72 #define VNDR_IE_COUNT_OFFSET 4
73 #define VNDR_IE_PKTFLAG_OFFSET 8
74 #define VNDR_IE_VSIE_OFFSET 12
75 #define VNDR_IE_HDR_SIZE 12
76 #define VNDR_IE_PARSE_LIMIT 5
78 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
79 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
81 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
82 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
84 static bool check_vif_up(struct brcmf_cfg80211_vif
*vif
)
86 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
)) {
87 brcmf_dbg(INFO
, "device is not ready : status (%lu)\n",
94 #define CHAN2G(_channel, _freq, _flags) { \
95 .band = IEEE80211_BAND_2GHZ, \
96 .center_freq = (_freq), \
97 .hw_value = (_channel), \
99 .max_antenna_gain = 0, \
103 #define CHAN5G(_channel, _flags) { \
104 .band = IEEE80211_BAND_5GHZ, \
105 .center_freq = 5000 + (5 * (_channel)), \
106 .hw_value = (_channel), \
108 .max_antenna_gain = 0, \
112 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
113 #define RATETAB_ENT(_rateid, _flags) \
115 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
116 .hw_value = (_rateid), \
120 static struct ieee80211_rate __wl_rates
[] = {
121 RATETAB_ENT(BRCM_RATE_1M
, 0),
122 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
123 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
124 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
125 RATETAB_ENT(BRCM_RATE_6M
, 0),
126 RATETAB_ENT(BRCM_RATE_9M
, 0),
127 RATETAB_ENT(BRCM_RATE_12M
, 0),
128 RATETAB_ENT(BRCM_RATE_18M
, 0),
129 RATETAB_ENT(BRCM_RATE_24M
, 0),
130 RATETAB_ENT(BRCM_RATE_36M
, 0),
131 RATETAB_ENT(BRCM_RATE_48M
, 0),
132 RATETAB_ENT(BRCM_RATE_54M
, 0),
135 #define wl_a_rates (__wl_rates + 4)
136 #define wl_a_rates_size 8
137 #define wl_g_rates (__wl_rates + 0)
138 #define wl_g_rates_size 12
140 static struct ieee80211_channel __wl_2ghz_channels
[] = {
157 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
158 CHAN5G(34, 0), CHAN5G(36, 0),
159 CHAN5G(38, 0), CHAN5G(40, 0),
160 CHAN5G(42, 0), CHAN5G(44, 0),
161 CHAN5G(46, 0), CHAN5G(48, 0),
162 CHAN5G(52, 0), CHAN5G(56, 0),
163 CHAN5G(60, 0), CHAN5G(64, 0),
164 CHAN5G(100, 0), CHAN5G(104, 0),
165 CHAN5G(108, 0), CHAN5G(112, 0),
166 CHAN5G(116, 0), CHAN5G(120, 0),
167 CHAN5G(124, 0), CHAN5G(128, 0),
168 CHAN5G(132, 0), CHAN5G(136, 0),
169 CHAN5G(140, 0), CHAN5G(149, 0),
170 CHAN5G(153, 0), CHAN5G(157, 0),
171 CHAN5G(161, 0), CHAN5G(165, 0),
172 CHAN5G(184, 0), CHAN5G(188, 0),
173 CHAN5G(192, 0), CHAN5G(196, 0),
174 CHAN5G(200, 0), CHAN5G(204, 0),
175 CHAN5G(208, 0), CHAN5G(212, 0),
179 static struct ieee80211_channel __wl_5ghz_n_channels
[] = {
180 CHAN5G(32, 0), CHAN5G(34, 0),
181 CHAN5G(36, 0), CHAN5G(38, 0),
182 CHAN5G(40, 0), CHAN5G(42, 0),
183 CHAN5G(44, 0), CHAN5G(46, 0),
184 CHAN5G(48, 0), CHAN5G(50, 0),
185 CHAN5G(52, 0), CHAN5G(54, 0),
186 CHAN5G(56, 0), CHAN5G(58, 0),
187 CHAN5G(60, 0), CHAN5G(62, 0),
188 CHAN5G(64, 0), CHAN5G(66, 0),
189 CHAN5G(68, 0), CHAN5G(70, 0),
190 CHAN5G(72, 0), CHAN5G(74, 0),
191 CHAN5G(76, 0), CHAN5G(78, 0),
192 CHAN5G(80, 0), CHAN5G(82, 0),
193 CHAN5G(84, 0), CHAN5G(86, 0),
194 CHAN5G(88, 0), CHAN5G(90, 0),
195 CHAN5G(92, 0), CHAN5G(94, 0),
196 CHAN5G(96, 0), CHAN5G(98, 0),
197 CHAN5G(100, 0), CHAN5G(102, 0),
198 CHAN5G(104, 0), CHAN5G(106, 0),
199 CHAN5G(108, 0), CHAN5G(110, 0),
200 CHAN5G(112, 0), CHAN5G(114, 0),
201 CHAN5G(116, 0), CHAN5G(118, 0),
202 CHAN5G(120, 0), CHAN5G(122, 0),
203 CHAN5G(124, 0), CHAN5G(126, 0),
204 CHAN5G(128, 0), CHAN5G(130, 0),
205 CHAN5G(132, 0), CHAN5G(134, 0),
206 CHAN5G(136, 0), CHAN5G(138, 0),
207 CHAN5G(140, 0), CHAN5G(142, 0),
208 CHAN5G(144, 0), CHAN5G(145, 0),
209 CHAN5G(146, 0), CHAN5G(147, 0),
210 CHAN5G(148, 0), CHAN5G(149, 0),
211 CHAN5G(150, 0), CHAN5G(151, 0),
212 CHAN5G(152, 0), CHAN5G(153, 0),
213 CHAN5G(154, 0), CHAN5G(155, 0),
214 CHAN5G(156, 0), CHAN5G(157, 0),
215 CHAN5G(158, 0), CHAN5G(159, 0),
216 CHAN5G(160, 0), CHAN5G(161, 0),
217 CHAN5G(162, 0), CHAN5G(163, 0),
218 CHAN5G(164, 0), CHAN5G(165, 0),
219 CHAN5G(166, 0), CHAN5G(168, 0),
220 CHAN5G(170, 0), CHAN5G(172, 0),
221 CHAN5G(174, 0), CHAN5G(176, 0),
222 CHAN5G(178, 0), CHAN5G(180, 0),
223 CHAN5G(182, 0), CHAN5G(184, 0),
224 CHAN5G(186, 0), CHAN5G(188, 0),
225 CHAN5G(190, 0), CHAN5G(192, 0),
226 CHAN5G(194, 0), CHAN5G(196, 0),
227 CHAN5G(198, 0), CHAN5G(200, 0),
228 CHAN5G(202, 0), CHAN5G(204, 0),
229 CHAN5G(206, 0), CHAN5G(208, 0),
230 CHAN5G(210, 0), CHAN5G(212, 0),
231 CHAN5G(214, 0), CHAN5G(216, 0),
232 CHAN5G(218, 0), CHAN5G(220, 0),
233 CHAN5G(222, 0), CHAN5G(224, 0),
234 CHAN5G(226, 0), CHAN5G(228, 0),
237 static struct ieee80211_supported_band __wl_band_2ghz
= {
238 .band
= IEEE80211_BAND_2GHZ
,
239 .channels
= __wl_2ghz_channels
,
240 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
241 .bitrates
= wl_g_rates
,
242 .n_bitrates
= wl_g_rates_size
,
245 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
246 .band
= IEEE80211_BAND_5GHZ
,
247 .channels
= __wl_5ghz_a_channels
,
248 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
249 .bitrates
= wl_a_rates
,
250 .n_bitrates
= wl_a_rates_size
,
253 static struct ieee80211_supported_band __wl_band_5ghz_n
= {
254 .band
= IEEE80211_BAND_5GHZ
,
255 .channels
= __wl_5ghz_n_channels
,
256 .n_channels
= ARRAY_SIZE(__wl_5ghz_n_channels
),
257 .bitrates
= wl_a_rates
,
258 .n_bitrates
= wl_a_rates_size
,
261 static const u32 __wl_cipher_suites
[] = {
262 WLAN_CIPHER_SUITE_WEP40
,
263 WLAN_CIPHER_SUITE_WEP104
,
264 WLAN_CIPHER_SUITE_TKIP
,
265 WLAN_CIPHER_SUITE_CCMP
,
266 WLAN_CIPHER_SUITE_AES_CMAC
,
269 /* Vendor specific ie. id = 221, oui and type defines exact ie */
270 struct brcmf_vs_tlv
{
277 struct parsed_vndr_ie_info
{
279 u32 ie_len
; /* total length including id & length field */
280 struct brcmf_vs_tlv vndrie
;
283 struct parsed_vndr_ies
{
285 struct parsed_vndr_ie_info ie_info
[VNDR_IE_PARSE_LIMIT
];
288 /* Quarter dBm units to mW
289 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
290 * Table is offset so the last entry is largest mW value that fits in
294 #define QDBM_OFFSET 153 /* Offset for first entry */
295 #define QDBM_TABLE_LEN 40 /* Table size */
297 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
298 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
300 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
302 /* Largest mW value that will round down to the last table entry,
303 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
304 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
305 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
307 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
309 static const u16 nqdBm_to_mW_map
[QDBM_TABLE_LEN
] = {
310 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
311 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
312 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
313 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
314 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
315 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
318 static u16
brcmf_qdbm_to_mw(u8 qdbm
)
321 int idx
= qdbm
- QDBM_OFFSET
;
323 if (idx
>= QDBM_TABLE_LEN
)
324 /* clamp to max u16 mW value */
327 /* scale the qdBm index up to the range of the table 0-40
328 * where an offset of 40 qdBm equals a factor of 10 mW.
335 /* return the mW value scaled down to the correct factor of 10,
336 * adding in factor/2 to get proper rounding.
338 return (nqdBm_to_mW_map
[idx
] + factor
/ 2) / factor
;
341 static u8
brcmf_mw_to_qdbm(u16 mw
)
348 /* handle boundary case */
352 offset
= QDBM_OFFSET
;
354 /* move mw into the range of the table */
355 while (mw_uint
< QDBM_TABLE_LOW_BOUND
) {
360 for (qdbm
= 0; qdbm
< QDBM_TABLE_LEN
- 1; qdbm
++) {
361 boundary
= nqdBm_to_mW_map
[qdbm
] + (nqdBm_to_mW_map
[qdbm
+ 1] -
362 nqdBm_to_mW_map
[qdbm
]) / 2;
363 if (mw_uint
< boundary
)
372 u16
channel_to_chanspec(struct ieee80211_channel
*ch
)
376 chanspec
= ieee80211_frequency_to_channel(ch
->center_freq
);
377 chanspec
&= WL_CHANSPEC_CHAN_MASK
;
379 if (ch
->band
== IEEE80211_BAND_2GHZ
)
380 chanspec
|= WL_CHANSPEC_BAND_2G
;
382 chanspec
|= WL_CHANSPEC_BAND_5G
;
384 chanspec
|= WL_CHANSPEC_BW_20
;
385 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
390 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
391 struct brcmf_wsec_key_le
*key_le
)
393 key_le
->index
= cpu_to_le32(key
->index
);
394 key_le
->len
= cpu_to_le32(key
->len
);
395 key_le
->algo
= cpu_to_le32(key
->algo
);
396 key_le
->flags
= cpu_to_le32(key
->flags
);
397 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
398 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
399 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
400 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
401 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
405 send_key_to_dongle(struct net_device
*ndev
, struct brcmf_wsec_key
*key
)
408 struct brcmf_wsec_key_le key_le
;
410 convert_key_from_CPU(key
, &key_le
);
412 brcmf_netdev_wait_pend8021x(ndev
);
414 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "wsec_key", &key_le
,
418 brcmf_err("wsec_key error (%d)\n", err
);
422 static struct wireless_dev
*brcmf_cfg80211_add_iface(struct wiphy
*wiphy
,
424 enum nl80211_iftype type
,
426 struct vif_params
*params
)
428 brcmf_dbg(TRACE
, "enter: %s type %d\n", name
, type
);
430 case NL80211_IFTYPE_ADHOC
:
431 case NL80211_IFTYPE_STATION
:
432 case NL80211_IFTYPE_AP
:
433 case NL80211_IFTYPE_AP_VLAN
:
434 case NL80211_IFTYPE_WDS
:
435 case NL80211_IFTYPE_MONITOR
:
436 case NL80211_IFTYPE_MESH_POINT
:
437 return ERR_PTR(-EOPNOTSUPP
);
438 case NL80211_IFTYPE_P2P_CLIENT
:
439 case NL80211_IFTYPE_P2P_GO
:
440 return brcmf_p2p_add_vif(wiphy
, name
, type
, flags
, params
);
441 case NL80211_IFTYPE_UNSPECIFIED
:
442 case NL80211_IFTYPE_P2P_DEVICE
:
444 return ERR_PTR(-EINVAL
);
449 int brcmf_cfg80211_del_iface(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
451 switch (wdev
->iftype
) {
452 case NL80211_IFTYPE_ADHOC
:
453 case NL80211_IFTYPE_STATION
:
454 case NL80211_IFTYPE_AP
:
455 case NL80211_IFTYPE_AP_VLAN
:
456 case NL80211_IFTYPE_WDS
:
457 case NL80211_IFTYPE_MONITOR
:
458 case NL80211_IFTYPE_MESH_POINT
:
460 case NL80211_IFTYPE_P2P_CLIENT
:
461 case NL80211_IFTYPE_P2P_GO
:
462 return brcmf_p2p_del_vif(wiphy
, wdev
);
463 case NL80211_IFTYPE_UNSPECIFIED
:
464 case NL80211_IFTYPE_P2P_DEVICE
:
472 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
473 enum nl80211_iftype type
, u32
*flags
,
474 struct vif_params
*params
)
476 struct brcmf_if
*ifp
= netdev_priv(ndev
);
477 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
482 brcmf_dbg(TRACE
, "Enter, ndev=%p, type=%d\n", ndev
, type
);
485 case NL80211_IFTYPE_MONITOR
:
486 case NL80211_IFTYPE_WDS
:
487 brcmf_err("type (%d) : currently we do not support this type\n",
490 case NL80211_IFTYPE_ADHOC
:
491 vif
->mode
= WL_MODE_IBSS
;
494 case NL80211_IFTYPE_STATION
:
495 vif
->mode
= WL_MODE_BSS
;
498 case NL80211_IFTYPE_AP
:
499 vif
->mode
= WL_MODE_AP
;
508 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &vif
->sme_state
);
509 brcmf_dbg(INFO
, "IF Type = AP\n");
511 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, infra
);
513 brcmf_err("WLC_SET_INFRA error (%d)\n", err
);
517 brcmf_dbg(INFO
, "IF Type = %s\n", (vif
->mode
== WL_MODE_IBSS
) ?
520 ndev
->ieee80211_ptr
->iftype
= type
;
523 brcmf_dbg(TRACE
, "Exit\n");
528 static void brcmf_set_mpc(struct net_device
*ndev
, int mpc
)
530 struct brcmf_if
*ifp
= netdev_priv(ndev
);
533 if (check_vif_up(ifp
->vif
)) {
534 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
536 brcmf_err("fail to set mpc\n");
539 brcmf_dbg(INFO
, "MPC : %d\n", mpc
);
543 static void brcmf_escan_prep(struct brcmf_scan_params_le
*params_le
,
544 struct cfg80211_scan_request
*request
)
552 struct brcmf_ssid_le ssid_le
;
554 memset(params_le
->bssid
, 0xFF, ETH_ALEN
);
555 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
556 params_le
->scan_type
= 0;
557 params_le
->channel_num
= 0;
558 params_le
->nprobes
= cpu_to_le32(-1);
559 params_le
->active_time
= cpu_to_le32(-1);
560 params_le
->passive_time
= cpu_to_le32(-1);
561 params_le
->home_time
= cpu_to_le32(-1);
562 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
564 /* if request is null exit so it will be all channel broadcast scan */
568 n_ssids
= request
->n_ssids
;
569 n_channels
= request
->n_channels
;
570 /* Copy channel array if applicable */
571 brcmf_dbg(SCAN
, "### List of channelspecs to scan ### %d\n",
573 if (n_channels
> 0) {
574 for (i
= 0; i
< n_channels
; i
++) {
575 chanspec
= channel_to_chanspec(request
->channels
[i
]);
576 brcmf_dbg(SCAN
, "Chan : %d, Channel spec: %x\n",
577 request
->channels
[i
]->hw_value
, chanspec
);
578 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
581 brcmf_dbg(SCAN
, "Scanning all channels\n");
583 /* Copy ssid array if applicable */
584 brcmf_dbg(SCAN
, "### List of SSIDs to scan ### %d\n", n_ssids
);
586 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
587 n_channels
* sizeof(u16
);
588 offset
= roundup(offset
, sizeof(u32
));
589 ptr
= (char *)params_le
+ offset
;
590 for (i
= 0; i
< n_ssids
; i
++) {
591 memset(&ssid_le
, 0, sizeof(ssid_le
));
593 cpu_to_le32(request
->ssids
[i
].ssid_len
);
594 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
595 request
->ssids
[i
].ssid_len
);
596 if (!ssid_le
.SSID_len
)
597 brcmf_dbg(SCAN
, "%d: Broadcast scan\n", i
);
599 brcmf_dbg(SCAN
, "%d: scan for %s size =%d\n",
600 i
, ssid_le
.SSID
, ssid_le
.SSID_len
);
601 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
602 ptr
+= sizeof(ssid_le
);
605 brcmf_dbg(SCAN
, "Broadcast scan %p\n", request
->ssids
);
606 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
607 brcmf_dbg(SCAN
, "SSID %s len=%d\n",
608 params_le
->ssid_le
.SSID
,
609 request
->ssids
->ssid_len
);
610 params_le
->ssid_le
.SSID_len
=
611 cpu_to_le32(request
->ssids
->ssid_len
);
612 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
613 request
->ssids
->ssid_len
);
616 /* Adding mask to channel numbers */
617 params_le
->channel_num
=
618 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
619 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
623 brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
624 struct net_device
*ndev
,
625 bool aborted
, bool fw_abort
)
627 struct brcmf_scan_params_le params_le
;
628 struct cfg80211_scan_request
*scan_request
;
631 brcmf_dbg(SCAN
, "Enter\n");
633 /* clear scan request, because the FW abort can cause a second call */
634 /* to this functon and might cause a double cfg80211_scan_done */
635 scan_request
= cfg
->scan_request
;
636 cfg
->scan_request
= NULL
;
638 if (timer_pending(&cfg
->escan_timeout
))
639 del_timer_sync(&cfg
->escan_timeout
);
642 /* Do a scan abort to stop the driver's scan engine */
643 brcmf_dbg(SCAN
, "ABORT scan in firmware\n");
644 memset(¶ms_le
, 0, sizeof(params_le
));
645 memset(params_le
.bssid
, 0xFF, ETH_ALEN
);
646 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
647 params_le
.scan_type
= 0;
648 params_le
.channel_num
= cpu_to_le32(1);
649 params_le
.nprobes
= cpu_to_le32(1);
650 params_le
.active_time
= cpu_to_le32(-1);
651 params_le
.passive_time
= cpu_to_le32(-1);
652 params_le
.home_time
= cpu_to_le32(-1);
653 /* Scan is aborted by setting channel_list[0] to -1 */
654 params_le
.channel_list
[0] = cpu_to_le16(-1);
655 /* E-Scan (or anyother type) can be aborted by SCAN */
656 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SCAN
,
657 ¶ms_le
, sizeof(params_le
));
659 brcmf_err("Scan abort failed\n");
662 * e-scan can be initiated by scheduled scan
663 * which takes precedence.
665 if (cfg
->sched_escan
) {
666 brcmf_dbg(SCAN
, "scheduled scan completed\n");
667 cfg
->sched_escan
= false;
669 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
670 brcmf_set_mpc(ndev
, 1);
671 } else if (scan_request
) {
672 brcmf_dbg(SCAN
, "ESCAN Completed scan: %s\n",
673 aborted
? "Aborted" : "Done");
674 cfg80211_scan_done(scan_request
, aborted
);
675 brcmf_set_mpc(ndev
, 1);
677 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
678 brcmf_err("Scan complete while device not scanning\n");
686 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct net_device
*ndev
,
687 struct cfg80211_scan_request
*request
, u16 action
)
689 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
690 offsetof(struct brcmf_escan_params_le
, params_le
);
691 struct brcmf_escan_params_le
*params
;
694 brcmf_dbg(SCAN
, "E-SCAN START\n");
696 if (request
!= NULL
) {
697 /* Allocate space for populating ssids in struct */
698 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
700 /* Allocate space for populating ssids in struct */
701 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
704 params
= kzalloc(params_size
, GFP_KERNEL
);
709 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
710 brcmf_escan_prep(¶ms
->params_le
, request
);
711 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
712 params
->action
= cpu_to_le16(action
);
713 params
->sync_id
= cpu_to_le16(0x1234);
715 err
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "escan",
716 params
, params_size
);
719 brcmf_dbg(INFO
, "system busy : escan canceled\n");
721 brcmf_err("error (%d)\n", err
);
730 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
731 struct net_device
*ndev
, struct cfg80211_scan_request
*request
)
735 struct brcmf_scan_results
*results
;
736 struct escan_info
*escan
= &cfg
->escan_info
;
738 brcmf_dbg(SCAN
, "Enter\n");
740 escan
->wiphy
= wiphy
;
741 escan
->escan_state
= WL_ESCAN_STATE_SCANNING
;
742 passive_scan
= cfg
->active_scan
? 0 : 1;
743 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_SET_PASSIVE_SCAN
,
746 brcmf_err("error (%d)\n", err
);
749 brcmf_set_mpc(ndev
, 0);
750 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
751 results
->version
= 0;
753 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
755 err
= escan
->run(cfg
, ndev
, request
, WL_ESCAN_ACTION_START
);
757 brcmf_set_mpc(ndev
, 1);
762 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct net_device
*ndev
,
763 struct cfg80211_scan_request
*request
,
764 struct cfg80211_ssid
*this_ssid
)
766 struct brcmf_if
*ifp
= netdev_priv(ndev
);
767 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
768 struct cfg80211_ssid
*ssids
;
769 struct brcmf_cfg80211_scan_req
*sr
= &cfg
->scan_req_int
;
776 brcmf_dbg(SCAN
, "START ESCAN\n");
778 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
779 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
782 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
783 brcmf_err("Scanning being aborted: status (%lu)\n",
787 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
788 brcmf_err("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
792 /* Arm scan timeout timer */
793 mod_timer(&cfg
->escan_timeout
, jiffies
+
794 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
799 ssids
= request
->ssids
;
803 /* we don't do escan in ibss */
807 cfg
->scan_request
= request
;
808 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
810 cfg
->escan_info
.run
= brcmf_run_escan
;
811 err
= brcmf_p2p_scan_prep(wiphy
, request
);
815 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
819 brcmf_dbg(SCAN
, "ssid \"%s\", ssid_len (%d)\n",
820 ssids
->ssid
, ssids
->ssid_len
);
821 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
822 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
823 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
826 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
827 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
830 brcmf_dbg(SCAN
, "Broadcast scan\n");
832 passive_scan
= cfg
->active_scan
? 0 : 1;
833 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
836 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
839 brcmf_set_mpc(ndev
, 0);
840 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
841 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
844 brcmf_dbg(INFO
, "BUSY: scan for \"%s\" canceled\n",
847 brcmf_err("WLC_SCAN error (%d)\n", err
);
849 brcmf_set_mpc(ndev
, 1);
857 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
858 if (timer_pending(&cfg
->escan_timeout
))
859 del_timer_sync(&cfg
->escan_timeout
);
860 cfg
->scan_request
= NULL
;
865 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
867 struct net_device
*ndev
= request
->wdev
->netdev
;
870 brcmf_dbg(TRACE
, "Enter\n");
872 if (!check_vif_up(container_of(request
->wdev
,
873 struct brcmf_cfg80211_vif
, wdev
)))
876 err
= brcmf_cfg80211_escan(wiphy
, ndev
, request
, NULL
);
879 brcmf_err("scan error (%d)\n", err
);
881 brcmf_dbg(TRACE
, "Exit\n");
885 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
889 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
892 brcmf_err("Error (%d)\n", err
);
897 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
901 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
904 brcmf_err("Error (%d)\n", err
);
909 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
912 u32 cmd
= (l
? BRCMF_C_SET_LRL
: BRCMF_C_SET_SRL
);
914 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
916 brcmf_err("cmd (%d) , error (%d)\n", cmd
, err
);
922 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
924 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
925 struct net_device
*ndev
= cfg_to_ndev(cfg
);
926 struct brcmf_if
*ifp
= netdev_priv(ndev
);
929 brcmf_dbg(TRACE
, "Enter\n");
930 if (!check_vif_up(ifp
->vif
))
933 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
934 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
935 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
936 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
940 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
941 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
942 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
943 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
947 if (changed
& WIPHY_PARAM_RETRY_LONG
948 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
949 cfg
->conf
->retry_long
= wiphy
->retry_long
;
950 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
954 if (changed
& WIPHY_PARAM_RETRY_SHORT
955 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
956 cfg
->conf
->retry_short
= wiphy
->retry_short
;
957 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
963 brcmf_dbg(TRACE
, "Exit\n");
967 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
969 memset(prof
, 0, sizeof(*prof
));
972 static void brcmf_link_down(struct brcmf_cfg80211_vif
*vif
)
976 brcmf_dbg(TRACE
, "Enter\n");
978 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
)) {
979 brcmf_dbg(INFO
, "Call WLC_DISASSOC to stop excess roaming\n ");
980 err
= brcmf_fil_cmd_data_set(vif
->ifp
,
981 BRCMF_C_DISASSOC
, NULL
, 0);
983 brcmf_err("WLC_DISASSOC failed (%d)\n", err
);
984 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
);
986 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
);
987 brcmf_dbg(TRACE
, "Exit\n");
991 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
992 struct cfg80211_ibss_params
*params
)
994 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
995 struct brcmf_if
*ifp
= netdev_priv(ndev
);
996 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
997 struct brcmf_join_params join_params
;
998 size_t join_params_size
= 0;
1004 brcmf_dbg(TRACE
, "Enter\n");
1005 if (!check_vif_up(ifp
->vif
))
1009 brcmf_dbg(CONN
, "SSID: %s\n", params
->ssid
);
1011 brcmf_dbg(CONN
, "SSID: NULL, Not supported\n");
1015 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1018 brcmf_dbg(CONN
, "BSSID: %pM\n", params
->bssid
);
1020 brcmf_dbg(CONN
, "No BSSID specified\n");
1022 if (params
->chandef
.chan
)
1023 brcmf_dbg(CONN
, "channel: %d\n",
1024 params
->chandef
.chan
->center_freq
);
1026 brcmf_dbg(CONN
, "no channel specified\n");
1028 if (params
->channel_fixed
)
1029 brcmf_dbg(CONN
, "fixed channel required\n");
1031 brcmf_dbg(CONN
, "no fixed channel required\n");
1033 if (params
->ie
&& params
->ie_len
)
1034 brcmf_dbg(CONN
, "ie len: %d\n", params
->ie_len
);
1036 brcmf_dbg(CONN
, "no ie specified\n");
1038 if (params
->beacon_interval
)
1039 brcmf_dbg(CONN
, "beacon interval: %d\n",
1040 params
->beacon_interval
);
1042 brcmf_dbg(CONN
, "no beacon interval specified\n");
1044 if (params
->basic_rates
)
1045 brcmf_dbg(CONN
, "basic rates: %08X\n", params
->basic_rates
);
1047 brcmf_dbg(CONN
, "no basic rates specified\n");
1049 if (params
->privacy
)
1050 brcmf_dbg(CONN
, "privacy required\n");
1052 brcmf_dbg(CONN
, "no privacy required\n");
1054 /* Configure Privacy for starter */
1055 if (params
->privacy
)
1056 wsec
|= WEP_ENABLED
;
1058 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1060 brcmf_err("wsec failed (%d)\n", err
);
1064 /* Configure Beacon Interval for starter */
1065 if (params
->beacon_interval
)
1066 bcnprd
= params
->beacon_interval
;
1070 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
, bcnprd
);
1072 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err
);
1076 /* Configure required join parameter */
1077 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1080 profile
->ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1081 memcpy(profile
->ssid
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1082 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1083 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1084 join_params_size
= sizeof(join_params
.ssid_le
);
1087 if (params
->bssid
) {
1088 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1089 join_params_size
= sizeof(join_params
.ssid_le
) +
1090 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1091 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1093 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1094 memset(profile
->bssid
, 0, ETH_ALEN
);
1098 if (params
->chandef
.chan
) {
1102 ieee80211_frequency_to_channel(
1103 params
->chandef
.chan
->center_freq
);
1104 if (params
->channel_fixed
) {
1105 /* adding chanspec */
1106 chanspec
= channel_to_chanspec(params
->chandef
.chan
);
1107 join_params
.params_le
.chanspec_list
[0] =
1108 cpu_to_le16(chanspec
);
1109 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1110 join_params_size
+= sizeof(join_params
.params_le
);
1113 /* set channel for starter */
1114 target_channel
= cfg
->channel
;
1115 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_CHANNEL
,
1118 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err
);
1124 cfg
->ibss_starter
= false;
1127 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1128 &join_params
, join_params_size
);
1130 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1136 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1137 brcmf_dbg(TRACE
, "Exit\n");
1142 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1144 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1147 brcmf_dbg(TRACE
, "Enter\n");
1148 if (!check_vif_up(ifp
->vif
))
1151 brcmf_link_down(ifp
->vif
);
1153 brcmf_dbg(TRACE
, "Exit\n");
1158 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1159 struct cfg80211_connect_params
*sme
)
1161 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1162 struct brcmf_cfg80211_security
*sec
;
1166 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1167 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1168 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1169 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1171 val
= WPA_AUTH_DISABLED
;
1172 brcmf_dbg(CONN
, "setting wpa_auth to 0x%0x\n", val
);
1173 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1175 brcmf_err("set wpa_auth failed (%d)\n", err
);
1178 sec
= &profile
->sec
;
1179 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1183 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1184 struct cfg80211_connect_params
*sme
)
1186 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1187 struct brcmf_cfg80211_security
*sec
;
1191 switch (sme
->auth_type
) {
1192 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1194 brcmf_dbg(CONN
, "open system\n");
1196 case NL80211_AUTHTYPE_SHARED_KEY
:
1198 brcmf_dbg(CONN
, "shared key\n");
1200 case NL80211_AUTHTYPE_AUTOMATIC
:
1202 brcmf_dbg(CONN
, "automatic\n");
1204 case NL80211_AUTHTYPE_NETWORK_EAP
:
1205 brcmf_dbg(CONN
, "network eap\n");
1208 brcmf_err("invalid auth type (%d)\n", sme
->auth_type
);
1212 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "auth", val
);
1214 brcmf_err("set auth failed (%d)\n", err
);
1217 sec
= &profile
->sec
;
1218 sec
->auth_type
= sme
->auth_type
;
1223 brcmf_set_set_cipher(struct net_device
*ndev
,
1224 struct cfg80211_connect_params
*sme
)
1226 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1227 struct brcmf_cfg80211_security
*sec
;
1232 if (sme
->crypto
.n_ciphers_pairwise
) {
1233 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1234 case WLAN_CIPHER_SUITE_WEP40
:
1235 case WLAN_CIPHER_SUITE_WEP104
:
1238 case WLAN_CIPHER_SUITE_TKIP
:
1239 pval
= TKIP_ENABLED
;
1241 case WLAN_CIPHER_SUITE_CCMP
:
1244 case WLAN_CIPHER_SUITE_AES_CMAC
:
1248 brcmf_err("invalid cipher pairwise (%d)\n",
1249 sme
->crypto
.ciphers_pairwise
[0]);
1253 if (sme
->crypto
.cipher_group
) {
1254 switch (sme
->crypto
.cipher_group
) {
1255 case WLAN_CIPHER_SUITE_WEP40
:
1256 case WLAN_CIPHER_SUITE_WEP104
:
1259 case WLAN_CIPHER_SUITE_TKIP
:
1260 gval
= TKIP_ENABLED
;
1262 case WLAN_CIPHER_SUITE_CCMP
:
1265 case WLAN_CIPHER_SUITE_AES_CMAC
:
1269 brcmf_err("invalid cipher group (%d)\n",
1270 sme
->crypto
.cipher_group
);
1275 brcmf_dbg(CONN
, "pval (%d) gval (%d)\n", pval
, gval
);
1276 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wsec", pval
| gval
);
1278 brcmf_err("error (%d)\n", err
);
1282 sec
= &profile
->sec
;
1283 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1284 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1290 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1292 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1293 struct brcmf_cfg80211_security
*sec
;
1297 if (sme
->crypto
.n_akm_suites
) {
1298 err
= brcmf_fil_iovar_int_get(netdev_priv(ndev
),
1301 brcmf_err("could not get wpa_auth (%d)\n", err
);
1304 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1305 switch (sme
->crypto
.akm_suites
[0]) {
1306 case WLAN_AKM_SUITE_8021X
:
1307 val
= WPA_AUTH_UNSPECIFIED
;
1309 case WLAN_AKM_SUITE_PSK
:
1313 brcmf_err("invalid cipher group (%d)\n",
1314 sme
->crypto
.cipher_group
);
1317 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1318 switch (sme
->crypto
.akm_suites
[0]) {
1319 case WLAN_AKM_SUITE_8021X
:
1320 val
= WPA2_AUTH_UNSPECIFIED
;
1322 case WLAN_AKM_SUITE_PSK
:
1323 val
= WPA2_AUTH_PSK
;
1326 brcmf_err("invalid cipher group (%d)\n",
1327 sme
->crypto
.cipher_group
);
1332 brcmf_dbg(CONN
, "setting wpa_auth to %d\n", val
);
1333 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
),
1336 brcmf_err("could not set wpa_auth (%d)\n", err
);
1340 sec
= &profile
->sec
;
1341 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1347 brcmf_set_sharedkey(struct net_device
*ndev
,
1348 struct cfg80211_connect_params
*sme
)
1350 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1351 struct brcmf_cfg80211_security
*sec
;
1352 struct brcmf_wsec_key key
;
1356 brcmf_dbg(CONN
, "key len (%d)\n", sme
->key_len
);
1358 if (sme
->key_len
== 0)
1361 sec
= &profile
->sec
;
1362 brcmf_dbg(CONN
, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1363 sec
->wpa_versions
, sec
->cipher_pairwise
);
1365 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1368 if (!(sec
->cipher_pairwise
&
1369 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1372 memset(&key
, 0, sizeof(key
));
1373 key
.len
= (u32
) sme
->key_len
;
1374 key
.index
= (u32
) sme
->key_idx
;
1375 if (key
.len
> sizeof(key
.data
)) {
1376 brcmf_err("Too long key length (%u)\n", key
.len
);
1379 memcpy(key
.data
, sme
->key
, key
.len
);
1380 key
.flags
= BRCMF_PRIMARY_KEY
;
1381 switch (sec
->cipher_pairwise
) {
1382 case WLAN_CIPHER_SUITE_WEP40
:
1383 key
.algo
= CRYPTO_ALGO_WEP1
;
1385 case WLAN_CIPHER_SUITE_WEP104
:
1386 key
.algo
= CRYPTO_ALGO_WEP128
;
1389 brcmf_err("Invalid algorithm (%d)\n",
1390 sme
->crypto
.ciphers_pairwise
[0]);
1393 /* Set the new key/index */
1394 brcmf_dbg(CONN
, "key length (%d) key index (%d) algo (%d)\n",
1395 key
.len
, key
.index
, key
.algo
);
1396 brcmf_dbg(CONN
, "key \"%s\"\n", key
.data
);
1397 err
= send_key_to_dongle(ndev
, &key
);
1401 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1402 brcmf_dbg(CONN
, "set auth_type to shared key\n");
1403 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1404 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1406 brcmf_err("set auth failed (%d)\n", err
);
1412 enum nl80211_auth_type
brcmf_war_auth_type(struct brcmf_if
*ifp
,
1413 enum nl80211_auth_type type
)
1416 if (type
== NL80211_AUTHTYPE_AUTOMATIC
) {
1417 /* shift to ignore chip revision */
1418 ci
= brcmf_get_chip_info(ifp
) >> 4;
1421 brcmf_dbg(CONN
, "43236 WAR: use OPEN instead of AUTO\n");
1422 return NL80211_AUTHTYPE_OPEN_SYSTEM
;
1431 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1432 struct cfg80211_connect_params
*sme
)
1434 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1435 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1436 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1437 struct ieee80211_channel
*chan
= sme
->channel
;
1438 struct brcmf_join_params join_params
;
1439 size_t join_params_size
;
1440 struct brcmf_ssid ssid
;
1445 brcmf_dbg(TRACE
, "Enter\n");
1446 if (!check_vif_up(ifp
->vif
))
1450 brcmf_err("Invalid ssid\n");
1454 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1458 ieee80211_frequency_to_channel(chan
->center_freq
);
1459 chanspec
= channel_to_chanspec(chan
);
1460 brcmf_dbg(CONN
, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1461 cfg
->channel
, chan
->center_freq
, chanspec
);
1467 brcmf_dbg(INFO
, "ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1469 err
= brcmf_set_wpa_version(ndev
, sme
);
1471 brcmf_err("wl_set_wpa_version failed (%d)\n", err
);
1475 sme
->auth_type
= brcmf_war_auth_type(ifp
, sme
->auth_type
);
1476 err
= brcmf_set_auth_type(ndev
, sme
);
1478 brcmf_err("wl_set_auth_type failed (%d)\n", err
);
1482 err
= brcmf_set_set_cipher(ndev
, sme
);
1484 brcmf_err("wl_set_set_cipher failed (%d)\n", err
);
1488 err
= brcmf_set_key_mgmt(ndev
, sme
);
1490 brcmf_err("wl_set_key_mgmt failed (%d)\n", err
);
1494 err
= brcmf_set_sharedkey(ndev
, sme
);
1496 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err
);
1500 memset(&join_params
, 0, sizeof(join_params
));
1501 join_params_size
= sizeof(join_params
.ssid_le
);
1503 profile
->ssid
.SSID_len
= min_t(u32
,
1504 sizeof(ssid
.SSID
), (u32
)sme
->ssid_len
);
1505 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1506 memcpy(&profile
->ssid
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1507 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1509 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1511 if (ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
)
1512 brcmf_dbg(CONN
, "ssid \"%s\", len (%d)\n",
1513 ssid
.SSID
, ssid
.SSID_len
);
1516 join_params
.params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
1517 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1518 join_params_size
+= sizeof(join_params
.params_le
);
1520 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1521 &join_params
, join_params_size
);
1523 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1527 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1528 brcmf_dbg(TRACE
, "Exit\n");
1533 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1536 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1537 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1538 struct brcmf_scb_val_le scbval
;
1541 brcmf_dbg(TRACE
, "Enter. Reason code = %d\n", reason_code
);
1542 if (!check_vif_up(ifp
->vif
))
1545 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
1547 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1548 scbval
.val
= cpu_to_le32(reason_code
);
1549 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1550 &scbval
, sizeof(scbval
));
1552 brcmf_err("error (%d)\n", err
);
1554 brcmf_dbg(TRACE
, "Exit\n");
1559 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1560 enum nl80211_tx_power_setting type
, s32 mbm
)
1563 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1564 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1565 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1569 s32 dbm
= MBM_TO_DBM(mbm
);
1571 brcmf_dbg(TRACE
, "Enter\n");
1572 if (!check_vif_up(ifp
->vif
))
1576 case NL80211_TX_POWER_AUTOMATIC
:
1578 case NL80211_TX_POWER_LIMITED
:
1579 case NL80211_TX_POWER_FIXED
:
1581 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1587 /* Make sure radio is off or on as far as software is concerned */
1588 disable
= WL_RADIO_SW_DISABLE
<< 16;
1589 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1591 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
1596 txpwrmw
= (u16
) dbm
;
1597 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1598 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1600 brcmf_err("qtxpower error (%d)\n", err
);
1601 cfg
->conf
->tx_power
= dbm
;
1604 brcmf_dbg(TRACE
, "Exit\n");
1608 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
,
1609 struct wireless_dev
*wdev
,
1612 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1613 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1618 brcmf_dbg(TRACE
, "Enter\n");
1619 if (!check_vif_up(ifp
->vif
))
1622 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &txpwrdbm
);
1624 brcmf_err("error (%d)\n", err
);
1628 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1629 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1632 brcmf_dbg(TRACE
, "Exit\n");
1637 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1638 u8 key_idx
, bool unicast
, bool multicast
)
1640 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1645 brcmf_dbg(TRACE
, "Enter\n");
1646 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1647 if (!check_vif_up(ifp
->vif
))
1650 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1652 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1656 if (wsec
& WEP_ENABLED
) {
1657 /* Just select a new current key */
1659 err
= brcmf_fil_cmd_int_set(ifp
,
1660 BRCMF_C_SET_KEY_PRIMARY
, index
);
1662 brcmf_err("error (%d)\n", err
);
1665 brcmf_dbg(TRACE
, "Exit\n");
1670 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1671 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1673 struct brcmf_wsec_key key
;
1676 memset(&key
, 0, sizeof(key
));
1677 key
.index
= (u32
) key_idx
;
1678 /* Instead of bcast for ea address for default wep keys,
1679 driver needs it to be Null */
1680 if (!is_multicast_ether_addr(mac_addr
))
1681 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1682 key
.len
= (u32
) params
->key_len
;
1683 /* check for key index change */
1686 err
= send_key_to_dongle(ndev
, &key
);
1688 brcmf_err("key delete error (%d)\n", err
);
1690 if (key
.len
> sizeof(key
.data
)) {
1691 brcmf_err("Invalid key length (%d)\n", key
.len
);
1695 brcmf_dbg(CONN
, "Setting the key index %d\n", key
.index
);
1696 memcpy(key
.data
, params
->key
, key
.len
);
1698 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1700 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1701 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1702 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1705 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1706 if (params
->seq
&& params
->seq_len
== 6) {
1709 ivptr
= (u8
*) params
->seq
;
1710 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1711 (ivptr
[3] << 8) | ivptr
[2];
1712 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1713 key
.iv_initialized
= true;
1716 switch (params
->cipher
) {
1717 case WLAN_CIPHER_SUITE_WEP40
:
1718 key
.algo
= CRYPTO_ALGO_WEP1
;
1719 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1721 case WLAN_CIPHER_SUITE_WEP104
:
1722 key
.algo
= CRYPTO_ALGO_WEP128
;
1723 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1725 case WLAN_CIPHER_SUITE_TKIP
:
1726 key
.algo
= CRYPTO_ALGO_TKIP
;
1727 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1729 case WLAN_CIPHER_SUITE_AES_CMAC
:
1730 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1731 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1733 case WLAN_CIPHER_SUITE_CCMP
:
1734 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1735 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1738 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1741 err
= send_key_to_dongle(ndev
, &key
);
1743 brcmf_err("wsec_key error (%d)\n", err
);
1749 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1750 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1751 struct key_params
*params
)
1753 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1754 struct brcmf_wsec_key key
;
1760 brcmf_dbg(TRACE
, "Enter\n");
1761 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1762 if (!check_vif_up(ifp
->vif
))
1766 brcmf_dbg(TRACE
, "Exit");
1767 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1769 memset(&key
, 0, sizeof(key
));
1771 key
.len
= (u32
) params
->key_len
;
1772 key
.index
= (u32
) key_idx
;
1774 if (key
.len
> sizeof(key
.data
)) {
1775 brcmf_err("Too long key length (%u)\n", key
.len
);
1779 memcpy(key
.data
, params
->key
, key
.len
);
1781 key
.flags
= BRCMF_PRIMARY_KEY
;
1782 switch (params
->cipher
) {
1783 case WLAN_CIPHER_SUITE_WEP40
:
1784 key
.algo
= CRYPTO_ALGO_WEP1
;
1786 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1788 case WLAN_CIPHER_SUITE_WEP104
:
1789 key
.algo
= CRYPTO_ALGO_WEP128
;
1791 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1793 case WLAN_CIPHER_SUITE_TKIP
:
1794 if (ifp
->vif
->mode
!= WL_MODE_AP
) {
1795 brcmf_dbg(CONN
, "Swapping key\n");
1796 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1797 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1798 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1800 key
.algo
= CRYPTO_ALGO_TKIP
;
1802 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1804 case WLAN_CIPHER_SUITE_AES_CMAC
:
1805 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1807 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1809 case WLAN_CIPHER_SUITE_CCMP
:
1810 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1812 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1815 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1820 err
= send_key_to_dongle(ndev
, &key
);
1824 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1826 brcmf_err("get wsec error (%d)\n", err
);
1830 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
1832 brcmf_err("set wsec error (%d)\n", err
);
1837 brcmf_dbg(TRACE
, "Exit\n");
1842 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1843 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
1845 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1846 struct brcmf_wsec_key key
;
1849 brcmf_dbg(TRACE
, "Enter\n");
1850 if (!check_vif_up(ifp
->vif
))
1853 if (key_idx
>= DOT11_MAX_DEFAULT_KEYS
) {
1854 /* we ignore this key index in this case */
1855 brcmf_err("invalid key index (%d)\n", key_idx
);
1859 memset(&key
, 0, sizeof(key
));
1861 key
.index
= (u32
) key_idx
;
1862 key
.flags
= BRCMF_PRIMARY_KEY
;
1863 key
.algo
= CRYPTO_ALGO_OFF
;
1865 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1867 /* Set the new key/index */
1868 err
= send_key_to_dongle(ndev
, &key
);
1870 brcmf_dbg(TRACE
, "Exit\n");
1875 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1876 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
1877 void (*callback
) (void *cookie
, struct key_params
* params
))
1879 struct key_params params
;
1880 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1881 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1882 struct brcmf_cfg80211_security
*sec
;
1886 brcmf_dbg(TRACE
, "Enter\n");
1887 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1888 if (!check_vif_up(ifp
->vif
))
1891 memset(¶ms
, 0, sizeof(params
));
1893 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1895 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1896 /* Ignore this error, may happen during DISASSOC */
1900 switch (wsec
& ~SES_OW_ENABLED
) {
1902 sec
= &profile
->sec
;
1903 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
1904 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
1905 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1906 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
1907 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
1908 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1912 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
1913 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1916 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
1917 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1920 brcmf_err("Invalid algo (0x%x)\n", wsec
);
1924 callback(cookie
, ¶ms
);
1927 brcmf_dbg(TRACE
, "Exit\n");
1932 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
1933 struct net_device
*ndev
, u8 key_idx
)
1935 brcmf_dbg(INFO
, "Not supported\n");
1941 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
1942 u8
*mac
, struct station_info
*sinfo
)
1944 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1945 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1946 struct brcmf_scb_val_le scb_val
;
1950 u8
*bssid
= profile
->bssid
;
1951 struct brcmf_sta_info_le sta_info_le
;
1953 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
1954 if (!check_vif_up(ifp
->vif
))
1957 if (ifp
->vif
->mode
== WL_MODE_AP
) {
1958 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
1959 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
1961 sizeof(sta_info_le
));
1963 brcmf_err("GET STA INFO failed, %d\n", err
);
1966 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
1967 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
1968 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
1969 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
1970 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
1972 brcmf_dbg(TRACE
, "STA idle time : %d ms, connected time :%d sec\n",
1973 sinfo
->inactive_time
, sinfo
->connected_time
);
1974 } else if (ifp
->vif
->mode
== WL_MODE_BSS
) {
1975 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
1976 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1981 /* Report the current tx rate */
1982 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
1984 brcmf_err("Could not get rate (%d)\n", err
);
1987 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1988 sinfo
->txrate
.legacy
= rate
* 5;
1989 brcmf_dbg(CONN
, "Rate %d Mbps\n", rate
/ 2);
1992 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
1993 &ifp
->vif
->sme_state
)) {
1994 memset(&scb_val
, 0, sizeof(scb_val
));
1995 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
1996 &scb_val
, sizeof(scb_val
));
1998 brcmf_err("Could not get rssi (%d)\n", err
);
2001 rssi
= le32_to_cpu(scb_val
.val
);
2002 sinfo
->filled
|= STATION_INFO_SIGNAL
;
2003 sinfo
->signal
= rssi
;
2004 brcmf_dbg(CONN
, "RSSI %d dBm\n", rssi
);
2010 brcmf_dbg(TRACE
, "Exit\n");
2015 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2016 bool enabled
, s32 timeout
)
2020 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2021 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2023 brcmf_dbg(TRACE
, "Enter\n");
2026 * Powersave enable/disable request is coming from the
2027 * cfg80211 even before the interface is up. In that
2028 * scenario, driver will be storing the power save
2029 * preference in cfg struct to apply this to
2030 * FW later while initializing the dongle
2032 cfg
->pwr_save
= enabled
;
2033 if (!check_vif_up(ifp
->vif
)) {
2035 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
2039 pm
= enabled
? PM_FAST
: PM_OFF
;
2040 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2042 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2045 brcmf_err("net_device is not ready yet\n");
2047 brcmf_err("error (%d)\n", err
);
2050 brcmf_dbg(TRACE
, "Exit\n");
2054 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2055 struct brcmf_bss_info_le
*bi
)
2057 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2058 struct ieee80211_channel
*notify_channel
;
2059 struct cfg80211_bss
*bss
;
2060 struct ieee80211_supported_band
*band
;
2064 u16 notify_capability
;
2065 u16 notify_interval
;
2067 size_t notify_ielen
;
2070 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2071 brcmf_err("Bss info is larger than buffer. Discarding\n");
2075 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2076 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2078 if (channel
<= CH_MAX_2G_CHANNEL
)
2079 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2081 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2083 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2084 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2086 notify_capability
= le16_to_cpu(bi
->capability
);
2087 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2088 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2089 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2090 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2092 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2093 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2094 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2095 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2096 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2098 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2099 0, notify_capability
, notify_interval
, notify_ie
,
2100 notify_ielen
, notify_signal
, GFP_KERNEL
);
2105 cfg80211_put_bss(bss
);
2110 static struct brcmf_bss_info_le
*
2111 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2114 return list
->bss_info_le
;
2115 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2116 le32_to_cpu(bss
->length
));
2119 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2121 struct brcmf_scan_results
*bss_list
;
2122 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2126 bss_list
= cfg
->bss_list
;
2127 if (bss_list
->count
!= 0 &&
2128 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2129 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2133 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2134 for (i
= 0; i
< bss_list
->count
; i
++) {
2135 bi
= next_bss_le(bss_list
, bi
);
2136 err
= brcmf_inform_single_bss(cfg
, bi
);
2143 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2144 struct net_device
*ndev
, const u8
*bssid
)
2146 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2147 struct ieee80211_channel
*notify_channel
;
2148 struct brcmf_bss_info_le
*bi
= NULL
;
2149 struct ieee80211_supported_band
*band
;
2150 struct cfg80211_bss
*bss
;
2155 u16 notify_capability
;
2156 u16 notify_interval
;
2158 size_t notify_ielen
;
2161 brcmf_dbg(TRACE
, "Enter\n");
2163 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2169 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2171 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2172 buf
, WL_BSS_INFO_MAX
);
2174 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2178 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2180 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2181 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2183 if (channel
<= CH_MAX_2G_CHANNEL
)
2184 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2186 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2188 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2189 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2191 notify_capability
= le16_to_cpu(bi
->capability
);
2192 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2193 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2194 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2195 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2197 brcmf_dbg(CONN
, "channel: %d(%d)\n", channel
, freq
);
2198 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2199 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2200 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2202 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2203 0, notify_capability
, notify_interval
,
2204 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2211 cfg80211_put_bss(bss
);
2217 brcmf_dbg(TRACE
, "Exit\n");
2222 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
2224 return vif
->mode
== WL_MODE_IBSS
;
2228 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2229 * triples, returning a pointer to the substring whose first element
2232 struct brcmf_tlv
*brcmf_parse_tlvs(void *buf
, int buflen
, uint key
)
2234 struct brcmf_tlv
*elt
;
2237 elt
= (struct brcmf_tlv
*) buf
;
2240 /* find tagged parameter */
2241 while (totlen
>= TLV_HDR_LEN
) {
2244 /* validate remaining totlen */
2245 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
2248 elt
= (struct brcmf_tlv
*) ((u8
*) elt
+ (len
+ TLV_HDR_LEN
));
2249 totlen
-= (len
+ TLV_HDR_LEN
);
2255 /* Is any of the tlvs the expected entry? If
2256 * not update the tlvs buffer pointer/length.
2259 brcmf_tlv_has_ie(u8
*ie
, u8
**tlvs
, u32
*tlvs_len
,
2260 u8
*oui
, u32 oui_len
, u8 type
)
2262 /* If the contents match the OUI and the type */
2263 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
2264 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
2265 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
2271 /* point to the next ie */
2272 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
2273 /* calculate the length of the rest of the buffer */
2274 *tlvs_len
-= (int)(ie
- *tlvs
);
2275 /* update the pointer to the start of the buffer */
2281 static struct brcmf_vs_tlv
*
2282 brcmf_find_wpaie(u8
*parse
, u32 len
)
2284 struct brcmf_tlv
*ie
;
2286 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
2287 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
2288 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
2289 return (struct brcmf_vs_tlv
*)ie
;
2294 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
)
2296 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2297 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
2298 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2299 struct brcmf_bss_info_le
*bi
;
2300 struct brcmf_ssid
*ssid
;
2301 struct brcmf_tlv
*tim
;
2302 u16 beacon_interval
;
2308 brcmf_dbg(TRACE
, "Enter\n");
2309 if (brcmf_is_ibssmode(ifp
->vif
))
2312 ssid
= &profile
->ssid
;
2314 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2315 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2316 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2318 brcmf_err("Could not get bss info %d\n", err
);
2319 goto update_bss_info_out
;
2322 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2323 err
= brcmf_inform_single_bss(cfg
, bi
);
2325 goto update_bss_info_out
;
2327 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2328 ie_len
= le32_to_cpu(bi
->ie_length
);
2329 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2331 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2333 dtim_period
= tim
->data
[1];
2336 * active scan was done so we could not get dtim
2337 * information out of probe response.
2338 * so we speficially query dtim information to dongle.
2341 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2343 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2344 goto update_bss_info_out
;
2346 dtim_period
= (u8
)var
;
2349 update_bss_info_out
:
2350 brcmf_dbg(TRACE
, "Exit");
2354 static void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2356 struct escan_info
*escan
= &cfg
->escan_info
;
2358 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2359 if (cfg
->scan_request
) {
2360 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2361 brcmf_notify_escan_complete(cfg
, escan
->ndev
, true, true);
2363 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2364 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2367 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2369 struct brcmf_cfg80211_info
*cfg
=
2370 container_of(work
, struct brcmf_cfg80211_info
,
2371 escan_timeout_work
);
2373 brcmf_notify_escan_complete(cfg
,
2374 cfg
->escan_info
.ndev
, true, true);
2377 static void brcmf_escan_timeout(unsigned long data
)
2379 struct brcmf_cfg80211_info
*cfg
=
2380 (struct brcmf_cfg80211_info
*)data
;
2382 if (cfg
->scan_request
) {
2383 brcmf_err("timer expired\n");
2384 schedule_work(&cfg
->escan_timeout_work
);
2389 brcmf_compare_update_same_bss(struct brcmf_bss_info_le
*bss
,
2390 struct brcmf_bss_info_le
*bss_info_le
)
2392 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2393 (CHSPEC_BAND(le16_to_cpu(bss_info_le
->chanspec
)) ==
2394 CHSPEC_BAND(le16_to_cpu(bss
->chanspec
))) &&
2395 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2396 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2397 if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) ==
2398 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
)) {
2399 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2400 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2402 /* preserve max RSSI if the measurements are
2403 * both on-channel or both off-channel
2405 if (bss_info_rssi
> bss_rssi
)
2406 bss
->RSSI
= bss_info_le
->RSSI
;
2407 } else if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) &&
2408 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) == 0) {
2409 /* preserve the on-channel rssi measurement
2410 * if the new measurement is off channel
2412 bss
->RSSI
= bss_info_le
->RSSI
;
2413 bss
->flags
|= WLC_BSS_RSSI_ON_CHANNEL
;
2421 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
2422 const struct brcmf_event_msg
*e
, void *data
)
2424 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2425 struct net_device
*ndev
= ifp
->ndev
;
2428 struct brcmf_escan_result_le
*escan_result_le
;
2429 struct brcmf_bss_info_le
*bss_info_le
;
2430 struct brcmf_bss_info_le
*bss
= NULL
;
2432 struct brcmf_scan_results
*list
;
2438 if (!ndev
|| !test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2439 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev
,
2440 !test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
));
2444 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2445 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
2446 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2447 if (!escan_result_le
) {
2448 brcmf_err("Invalid escan result (NULL pointer)\n");
2451 if (!cfg
->scan_request
) {
2452 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
2456 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2457 brcmf_err("Invalid bss_count %d: ignoring\n",
2458 escan_result_le
->bss_count
);
2461 bss_info_le
= &escan_result_le
->bss_info_le
;
2463 bi_length
= le32_to_cpu(bss_info_le
->length
);
2464 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2465 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2466 brcmf_err("Invalid bss_info length %d: ignoring\n",
2471 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
2472 BIT(NL80211_IFTYPE_ADHOC
))) {
2473 if (le16_to_cpu(bss_info_le
->capability
) &
2474 WLAN_CAPABILITY_IBSS
) {
2475 brcmf_err("Ignoring IBSS result\n");
2480 list
= (struct brcmf_scan_results
*)
2481 cfg
->escan_info
.escan_buf
;
2482 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2483 brcmf_err("Buffer is too small: ignoring\n");
2487 for (i
= 0; i
< list
->count
; i
++) {
2488 bss
= bss
? (struct brcmf_bss_info_le
*)
2489 ((unsigned char *)bss
+
2490 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2491 if (brcmf_compare_update_same_bss(bss
, bss_info_le
))
2494 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
2495 bss_info_le
, bi_length
);
2496 list
->version
= le32_to_cpu(bss_info_le
->version
);
2497 list
->buflen
+= bi_length
;
2500 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2501 if (cfg
->scan_request
) {
2502 cfg
->bss_list
= (struct brcmf_scan_results
*)
2503 cfg
->escan_info
.escan_buf
;
2504 brcmf_inform_bss(cfg
);
2505 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2506 brcmf_notify_escan_complete(cfg
, ndev
, aborted
,
2509 brcmf_err("Unexpected scan result 0x%x\n", status
);
2515 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2517 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
2518 brcmf_cfg80211_escan_handler
);
2519 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2520 /* Init scan_timeout timer */
2521 init_timer(&cfg
->escan_timeout
);
2522 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2523 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2524 INIT_WORK(&cfg
->escan_timeout_work
,
2525 brcmf_cfg80211_escan_timeout_worker
);
2528 static __always_inline
void brcmf_delay(u32 ms
)
2530 if (ms
< 1000 / HZ
) {
2538 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2540 brcmf_dbg(TRACE
, "Enter\n");
2545 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2546 struct cfg80211_wowlan
*wow
)
2548 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2549 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2550 struct brcmf_cfg80211_vif
*vif
;
2552 brcmf_dbg(TRACE
, "Enter\n");
2555 * if the primary net_device is not READY there is nothing
2556 * we can do but pray resume goes smoothly.
2558 vif
= ((struct brcmf_if
*)netdev_priv(ndev
))->vif
;
2559 if (!check_vif_up(vif
))
2562 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
2563 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
2566 * While going to suspend if associated with AP disassociate
2567 * from AP to save power while system is in suspended state
2569 brcmf_link_down(vif
);
2571 /* Make sure WPA_Supplicant receives all the event
2572 * generated due to DISASSOC call to the fw to keep
2573 * the state fw and WPA_Supplicant state consistent
2578 /* end any scanning */
2579 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
2580 brcmf_abort_scanning(cfg
);
2582 /* Turn off watchdog timer */
2583 brcmf_set_mpc(ndev
, 1);
2586 brcmf_dbg(TRACE
, "Exit\n");
2587 /* clear any scanning activity */
2588 cfg
->scan_status
= 0;
2593 brcmf_update_pmklist(struct net_device
*ndev
,
2594 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2599 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
2601 brcmf_dbg(CONN
, "No of elements %d\n", pmkid_len
);
2602 for (i
= 0; i
< pmkid_len
; i
++) {
2603 brcmf_dbg(CONN
, "PMKID[%d]: %pM =\n", i
,
2604 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2605 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2606 brcmf_dbg(CONN
, "%02x\n",
2607 pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2611 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
2612 (char *)pmk_list
, sizeof(*pmk_list
));
2618 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2619 struct cfg80211_pmksa
*pmksa
)
2621 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2622 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2623 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
2628 brcmf_dbg(TRACE
, "Enter\n");
2629 if (!check_vif_up(ifp
->vif
))
2632 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
2633 for (i
= 0; i
< pmkid_len
; i
++)
2634 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2636 if (i
< WL_NUM_PMKIDS_MAX
) {
2637 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2638 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2639 if (i
== pmkid_len
) {
2641 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
2646 brcmf_dbg(CONN
, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2647 pmkids
->pmkid
[pmkid_len
].BSSID
);
2648 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2649 brcmf_dbg(CONN
, "%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
2651 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2653 brcmf_dbg(TRACE
, "Exit\n");
2658 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2659 struct cfg80211_pmksa
*pmksa
)
2661 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2662 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2663 struct pmkid_list pmkid
;
2667 brcmf_dbg(TRACE
, "Enter\n");
2668 if (!check_vif_up(ifp
->vif
))
2671 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2672 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2674 brcmf_dbg(CONN
, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2675 &pmkid
.pmkid
[0].BSSID
);
2676 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2677 brcmf_dbg(CONN
, "%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2679 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
2680 for (i
= 0; i
< pmkid_len
; i
++)
2682 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2687 && (i
< pmkid_len
)) {
2688 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
2689 sizeof(struct pmkid
));
2690 for (; i
< (pmkid_len
- 1); i
++) {
2691 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2692 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2694 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2695 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2698 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
2702 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2704 brcmf_dbg(TRACE
, "Exit\n");
2710 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
2712 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2713 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2716 brcmf_dbg(TRACE
, "Enter\n");
2717 if (!check_vif_up(ifp
->vif
))
2720 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
2721 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2723 brcmf_dbg(TRACE
, "Exit\n");
2729 * PFN result doesn't have all the info which are
2730 * required by the supplicant
2731 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2732 * via wl_inform_single_bss in the required format. Escan does require the
2733 * scan request in the form of cfg80211_scan_request. For timebeing, create
2734 * cfg80211_scan_request one out of the received PNO event.
2737 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
2738 const struct brcmf_event_msg
*e
, void *data
)
2740 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2741 struct net_device
*ndev
= ifp
->ndev
;
2742 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
2743 struct cfg80211_scan_request
*request
= NULL
;
2744 struct cfg80211_ssid
*ssid
= NULL
;
2745 struct ieee80211_channel
*channel
= NULL
;
2746 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2748 int channel_req
= 0;
2750 struct brcmf_pno_scanresults_le
*pfn_result
;
2754 brcmf_dbg(SCAN
, "Enter\n");
2756 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
2757 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
2761 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
2762 result_count
= le32_to_cpu(pfn_result
->count
);
2763 status
= le32_to_cpu(pfn_result
->status
);
2766 * PFN event is limited to fit 512 bytes so we may get
2767 * multiple NET_FOUND events. For now place a warning here.
2769 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
2770 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
2771 if (result_count
> 0) {
2774 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
2775 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
2776 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
2777 if (!request
|| !ssid
|| !channel
) {
2782 request
->wiphy
= wiphy
;
2783 data
+= sizeof(struct brcmf_pno_scanresults_le
);
2784 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
2786 for (i
= 0; i
< result_count
; i
++) {
2787 netinfo
= &netinfo_start
[i
];
2789 brcmf_err("Invalid netinfo ptr. index: %d\n",
2795 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
2796 netinfo
->SSID
, netinfo
->channel
);
2797 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
2798 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
2801 channel_req
= netinfo
->channel
;
2802 if (channel_req
<= CH_MAX_2G_CHANNEL
)
2803 band
= NL80211_BAND_2GHZ
;
2805 band
= NL80211_BAND_5GHZ
;
2806 channel
[i
].center_freq
=
2807 ieee80211_channel_to_frequency(channel_req
,
2809 channel
[i
].band
= band
;
2810 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
2811 request
->channels
[i
] = &channel
[i
];
2812 request
->n_channels
++;
2815 /* assign parsed ssid array */
2816 if (request
->n_ssids
)
2817 request
->ssids
= &ssid
[0];
2819 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2820 /* Abort any on-going scan */
2821 brcmf_abort_scanning(cfg
);
2824 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2825 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
2827 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2830 cfg
->sched_escan
= true;
2831 cfg
->scan_request
= request
;
2833 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2846 cfg80211_sched_scan_stopped(wiphy
);
2850 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
2855 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
2858 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
2862 brcmf_err("failed code %d\n", ret
);
2867 static int brcmf_dev_pno_config(struct net_device
*ndev
)
2869 struct brcmf_pno_param_le pfn_param
;
2871 memset(&pfn_param
, 0, sizeof(pfn_param
));
2872 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
2874 /* set extra pno params */
2875 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
2876 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
2877 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
2879 /* set up pno scan fr */
2880 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
2882 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
2883 &pfn_param
, sizeof(pfn_param
));
2887 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
2888 struct net_device
*ndev
,
2889 struct cfg80211_sched_scan_request
*request
)
2891 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2892 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
2893 struct brcmf_pno_net_param_le pfn
;
2897 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
2898 request
->n_match_sets
, request
->n_ssids
);
2899 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2900 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
2904 if (!request
|| !request
->n_ssids
|| !request
->n_match_sets
) {
2905 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
2906 request
? request
->n_ssids
: 0);
2910 if (request
->n_ssids
> 0) {
2911 for (i
= 0; i
< request
->n_ssids
; i
++) {
2912 /* Active scan req for ssids */
2913 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
2914 request
->ssids
[i
].ssid
);
2917 * match_set ssids is a supert set of n_ssid list,
2918 * so we need not add these set seperately.
2923 if (request
->n_match_sets
> 0) {
2924 /* clean up everything */
2925 ret
= brcmf_dev_pno_clean(ndev
);
2927 brcmf_err("failed error=%d\n", ret
);
2932 ret
= brcmf_dev_pno_config(ndev
);
2934 brcmf_err("PNO setup failed!! ret=%d\n", ret
);
2938 /* configure each match set */
2939 for (i
= 0; i
< request
->n_match_sets
; i
++) {
2940 struct cfg80211_ssid
*ssid
;
2943 ssid
= &request
->match_sets
[i
].ssid
;
2944 ssid_len
= ssid
->ssid_len
;
2947 brcmf_err("skip broadcast ssid\n");
2950 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
2951 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
2952 pfn
.wsec
= cpu_to_le32(0);
2953 pfn
.infra
= cpu_to_le32(1);
2954 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
2955 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
2956 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
2957 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
2959 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
2960 ret
== 0 ? "set" : "failed", ssid
->ssid
);
2962 /* Enable the PNO */
2963 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
2964 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
2974 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
2975 struct net_device
*ndev
)
2977 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2979 brcmf_dbg(SCAN
, "enter\n");
2980 brcmf_dev_pno_clean(ndev
);
2981 if (cfg
->sched_escan
)
2982 brcmf_notify_escan_complete(cfg
, ndev
, true, true);
2986 #ifdef CONFIG_NL80211_TESTMODE
2987 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
, void *data
, int len
)
2989 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2990 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2991 struct brcmf_dcmd
*dcmd
= data
;
2992 struct sk_buff
*reply
;
2995 brcmf_dbg(TRACE
, "cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
2996 dcmd
->buf
, dcmd
->len
);
2999 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
3000 dcmd
->buf
, dcmd
->len
);
3002 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
3003 dcmd
->buf
, dcmd
->len
);
3005 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3006 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3007 ret
= cfg80211_testmode_reply(reply
);
3013 static s32
brcmf_configure_opensecurity(struct brcmf_if
*ifp
)
3018 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3020 brcmf_err("auth error %d\n", err
);
3024 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3026 brcmf_err("wsec error %d\n", err
);
3029 /* set upper-layer auth */
3030 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3032 brcmf_err("wpa_auth error %d\n", err
);
3039 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3042 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3044 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3048 brcmf_configure_wpaie(struct net_device
*ndev
, struct brcmf_vs_tlv
*wpa_ie
,
3051 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3052 u32 auth
= 0; /* d11 open authentication */
3064 u32 wme_bss_disable
;
3066 brcmf_dbg(TRACE
, "Enter\n");
3070 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3071 data
= (u8
*)wpa_ie
;
3072 offset
= TLV_HDR_LEN
;
3074 offset
+= VS_IE_FIXED_HDR_LEN
;
3076 offset
+= WPA_IE_VERSION_LEN
;
3078 /* check for multicast cipher suite */
3079 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3081 brcmf_err("no multicast cipher suite\n");
3085 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3087 brcmf_err("ivalid OUI\n");
3090 offset
+= TLV_OUI_LEN
;
3092 /* pick up multicast cipher */
3093 switch (data
[offset
]) {
3094 case WPA_CIPHER_NONE
:
3097 case WPA_CIPHER_WEP_40
:
3098 case WPA_CIPHER_WEP_104
:
3101 case WPA_CIPHER_TKIP
:
3102 gval
= TKIP_ENABLED
;
3104 case WPA_CIPHER_AES_CCM
:
3109 brcmf_err("Invalid multi cast cipher info\n");
3114 /* walk thru unicast cipher list and pick up what we recognize */
3115 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3116 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3117 /* Check for unicast suite(s) */
3118 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3120 brcmf_err("no unicast cipher suite\n");
3123 for (i
= 0; i
< count
; i
++) {
3124 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3126 brcmf_err("ivalid OUI\n");
3129 offset
+= TLV_OUI_LEN
;
3130 switch (data
[offset
]) {
3131 case WPA_CIPHER_NONE
:
3133 case WPA_CIPHER_WEP_40
:
3134 case WPA_CIPHER_WEP_104
:
3135 pval
|= WEP_ENABLED
;
3137 case WPA_CIPHER_TKIP
:
3138 pval
|= TKIP_ENABLED
;
3140 case WPA_CIPHER_AES_CCM
:
3141 pval
|= AES_ENABLED
;
3144 brcmf_err("Ivalid unicast security info\n");
3148 /* walk thru auth management suite list and pick up what we recognize */
3149 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3150 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3151 /* Check for auth key management suite(s) */
3152 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3154 brcmf_err("no auth key mgmt suite\n");
3157 for (i
= 0; i
< count
; i
++) {
3158 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3160 brcmf_err("ivalid OUI\n");
3163 offset
+= TLV_OUI_LEN
;
3164 switch (data
[offset
]) {
3166 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
3167 wpa_auth
|= WPA_AUTH_NONE
;
3169 case RSN_AKM_UNSPECIFIED
:
3170 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
3171 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3172 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3175 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
3176 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3177 (wpa_auth
|= WPA_AUTH_PSK
);
3180 brcmf_err("Ivalid key mgmt info\n");
3186 wme_bss_disable
= 1;
3187 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3188 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3189 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3190 wme_bss_disable
= 0;
3192 /* set wme_bss_disable to sync RSN Capabilities */
3193 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3196 brcmf_err("wme_bss_disable error %d\n", err
);
3200 /* FOR WPS , set SES_OW_ENABLED */
3201 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3204 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3206 brcmf_err("auth error %d\n", err
);
3210 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3212 brcmf_err("wsec error %d\n", err
);
3215 /* set upper-layer auth */
3216 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3218 brcmf_err("wpa_auth error %d\n", err
);
3227 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3228 struct parsed_vndr_ies
*vndr_ies
)
3231 struct brcmf_vs_tlv
*vndrie
;
3232 struct brcmf_tlv
*ie
;
3233 struct parsed_vndr_ie_info
*parsed_info
;
3236 remaining_len
= (s32
)vndr_ie_len
;
3237 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3239 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3241 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3243 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3244 /* len should be bigger than OUI length + one */
3245 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3246 brcmf_err("invalid vndr ie. length is too small %d\n",
3250 /* if wpa or wme ie, do not add ie */
3251 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3252 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3253 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3254 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
3258 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3260 /* save vndr ie information */
3261 parsed_info
->ie_ptr
= (char *)vndrie
;
3262 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3263 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3267 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
3268 parsed_info
->vndrie
.oui
[0],
3269 parsed_info
->vndrie
.oui
[1],
3270 parsed_info
->vndrie
.oui
[2],
3271 parsed_info
->vndrie
.oui_type
);
3273 if (vndr_ies
->count
>= VNDR_IE_PARSE_LIMIT
)
3276 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
3277 if (remaining_len
<= TLV_HDR_LEN
)
3280 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
3287 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3293 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3294 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3296 iecount_le
= cpu_to_le32(1);
3297 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3299 pktflag_le
= cpu_to_le32(pktflag
);
3300 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3302 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3304 return ie_len
+ VNDR_IE_HDR_SIZE
;
3307 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
3308 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3310 struct brcmf_if
*ifp
;
3311 struct vif_saved_ie
*saved_ie
;
3315 u8
*mgmt_ie_buf
= NULL
;
3316 int mgmt_ie_buf_len
;
3318 u32 del_add_ie_buf_len
= 0;
3319 u32 total_ie_buf_len
= 0;
3320 u32 parsed_ie_buf_len
= 0;
3321 struct parsed_vndr_ies old_vndr_ies
;
3322 struct parsed_vndr_ies new_vndr_ies
;
3323 struct parsed_vndr_ie_info
*vndrie_info
;
3326 int remained_buf_len
;
3331 saved_ie
= &vif
->saved_ie
;
3333 brcmf_dbg(TRACE
, "bssidx %d, pktflag : 0x%02X\n", ifp
->bssidx
, pktflag
);
3334 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3337 curr_ie_buf
= iovar_ie_buf
;
3338 if (ifp
->vif
->mode
== WL_MODE_AP
) {
3340 case BRCMF_VNDR_IE_PRBRSP_FLAG
:
3341 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
3342 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
3343 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
3345 case BRCMF_VNDR_IE_BEACON_FLAG
:
3346 mgmt_ie_buf
= saved_ie
->beacon_ie
;
3347 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
3348 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
3352 brcmf_err("not suitable type\n");
3357 case BRCMF_VNDR_IE_PRBREQ_FLAG
:
3358 mgmt_ie_buf
= saved_ie
->probe_req_ie
;
3359 mgmt_ie_len
= &saved_ie
->probe_req_ie_len
;
3360 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_req_ie
);
3364 brcmf_err("not suitable type\n");
3369 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3371 brcmf_err("extra IE size too big\n");
3375 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3376 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3378 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3379 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3380 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3381 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3382 vndrie_info
->ie_len
);
3383 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3387 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
3388 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3389 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3390 parsed_ie_buf_len
) == 0)) {
3391 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
3395 /* parse old vndr_ie */
3396 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3398 /* make a command to delete old ie */
3399 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3400 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3402 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3403 vndrie_info
->vndrie
.id
,
3404 vndrie_info
->vndrie
.len
,
3405 vndrie_info
->vndrie
.oui
[0],
3406 vndrie_info
->vndrie
.oui
[1],
3407 vndrie_info
->vndrie
.oui
[2]);
3409 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3410 vndrie_info
->ie_ptr
,
3411 vndrie_info
->ie_len
,
3413 curr_ie_buf
+= del_add_ie_buf_len
;
3414 total_ie_buf_len
+= del_add_ie_buf_len
;
3419 /* Add if there is any extra IE */
3420 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3423 remained_buf_len
= mgmt_ie_buf_len
;
3425 /* make a command to add new ie */
3426 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3427 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3429 /* verify remained buf size before copy data */
3430 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
3431 VNDR_IE_VSIE_OFFSET
)) {
3432 brcmf_err("no space in mgmt_ie_buf: len left %d",
3436 remained_buf_len
-= (vndrie_info
->ie_len
+
3437 VNDR_IE_VSIE_OFFSET
);
3439 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3440 vndrie_info
->vndrie
.id
,
3441 vndrie_info
->vndrie
.len
,
3442 vndrie_info
->vndrie
.oui
[0],
3443 vndrie_info
->vndrie
.oui
[1],
3444 vndrie_info
->vndrie
.oui
[2]);
3446 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3447 vndrie_info
->ie_ptr
,
3448 vndrie_info
->ie_len
,
3451 /* save the parsed IE in wl struct */
3452 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3453 vndrie_info
->ie_len
);
3454 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3456 curr_ie_buf
+= del_add_ie_buf_len
;
3457 total_ie_buf_len
+= del_add_ie_buf_len
;
3460 if (total_ie_buf_len
) {
3461 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
3464 brcmf_err("vndr ie set error : %d\n", err
);
3468 kfree(iovar_ie_buf
);
3473 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3474 struct cfg80211_ap_settings
*settings
)
3477 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3478 struct brcmf_tlv
*ssid_ie
;
3479 struct brcmf_ssid_le ssid_le
;
3481 struct brcmf_tlv
*rsn_ie
;
3482 struct brcmf_vs_tlv
*wpa_ie
;
3483 struct brcmf_join_params join_params
;
3485 brcmf_dbg(TRACE
, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3486 cfg80211_get_chandef_type(&settings
->chandef
),
3487 settings
->beacon_interval
,
3488 settings
->dtim_period
);
3489 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3490 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3491 settings
->inactivity_timeout
);
3493 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
)) {
3494 brcmf_err("Not in AP creation mode\n");
3498 memset(&ssid_le
, 0, sizeof(ssid_le
));
3499 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3500 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3501 ssid_ie
= brcmf_parse_tlvs(
3502 (u8
*)&settings
->beacon
.head
[ie_offset
],
3503 settings
->beacon
.head_len
- ie_offset
,
3508 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3509 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3510 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
3512 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3513 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3516 brcmf_set_mpc(ndev
, 0);
3517 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3519 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
3522 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3524 brcmf_err("SET INFRA error %d\n", err
);
3527 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3529 brcmf_err("setting AP mode failed %d\n", err
);
3533 /* find the RSN_IE */
3534 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3535 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3537 /* find the WPA_IE */
3538 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3539 settings
->beacon
.tail_len
);
3541 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3542 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
3543 if (wpa_ie
!= NULL
) {
3545 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false);
3550 err
= brcmf_configure_wpaie(ndev
,
3551 (struct brcmf_vs_tlv
*)rsn_ie
, true);
3556 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
3557 brcmf_configure_opensecurity(ifp
);
3559 /* Set Beacon IEs to FW */
3560 err
= brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev
),
3561 BRCMF_VNDR_IE_BEACON_FLAG
,
3562 settings
->beacon
.tail
,
3563 settings
->beacon
.tail_len
);
3565 brcmf_err("Set Beacon IE Failed\n");
3567 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
3569 /* Set Probe Response IEs to FW */
3570 err
= brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev
),
3571 BRCMF_VNDR_IE_PRBRSP_FLAG
,
3572 settings
->beacon
.proberesp_ies
,
3573 settings
->beacon
.proberesp_ies_len
);
3575 brcmf_err("Set Probe Resp IE Failed\n");
3577 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
3579 if (settings
->beacon_interval
) {
3580 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
3581 settings
->beacon_interval
);
3583 brcmf_err("Beacon Interval Set Error, %d\n", err
);
3587 if (settings
->dtim_period
) {
3588 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
3589 settings
->dtim_period
);
3591 brcmf_err("DTIM Interval Set Error, %d\n", err
);
3595 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
3597 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
3599 brcmf_fil_iovar_int_set(ifp
, "apsta", 0);
3602 memset(&join_params
, 0, sizeof(join_params
));
3603 /* join parameters starts with ssid */
3604 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
3606 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3607 &join_params
, sizeof(join_params
));
3609 brcmf_err("SET SSID error (%d)\n", err
);
3612 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3613 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3617 brcmf_set_mpc(ndev
, 1);
3621 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3623 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3626 brcmf_dbg(TRACE
, "Enter\n");
3628 if (ifp
->vif
->mode
== WL_MODE_AP
) {
3629 /* Due to most likely deauths outstanding we sleep */
3630 /* first to make sure they get processed by fw. */
3632 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
3634 brcmf_err("setting AP mode failed %d\n", err
);
3637 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
3639 brcmf_err("BRCMF_C_UP error %d\n", err
);
3642 brcmf_set_mpc(ndev
, 1);
3643 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3644 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3651 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3654 struct brcmf_scb_val_le scbval
;
3655 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3661 brcmf_dbg(TRACE
, "Enter %pM\n", mac
);
3663 if (!check_vif_up(ifp
->vif
))
3666 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
3667 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
3668 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
3669 &scbval
, sizeof(scbval
));
3671 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
3673 brcmf_dbg(TRACE
, "Exit\n");
3677 static struct cfg80211_ops wl_cfg80211_ops
= {
3678 .add_virtual_intf
= brcmf_cfg80211_add_iface
,
3679 .del_virtual_intf
= brcmf_cfg80211_del_iface
,
3680 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
3681 .scan
= brcmf_cfg80211_scan
,
3682 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
3683 .join_ibss
= brcmf_cfg80211_join_ibss
,
3684 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
3685 .get_station
= brcmf_cfg80211_get_station
,
3686 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
3687 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
3688 .add_key
= brcmf_cfg80211_add_key
,
3689 .del_key
= brcmf_cfg80211_del_key
,
3690 .get_key
= brcmf_cfg80211_get_key
,
3691 .set_default_key
= brcmf_cfg80211_config_default_key
,
3692 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
3693 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
3694 .connect
= brcmf_cfg80211_connect
,
3695 .disconnect
= brcmf_cfg80211_disconnect
,
3696 .suspend
= brcmf_cfg80211_suspend
,
3697 .resume
= brcmf_cfg80211_resume
,
3698 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
3699 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
3700 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
3701 .start_ap
= brcmf_cfg80211_start_ap
,
3702 .stop_ap
= brcmf_cfg80211_stop_ap
,
3703 .del_station
= brcmf_cfg80211_del_station
,
3704 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
3705 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
3706 #ifdef CONFIG_NL80211_TESTMODE
3707 .testmode_cmd
= brcmf_cfg80211_testmode
3711 static s32
brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type
)
3714 case NL80211_IFTYPE_AP_VLAN
:
3715 case NL80211_IFTYPE_WDS
:
3716 case NL80211_IFTYPE_MONITOR
:
3717 case NL80211_IFTYPE_MESH_POINT
:
3719 case NL80211_IFTYPE_ADHOC
:
3720 return WL_MODE_IBSS
;
3721 case NL80211_IFTYPE_STATION
:
3722 case NL80211_IFTYPE_P2P_CLIENT
:
3724 case NL80211_IFTYPE_AP
:
3725 case NL80211_IFTYPE_P2P_GO
:
3727 case NL80211_IFTYPE_P2P_DEVICE
:
3729 case NL80211_IFTYPE_UNSPECIFIED
:
3737 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
3739 /* scheduled scan settings */
3740 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
3741 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
3742 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
3743 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
3746 static const struct ieee80211_iface_limit brcmf_iface_limits
[] = {
3749 .types
= BIT(NL80211_IFTYPE_STATION
) |
3750 BIT(NL80211_IFTYPE_ADHOC
) |
3751 BIT(NL80211_IFTYPE_AP
)
3755 .types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
3756 BIT(NL80211_IFTYPE_P2P_GO
)
3759 static const struct ieee80211_iface_combination brcmf_iface_combos
[] = {
3761 .max_interfaces
= BRCMF_IFACE_MAX_CNT
- 1,
3762 .num_different_channels
= 1, /* no multi-channel for now */
3763 .n_limits
= ARRAY_SIZE(brcmf_iface_limits
),
3764 .limits
= brcmf_iface_limits
3768 static struct wiphy
*brcmf_setup_wiphy(struct device
*phydev
)
3770 struct wiphy
*wiphy
;
3773 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
3775 brcmf_err("Could not allocate wiphy device\n");
3776 return ERR_PTR(-ENOMEM
);
3778 set_wiphy_dev(wiphy
, phydev
);
3779 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
3780 wiphy
->max_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
3781 wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
3782 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
3783 BIT(NL80211_IFTYPE_ADHOC
) |
3784 BIT(NL80211_IFTYPE_AP
) |
3785 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
3786 BIT(NL80211_IFTYPE_P2P_GO
);
3787 wiphy
->iface_combinations
= brcmf_iface_combos
;
3788 wiphy
->n_iface_combinations
= ARRAY_SIZE(brcmf_iface_combos
);
3789 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
3790 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
3791 * it as 11a by default.
3792 * This will be updated with
3795 * if phy has 11n capability
3797 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
3798 wiphy
->cipher_suites
= __wl_cipher_suites
;
3799 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
3800 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
3804 brcmf_wiphy_pno_params(wiphy
);
3805 err
= wiphy_register(wiphy
);
3807 brcmf_err("Could not register wiphy device (%d)\n", err
);
3809 return ERR_PTR(err
);
3814 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
3815 enum nl80211_iftype type
,
3818 struct brcmf_cfg80211_vif
*vif
;
3820 if (cfg
->vif_cnt
== BRCMF_IFACE_MAX_CNT
)
3821 return ERR_PTR(-ENOSPC
);
3823 brcmf_dbg(TRACE
, "allocating virtual interface (size=%d)\n",
3825 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
3827 return ERR_PTR(-ENOMEM
);
3829 vif
->wdev
.wiphy
= cfg
->wiphy
;
3830 vif
->wdev
.iftype
= type
;
3832 vif
->mode
= brcmf_nl80211_iftype_to_mode(type
);
3833 vif
->pm_block
= pm_block
;
3836 brcmf_init_prof(&vif
->profile
);
3838 list_add_tail(&vif
->list
, &cfg
->vif_list
);
3843 void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
3845 struct brcmf_cfg80211_info
*cfg
;
3846 struct wiphy
*wiphy
;
3848 wiphy
= vif
->wdev
.wiphy
;
3849 cfg
= wiphy_priv(wiphy
);
3850 list_del(&vif
->list
);
3854 if (!cfg
->vif_cnt
) {
3855 wiphy_unregister(wiphy
);
3860 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
3862 u32 event
= e
->event_code
;
3863 u32 status
= e
->status
;
3865 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
3866 brcmf_dbg(CONN
, "Processing set ssid\n");
3873 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
3875 u32 event
= e
->event_code
;
3876 u16 flags
= e
->flags
;
3878 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
3879 brcmf_dbg(CONN
, "Processing link down\n");
3885 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
3886 const struct brcmf_event_msg
*e
)
3888 u32 event
= e
->event_code
;
3889 u32 status
= e
->status
;
3891 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
3892 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
3893 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
3897 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
3898 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
3905 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
3907 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3909 kfree(conn_info
->req_ie
);
3910 conn_info
->req_ie
= NULL
;
3911 conn_info
->req_ie_len
= 0;
3912 kfree(conn_info
->resp_ie
);
3913 conn_info
->resp_ie
= NULL
;
3914 conn_info
->resp_ie_len
= 0;
3917 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
3919 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
3920 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
3921 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3926 brcmf_clear_assoc_ies(cfg
);
3928 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
3929 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
3931 brcmf_err("could not get assoc info (%d)\n", err
);
3935 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
3936 req_len
= le32_to_cpu(assoc_info
->req_len
);
3937 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
3939 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
3943 brcmf_err("could not get assoc req (%d)\n", err
);
3946 conn_info
->req_ie_len
= req_len
;
3948 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
3951 conn_info
->req_ie_len
= 0;
3952 conn_info
->req_ie
= NULL
;
3955 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
3959 brcmf_err("could not get assoc resp (%d)\n", err
);
3962 conn_info
->resp_ie_len
= resp_len
;
3963 conn_info
->resp_ie
=
3964 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
3967 conn_info
->resp_ie_len
= 0;
3968 conn_info
->resp_ie
= NULL
;
3970 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
3971 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
3977 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
3978 struct net_device
*ndev
,
3979 const struct brcmf_event_msg
*e
)
3981 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3982 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
3983 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3984 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
3985 struct ieee80211_channel
*notify_channel
= NULL
;
3986 struct ieee80211_supported_band
*band
;
3987 struct brcmf_bss_info_le
*bi
;
3993 brcmf_dbg(TRACE
, "Enter\n");
3995 brcmf_get_assoc_ies(cfg
);
3996 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
3997 brcmf_update_bss_info(cfg
);
3999 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4005 /* data sent to dongle has to be little endian */
4006 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
4007 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
4008 buf
, WL_BSS_INFO_MAX
);
4013 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
4014 target_channel
= bi
->ctl_ch
? bi
->ctl_ch
:
4015 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
4017 if (target_channel
<= CH_MAX_2G_CHANNEL
)
4018 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
4020 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
4022 freq
= ieee80211_channel_to_frequency(target_channel
, band
->band
);
4023 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
4027 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
4028 conn_info
->req_ie
, conn_info
->req_ie_len
,
4029 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
4030 brcmf_dbg(CONN
, "Report roaming result\n");
4032 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
4033 brcmf_dbg(TRACE
, "Exit\n");
4038 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
4039 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
4042 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4043 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4044 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4047 brcmf_dbg(TRACE
, "Enter\n");
4049 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4050 &ifp
->vif
->sme_state
)) {
4052 brcmf_get_assoc_ies(cfg
);
4053 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4054 brcmf_update_bss_info(cfg
);
4056 cfg80211_connect_result(ndev
,
4057 (u8
*)profile
->bssid
,
4059 conn_info
->req_ie_len
,
4061 conn_info
->resp_ie_len
,
4062 completed
? WLAN_STATUS_SUCCESS
:
4063 WLAN_STATUS_AUTH_TIMEOUT
,
4066 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4067 &ifp
->vif
->sme_state
);
4068 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
4069 completed
? "succeeded" : "failed");
4071 brcmf_dbg(TRACE
, "Exit\n");
4076 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
4077 struct net_device
*ndev
,
4078 const struct brcmf_event_msg
*e
, void *data
)
4080 static int generation
;
4081 u32 event
= e
->event_code
;
4082 u32 reason
= e
->reason
;
4083 struct station_info sinfo
;
4085 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
4087 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4088 (reason
== BRCMF_E_STATUS_SUCCESS
)) {
4089 memset(&sinfo
, 0, sizeof(sinfo
));
4090 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4092 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4095 sinfo
.assoc_req_ies
= data
;
4096 sinfo
.assoc_req_ies_len
= e
->datalen
;
4098 sinfo
.generation
= generation
;
4099 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_KERNEL
);
4100 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4101 (event
== BRCMF_E_DEAUTH_IND
) ||
4102 (event
== BRCMF_E_DEAUTH
)) {
4103 cfg80211_del_sta(ndev
, e
->addr
, GFP_KERNEL
);
4109 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
4110 const struct brcmf_event_msg
*e
, void *data
)
4112 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4113 struct net_device
*ndev
= ifp
->ndev
;
4114 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4117 if (ifp
->vif
->mode
== WL_MODE_AP
) {
4118 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4119 } else if (brcmf_is_linkup(e
)) {
4120 brcmf_dbg(CONN
, "Linkup\n");
4121 if (brcmf_is_ibssmode(ifp
->vif
)) {
4122 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4123 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4124 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
4125 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4126 &ifp
->vif
->sme_state
);
4127 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4128 &ifp
->vif
->sme_state
);
4130 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4131 } else if (brcmf_is_linkdown(e
)) {
4132 brcmf_dbg(CONN
, "Linkdown\n");
4133 if (!brcmf_is_ibssmode(ifp
->vif
)) {
4134 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4135 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
,
4136 &ifp
->vif
->sme_state
))
4137 cfg80211_disconnected(ndev
, 0, NULL
, 0,
4140 brcmf_link_down(ifp
->vif
);
4141 brcmf_init_prof(ndev_to_prof(ndev
));
4142 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4143 if (brcmf_is_ibssmode(ifp
->vif
))
4144 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4145 &ifp
->vif
->sme_state
);
4147 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4154 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
4155 const struct brcmf_event_msg
*e
, void *data
)
4157 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4159 u32 event
= e
->event_code
;
4160 u32 status
= e
->status
;
4162 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4163 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
4164 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
4166 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
4173 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
4174 const struct brcmf_event_msg
*e
, void *data
)
4176 u16 flags
= e
->flags
;
4177 enum nl80211_key_type key_type
;
4179 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4180 key_type
= NL80211_KEYTYPE_GROUP
;
4182 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4184 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
4190 static s32
brcmf_notify_vif_event(struct brcmf_if
*ifp
,
4191 const struct brcmf_event_msg
*e
, void *data
)
4193 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4194 struct brcmf_if_event
*ifevent
= (struct brcmf_if_event
*)data
;
4195 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4196 struct brcmf_cfg80211_vif
*vif
;
4198 brcmf_dbg(TRACE
, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4199 ifevent
->action
, ifevent
->flags
, ifevent
->ifidx
,
4203 mutex_lock(&event
->vif_event_lock
);
4204 event
->action
= ifevent
->action
;
4207 switch (ifevent
->action
) {
4208 case BRCMF_E_IF_ADD
:
4209 /* waiting process may have timed out */
4210 if (!cfg
->vif_event
.vif
)
4215 vif
->wdev
.netdev
= ifp
->ndev
;
4216 ifp
->ndev
->ieee80211_ptr
= &vif
->wdev
;
4217 SET_NETDEV_DEV(ifp
->ndev
, wiphy_dev(cfg
->wiphy
));
4218 mutex_unlock(&event
->vif_event_lock
);
4219 wake_up(&event
->vif_wq
);
4221 /* waiting process need to set the netdev name */
4222 wait_for_completion(&event
->vif_complete
);
4223 return brcmf_net_attach(ifp
);
4225 case BRCMF_E_IF_DEL
:
4227 brcmf_free_vif(vif
);
4228 mutex_unlock(&event
->vif_event_lock
);
4229 /* event may not be upon user request */
4230 if (brcmf_cfg80211_vif_event_armed(cfg
))
4231 wake_up(&event
->vif_wq
);
4235 mutex_unlock(&event
->vif_event_lock
);
4241 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4243 conf
->frag_threshold
= (u32
)-1;
4244 conf
->rts_threshold
= (u32
)-1;
4245 conf
->retry_short
= (u32
)-1;
4246 conf
->retry_long
= (u32
)-1;
4247 conf
->tx_power
= -1;
4250 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
4252 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
4253 brcmf_notify_connect_status
);
4254 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
4255 brcmf_notify_connect_status
);
4256 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
4257 brcmf_notify_connect_status
);
4258 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
4259 brcmf_notify_connect_status
);
4260 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
4261 brcmf_notify_connect_status
);
4262 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
4263 brcmf_notify_connect_status
);
4264 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
4265 brcmf_notify_roaming_status
);
4266 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
4267 brcmf_notify_mic_status
);
4268 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
4269 brcmf_notify_connect_status
);
4270 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
4271 brcmf_notify_sched_scan_results
);
4272 brcmf_fweh_register(cfg
->pub
, BRCMF_E_IF
,
4273 brcmf_notify_vif_event
);
4276 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4280 kfree(cfg
->escan_ioctl_buf
);
4281 cfg
->escan_ioctl_buf
= NULL
;
4282 kfree(cfg
->extra_buf
);
4283 cfg
->extra_buf
= NULL
;
4284 kfree(cfg
->pmk_list
);
4285 cfg
->pmk_list
= NULL
;
4288 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4290 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4292 goto init_priv_mem_out
;
4293 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4294 if (!cfg
->escan_ioctl_buf
)
4295 goto init_priv_mem_out
;
4296 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4297 if (!cfg
->extra_buf
)
4298 goto init_priv_mem_out
;
4299 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4301 goto init_priv_mem_out
;
4306 brcmf_deinit_priv_mem(cfg
);
4311 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4315 cfg
->scan_request
= NULL
;
4316 cfg
->pwr_save
= true;
4317 cfg
->roam_on
= true; /* roam on & off switch.
4318 we enable roam per default */
4319 cfg
->active_scan
= true; /* we do active scan for
4320 specific scan per default */
4321 cfg
->dongle_up
= false; /* dongle is not up yet */
4322 err
= brcmf_init_priv_mem(cfg
);
4325 brcmf_register_event_handlers(cfg
);
4326 mutex_init(&cfg
->usr_sync
);
4327 brcmf_init_escan(cfg
);
4328 brcmf_init_conf(cfg
->conf
);
4333 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4335 cfg
->dongle_up
= false; /* dongle down */
4336 brcmf_abort_scanning(cfg
);
4337 brcmf_deinit_priv_mem(cfg
);
4340 static void init_vif_event(struct brcmf_cfg80211_vif_event
*event
)
4342 init_waitqueue_head(&event
->vif_wq
);
4343 init_completion(&event
->vif_complete
);
4344 mutex_init(&event
->vif_event_lock
);
4347 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
4348 struct device
*busdev
)
4350 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4351 struct brcmf_cfg80211_info
*cfg
;
4352 struct wiphy
*wiphy
;
4353 struct brcmf_cfg80211_vif
*vif
;
4354 struct brcmf_if
*ifp
;
4358 brcmf_err("ndev is invalid\n");
4362 ifp
= netdev_priv(ndev
);
4363 wiphy
= brcmf_setup_wiphy(busdev
);
4367 cfg
= wiphy_priv(wiphy
);
4370 init_vif_event(&cfg
->vif_event
);
4371 INIT_LIST_HEAD(&cfg
->vif_list
);
4373 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_STATION
, false);
4380 vif
->wdev
.netdev
= ndev
;
4381 ndev
->ieee80211_ptr
= &vif
->wdev
;
4382 SET_NETDEV_DEV(ndev
, wiphy_dev(cfg
->wiphy
));
4384 err
= wl_init_priv(cfg
);
4386 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
4387 goto cfg80211_attach_out
;
4389 brcmf_p2p_attach(cfg
);
4394 cfg80211_attach_out
:
4395 brcmf_free_vif(vif
);
4400 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
4402 struct brcmf_cfg80211_vif
*vif
;
4403 struct brcmf_cfg80211_vif
*tmp
;
4405 wl_deinit_priv(cfg
);
4406 list_for_each_entry_safe(vif
, tmp
, &cfg
->vif_list
, list
) {
4407 brcmf_free_vif(vif
);
4412 brcmf_dongle_roam(struct brcmf_if
*ifp
, u32 roamvar
, u32 bcn_timeout
)
4415 __le32 roamtrigger
[2];
4416 __le32 roam_delta
[2];
4419 * Setup timeout if Beacons are lost and roam is
4420 * off to report link down
4423 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
4425 brcmf_err("bcn_timeout error (%d)\n", err
);
4426 goto dongle_rom_out
;
4431 * Enable/Disable built-in roaming to allow supplicant
4432 * to take care of roaming
4434 brcmf_dbg(INFO
, "Internal Roaming = %s\n", roamvar
? "Off" : "On");
4435 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", roamvar
);
4437 brcmf_err("roam_off error (%d)\n", err
);
4438 goto dongle_rom_out
;
4441 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
4442 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4443 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
4444 (void *)roamtrigger
, sizeof(roamtrigger
));
4446 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
4447 goto dongle_rom_out
;
4450 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
4451 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4452 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
4453 (void *)roam_delta
, sizeof(roam_delta
));
4455 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
4456 goto dongle_rom_out
;
4464 brcmf_dongle_scantime(struct brcmf_if
*ifp
, s32 scan_assoc_time
,
4465 s32 scan_unassoc_time
, s32 scan_passive_time
)
4469 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
4472 if (err
== -EOPNOTSUPP
)
4473 brcmf_dbg(INFO
, "Scan assoc time is not supported\n");
4475 brcmf_err("Scan assoc time error (%d)\n", err
);
4476 goto dongle_scantime_out
;
4478 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
4481 if (err
== -EOPNOTSUPP
)
4482 brcmf_dbg(INFO
, "Scan unassoc time is not supported\n");
4484 brcmf_err("Scan unassoc time error (%d)\n", err
);
4485 goto dongle_scantime_out
;
4488 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
4491 if (err
== -EOPNOTSUPP
)
4492 brcmf_dbg(INFO
, "Scan passive time is not supported\n");
4494 brcmf_err("Scan passive time error (%d)\n", err
);
4495 goto dongle_scantime_out
;
4498 dongle_scantime_out
:
4502 static s32
wl_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
4504 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
4505 struct wiphy
*wiphy
;
4510 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_PHYLIST
,
4511 &phy_list
, sizeof(phy_list
));
4513 brcmf_err("error (%d)\n", err
);
4517 phy
= ((char *)&phy_list
)[0];
4518 brcmf_dbg(INFO
, "%c phy\n", phy
);
4519 if (phy
== 'n' || phy
== 'a') {
4520 wiphy
= cfg_to_wiphy(cfg
);
4521 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
4527 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
4529 return wl_update_wiphybands(cfg
);
4532 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
4534 struct net_device
*ndev
;
4535 struct wireless_dev
*wdev
;
4536 struct brcmf_if
*ifp
;
4543 ndev
= cfg_to_ndev(cfg
);
4544 wdev
= ndev
->ieee80211_ptr
;
4545 ifp
= netdev_priv(ndev
);
4547 /* make sure RF is ready for work */
4548 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
4550 brcmf_dongle_scantime(ifp
, WL_SCAN_CHANNEL_TIME
,
4551 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
4553 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
4554 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
4556 goto default_conf_out
;
4557 brcmf_dbg(INFO
, "power save set to %s\n",
4558 (power_mode
? "enabled" : "disabled"));
4560 err
= brcmf_dongle_roam(ifp
, (cfg
->roam_on
? 0 : 1), WL_BEACON_TIMEOUT
);
4562 goto default_conf_out
;
4563 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
4566 goto default_conf_out
;
4567 err
= brcmf_dongle_probecap(cfg
);
4569 goto default_conf_out
;
4571 cfg
->dongle_up
= true;
4578 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
4580 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
4582 return brcmf_config_dongle(ifp
->drvr
->config
);
4585 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
4587 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4590 * While going down, if associated with AP disassociate
4591 * from AP to save power
4593 if (check_vif_up(ifp
->vif
)) {
4594 brcmf_link_down(ifp
->vif
);
4596 /* Make sure WPA_Supplicant receives all the event
4597 generated due to DISASSOC call to the fw to keep
4598 the state fw and WPA_Supplicant state consistent
4603 brcmf_abort_scanning(cfg
);
4604 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
4609 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
4611 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4612 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4615 mutex_lock(&cfg
->usr_sync
);
4616 err
= __brcmf_cfg80211_up(ifp
);
4617 mutex_unlock(&cfg
->usr_sync
);
4622 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
4624 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4625 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4628 mutex_lock(&cfg
->usr_sync
);
4629 err
= __brcmf_cfg80211_down(ifp
);
4630 mutex_unlock(&cfg
->usr_sync
);
4635 u32
wl_get_vif_state_all(struct brcmf_cfg80211_info
*cfg
, unsigned long state
)
4637 struct brcmf_cfg80211_vif
*vif
;
4640 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
4641 if (test_bit(state
, &vif
->sme_state
))
4647 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event
*event
,
4652 mutex_lock(&event
->vif_event_lock
);
4653 evt_action
= event
->action
;
4654 mutex_unlock(&event
->vif_event_lock
);
4655 return evt_action
== action
;
4658 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info
*cfg
,
4659 struct brcmf_cfg80211_vif
*vif
)
4661 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4663 mutex_lock(&event
->vif_event_lock
);
4666 mutex_unlock(&event
->vif_event_lock
);
4669 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info
*cfg
)
4671 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4674 mutex_lock(&event
->vif_event_lock
);
4675 armed
= event
->vif
!= NULL
;
4676 mutex_unlock(&event
->vif_event_lock
);
4680 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info
*cfg
,
4681 u8 action
, ulong timeout
)
4683 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4685 return wait_event_timeout(event
->vif_wq
,
4686 vif_event_equals(event
, action
), timeout
);
4689 void brcmf_cfg80211_vif_complete(struct brcmf_cfg80211_info
*cfg
)
4691 complete(&cfg
->vif_event
.vif_complete
);