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 #include <linux/kernel.h>
18 #include <linux/if_arp.h>
19 #include <linux/sched.h>
20 #include <linux/kthread.h>
21 #include <linux/netdevice.h>
22 #include <linux/sched.h>
23 #include <linux/bitops.h>
24 #include <linux/etherdevice.h>
25 #include <linux/ieee80211.h>
26 #include <linux/mmc/sdio_func.h>
27 #include <linux/uaccess.h>
28 #include <net/cfg80211.h>
29 #include <net/rtnetlink.h>
31 #include <brcmu_utils.h>
33 #include <brcmu_wifi.h>
35 #include "wl_cfg80211.h"
37 static struct sdio_func
*cfg80211_sdio_func
;
38 static struct brcmf_cfg80211_dev
*cfg80211_dev
;
39 static const u8 ether_bcast
[ETH_ALEN
] = {255, 255, 255, 255, 255, 255};
41 u32 brcmf_dbg_level
= WL_DBG_ERR
;
44 ** cfg80211_ops api/callback list
46 static s32
brcmf_cfg80211_change_iface(struct wiphy
*wiphy
,
47 struct net_device
*ndev
,
48 enum nl80211_iftype type
, u32
*flags
,
49 struct vif_params
*params
);
50 static s32
__brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
51 struct cfg80211_scan_request
*request
,
52 struct cfg80211_ssid
*this_ssid
);
53 static s32
brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
54 struct cfg80211_scan_request
*request
);
55 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
);
56 static s32
brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
57 struct cfg80211_ibss_params
*params
);
58 static s32
brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
,
59 struct net_device
*dev
);
60 static s32
brcmf_cfg80211_get_station(struct wiphy
*wiphy
,
61 struct net_device
*dev
, u8
*mac
,
62 struct station_info
*sinfo
);
63 static s32
brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
64 struct net_device
*dev
, bool enabled
,
66 static s32
brcmf_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
,
67 struct net_device
*dev
,
69 const struct cfg80211_bitrate_mask
71 static int brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
72 struct cfg80211_connect_params
*sme
);
73 static s32
brcmf_cfg80211_disconnect(struct wiphy
*wiphy
,
74 struct net_device
*dev
,
76 static s32
brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
,
77 enum nl80211_tx_power_setting type
,
79 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
);
80 static s32
brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
,
81 struct net_device
*dev
, u8 key_idx
,
82 bool unicast
, bool multicast
);
83 static s32
brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
84 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
85 struct key_params
*params
);
86 static s32
brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
87 u8 key_idx
, bool pairwise
, const u8
*mac_addr
);
88 static s32
brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
89 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
90 void *cookie
, void (*callback
) (void *cookie
,
94 static s32
brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
95 struct net_device
*dev
,
97 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
);
98 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
99 struct cfg80211_wowlan
*wow
);
100 static s32
brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
101 struct cfg80211_pmksa
*pmksa
);
102 static s32
brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
103 struct cfg80211_pmksa
*pmksa
);
104 static s32
brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
,
105 struct net_device
*dev
);
107 ** event & event Q handlers for cfg80211 interfaces
109 static s32
brcmf_create_event_handler(struct brcmf_cfg80211_priv
*cfg_priv
);
110 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv
*cfg_priv
);
111 static s32
brcmf_event_handler(void *data
);
112 static void brcmf_init_eq(struct brcmf_cfg80211_priv
*cfg_priv
);
113 static void brcmf_flush_eq(struct brcmf_cfg80211_priv
*cfg_priv
);
114 static void brcmf_lock_eq(struct brcmf_cfg80211_priv
*cfg_priv
);
115 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv
*cfg_priv
);
116 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv
*cfg_priv
);
117 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop
*el
);
118 static struct brcmf_cfg80211_event_q
*
119 brcmf_deq_event(struct brcmf_cfg80211_priv
*cfg_priv
);
120 static s32
brcmf_enq_event(struct brcmf_cfg80211_priv
*cfg_priv
, u32 type
,
121 const struct brcmf_event_msg
*msg
);
122 static void brcmf_put_event(struct brcmf_cfg80211_event_q
*e
);
123 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv
*cfg_priv
);
124 static s32
brcmf_notify_connect_status(struct brcmf_cfg80211_priv
*cfg_priv
,
125 struct net_device
*ndev
,
126 const struct brcmf_event_msg
*e
,
128 static s32
brcmf_notify_roaming_status(struct brcmf_cfg80211_priv
*cfg_priv
,
129 struct net_device
*ndev
,
130 const struct brcmf_event_msg
*e
,
132 static s32
brcmf_notify_scan_status(struct brcmf_cfg80211_priv
*cfg_priv
,
133 struct net_device
*ndev
,
134 const struct brcmf_event_msg
*e
,
136 static s32
brcmf_bss_connect_done(struct brcmf_cfg80211_priv
*cfg_priv
,
137 struct net_device
*ndev
,
138 const struct brcmf_event_msg
*e
,
140 static s32
brcmf_bss_roaming_done(struct brcmf_cfg80211_priv
*cfg_priv
,
141 struct net_device
*ndev
,
142 const struct brcmf_event_msg
*e
);
143 static s32
brcmf_notify_mic_status(struct brcmf_cfg80211_priv
*cfg_priv
,
144 struct net_device
*ndev
,
145 const struct brcmf_event_msg
*e
, void *data
);
148 ** register/deregister sdio function
150 static void brcmf_clear_sdio_func(void);
155 static s32
brcmf_dev_bufvar_get(struct net_device
*dev
, s8
*name
, s8
*buf
,
157 static __used s32
brcmf_dev_bufvar_set(struct net_device
*dev
, s8
*name
,
159 static s32
brcmf_dev_intvar_set(struct net_device
*dev
, s8
*name
, s32 val
);
160 static s32
brcmf_dev_intvar_get(struct net_device
*dev
, s8
*name
,
162 static s32
brcmf_dev_ioctl(struct net_device
*dev
, u32 cmd
, void *arg
,
166 ** cfg80211 set_wiphy_params utilities
168 static s32
brcmf_set_frag(struct net_device
*dev
, u32 frag_threshold
);
169 static s32
brcmf_set_rts(struct net_device
*dev
, u32 frag_threshold
);
170 static s32
brcmf_set_retry(struct net_device
*dev
, u32 retry
, bool l
);
173 ** wl profile utilities
175 static s32
brcmf_update_prof(struct brcmf_cfg80211_priv
*cfg_priv
,
176 const struct brcmf_event_msg
*e
,
177 void *data
, s32 item
);
178 static void *brcmf_read_prof(struct brcmf_cfg80211_priv
*cfg_priv
, s32 item
);
179 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
);
182 ** cfg80211 connect utilites
184 static s32
brcmf_set_wpa_version(struct net_device
*dev
,
185 struct cfg80211_connect_params
*sme
);
186 static s32
brcmf_set_auth_type(struct net_device
*dev
,
187 struct cfg80211_connect_params
*sme
);
188 static s32
brcmf_set_set_cipher(struct net_device
*dev
,
189 struct cfg80211_connect_params
*sme
);
190 static s32
brcmf_set_key_mgmt(struct net_device
*dev
,
191 struct cfg80211_connect_params
*sme
);
192 static s32
brcmf_set_set_sharedkey(struct net_device
*dev
,
193 struct cfg80211_connect_params
*sme
);
194 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_priv
*cfg_priv
);
195 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv
*cfg_priv
);
196 static void brcmf_ch_to_chanspec(int ch
,
197 struct brcmf_join_params
*join_params
, size_t *join_params_size
);
200 ** information element utilities
202 static __used s32
brcmf_add_ie(struct brcmf_cfg80211_priv
*cfg_priv
,
204 static s32
brcmf_mode_to_nl80211_iftype(s32 mode
);
205 static struct wireless_dev
*brcmf_alloc_wdev(s32 sizeof_iface
,
207 static void brcmf_free_wdev(struct brcmf_cfg80211_priv
*cfg_priv
);
208 static s32
brcmf_inform_bss(struct brcmf_cfg80211_priv
*cfg_priv
);
209 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_priv
*cfg_priv
,
210 struct brcmf_bss_info
*bi
);
211 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_priv
*cfg_priv
);
212 static s32
brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*dev
,
213 u8 key_idx
, const u8
*mac_addr
,
214 struct key_params
*params
);
217 ** key indianess swap utilities
219 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
);
220 static void convert_key_to_CPU(struct brcmf_wsec_key
*key
);
223 ** brcmf_cfg80211_priv memory init/deinit utilities
225 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_priv
*cfg_priv
);
226 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv
*cfg_priv
);
228 static void brcmf_delay(u32 ms
);
231 ** store/restore cfg80211 instance data
233 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev
*dev
, void *data
);
234 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev
*dev
);
237 ** ibss mode utilities
239 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv
*cfg_priv
);
242 ** dongle up/down , default configuration utilities
244 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv
*cfg_priv
,
245 const struct brcmf_event_msg
*e
);
246 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv
*cfg_priv
,
247 const struct brcmf_event_msg
*e
);
248 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv
*cfg_priv
,
249 const struct brcmf_event_msg
*e
);
250 static void brcmf_link_down(struct brcmf_cfg80211_priv
*cfg_priv
);
251 static s32
brcmf_dongle_mode(struct net_device
*ndev
, s32 iftype
);
252 static s32
__brcmf_cfg80211_up(struct brcmf_cfg80211_priv
*cfg_priv
);
253 static s32
__brcmf_cfg80211_down(struct brcmf_cfg80211_priv
*cfg_priv
);
254 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_priv
*cfg_priv
);
255 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
);
258 ** dongle configuration utilities
260 static s32
brcmf_dongle_eventmsg(struct net_device
*ndev
);
261 static s32
brcmf_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
262 s32 scan_unassoc_time
, s32 scan_passive_time
);
263 static s32
brcmf_config_dongle(struct brcmf_cfg80211_priv
*cfg_priv
,
265 static s32
brcmf_dongle_roam(struct net_device
*ndev
, u32 roamvar
,
271 static void brcmf_iscan_timer(unsigned long data
);
272 static void brcmf_term_iscan(struct brcmf_cfg80211_priv
*cfg_priv
);
273 static s32
brcmf_init_iscan(struct brcmf_cfg80211_priv
*cfg_priv
);
274 static s32
brcmf_iscan_thread(void *data
);
275 static s32
brcmf_dev_iovar_setbuf(struct net_device
*dev
, s8
*iovar
,
276 void *param
, s32 paramlen
, void *bufptr
,
278 static s32
brcmf_dev_iovar_getbuf(struct net_device
*dev
, s8
*iovar
,
279 void *param
, s32 paramlen
, void *bufptr
,
281 static s32
brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl
*iscan
,
282 struct brcmf_ssid
*ssid
, u16 action
);
283 static s32
brcmf_do_iscan(struct brcmf_cfg80211_priv
*cfg_priv
);
284 static s32
brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl
*iscan
);
285 static s32
brcmf_invoke_iscan(struct brcmf_cfg80211_priv
*cfg_priv
);
286 static s32
brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl
*iscan
,
288 struct brcmf_scan_results
**bss_list
);
289 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl
*iscan
,
291 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop
*el
);
292 static s32
brcmf_iscan_done(struct brcmf_cfg80211_priv
*cfg_priv
);
293 static s32
brcmf_iscan_pending(struct brcmf_cfg80211_priv
*cfg_priv
);
294 static s32
brcmf_iscan_inprogress(struct brcmf_cfg80211_priv
*cfg_priv
);
295 static s32
brcmf_iscan_aborted(struct brcmf_cfg80211_priv
*cfg_priv
);
298 * update pmklist to dongle
300 static __used s32
brcmf_update_pmklist(struct net_device
*dev
,
301 struct brcmf_cfg80211_pmk_list
*pmk_list
,
304 static void brcmf_set_mpc(struct net_device
*ndev
, int mpc
);
310 brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv
*cfg_priv
);
311 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv
*cfg_priv
);
313 #define WL_PRIV_GET() \
315 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg80211_dev); \
316 if (unlikely(!ci)) { \
317 WL_ERR("wl_cfg80211_dev is unavailable\n"); \
323 #define CHECK_SYS_UP() \
325 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); \
326 if (unlikely(!test_bit(WL_STATUS_READY, &cfg_priv->status))) { \
327 WL_INFO("device is not ready : status (%d)\n", \
328 (int)cfg_priv->status); \
333 #define CHAN2G(_channel, _freq, _flags) { \
334 .band = IEEE80211_BAND_2GHZ, \
335 .center_freq = (_freq), \
336 .hw_value = (_channel), \
338 .max_antenna_gain = 0, \
342 #define CHAN5G(_channel, _flags) { \
343 .band = IEEE80211_BAND_5GHZ, \
344 .center_freq = 5000 + (5 * (_channel)), \
345 .hw_value = (_channel), \
347 .max_antenna_gain = 0, \
351 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
352 #define RATETAB_ENT(_rateid, _flags) \
354 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
355 .hw_value = (_rateid), \
359 static struct ieee80211_rate __wl_rates
[] = {
360 RATETAB_ENT(BRCM_RATE_1M
, 0),
361 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
362 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
363 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
364 RATETAB_ENT(BRCM_RATE_6M
, 0),
365 RATETAB_ENT(BRCM_RATE_9M
, 0),
366 RATETAB_ENT(BRCM_RATE_12M
, 0),
367 RATETAB_ENT(BRCM_RATE_18M
, 0),
368 RATETAB_ENT(BRCM_RATE_24M
, 0),
369 RATETAB_ENT(BRCM_RATE_36M
, 0),
370 RATETAB_ENT(BRCM_RATE_48M
, 0),
371 RATETAB_ENT(BRCM_RATE_54M
, 0),
374 #define wl_a_rates (__wl_rates + 4)
375 #define wl_a_rates_size 8
376 #define wl_g_rates (__wl_rates + 0)
377 #define wl_g_rates_size 12
379 static struct ieee80211_channel __wl_2ghz_channels
[] = {
396 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
397 CHAN5G(34, 0), CHAN5G(36, 0),
398 CHAN5G(38, 0), CHAN5G(40, 0),
399 CHAN5G(42, 0), CHAN5G(44, 0),
400 CHAN5G(46, 0), CHAN5G(48, 0),
401 CHAN5G(52, 0), CHAN5G(56, 0),
402 CHAN5G(60, 0), CHAN5G(64, 0),
403 CHAN5G(100, 0), CHAN5G(104, 0),
404 CHAN5G(108, 0), CHAN5G(112, 0),
405 CHAN5G(116, 0), CHAN5G(120, 0),
406 CHAN5G(124, 0), CHAN5G(128, 0),
407 CHAN5G(132, 0), CHAN5G(136, 0),
408 CHAN5G(140, 0), CHAN5G(149, 0),
409 CHAN5G(153, 0), CHAN5G(157, 0),
410 CHAN5G(161, 0), CHAN5G(165, 0),
411 CHAN5G(184, 0), CHAN5G(188, 0),
412 CHAN5G(192, 0), CHAN5G(196, 0),
413 CHAN5G(200, 0), CHAN5G(204, 0),
414 CHAN5G(208, 0), CHAN5G(212, 0),
418 static struct ieee80211_channel __wl_5ghz_n_channels
[] = {
419 CHAN5G(32, 0), CHAN5G(34, 0),
420 CHAN5G(36, 0), CHAN5G(38, 0),
421 CHAN5G(40, 0), CHAN5G(42, 0),
422 CHAN5G(44, 0), CHAN5G(46, 0),
423 CHAN5G(48, 0), CHAN5G(50, 0),
424 CHAN5G(52, 0), CHAN5G(54, 0),
425 CHAN5G(56, 0), CHAN5G(58, 0),
426 CHAN5G(60, 0), CHAN5G(62, 0),
427 CHAN5G(64, 0), CHAN5G(66, 0),
428 CHAN5G(68, 0), CHAN5G(70, 0),
429 CHAN5G(72, 0), CHAN5G(74, 0),
430 CHAN5G(76, 0), CHAN5G(78, 0),
431 CHAN5G(80, 0), CHAN5G(82, 0),
432 CHAN5G(84, 0), CHAN5G(86, 0),
433 CHAN5G(88, 0), CHAN5G(90, 0),
434 CHAN5G(92, 0), CHAN5G(94, 0),
435 CHAN5G(96, 0), CHAN5G(98, 0),
436 CHAN5G(100, 0), CHAN5G(102, 0),
437 CHAN5G(104, 0), CHAN5G(106, 0),
438 CHAN5G(108, 0), CHAN5G(110, 0),
439 CHAN5G(112, 0), CHAN5G(114, 0),
440 CHAN5G(116, 0), CHAN5G(118, 0),
441 CHAN5G(120, 0), CHAN5G(122, 0),
442 CHAN5G(124, 0), CHAN5G(126, 0),
443 CHAN5G(128, 0), CHAN5G(130, 0),
444 CHAN5G(132, 0), CHAN5G(134, 0),
445 CHAN5G(136, 0), CHAN5G(138, 0),
446 CHAN5G(140, 0), CHAN5G(142, 0),
447 CHAN5G(144, 0), CHAN5G(145, 0),
448 CHAN5G(146, 0), CHAN5G(147, 0),
449 CHAN5G(148, 0), CHAN5G(149, 0),
450 CHAN5G(150, 0), CHAN5G(151, 0),
451 CHAN5G(152, 0), CHAN5G(153, 0),
452 CHAN5G(154, 0), CHAN5G(155, 0),
453 CHAN5G(156, 0), CHAN5G(157, 0),
454 CHAN5G(158, 0), CHAN5G(159, 0),
455 CHAN5G(160, 0), CHAN5G(161, 0),
456 CHAN5G(162, 0), CHAN5G(163, 0),
457 CHAN5G(164, 0), CHAN5G(165, 0),
458 CHAN5G(166, 0), CHAN5G(168, 0),
459 CHAN5G(170, 0), CHAN5G(172, 0),
460 CHAN5G(174, 0), CHAN5G(176, 0),
461 CHAN5G(178, 0), CHAN5G(180, 0),
462 CHAN5G(182, 0), CHAN5G(184, 0),
463 CHAN5G(186, 0), CHAN5G(188, 0),
464 CHAN5G(190, 0), CHAN5G(192, 0),
465 CHAN5G(194, 0), CHAN5G(196, 0),
466 CHAN5G(198, 0), CHAN5G(200, 0),
467 CHAN5G(202, 0), CHAN5G(204, 0),
468 CHAN5G(206, 0), CHAN5G(208, 0),
469 CHAN5G(210, 0), CHAN5G(212, 0),
470 CHAN5G(214, 0), CHAN5G(216, 0),
471 CHAN5G(218, 0), CHAN5G(220, 0),
472 CHAN5G(222, 0), CHAN5G(224, 0),
473 CHAN5G(226, 0), CHAN5G(228, 0),
476 static struct ieee80211_supported_band __wl_band_2ghz
= {
477 .band
= IEEE80211_BAND_2GHZ
,
478 .channels
= __wl_2ghz_channels
,
479 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
480 .bitrates
= wl_g_rates
,
481 .n_bitrates
= wl_g_rates_size
,
484 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
485 .band
= IEEE80211_BAND_5GHZ
,
486 .channels
= __wl_5ghz_a_channels
,
487 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
488 .bitrates
= wl_a_rates
,
489 .n_bitrates
= wl_a_rates_size
,
492 static struct ieee80211_supported_band __wl_band_5ghz_n
= {
493 .band
= IEEE80211_BAND_5GHZ
,
494 .channels
= __wl_5ghz_n_channels
,
495 .n_channels
= ARRAY_SIZE(__wl_5ghz_n_channels
),
496 .bitrates
= wl_a_rates
,
497 .n_bitrates
= wl_a_rates_size
,
500 static const u32 __wl_cipher_suites
[] = {
501 WLAN_CIPHER_SUITE_WEP40
,
502 WLAN_CIPHER_SUITE_WEP104
,
503 WLAN_CIPHER_SUITE_TKIP
,
504 WLAN_CIPHER_SUITE_CCMP
,
505 WLAN_CIPHER_SUITE_AES_CMAC
,
508 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
)
510 key
->index
= cpu_to_le32(key
->index
);
511 key
->len
= cpu_to_le32(key
->len
);
512 key
->algo
= cpu_to_le32(key
->algo
);
513 key
->flags
= cpu_to_le32(key
->flags
);
514 key
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
515 key
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
516 key
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
519 static void convert_key_to_CPU(struct brcmf_wsec_key
*key
)
521 key
->index
= le32_to_cpu(key
->index
);
522 key
->len
= le32_to_cpu(key
->len
);
523 key
->algo
= le32_to_cpu(key
->algo
);
524 key
->flags
= le32_to_cpu(key
->flags
);
525 key
->rxiv
.hi
= le32_to_cpu(key
->rxiv
.hi
);
526 key
->rxiv
.lo
= le16_to_cpu(key
->rxiv
.lo
);
527 key
->iv_initialized
= le32_to_cpu(key
->iv_initialized
);
531 brcmf_dev_ioctl(struct net_device
*dev
, u32 cmd
, void *arg
, u32 len
)
534 struct brcmf_ioctl ioc
;
538 memset(&ioc
, 0, sizeof(ioc
));
542 strcpy(ifr
.ifr_name
, dev
->name
);
543 ifr
.ifr_data
= (caddr_t
)&ioc
;
547 err
= dev
->netdev_ops
->ndo_do_ioctl(dev
, &ifr
, SIOCDEVPRIVATE
);
554 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
555 enum nl80211_iftype type
, u32
*flags
,
556 struct vif_params
*params
)
558 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
559 struct wireless_dev
*wdev
;
567 case NL80211_IFTYPE_MONITOR
:
568 case NL80211_IFTYPE_WDS
:
569 WL_ERR("type (%d) : currently we do not support this type\n",
572 case NL80211_IFTYPE_ADHOC
:
573 cfg_priv
->conf
->mode
= WL_MODE_IBSS
;
576 case NL80211_IFTYPE_STATION
:
577 cfg_priv
->conf
->mode
= WL_MODE_BSS
;
585 infra
= cpu_to_le32(infra
);
586 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_INFRA
, &infra
, sizeof(infra
));
588 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
591 wdev
= ndev
->ieee80211_ptr
;
595 WL_INFO("IF Type = %s\n",
596 (cfg_priv
->conf
->mode
== WL_MODE_IBSS
) ? "Adhoc" : "Infra");
604 static void wl_iscan_prep(struct brcmf_scan_params
*params
,
605 struct brcmf_ssid
*ssid
)
607 memcpy(params
->bssid
, ether_bcast
, ETH_ALEN
);
608 params
->bss_type
= DOT11_BSSTYPE_ANY
;
609 params
->scan_type
= 0;
610 params
->nprobes
= -1;
611 params
->active_time
= -1;
612 params
->passive_time
= -1;
613 params
->home_time
= -1;
614 params
->channel_num
= 0;
616 params
->nprobes
= cpu_to_le32(params
->nprobes
);
617 params
->active_time
= cpu_to_le32(params
->active_time
);
618 params
->passive_time
= cpu_to_le32(params
->passive_time
);
619 params
->home_time
= cpu_to_le32(params
->home_time
);
620 if (ssid
&& ssid
->SSID_len
)
621 memcpy(¶ms
->ssid
, ssid
, sizeof(struct brcmf_ssid
));
626 brcmf_dev_iovar_setbuf(struct net_device
*dev
, s8
* iovar
, void *param
,
627 s32 paramlen
, void *bufptr
, s32 buflen
)
631 iolen
= brcmu_mkiovar(iovar
, param
, paramlen
, bufptr
, buflen
);
634 return brcmf_dev_ioctl(dev
, BRCMF_C_SET_VAR
, bufptr
, iolen
);
638 brcmf_dev_iovar_getbuf(struct net_device
*dev
, s8
* iovar
, void *param
,
639 s32 paramlen
, void *bufptr
, s32 buflen
)
643 iolen
= brcmu_mkiovar(iovar
, param
, paramlen
, bufptr
, buflen
);
646 return brcmf_dev_ioctl(dev
, BRCMF_C_GET_VAR
, bufptr
, buflen
);
650 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl
*iscan
,
651 struct brcmf_ssid
*ssid
, u16 action
)
653 s32 params_size
= (BRCMF_SCAN_PARAMS_FIXED_SIZE
+
654 offsetof(struct brcmf_iscan_params
, params
));
655 struct brcmf_iscan_params
*params
;
658 if (ssid
&& ssid
->SSID_len
)
659 params_size
+= sizeof(struct brcmf_ssid
);
660 params
= kzalloc(params_size
, GFP_KERNEL
);
661 if (unlikely(!params
))
663 BUG_ON(params_size
>= BRCMF_C_IOCTL_SMLEN
);
665 wl_iscan_prep(¶ms
->params
, ssid
);
667 params
->version
= cpu_to_le32(BRCMF_ISCAN_REQ_VERSION
);
668 params
->action
= cpu_to_le16(action
);
669 params
->scan_duration
= cpu_to_le16(0);
671 /* params_size += offsetof(struct brcmf_iscan_params, params); */
672 err
= brcmf_dev_iovar_setbuf(iscan
->dev
, "iscan", params
, params_size
,
673 iscan
->ioctl_buf
, BRCMF_C_IOCTL_SMLEN
);
676 WL_INFO("system busy : iscan canceled\n");
678 WL_ERR("error (%d)\n", err
);
685 static s32
brcmf_do_iscan(struct brcmf_cfg80211_priv
*cfg_priv
)
687 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg_priv
);
688 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
689 struct brcmf_ssid ssid
;
693 /* Broadcast scan by default */
694 memset(&ssid
, 0, sizeof(ssid
));
696 iscan
->state
= WL_ISCAN_STATE_SCANING
;
698 passive_scan
= cfg_priv
->active_scan
? 0 : 1;
699 err
= brcmf_dev_ioctl(cfg_to_ndev(cfg_priv
), BRCMF_C_SET_PASSIVE_SCAN
,
700 &passive_scan
, sizeof(passive_scan
));
702 WL_ERR("error (%d)\n", err
);
705 brcmf_set_mpc(ndev
, 0);
706 cfg_priv
->iscan_kickstart
= true;
707 err
= brcmf_run_iscan(iscan
, &ssid
, BRCMF_SCAN_ACTION_START
);
709 brcmf_set_mpc(ndev
, 1);
710 cfg_priv
->iscan_kickstart
= false;
713 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
719 __brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
720 struct cfg80211_scan_request
*request
,
721 struct cfg80211_ssid
*this_ssid
)
723 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
724 struct cfg80211_ssid
*ssids
;
725 struct brcmf_cfg80211_scan_req
*sr
= cfg_priv
->scan_req_int
;
731 if (unlikely(test_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
))) {
732 WL_ERR("Scanning already : status (%lu)\n", cfg_priv
->status
);
735 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
))) {
736 WL_ERR("Scanning being aborted : status (%lu)\n",
740 if (test_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
)) {
741 WL_ERR("Connecting : status (%lu)\n",
750 ssids
= request
->ssids
;
751 if (cfg_priv
->iscan_on
&& (!ssids
|| !ssids
->ssid_len
))
755 /* we don't do iscan in ibss */
759 cfg_priv
->scan_request
= request
;
760 set_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
);
762 err
= brcmf_do_iscan(cfg_priv
);
768 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
769 ssids
->ssid
, ssids
->ssid_len
);
770 memset(&sr
->ssid
, 0, sizeof(sr
->ssid
));
772 min_t(u8
, sizeof(sr
->ssid
.SSID
), ssids
->ssid_len
);
773 if (sr
->ssid
.SSID_len
) {
774 memcpy(sr
->ssid
.SSID
, ssids
->ssid
, sr
->ssid
.SSID_len
);
775 sr
->ssid
.SSID_len
= cpu_to_le32(sr
->ssid
.SSID_len
);
778 WL_SCAN("Broadcast scan\n");
781 passive_scan
= cfg_priv
->active_scan
? 0 : 1;
782 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_PASSIVE_SCAN
,
783 &passive_scan
, sizeof(passive_scan
));
785 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
788 brcmf_set_mpc(ndev
, 0);
789 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SCAN
, &sr
->ssid
,
793 WL_INFO("system busy : scan for \"%s\" "
794 "canceled\n", sr
->ssid
.SSID
);
796 WL_ERR("WLC_SCAN error (%d)\n", err
);
798 brcmf_set_mpc(ndev
, 1);
806 clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
);
807 cfg_priv
->scan_request
= NULL
;
812 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
813 struct cfg80211_scan_request
*request
)
821 err
= __brcmf_cfg80211_scan(wiphy
, ndev
, request
, NULL
);
823 WL_ERR("scan error (%d)\n", err
);
829 static s32
brcmf_dev_intvar_set(struct net_device
*dev
, s8
*name
, s32 val
)
831 s8 buf
[BRCMF_C_IOCTL_SMLEN
];
835 val
= cpu_to_le32(val
);
836 len
= brcmu_mkiovar(name
, (char *)(&val
), sizeof(val
), buf
,
840 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_VAR
, buf
, len
);
842 WL_ERR("error (%d)\n", err
);
848 brcmf_dev_intvar_get(struct net_device
*dev
, s8
*name
, s32
*retval
)
851 s8 buf
[BRCMF_C_IOCTL_SMLEN
];
859 brcmu_mkiovar(name
, (char *)(&data_null
), 0, (char *)(&var
),
862 err
= brcmf_dev_ioctl(dev
, BRCMF_C_GET_VAR
, &var
, len
);
864 WL_ERR("error (%d)\n", err
);
866 *retval
= le32_to_cpu(var
.val
);
871 static s32
brcmf_set_rts(struct net_device
*dev
, u32 rts_threshold
)
875 err
= brcmf_dev_intvar_set(dev
, "rtsthresh", rts_threshold
);
877 WL_ERR("Error (%d)\n", err
);
882 static s32
brcmf_set_frag(struct net_device
*dev
, u32 frag_threshold
)
886 err
= brcmf_dev_intvar_set(dev
, "fragthresh", frag_threshold
);
888 WL_ERR("Error (%d)\n", err
);
893 static s32
brcmf_set_retry(struct net_device
*dev
, u32 retry
, bool l
)
896 u32 cmd
= (l
? BRCM_SET_LRL
: BRCM_SET_SRL
);
898 retry
= cpu_to_le32(retry
);
899 err
= brcmf_dev_ioctl(dev
, cmd
, &retry
, sizeof(retry
));
901 WL_ERR("cmd (%d) , error (%d)\n", cmd
, err
);
907 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
909 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
910 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
916 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
917 (cfg_priv
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
918 cfg_priv
->conf
->rts_threshold
= wiphy
->rts_threshold
;
919 err
= brcmf_set_rts(ndev
, cfg_priv
->conf
->rts_threshold
);
923 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
924 (cfg_priv
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
925 cfg_priv
->conf
->frag_threshold
= wiphy
->frag_threshold
;
926 err
= brcmf_set_frag(ndev
, cfg_priv
->conf
->frag_threshold
);
930 if (changed
& WIPHY_PARAM_RETRY_LONG
931 && (cfg_priv
->conf
->retry_long
!= wiphy
->retry_long
)) {
932 cfg_priv
->conf
->retry_long
= wiphy
->retry_long
;
933 err
= brcmf_set_retry(ndev
, cfg_priv
->conf
->retry_long
, true);
937 if (changed
& WIPHY_PARAM_RETRY_SHORT
938 && (cfg_priv
->conf
->retry_short
!= wiphy
->retry_short
)) {
939 cfg_priv
->conf
->retry_short
= wiphy
->retry_short
;
940 err
= brcmf_set_retry(ndev
, cfg_priv
->conf
->retry_short
, false);
951 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
952 struct cfg80211_ibss_params
*params
)
954 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
955 struct brcmf_join_params join_params
;
956 size_t join_params_size
= 0;
965 WL_CONN("SSID: %s\n", params
->ssid
);
967 WL_CONN("SSID: NULL, Not supported\n");
971 set_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
974 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
975 params
->bssid
[0], params
->bssid
[1], params
->bssid
[2],
976 params
->bssid
[3], params
->bssid
[4], params
->bssid
[5]);
978 WL_CONN("No BSSID specified\n");
981 WL_CONN("channel: %d\n", params
->channel
->center_freq
);
983 WL_CONN("no channel specified\n");
985 if (params
->channel_fixed
)
986 WL_CONN("fixed channel required\n");
988 WL_CONN("no fixed channel required\n");
990 if (params
->ie
&& params
->ie_len
)
991 WL_CONN("ie len: %d\n", params
->ie_len
);
993 WL_CONN("no ie specified\n");
995 if (params
->beacon_interval
)
996 WL_CONN("beacon interval: %d\n", params
->beacon_interval
);
998 WL_CONN("no beacon interval specified\n");
1000 if (params
->basic_rates
)
1001 WL_CONN("basic rates: %08X\n", params
->basic_rates
);
1003 WL_CONN("no basic rates specified\n");
1005 if (params
->privacy
)
1006 WL_CONN("privacy required\n");
1008 WL_CONN("no privacy required\n");
1010 /* Configure Privacy for starter */
1011 if (params
->privacy
)
1012 wsec
|= WEP_ENABLED
;
1014 err
= brcmf_dev_intvar_set(dev
, "wsec", wsec
);
1015 if (unlikely(err
)) {
1016 WL_ERR("wsec failed (%d)\n", err
);
1020 /* Configure Beacon Interval for starter */
1021 if (params
->beacon_interval
)
1022 bcnprd
= cpu_to_le32(params
->beacon_interval
);
1024 bcnprd
= cpu_to_le32(100);
1026 err
= brcmf_dev_ioctl(dev
, BRCM_SET_BCNPRD
, &bcnprd
, sizeof(bcnprd
));
1027 if (unlikely(err
)) {
1028 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err
);
1032 /* Configure required join parameter */
1033 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1036 join_params
.ssid
.SSID_len
=
1037 (params
->ssid_len
> 32) ? 32 : params
->ssid_len
;
1038 memcpy(join_params
.ssid
.SSID
, params
->ssid
, join_params
.ssid
.SSID_len
);
1039 join_params
.ssid
.SSID_len
= cpu_to_le32(join_params
.ssid
.SSID_len
);
1040 join_params_size
= sizeof(join_params
.ssid
);
1041 brcmf_update_prof(cfg_priv
, NULL
, &join_params
.ssid
, WL_PROF_SSID
);
1044 if (params
->bssid
) {
1045 memcpy(join_params
.params
.bssid
, params
->bssid
, ETH_ALEN
);
1046 join_params_size
= sizeof(join_params
.ssid
) +
1047 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1049 memcpy(join_params
.params
.bssid
, ether_bcast
, ETH_ALEN
);
1052 brcmf_update_prof(cfg_priv
, NULL
,
1053 &join_params
.params
.bssid
, WL_PROF_BSSID
);
1056 if (params
->channel
) {
1060 ieee80211_frequency_to_channel(
1061 params
->channel
->center_freq
);
1062 if (params
->channel_fixed
) {
1063 /* adding chanspec */
1064 brcmf_ch_to_chanspec(cfg_priv
->channel
,
1065 &join_params
, &join_params_size
);
1068 /* set channel for starter */
1069 target_channel
= cpu_to_le32(cfg_priv
->channel
);
1070 err
= brcmf_dev_ioctl(dev
, BRCM_SET_CHANNEL
,
1071 &target_channel
, sizeof(target_channel
));
1072 if (unlikely(err
)) {
1073 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err
);
1077 cfg_priv
->channel
= 0;
1079 cfg_priv
->ibss_starter
= false;
1082 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_SSID
,
1083 &join_params
, join_params_size
);
1084 if (unlikely(err
)) {
1085 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1091 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
1097 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
1099 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1102 WL_TRACE("Enter\n");
1105 brcmf_link_down(cfg_priv
);
1112 static s32
brcmf_set_wpa_version(struct net_device
*dev
,
1113 struct cfg80211_connect_params
*sme
)
1115 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(dev
);
1116 struct brcmf_cfg80211_security
*sec
;
1120 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1121 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1122 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1123 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1125 val
= WPA_AUTH_DISABLED
;
1126 WL_CONN("setting wpa_auth to 0x%0x\n", val
);
1127 err
= brcmf_dev_intvar_set(dev
, "wpa_auth", val
);
1128 if (unlikely(err
)) {
1129 WL_ERR("set wpa_auth failed (%d)\n", err
);
1132 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1133 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1138 brcmf_set_auth_type(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1140 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(dev
);
1141 struct brcmf_cfg80211_security
*sec
;
1145 switch (sme
->auth_type
) {
1146 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1148 WL_CONN("open system\n");
1150 case NL80211_AUTHTYPE_SHARED_KEY
:
1152 WL_CONN("shared key\n");
1154 case NL80211_AUTHTYPE_AUTOMATIC
:
1156 WL_CONN("automatic\n");
1158 case NL80211_AUTHTYPE_NETWORK_EAP
:
1159 WL_CONN("network eap\n");
1162 WL_ERR("invalid auth type (%d)\n", sme
->auth_type
);
1166 err
= brcmf_dev_intvar_set(dev
, "auth", val
);
1167 if (unlikely(err
)) {
1168 WL_ERR("set auth failed (%d)\n", err
);
1171 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1172 sec
->auth_type
= sme
->auth_type
;
1177 brcmf_set_set_cipher(struct net_device
*dev
,
1178 struct cfg80211_connect_params
*sme
)
1180 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(dev
);
1181 struct brcmf_cfg80211_security
*sec
;
1186 if (sme
->crypto
.n_ciphers_pairwise
) {
1187 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1188 case WLAN_CIPHER_SUITE_WEP40
:
1189 case WLAN_CIPHER_SUITE_WEP104
:
1192 case WLAN_CIPHER_SUITE_TKIP
:
1193 pval
= TKIP_ENABLED
;
1195 case WLAN_CIPHER_SUITE_CCMP
:
1198 case WLAN_CIPHER_SUITE_AES_CMAC
:
1202 WL_ERR("invalid cipher pairwise (%d)\n",
1203 sme
->crypto
.ciphers_pairwise
[0]);
1207 if (sme
->crypto
.cipher_group
) {
1208 switch (sme
->crypto
.cipher_group
) {
1209 case WLAN_CIPHER_SUITE_WEP40
:
1210 case WLAN_CIPHER_SUITE_WEP104
:
1213 case WLAN_CIPHER_SUITE_TKIP
:
1214 gval
= TKIP_ENABLED
;
1216 case WLAN_CIPHER_SUITE_CCMP
:
1219 case WLAN_CIPHER_SUITE_AES_CMAC
:
1223 WL_ERR("invalid cipher group (%d)\n",
1224 sme
->crypto
.cipher_group
);
1229 WL_CONN("pval (%d) gval (%d)\n", pval
, gval
);
1230 err
= brcmf_dev_intvar_set(dev
, "wsec", pval
| gval
);
1231 if (unlikely(err
)) {
1232 WL_ERR("error (%d)\n", err
);
1236 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1237 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1238 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1244 brcmf_set_key_mgmt(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1246 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(dev
);
1247 struct brcmf_cfg80211_security
*sec
;
1251 if (sme
->crypto
.n_akm_suites
) {
1252 err
= brcmf_dev_intvar_get(dev
, "wpa_auth", &val
);
1253 if (unlikely(err
)) {
1254 WL_ERR("could not get wpa_auth (%d)\n", err
);
1257 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1258 switch (sme
->crypto
.akm_suites
[0]) {
1259 case WLAN_AKM_SUITE_8021X
:
1260 val
= WPA_AUTH_UNSPECIFIED
;
1262 case WLAN_AKM_SUITE_PSK
:
1266 WL_ERR("invalid cipher group (%d)\n",
1267 sme
->crypto
.cipher_group
);
1270 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1271 switch (sme
->crypto
.akm_suites
[0]) {
1272 case WLAN_AKM_SUITE_8021X
:
1273 val
= WPA2_AUTH_UNSPECIFIED
;
1275 case WLAN_AKM_SUITE_PSK
:
1276 val
= WPA2_AUTH_PSK
;
1279 WL_ERR("invalid cipher group (%d)\n",
1280 sme
->crypto
.cipher_group
);
1285 WL_CONN("setting wpa_auth to %d\n", val
);
1286 err
= brcmf_dev_intvar_set(dev
, "wpa_auth", val
);
1287 if (unlikely(err
)) {
1288 WL_ERR("could not set wpa_auth (%d)\n", err
);
1292 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1293 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1299 brcmf_set_set_sharedkey(struct net_device
*dev
,
1300 struct cfg80211_connect_params
*sme
)
1302 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(dev
);
1303 struct brcmf_cfg80211_security
*sec
;
1304 struct brcmf_wsec_key key
;
1308 WL_CONN("key len (%d)\n", sme
->key_len
);
1310 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1311 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1312 sec
->wpa_versions
, sec
->cipher_pairwise
);
1314 (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
|
1315 NL80211_WPA_VERSION_2
))
1316 && (sec
->cipher_pairwise
& (WLAN_CIPHER_SUITE_WEP40
|
1317 WLAN_CIPHER_SUITE_WEP104
))) {
1318 memset(&key
, 0, sizeof(key
));
1319 key
.len
= (u32
) sme
->key_len
;
1320 key
.index
= (u32
) sme
->key_idx
;
1321 if (unlikely(key
.len
> sizeof(key
.data
))) {
1322 WL_ERR("Too long key length (%u)\n", key
.len
);
1325 memcpy(key
.data
, sme
->key
, key
.len
);
1326 key
.flags
= BRCMF_PRIMARY_KEY
;
1327 switch (sec
->cipher_pairwise
) {
1328 case WLAN_CIPHER_SUITE_WEP40
:
1329 key
.algo
= CRYPTO_ALGO_WEP1
;
1331 case WLAN_CIPHER_SUITE_WEP104
:
1332 key
.algo
= CRYPTO_ALGO_WEP128
;
1335 WL_ERR("Invalid algorithm (%d)\n",
1336 sme
->crypto
.ciphers_pairwise
[0]);
1339 /* Set the new key/index */
1340 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1341 key
.len
, key
.index
, key
.algo
);
1342 WL_CONN("key \"%s\"\n", key
.data
);
1343 convert_key_from_CPU(&key
);
1344 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_KEY
, &key
,
1346 if (unlikely(err
)) {
1347 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1350 if (sec
->auth_type
== NL80211_AUTHTYPE_OPEN_SYSTEM
) {
1351 WL_CONN("set auth_type to shared key\n");
1352 val
= 1; /* shared key */
1353 err
= brcmf_dev_intvar_set(dev
, "auth", val
);
1354 if (unlikely(err
)) {
1355 WL_ERR("set auth failed (%d)\n", err
);
1365 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
1366 struct cfg80211_connect_params
*sme
)
1368 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1369 struct ieee80211_channel
*chan
= sme
->channel
;
1370 struct brcmf_join_params join_params
;
1371 size_t join_params_size
;
1375 WL_TRACE("Enter\n");
1378 if (unlikely(!sme
->ssid
)) {
1379 WL_ERR("Invalid ssid\n");
1383 set_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
1387 ieee80211_frequency_to_channel(chan
->center_freq
);
1388 WL_CONN("channel (%d), center_req (%d)\n",
1389 cfg_priv
->channel
, chan
->center_freq
);
1391 cfg_priv
->channel
= 0;
1393 WL_INFO("ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1395 err
= brcmf_set_wpa_version(dev
, sme
);
1397 WL_ERR("wl_set_wpa_version failed (%d)\n", err
);
1401 err
= brcmf_set_auth_type(dev
, sme
);
1403 WL_ERR("wl_set_auth_type failed (%d)\n", err
);
1407 err
= brcmf_set_set_cipher(dev
, sme
);
1409 WL_ERR("wl_set_set_cipher failed (%d)\n", err
);
1413 err
= brcmf_set_key_mgmt(dev
, sme
);
1415 WL_ERR("wl_set_key_mgmt failed (%d)\n", err
);
1419 err
= brcmf_set_set_sharedkey(dev
, sme
);
1421 WL_ERR("wl_set_set_sharedkey failed (%d)\n", err
);
1425 memset(&join_params
, 0, sizeof(join_params
));
1426 join_params_size
= sizeof(join_params
.ssid
);
1428 join_params
.ssid
.SSID_len
=
1429 min(sizeof(join_params
.ssid
.SSID
), sme
->ssid_len
);
1430 memcpy(&join_params
.ssid
.SSID
, sme
->ssid
, join_params
.ssid
.SSID_len
);
1431 join_params
.ssid
.SSID_len
= cpu_to_le32(join_params
.ssid
.SSID_len
);
1432 brcmf_update_prof(cfg_priv
, NULL
, &join_params
.ssid
, WL_PROF_SSID
);
1434 memcpy(join_params
.params
.bssid
, ether_bcast
, ETH_ALEN
);
1436 if (join_params
.ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
)
1437 WL_CONN("ssid \"%s\", len (%d)\n",
1438 join_params
.ssid
.SSID
, join_params
.ssid
.SSID_len
);
1440 brcmf_ch_to_chanspec(cfg_priv
->channel
,
1441 &join_params
, &join_params_size
);
1442 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_SSID
,
1443 &join_params
, join_params_size
);
1445 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1449 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
1455 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
1458 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1459 struct brcmf_scb_val scbval
;
1462 WL_TRACE("Enter. Reason code = %d\n", reason_code
);
1465 clear_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
);
1467 scbval
.val
= reason_code
;
1468 memcpy(&scbval
.ea
, brcmf_read_prof(cfg_priv
, WL_PROF_BSSID
), ETH_ALEN
);
1469 scbval
.val
= cpu_to_le32(scbval
.val
);
1470 err
= brcmf_dev_ioctl(dev
, BRCMF_C_DISASSOC
, &scbval
,
1471 sizeof(struct brcmf_scb_val
));
1473 WL_ERR("error (%d)\n", err
);
1475 cfg_priv
->link_up
= false;
1482 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
,
1483 enum nl80211_tx_power_setting type
, s32 dbm
)
1486 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1487 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
1492 WL_TRACE("Enter\n");
1496 case NL80211_TX_POWER_AUTOMATIC
:
1498 case NL80211_TX_POWER_LIMITED
:
1500 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1505 case NL80211_TX_POWER_FIXED
:
1507 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1513 /* Make sure radio is off or on as far as software is concerned */
1514 disable
= WL_RADIO_SW_DISABLE
<< 16;
1515 disable
= cpu_to_le32(disable
);
1516 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_RADIO
, &disable
,
1519 WL_ERR("WLC_SET_RADIO error (%d)\n", err
);
1524 txpwrmw
= (u16
) dbm
;
1525 err
= brcmf_dev_intvar_set(ndev
, "qtxpower",
1526 (s32
) (brcmu_mw_to_qdbm(txpwrmw
)));
1528 WL_ERR("qtxpower error (%d)\n", err
);
1529 cfg_priv
->conf
->tx_power
= dbm
;
1536 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
)
1538 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1539 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
1544 WL_TRACE("Enter\n");
1547 err
= brcmf_dev_intvar_get(ndev
, "qtxpower", &txpwrdbm
);
1548 if (unlikely(err
)) {
1549 WL_ERR("error (%d)\n", err
);
1553 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1554 *dbm
= (s32
) brcmu_qdbm_to_mw(result
);
1562 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1563 u8 key_idx
, bool unicast
, bool multicast
)
1569 WL_TRACE("Enter\n");
1570 WL_CONN("key index (%d)\n", key_idx
);
1573 err
= brcmf_dev_ioctl(dev
, BRCMF_C_GET_WSEC
, &wsec
, sizeof(wsec
));
1574 if (unlikely(err
)) {
1575 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1579 wsec
= le32_to_cpu(wsec
);
1580 if (wsec
& WEP_ENABLED
) {
1581 /* Just select a new current key */
1582 index
= (u32
) key_idx
;
1583 index
= cpu_to_le32(index
);
1584 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_KEY_PRIMARY
, &index
,
1587 WL_ERR("error (%d)\n", err
);
1595 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*dev
,
1596 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1598 struct brcmf_wsec_key key
;
1601 memset(&key
, 0, sizeof(key
));
1602 key
.index
= (u32
) key_idx
;
1603 /* Instead of bcast for ea address for default wep keys,
1604 driver needs it to be Null */
1605 if (!is_multicast_ether_addr(mac_addr
))
1606 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1607 key
.len
= (u32
) params
->key_len
;
1608 /* check for key index change */
1611 convert_key_from_CPU(&key
);
1612 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_KEY
, &key
, sizeof(key
));
1613 if (unlikely(err
)) {
1614 WL_ERR("key delete error (%d)\n", err
);
1618 if (key
.len
> sizeof(key
.data
)) {
1619 WL_ERR("Invalid key length (%d)\n", key
.len
);
1623 WL_CONN("Setting the key index %d\n", key
.index
);
1624 memcpy(key
.data
, params
->key
, key
.len
);
1626 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1628 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1629 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1630 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1633 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1634 if (params
->seq
&& params
->seq_len
== 6) {
1637 ivptr
= (u8
*) params
->seq
;
1638 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1639 (ivptr
[3] << 8) | ivptr
[2];
1640 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1641 key
.iv_initialized
= true;
1644 switch (params
->cipher
) {
1645 case WLAN_CIPHER_SUITE_WEP40
:
1646 key
.algo
= CRYPTO_ALGO_WEP1
;
1647 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1649 case WLAN_CIPHER_SUITE_WEP104
:
1650 key
.algo
= CRYPTO_ALGO_WEP128
;
1651 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1653 case WLAN_CIPHER_SUITE_TKIP
:
1654 key
.algo
= CRYPTO_ALGO_TKIP
;
1655 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1657 case WLAN_CIPHER_SUITE_AES_CMAC
:
1658 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1659 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1661 case WLAN_CIPHER_SUITE_CCMP
:
1662 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1663 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1666 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1669 convert_key_from_CPU(&key
);
1671 brcmf_netdev_wait_pend8021x(dev
);
1672 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_KEY
, &key
, sizeof(key
));
1673 if (unlikely(err
)) {
1674 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1682 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1683 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1684 struct key_params
*params
)
1686 struct brcmf_wsec_key key
;
1692 WL_TRACE("Enter\n");
1693 WL_CONN("key index (%d)\n", key_idx
);
1698 return brcmf_add_keyext(wiphy
, dev
, key_idx
, mac_addr
, params
);
1700 memset(&key
, 0, sizeof(key
));
1702 key
.len
= (u32
) params
->key_len
;
1703 key
.index
= (u32
) key_idx
;
1705 if (unlikely(key
.len
> sizeof(key
.data
))) {
1706 WL_ERR("Too long key length (%u)\n", key
.len
);
1710 memcpy(key
.data
, params
->key
, key
.len
);
1712 key
.flags
= BRCMF_PRIMARY_KEY
;
1713 switch (params
->cipher
) {
1714 case WLAN_CIPHER_SUITE_WEP40
:
1715 key
.algo
= CRYPTO_ALGO_WEP1
;
1716 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1718 case WLAN_CIPHER_SUITE_WEP104
:
1719 key
.algo
= CRYPTO_ALGO_WEP128
;
1720 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1722 case WLAN_CIPHER_SUITE_TKIP
:
1723 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1724 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1725 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1726 key
.algo
= CRYPTO_ALGO_TKIP
;
1727 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1729 case WLAN_CIPHER_SUITE_AES_CMAC
:
1730 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1731 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1733 case WLAN_CIPHER_SUITE_CCMP
:
1734 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1735 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1738 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1743 /* Set the new key/index */
1744 convert_key_from_CPU(&key
);
1745 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_KEY
, &key
, sizeof(key
));
1746 if (unlikely(err
)) {
1747 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1752 err
= brcmf_dev_intvar_get(dev
, "wsec", &wsec
);
1753 if (unlikely(err
)) {
1754 WL_ERR("get wsec error (%d)\n", err
);
1757 wsec
&= ~(WEP_ENABLED
);
1759 err
= brcmf_dev_intvar_set(dev
, "wsec", wsec
);
1760 if (unlikely(err
)) {
1761 WL_ERR("set wsec error (%d)\n", err
);
1765 val
= 1; /* assume shared key. otherwise 0 */
1766 val
= cpu_to_le32(val
);
1767 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_AUTH
, &val
, sizeof(val
));
1769 WL_ERR("WLC_SET_AUTH error (%d)\n", err
);
1776 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1777 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
1779 struct brcmf_wsec_key key
;
1784 WL_TRACE("Enter\n");
1786 memset(&key
, 0, sizeof(key
));
1788 key
.index
= (u32
) key_idx
;
1789 key
.flags
= BRCMF_PRIMARY_KEY
;
1790 key
.algo
= CRYPTO_ALGO_OFF
;
1792 WL_CONN("key index (%d)\n", key_idx
);
1793 /* Set the new key/index */
1794 convert_key_from_CPU(&key
);
1795 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_KEY
, &key
, sizeof(key
));
1796 if (unlikely(err
)) {
1797 if (err
== -EINVAL
) {
1798 if (key
.index
>= DOT11_MAX_DEFAULT_KEYS
)
1799 /* we ignore this key index in this case */
1800 WL_ERR("invalid key index (%d)\n", key_idx
);
1802 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1804 /* Ignore this error, may happen during DISASSOC */
1810 err
= brcmf_dev_intvar_get(dev
, "wsec", &wsec
);
1811 if (unlikely(err
)) {
1812 WL_ERR("get wsec error (%d)\n", err
);
1813 /* Ignore this error, may happen during DISASSOC */
1817 wsec
&= ~(WEP_ENABLED
);
1819 err
= brcmf_dev_intvar_set(dev
, "wsec", wsec
);
1820 if (unlikely(err
)) {
1821 WL_ERR("set wsec error (%d)\n", err
);
1822 /* Ignore this error, may happen during DISASSOC */
1827 val
= 0; /* assume open key. otherwise 1 */
1828 val
= cpu_to_le32(val
);
1829 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_AUTH
, &val
, sizeof(val
));
1830 if (unlikely(err
)) {
1831 WL_ERR("WLC_SET_AUTH error (%d)\n", err
);
1832 /* Ignore this error, may happen during DISASSOC */
1841 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1842 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
1843 void (*callback
) (void *cookie
, struct key_params
* params
))
1845 struct key_params params
;
1846 struct brcmf_wsec_key key
;
1847 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1848 struct brcmf_cfg80211_security
*sec
;
1852 WL_TRACE("Enter\n");
1853 WL_CONN("key index (%d)\n", key_idx
);
1856 memset(&key
, 0, sizeof(key
));
1857 key
.index
= key_idx
;
1858 convert_key_to_CPU(&key
);
1859 memset(¶ms
, 0, sizeof(params
));
1860 params
.key_len
= (u8
) min_t(u8
, WLAN_MAX_KEY_LEN
, key
.len
);
1861 memcpy(params
.key
, key
.data
, params
.key_len
);
1863 err
= brcmf_dev_ioctl(dev
, BRCMF_C_GET_WSEC
, &wsec
, sizeof(wsec
));
1864 if (unlikely(err
)) {
1865 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1866 /* Ignore this error, may happen during DISASSOC */
1870 wsec
= le32_to_cpu(wsec
);
1873 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1874 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
1875 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
1876 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1877 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
1878 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
1879 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1883 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
1884 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1887 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
1888 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1891 WL_ERR("Invalid algo (0x%x)\n", wsec
);
1895 callback(cookie
, ¶ms
);
1903 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
1904 struct net_device
*dev
, u8 key_idx
)
1906 WL_INFO("Not supported\n");
1913 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1914 u8
*mac
, struct station_info
*sinfo
)
1916 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1917 struct brcmf_scb_val scb_val
;
1921 u8
*bssid
= brcmf_read_prof(cfg_priv
, WL_PROF_BSSID
);
1923 WL_TRACE("Enter\n");
1927 (memcmp(mac
, bssid
, ETH_ALEN
))) {
1928 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1929 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1930 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5],
1931 bssid
[0], bssid
[1], bssid
[2], bssid
[3],
1932 bssid
[4], bssid
[5]);
1937 /* Report the current tx rate */
1938 err
= brcmf_dev_ioctl(dev
, BRCMF_C_GET_RATE
, &rate
, sizeof(rate
));
1940 WL_ERR("Could not get rate (%d)\n", err
);
1942 rate
= le32_to_cpu(rate
);
1943 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1944 sinfo
->txrate
.legacy
= rate
* 5;
1945 WL_CONN("Rate %d Mbps\n", rate
/ 2);
1948 if (test_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
)) {
1950 err
= brcmf_dev_ioctl(dev
, BRCMF_C_GET_RSSI
, &scb_val
,
1951 sizeof(struct brcmf_scb_val
));
1953 WL_ERR("Could not get rssi (%d)\n", err
);
1955 rssi
= le32_to_cpu(scb_val
.val
);
1956 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1957 sinfo
->signal
= rssi
;
1958 WL_CONN("RSSI %d dBm\n", rssi
);
1967 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*dev
,
1968 bool enabled
, s32 timeout
)
1972 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1974 WL_TRACE("Enter\n");
1977 * Powersave enable/disable request is coming from the
1978 * cfg80211 even before the interface is up. In that
1979 * scenario, driver will be storing the power save
1980 * preference in cfg_priv struct to apply this to
1981 * FW later while initializing the dongle
1983 cfg_priv
->pwr_save
= enabled
;
1984 if (!test_bit(WL_STATUS_READY
, &cfg_priv
->status
)) {
1986 WL_INFO("Device is not ready,"
1987 "storing the value in cfg_priv struct\n");
1991 pm
= enabled
? PM_FAST
: PM_OFF
;
1992 pm
= cpu_to_le32(pm
);
1993 WL_INFO("power save %s\n", (pm
? "enabled" : "disabled"));
1995 err
= brcmf_dev_ioctl(dev
, BRCMF_C_SET_PM
, &pm
, sizeof(pm
));
1996 if (unlikely(err
)) {
1998 WL_ERR("net_device is not ready yet\n");
2000 WL_ERR("error (%d)\n", err
);
2008 brcmf_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
, struct net_device
*dev
,
2010 const struct cfg80211_bitrate_mask
*mask
)
2012 struct brcm_rateset rateset
;
2020 WL_TRACE("Enter\n");
2023 /* addr param is always NULL. ignore it */
2024 /* Get current rateset */
2025 err
= brcmf_dev_ioctl(dev
, BRCM_GET_CURR_RATESET
, &rateset
,
2027 if (unlikely(err
)) {
2028 WL_ERR("could not get current rateset (%d)\n", err
);
2032 rateset
.count
= le32_to_cpu(rateset
.count
);
2034 legacy
= ffs(mask
->control
[IEEE80211_BAND_2GHZ
].legacy
& 0xFFFF);
2036 legacy
= ffs(mask
->control
[IEEE80211_BAND_5GHZ
].legacy
&
2039 val
= wl_g_rates
[legacy
- 1].bitrate
* 100000;
2041 if (val
< rateset
.count
)
2042 /* Select rate by rateset index */
2043 rate
= rateset
.rates
[val
] & 0x7f;
2045 /* Specified rate in bps */
2046 rate
= val
/ 500000;
2048 WL_CONN("rate %d mbps\n", rate
/ 2);
2052 * Set rate override,
2053 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2055 err_bg
= brcmf_dev_intvar_set(dev
, "bg_rate", rate
);
2056 err_a
= brcmf_dev_intvar_set(dev
, "a_rate", rate
);
2057 if (unlikely(err_bg
&& err_a
)) {
2058 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg
, err_a
);
2059 err
= err_bg
| err_a
;
2067 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2069 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2072 * Check for WL_STATUS_READY before any function call which
2073 * could result is bus access. Don't block the resume for
2074 * any driver error conditions
2076 WL_TRACE("Enter\n");
2078 if (test_bit(WL_STATUS_READY
, &cfg_priv
->status
))
2079 brcmf_invoke_iscan(wiphy_to_cfg(wiphy
));
2085 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2086 struct cfg80211_wowlan
*wow
)
2088 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2089 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
2091 WL_TRACE("Enter\n");
2094 * Check for WL_STATUS_READY before any function call which
2095 * could result is bus access. Don't block the suspend for
2096 * any driver error conditions
2100 * While going to suspend if associated with AP disassociate
2101 * from AP to save power while system is in suspended state
2103 if ((test_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
) ||
2104 test_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
)) &&
2105 test_bit(WL_STATUS_READY
, &cfg_priv
->status
)) {
2106 WL_INFO("Disassociating from AP"
2107 " while entering suspend state\n");
2108 brcmf_link_down(cfg_priv
);
2111 * Make sure WPA_Supplicant receives all the event
2112 * generated due to DISASSOC call to the fw to keep
2113 * the state fw and WPA_Supplicant state consistent
2120 set_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
);
2121 if (test_bit(WL_STATUS_READY
, &cfg_priv
->status
))
2122 brcmf_term_iscan(cfg_priv
);
2124 if (cfg_priv
->scan_request
) {
2125 /* Indidate scan abort to cfg80211 layer */
2126 WL_INFO("Terminating scan in progress\n");
2127 cfg80211_scan_done(cfg_priv
->scan_request
, true);
2128 cfg_priv
->scan_request
= NULL
;
2130 clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
);
2131 clear_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
);
2133 /* Turn off watchdog timer */
2134 if (test_bit(WL_STATUS_READY
, &cfg_priv
->status
)) {
2135 WL_INFO("Enable MPC\n");
2136 brcmf_set_mpc(ndev
, 1);
2145 brcmf_update_pmklist(struct net_device
*dev
,
2146 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2150 WL_CONN("No of elements %d\n", pmk_list
->pmkids
.npmkid
);
2151 for (i
= 0; i
< pmk_list
->pmkids
.npmkid
; i
++) {
2152 WL_CONN("PMKID[%d]: %pM =\n", i
,
2153 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2154 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2155 WL_CONN("%02x\n", pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2159 brcmf_dev_bufvar_set(dev
, "pmkid_info", (char *)pmk_list
,
2166 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
2167 struct cfg80211_pmksa
*pmksa
)
2169 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2170 struct pmkid_list
*pmkids
= &cfg_priv
->pmk_list
->pmkids
;
2174 WL_TRACE("Enter\n");
2177 for (i
= 0; i
< pmkids
->npmkid
; i
++)
2178 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2180 if (i
< WL_NUM_PMKIDS_MAX
) {
2181 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2182 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2183 if (i
== pmkids
->npmkid
)
2188 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2189 pmkids
->pmkid
[pmkids
->npmkid
].BSSID
);
2190 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2191 WL_CONN("%02x\n", pmkids
->pmkid
[pmkids
->npmkid
].PMKID
[i
]);
2193 err
= brcmf_update_pmklist(dev
, cfg_priv
->pmk_list
, err
);
2200 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
2201 struct cfg80211_pmksa
*pmksa
)
2203 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2204 struct pmkid_list pmkid
;
2208 WL_TRACE("Enter\n");
2210 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2211 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2213 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2214 &pmkid
.pmkid
[0].BSSID
);
2215 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2216 WL_CONN("%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2218 for (i
= 0; i
< cfg_priv
->pmk_list
->pmkids
.npmkid
; i
++)
2220 (pmksa
->bssid
, &cfg_priv
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2224 if ((cfg_priv
->pmk_list
->pmkids
.npmkid
> 0)
2225 && (i
< cfg_priv
->pmk_list
->pmkids
.npmkid
)) {
2226 memset(&cfg_priv
->pmk_list
->pmkids
.pmkid
[i
], 0,
2227 sizeof(struct pmkid
));
2228 for (; i
< (cfg_priv
->pmk_list
->pmkids
.npmkid
- 1); i
++) {
2229 memcpy(&cfg_priv
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2230 &cfg_priv
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2232 memcpy(&cfg_priv
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2233 &cfg_priv
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2236 cfg_priv
->pmk_list
->pmkids
.npmkid
--;
2240 err
= brcmf_update_pmklist(dev
, cfg_priv
->pmk_list
, err
);
2248 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
)
2250 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2253 WL_TRACE("Enter\n");
2256 memset(cfg_priv
->pmk_list
, 0, sizeof(*cfg_priv
->pmk_list
));
2257 err
= brcmf_update_pmklist(dev
, cfg_priv
->pmk_list
, err
);
2264 static struct cfg80211_ops wl_cfg80211_ops
= {
2265 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
2266 .scan
= brcmf_cfg80211_scan
,
2267 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
2268 .join_ibss
= brcmf_cfg80211_join_ibss
,
2269 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
2270 .get_station
= brcmf_cfg80211_get_station
,
2271 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
2272 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
2273 .add_key
= brcmf_cfg80211_add_key
,
2274 .del_key
= brcmf_cfg80211_del_key
,
2275 .get_key
= brcmf_cfg80211_get_key
,
2276 .set_default_key
= brcmf_cfg80211_config_default_key
,
2277 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
2278 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
2279 .set_bitrate_mask
= brcmf_cfg80211_set_bitrate_mask
,
2280 .connect
= brcmf_cfg80211_connect
,
2281 .disconnect
= brcmf_cfg80211_disconnect
,
2282 .suspend
= brcmf_cfg80211_suspend
,
2283 .resume
= brcmf_cfg80211_resume
,
2284 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
2285 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
2286 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
2289 static s32
brcmf_mode_to_nl80211_iftype(s32 mode
)
2295 return NL80211_IFTYPE_STATION
;
2297 return NL80211_IFTYPE_ADHOC
;
2299 return NL80211_IFTYPE_UNSPECIFIED
;
2305 static struct wireless_dev
*brcmf_alloc_wdev(s32 sizeof_iface
,
2308 struct wireless_dev
*wdev
;
2311 wdev
= kzalloc(sizeof(*wdev
), GFP_KERNEL
);
2312 if (unlikely(!wdev
)) {
2313 WL_ERR("Could not allocate wireless device\n");
2314 return ERR_PTR(-ENOMEM
);
2317 wiphy_new(&wl_cfg80211_ops
,
2318 sizeof(struct brcmf_cfg80211_priv
) + sizeof_iface
);
2319 if (unlikely(!wdev
->wiphy
)) {
2320 WL_ERR("Couldn not allocate wiphy device\n");
2324 set_wiphy_dev(wdev
->wiphy
, dev
);
2325 wdev
->wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
2326 wdev
->wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
2327 wdev
->wiphy
->interface_modes
=
2328 BIT(NL80211_IFTYPE_STATION
) | BIT(NL80211_IFTYPE_ADHOC
);
2329 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
2330 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
2331 * it as 11a by default.
2332 * This will be updated with
2335 * if phy has 11n capability
2337 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
2338 wdev
->wiphy
->cipher_suites
= __wl_cipher_suites
;
2339 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
2340 #ifndef WL_POWERSAVE_DISABLED
2341 wdev
->wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
2346 wdev
->wiphy
->flags
&= ~WIPHY_FLAG_PS_ON_BY_DEFAULT
;
2347 #endif /* !WL_POWERSAVE_DISABLED */
2348 err
= wiphy_register(wdev
->wiphy
);
2349 if (unlikely(err
< 0)) {
2350 WL_ERR("Couldn not register wiphy device (%d)\n", err
);
2351 goto wiphy_register_out
;
2356 wiphy_free(wdev
->wiphy
);
2361 return ERR_PTR(err
);
2364 static void brcmf_free_wdev(struct brcmf_cfg80211_priv
*cfg_priv
)
2366 struct wireless_dev
*wdev
= cfg_to_wdev(cfg_priv
);
2368 if (unlikely(!wdev
)) {
2369 WL_ERR("wdev is invalid\n");
2372 wiphy_unregister(wdev
->wiphy
);
2373 wiphy_free(wdev
->wiphy
);
2375 cfg_to_wdev(cfg_priv
) = NULL
;
2378 static s32
brcmf_inform_bss(struct brcmf_cfg80211_priv
*cfg_priv
)
2380 struct brcmf_scan_results
*bss_list
;
2381 struct brcmf_bss_info
*bi
= NULL
; /* must be initialized */
2385 bss_list
= cfg_priv
->bss_list
;
2386 if (unlikely(bss_list
->version
!= BRCMF_BSS_INFO_VERSION
)) {
2387 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2391 WL_SCAN("scanned AP count (%d)\n", bss_list
->count
);
2392 bi
= next_bss(bss_list
, bi
);
2393 for_each_bss(bss_list
, bi
, i
) {
2394 err
= brcmf_inform_single_bss(cfg_priv
, bi
);
2402 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_priv
*cfg_priv
,
2403 struct brcmf_bss_info
*bi
)
2405 struct wiphy
*wiphy
= cfg_to_wiphy(cfg_priv
);
2406 struct ieee80211_channel
*notify_channel
;
2407 struct cfg80211_bss
*bss
;
2408 struct ieee80211_supported_band
*band
;
2412 u64 notify_timestamp
;
2413 u16 notify_capability
;
2414 u16 notify_interval
;
2416 size_t notify_ielen
;
2419 if (unlikely(le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
)) {
2420 WL_ERR("Bss info is larger than buffer. Discarding\n");
2424 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2425 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2427 if (channel
<= CH_MAX_2G_CHANNEL
)
2428 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2430 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2432 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2433 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2435 notify_timestamp
= jiffies_to_msecs(jiffies
)*1000; /* uSec */
2436 notify_capability
= le16_to_cpu(bi
->capability
);
2437 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2438 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2439 notify_ielen
= le16_to_cpu(bi
->ie_length
);
2440 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2442 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2443 bi
->BSSID
[0], bi
->BSSID
[1], bi
->BSSID
[2],
2444 bi
->BSSID
[3], bi
->BSSID
[4], bi
->BSSID
[5]);
2445 WL_CONN("Channel: %d(%d)\n", channel
, freq
);
2446 WL_CONN("Capability: %X\n", notify_capability
);
2447 WL_CONN("Beacon interval: %d\n", notify_interval
);
2448 WL_CONN("Signal: %d\n", notify_signal
);
2449 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp
);
2451 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2452 notify_timestamp
, notify_capability
, notify_interval
, notify_ie
,
2453 notify_ielen
, notify_signal
, GFP_KERNEL
);
2455 if (unlikely(!bss
)) {
2456 WL_ERR("cfg80211_inform_bss_frame error\n");
2463 static s32
wl_inform_ibss(struct brcmf_cfg80211_priv
*cfg_priv
,
2464 struct net_device
*dev
, const u8
*bssid
)
2466 struct wiphy
*wiphy
= cfg_to_wiphy(cfg_priv
);
2467 struct ieee80211_channel
*notify_channel
;
2468 struct brcmf_bss_info
*bi
= NULL
;
2469 struct ieee80211_supported_band
*band
;
2474 u64 notify_timestamp
;
2475 u16 notify_capability
;
2476 u16 notify_interval
;
2478 size_t notify_ielen
;
2481 WL_TRACE("Enter\n");
2483 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2485 WL_ERR("kzalloc() failed\n");
2490 *(u32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2492 err
= brcmf_dev_ioctl(dev
, BRCMF_C_GET_BSS_INFO
, buf
, WL_BSS_INFO_MAX
);
2493 if (unlikely(err
)) {
2494 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err
);
2498 bi
= (struct brcmf_bss_info
*)(buf
+ 4);
2500 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2501 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2503 if (channel
<= CH_MAX_2G_CHANNEL
)
2504 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2506 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2508 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2509 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2511 notify_timestamp
= jiffies_to_msecs(jiffies
)*1000; /* uSec */
2512 notify_capability
= le16_to_cpu(bi
->capability
);
2513 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2514 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2515 notify_ielen
= le16_to_cpu(bi
->ie_length
);
2516 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2518 WL_CONN("channel: %d(%d)\n", channel
, freq
);
2519 WL_CONN("capability: %X\n", notify_capability
);
2520 WL_CONN("beacon interval: %d\n", notify_interval
);
2521 WL_CONN("signal: %d\n", notify_signal
);
2522 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp
);
2524 cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2525 notify_timestamp
, notify_capability
, notify_interval
,
2526 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2537 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv
*cfg_priv
,
2538 const struct brcmf_event_msg
*e
)
2540 u32 event
= be32_to_cpu(e
->event_type
);
2541 u32 status
= be32_to_cpu(e
->status
);
2543 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
2544 WL_CONN("Processing set ssid\n");
2545 cfg_priv
->link_up
= true;
2552 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv
*cfg_priv
,
2553 const struct brcmf_event_msg
*e
)
2555 u32 event
= be32_to_cpu(e
->event_type
);
2556 u16 flags
= be16_to_cpu(e
->flags
);
2558 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
2559 WL_CONN("Processing link down\n");
2565 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv
*cfg_priv
,
2566 const struct brcmf_event_msg
*e
)
2568 u32 event
= be32_to_cpu(e
->event_type
);
2569 u32 status
= be32_to_cpu(e
->status
);
2571 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
2572 WL_CONN("Processing Link %s & no network found\n",
2573 be16_to_cpu(e
->flags
) & BRCMF_EVENT_MSG_LINK
?
2578 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
2579 WL_CONN("Processing connecting & no network found\n");
2587 brcmf_notify_connect_status(struct brcmf_cfg80211_priv
*cfg_priv
,
2588 struct net_device
*ndev
,
2589 const struct brcmf_event_msg
*e
, void *data
)
2593 if (brcmf_is_linkup(cfg_priv
, e
)) {
2594 WL_CONN("Linkup\n");
2595 if (brcmf_is_ibssmode(cfg_priv
)) {
2596 brcmf_update_prof(cfg_priv
, NULL
, (void *)e
->addr
,
2598 wl_inform_ibss(cfg_priv
, ndev
, e
->addr
);
2599 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
2600 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
2601 set_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
);
2603 brcmf_bss_connect_done(cfg_priv
, ndev
, e
, true);
2604 } else if (brcmf_is_linkdown(cfg_priv
, e
)) {
2605 WL_CONN("Linkdown\n");
2606 if (brcmf_is_ibssmode(cfg_priv
)) {
2607 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
2608 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
2610 brcmf_link_down(cfg_priv
);
2612 brcmf_bss_connect_done(cfg_priv
, ndev
, e
, false);
2613 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
2614 &cfg_priv
->status
)) {
2615 cfg80211_disconnected(ndev
, 0, NULL
, 0,
2617 brcmf_link_down(cfg_priv
);
2620 brcmf_init_prof(cfg_priv
->profile
);
2621 } else if (brcmf_is_nonetwork(cfg_priv
, e
)) {
2622 if (brcmf_is_ibssmode(cfg_priv
))
2623 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
2625 brcmf_bss_connect_done(cfg_priv
, ndev
, e
, false);
2632 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv
*cfg_priv
,
2633 struct net_device
*ndev
,
2634 const struct brcmf_event_msg
*e
, void *data
)
2637 u32 event
= be32_to_cpu(e
->event_type
);
2638 u32 status
= be32_to_cpu(e
->status
);
2640 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
2641 if (test_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
))
2642 brcmf_bss_roaming_done(cfg_priv
, ndev
, e
);
2644 brcmf_bss_connect_done(cfg_priv
, ndev
, e
, true);
2651 brcmf_dev_bufvar_set(struct net_device
*dev
, s8
*name
, s8
*buf
, s32 len
)
2653 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(dev
);
2656 buflen
= brcmu_mkiovar(name
, buf
, len
, cfg_priv
->ioctl_buf
,
2660 return brcmf_dev_ioctl(dev
, BRCMF_C_SET_VAR
, cfg_priv
->ioctl_buf
,
2665 brcmf_dev_bufvar_get(struct net_device
*dev
, s8
*name
, s8
*buf
,
2668 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(dev
);
2672 len
= brcmu_mkiovar(name
, NULL
, 0, cfg_priv
->ioctl_buf
,
2675 err
= brcmf_dev_ioctl(dev
, BRCMF_C_GET_VAR
, (void *)cfg_priv
->ioctl_buf
,
2677 if (unlikely(err
)) {
2678 WL_ERR("error (%d)\n", err
);
2681 memcpy(buf
, cfg_priv
->ioctl_buf
, buf_len
);
2686 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_priv
*cfg_priv
)
2688 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
2689 struct brcmf_cfg80211_assoc_ielen
*assoc_info
;
2690 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg_priv
);
2695 brcmf_clear_assoc_ies(cfg_priv
);
2697 err
= brcmf_dev_bufvar_get(ndev
, "assoc_info", cfg_priv
->extra_buf
,
2699 if (unlikely(err
)) {
2700 WL_ERR("could not get assoc info (%d)\n", err
);
2703 assoc_info
= (struct brcmf_cfg80211_assoc_ielen
*)cfg_priv
->extra_buf
;
2704 req_len
= assoc_info
->req_len
;
2705 resp_len
= assoc_info
->resp_len
;
2707 err
= brcmf_dev_bufvar_get(ndev
, "assoc_req_ies",
2708 cfg_priv
->extra_buf
,
2710 if (unlikely(err
)) {
2711 WL_ERR("could not get assoc req (%d)\n", err
);
2714 conn_info
->req_ie_len
= req_len
;
2716 kmemdup(cfg_priv
->extra_buf
, conn_info
->req_ie_len
,
2719 conn_info
->req_ie_len
= 0;
2720 conn_info
->req_ie
= NULL
;
2723 err
= brcmf_dev_bufvar_get(ndev
, "assoc_resp_ies",
2724 cfg_priv
->extra_buf
,
2726 if (unlikely(err
)) {
2727 WL_ERR("could not get assoc resp (%d)\n", err
);
2730 conn_info
->resp_ie_len
= resp_len
;
2731 conn_info
->resp_ie
=
2732 kmemdup(cfg_priv
->extra_buf
, conn_info
->resp_ie_len
,
2735 conn_info
->resp_ie_len
= 0;
2736 conn_info
->resp_ie
= NULL
;
2738 WL_CONN("req len (%d) resp len (%d)\n",
2739 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
2744 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv
*cfg_priv
)
2746 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg_priv
);
2748 kfree(conn_info
->req_ie
);
2749 conn_info
->req_ie
= NULL
;
2750 conn_info
->req_ie_len
= 0;
2751 kfree(conn_info
->resp_ie
);
2752 conn_info
->resp_ie
= NULL
;
2753 conn_info
->resp_ie_len
= 0;
2757 static void brcmf_ch_to_chanspec(int ch
, struct brcmf_join_params
*join_params
,
2758 size_t *join_params_size
)
2763 join_params
->params
.chanspec_num
= 1;
2764 join_params
->params
.chanspec_list
[0] = ch
;
2766 if (join_params
->params
.chanspec_list
[0] <= CH_MAX_2G_CHANNEL
)
2767 chanspec
|= WL_CHANSPEC_BAND_2G
;
2769 chanspec
|= WL_CHANSPEC_BAND_5G
;
2771 chanspec
|= WL_CHANSPEC_BW_20
;
2772 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
2774 *join_params_size
+= BRCMF_ASSOC_PARAMS_FIXED_SIZE
+
2775 join_params
->params
.chanspec_num
* sizeof(u16
);
2777 join_params
->params
.chanspec_list
[0] &= WL_CHANSPEC_CHAN_MASK
;
2778 join_params
->params
.chanspec_list
[0] |= chanspec
;
2779 join_params
->params
.chanspec_list
[0] =
2780 cpu_to_le16(join_params
->params
.chanspec_list
[0]);
2782 join_params
->params
.chanspec_num
=
2783 cpu_to_le32(join_params
->params
.chanspec_num
);
2785 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2786 "channel %d, chanspec %#X\n",
2787 join_params
->params
.chanspec_list
[0], ch
, chanspec
);
2791 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_priv
*cfg_priv
)
2793 struct brcmf_bss_info
*bi
;
2794 struct brcmf_ssid
*ssid
;
2795 struct brcmu_tlv
*tim
;
2796 u16 beacon_interval
;
2802 WL_TRACE("Enter\n");
2803 if (brcmf_is_ibssmode(cfg_priv
))
2806 ssid
= (struct brcmf_ssid
*)brcmf_read_prof(cfg_priv
, WL_PROF_SSID
);
2808 *(u32
*)cfg_priv
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2809 err
= brcmf_dev_ioctl(cfg_to_ndev(cfg_priv
), BRCMF_C_GET_BSS_INFO
,
2810 cfg_priv
->extra_buf
, WL_EXTRA_BUF_MAX
);
2811 if (unlikely(err
)) {
2812 WL_ERR("Could not get bss info %d\n", err
);
2813 goto update_bss_info_out
;
2816 bi
= (struct brcmf_bss_info
*)(cfg_priv
->extra_buf
+ 4);
2817 err
= brcmf_inform_single_bss(cfg_priv
, bi
);
2819 goto update_bss_info_out
;
2821 ie
= ((u8
*)bi
) + bi
->ie_offset
;
2822 ie_len
= bi
->ie_length
;
2823 beacon_interval
= cpu_to_le16(bi
->beacon_period
);
2825 tim
= brcmu_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2827 dtim_period
= tim
->data
[1];
2830 * active scan was done so we could not get dtim
2831 * information out of probe response.
2832 * so we speficially query dtim information to dongle.
2835 err
= brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv
),
2836 "dtim_assoc", &var
);
2837 if (unlikely(err
)) {
2838 WL_ERR("wl dtim_assoc failed (%d)\n", err
);
2839 goto update_bss_info_out
;
2841 dtim_period
= (u8
)var
;
2844 brcmf_update_prof(cfg_priv
, NULL
, &beacon_interval
, WL_PROF_BEACONINT
);
2845 brcmf_update_prof(cfg_priv
, NULL
, &dtim_period
, WL_PROF_DTIMPERIOD
);
2847 update_bss_info_out
:
2853 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv
*cfg_priv
,
2854 struct net_device
*ndev
,
2855 const struct brcmf_event_msg
*e
)
2857 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg_priv
);
2858 struct wiphy
*wiphy
= cfg_to_wiphy(cfg_priv
);
2859 struct brcmf_channel_info channel
;
2860 struct ieee80211_channel
*notify_channel
;
2861 struct ieee80211_supported_band
*band
;
2865 WL_TRACE("Enter\n");
2867 brcmf_get_assoc_ies(cfg_priv
);
2868 brcmf_update_prof(cfg_priv
, NULL
, &e
->addr
, WL_PROF_BSSID
);
2869 brcmf_update_bss_info(cfg_priv
);
2871 brcmf_dev_ioctl(ndev
, BRCMF_C_GET_CHANNEL
, &channel
, sizeof(channel
));
2873 channel
.target_channel
= le32_to_cpu(channel
.target_channel
);
2874 WL_CONN("Roamed to channel %d\n", channel
.target_channel
);
2876 if (channel
.target_channel
<= CH_MAX_2G_CHANNEL
)
2877 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2879 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2881 freq
= ieee80211_channel_to_frequency(channel
.target_channel
,
2883 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2885 cfg80211_roamed(ndev
, notify_channel
,
2886 (u8
*)brcmf_read_prof(cfg_priv
, WL_PROF_BSSID
),
2887 conn_info
->req_ie
, conn_info
->req_ie_len
,
2888 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
2889 WL_CONN("Report roaming result\n");
2891 set_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
);
2897 brcmf_bss_connect_done(struct brcmf_cfg80211_priv
*cfg_priv
,
2898 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
2901 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg_priv
);
2904 WL_TRACE("Enter\n");
2906 if (test_and_clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
)) {
2908 brcmf_get_assoc_ies(cfg_priv
);
2909 brcmf_update_prof(cfg_priv
, NULL
, &e
->addr
,
2911 brcmf_update_bss_info(cfg_priv
);
2913 cfg80211_connect_result(ndev
,
2914 (u8
*)brcmf_read_prof(cfg_priv
,
2917 conn_info
->req_ie_len
,
2919 conn_info
->resp_ie_len
,
2920 completed
? WLAN_STATUS_SUCCESS
:
2921 WLAN_STATUS_AUTH_TIMEOUT
,
2924 set_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
);
2925 WL_CONN("Report connect result - connection %s\n",
2926 completed
? "succeeded" : "failed");
2933 brcmf_notify_mic_status(struct brcmf_cfg80211_priv
*cfg_priv
,
2934 struct net_device
*ndev
,
2935 const struct brcmf_event_msg
*e
, void *data
)
2937 u16 flags
= be16_to_cpu(e
->flags
);
2938 enum nl80211_key_type key_type
;
2941 if (flags
& BRCMF_EVENT_MSG_GROUP
)
2942 key_type
= NL80211_KEYTYPE_GROUP
;
2944 key_type
= NL80211_KEYTYPE_PAIRWISE
;
2946 cfg80211_michael_mic_failure(ndev
, (u8
*)&e
->addr
, key_type
, -1,
2954 brcmf_notify_scan_status(struct brcmf_cfg80211_priv
*cfg_priv
,
2955 struct net_device
*ndev
,
2956 const struct brcmf_event_msg
*e
, void *data
)
2958 struct brcmf_channel_info channel_inform
;
2959 struct brcmf_scan_results
*bss_list
;
2960 u32 len
= WL_SCAN_BUF_MAX
;
2962 bool scan_abort
= false;
2964 WL_TRACE("Enter\n");
2966 if (cfg_priv
->iscan_on
&& cfg_priv
->iscan_kickstart
) {
2968 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv
));
2971 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING
,
2972 &cfg_priv
->status
))) {
2973 WL_ERR("Scan complete while device not scanning\n");
2979 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_GET_CHANNEL
, &channel_inform
,
2980 sizeof(channel_inform
));
2981 if (unlikely(err
)) {
2982 WL_ERR("scan busy (%d)\n", err
);
2986 channel_inform
.scan_channel
= le32_to_cpu(channel_inform
.scan_channel
);
2987 if (unlikely(channel_inform
.scan_channel
)) {
2989 WL_CONN("channel_inform.scan_channel (%d)\n",
2990 channel_inform
.scan_channel
);
2992 cfg_priv
->bss_list
= cfg_priv
->scan_results
;
2993 bss_list
= cfg_priv
->bss_list
;
2994 memset(bss_list
, 0, len
);
2995 bss_list
->buflen
= cpu_to_le32(len
);
2997 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SCAN_RESULTS
, bss_list
, len
);
2998 if (unlikely(err
)) {
2999 WL_ERR("%s Scan_results error (%d)\n", ndev
->name
, err
);
3004 bss_list
->buflen
= le32_to_cpu(bss_list
->buflen
);
3005 bss_list
->version
= le32_to_cpu(bss_list
->version
);
3006 bss_list
->count
= le32_to_cpu(bss_list
->count
);
3008 err
= brcmf_inform_bss(cfg_priv
);
3015 if (cfg_priv
->scan_request
) {
3016 WL_SCAN("calling cfg80211_scan_done\n");
3017 cfg80211_scan_done(cfg_priv
->scan_request
, scan_abort
);
3018 brcmf_set_mpc(ndev
, 1);
3019 cfg_priv
->scan_request
= NULL
;
3027 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
3029 conf
->mode
= (u32
)-1;
3030 conf
->frag_threshold
= (u32
)-1;
3031 conf
->rts_threshold
= (u32
)-1;
3032 conf
->retry_short
= (u32
)-1;
3033 conf
->retry_long
= (u32
)-1;
3034 conf
->tx_power
= -1;
3037 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
3039 memset(prof
, 0, sizeof(*prof
));
3042 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop
*el
)
3044 memset(el
, 0, sizeof(*el
));
3045 el
->handler
[BRCMF_E_SCAN_COMPLETE
] = brcmf_notify_scan_status
;
3046 el
->handler
[BRCMF_E_LINK
] = brcmf_notify_connect_status
;
3047 el
->handler
[BRCMF_E_ROAM
] = brcmf_notify_roaming_status
;
3048 el
->handler
[BRCMF_E_MIC_ERROR
] = brcmf_notify_mic_status
;
3049 el
->handler
[BRCMF_E_SET_SSID
] = brcmf_notify_connect_status
;
3052 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_priv
*cfg_priv
)
3054 cfg_priv
->scan_results
= kzalloc(WL_SCAN_BUF_MAX
, GFP_KERNEL
);
3055 if (unlikely(!cfg_priv
->scan_results
)) {
3056 WL_ERR("Scan results alloc failed\n");
3057 goto init_priv_mem_out
;
3059 cfg_priv
->conf
= kzalloc(sizeof(*cfg_priv
->conf
), GFP_KERNEL
);
3060 if (unlikely(!cfg_priv
->conf
)) {
3061 WL_ERR("wl_conf alloc failed\n");
3062 goto init_priv_mem_out
;
3064 cfg_priv
->profile
= kzalloc(sizeof(*cfg_priv
->profile
), GFP_KERNEL
);
3065 if (unlikely(!cfg_priv
->profile
)) {
3066 WL_ERR("wl_profile alloc failed\n");
3067 goto init_priv_mem_out
;
3069 cfg_priv
->bss_info
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
3070 if (unlikely(!cfg_priv
->bss_info
)) {
3071 WL_ERR("Bss information alloc failed\n");
3072 goto init_priv_mem_out
;
3074 cfg_priv
->scan_req_int
= kzalloc(sizeof(*cfg_priv
->scan_req_int
),
3076 if (unlikely(!cfg_priv
->scan_req_int
)) {
3077 WL_ERR("Scan req alloc failed\n");
3078 goto init_priv_mem_out
;
3080 cfg_priv
->ioctl_buf
= kzalloc(WL_IOCTL_LEN_MAX
, GFP_KERNEL
);
3081 if (unlikely(!cfg_priv
->ioctl_buf
)) {
3082 WL_ERR("Ioctl buf alloc failed\n");
3083 goto init_priv_mem_out
;
3085 cfg_priv
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3086 if (unlikely(!cfg_priv
->extra_buf
)) {
3087 WL_ERR("Extra buf alloc failed\n");
3088 goto init_priv_mem_out
;
3090 cfg_priv
->iscan
= kzalloc(sizeof(*cfg_priv
->iscan
), GFP_KERNEL
);
3091 if (unlikely(!cfg_priv
->iscan
)) {
3092 WL_ERR("Iscan buf alloc failed\n");
3093 goto init_priv_mem_out
;
3095 cfg_priv
->pmk_list
= kzalloc(sizeof(*cfg_priv
->pmk_list
), GFP_KERNEL
);
3096 if (unlikely(!cfg_priv
->pmk_list
)) {
3097 WL_ERR("pmk list alloc failed\n");
3098 goto init_priv_mem_out
;
3104 brcmf_deinit_priv_mem(cfg_priv
);
3109 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv
*cfg_priv
)
3111 kfree(cfg_priv
->scan_results
);
3112 cfg_priv
->scan_results
= NULL
;
3113 kfree(cfg_priv
->bss_info
);
3114 cfg_priv
->bss_info
= NULL
;
3115 kfree(cfg_priv
->conf
);
3116 cfg_priv
->conf
= NULL
;
3117 kfree(cfg_priv
->profile
);
3118 cfg_priv
->profile
= NULL
;
3119 kfree(cfg_priv
->scan_req_int
);
3120 cfg_priv
->scan_req_int
= NULL
;
3121 kfree(cfg_priv
->ioctl_buf
);
3122 cfg_priv
->ioctl_buf
= NULL
;
3123 kfree(cfg_priv
->extra_buf
);
3124 cfg_priv
->extra_buf
= NULL
;
3125 kfree(cfg_priv
->iscan
);
3126 cfg_priv
->iscan
= NULL
;
3127 kfree(cfg_priv
->pmk_list
);
3128 cfg_priv
->pmk_list
= NULL
;
3131 static s32
brcmf_create_event_handler(struct brcmf_cfg80211_priv
*cfg_priv
)
3133 init_waitqueue_head(&cfg_priv
->event_waitq
);
3134 cfg_priv
->event_tsk
= kthread_run(brcmf_event_handler
, cfg_priv
,
3135 "wl_event_handler");
3136 if (IS_ERR(cfg_priv
->event_tsk
)) {
3137 cfg_priv
->event_tsk
= NULL
;
3138 WL_ERR("failed to create event thread\n");
3144 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv
*cfg_priv
)
3146 if (cfg_priv
->event_tsk
) {
3147 send_sig(SIGTERM
, cfg_priv
->event_tsk
, 1);
3148 kthread_stop(cfg_priv
->event_tsk
);
3149 cfg_priv
->event_tsk
= NULL
;
3153 static void brcmf_term_iscan(struct brcmf_cfg80211_priv
*cfg_priv
)
3155 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg_priv
);
3156 struct brcmf_ssid ssid
;
3158 if (cfg_priv
->iscan_on
&& iscan
->tsk
) {
3159 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3160 send_sig(SIGTERM
, iscan
->tsk
, 1);
3163 * The iscan task may want to acquire the rtnl_lock
3164 * so release it here upon stopping the task.
3167 kthread_stop(iscan
->tsk
);
3171 /* Abort iscan running in FW */
3172 memset(&ssid
, 0, sizeof(ssid
));
3173 brcmf_run_iscan(iscan
, &ssid
, WL_SCAN_ACTION_ABORT
);
3177 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl
*iscan
,
3180 struct brcmf_cfg80211_priv
*cfg_priv
= iscan_to_cfg(iscan
);
3181 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
3183 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING
,
3184 &cfg_priv
->status
))) {
3185 WL_ERR("Scan complete while device not scanning\n");
3188 if (likely(cfg_priv
->scan_request
)) {
3189 WL_SCAN("ISCAN Completed scan: %s\n",
3190 aborted
? "Aborted" : "Done");
3191 cfg80211_scan_done(cfg_priv
->scan_request
, aborted
);
3192 brcmf_set_mpc(ndev
, 1);
3193 cfg_priv
->scan_request
= NULL
;
3195 cfg_priv
->iscan_kickstart
= false;
3198 static s32
brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl
*iscan
)
3200 if (likely(iscan
->state
!= WL_ISCAN_STATE_IDLE
)) {
3201 WL_SCAN("wake up iscan\n");
3202 wake_up(&iscan
->waitq
);
3210 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl
*iscan
, u32
*status
,
3211 struct brcmf_scan_results
**bss_list
)
3213 struct brcmf_iscan_results list
;
3214 struct brcmf_scan_results
*results
;
3215 struct brcmf_iscan_results
*list_buf
;
3218 memset(iscan
->scan_buf
, 0, WL_ISCAN_BUF_MAX
);
3219 list_buf
= (struct brcmf_iscan_results
*)iscan
->scan_buf
;
3220 results
= &list_buf
->results
;
3221 results
->buflen
= BRCMF_ISCAN_RESULTS_FIXED_SIZE
;
3222 results
->version
= 0;
3225 memset(&list
, 0, sizeof(list
));
3226 list
.results
.buflen
= cpu_to_le32(WL_ISCAN_BUF_MAX
);
3227 err
= brcmf_dev_iovar_getbuf(iscan
->dev
, "iscanresults", &list
,
3228 BRCMF_ISCAN_RESULTS_FIXED_SIZE
, iscan
->scan_buf
,
3230 if (unlikely(err
)) {
3231 WL_ERR("error (%d)\n", err
);
3234 results
->buflen
= le32_to_cpu(results
->buflen
);
3235 results
->version
= le32_to_cpu(results
->version
);
3236 results
->count
= le32_to_cpu(results
->count
);
3237 WL_SCAN("results->count = %d\n", results
->count
);
3238 WL_SCAN("results->buflen = %d\n", results
->buflen
);
3239 *status
= le32_to_cpu(list_buf
->status
);
3240 WL_SCAN("status = %d\n", *status
);
3241 *bss_list
= results
;
3246 static s32
brcmf_iscan_done(struct brcmf_cfg80211_priv
*cfg_priv
)
3248 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_priv
->iscan
;
3251 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3253 brcmf_inform_bss(cfg_priv
);
3254 brcmf_notify_iscan_complete(iscan
, false);
3260 static s32
brcmf_iscan_pending(struct brcmf_cfg80211_priv
*cfg_priv
)
3262 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_priv
->iscan
;
3265 /* Reschedule the timer */
3266 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
3267 iscan
->timer_on
= 1;
3272 static s32
brcmf_iscan_inprogress(struct brcmf_cfg80211_priv
*cfg_priv
)
3274 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_priv
->iscan
;
3278 brcmf_inform_bss(cfg_priv
);
3279 brcmf_run_iscan(iscan
, NULL
, BRCMF_SCAN_ACTION_CONTINUE
);
3281 /* Reschedule the timer */
3282 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
3283 iscan
->timer_on
= 1;
3288 static s32
brcmf_iscan_aborted(struct brcmf_cfg80211_priv
*cfg_priv
)
3290 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_priv
->iscan
;
3293 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3295 brcmf_notify_iscan_complete(iscan
, true);
3301 static s32
brcmf_iscan_thread(void *data
)
3303 struct sched_param param
= {.sched_priority
= MAX_RT_PRIO
- 1 };
3304 struct brcmf_cfg80211_iscan_ctrl
*iscan
=
3305 (struct brcmf_cfg80211_iscan_ctrl
*)data
;
3306 struct brcmf_cfg80211_priv
*cfg_priv
= iscan_to_cfg(iscan
);
3307 struct brcmf_cfg80211_iscan_eloop
*el
= &iscan
->el
;
3308 DECLARE_WAITQUEUE(wait
, current
);
3312 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
3313 allow_signal(SIGTERM
);
3314 status
= BRCMF_SCAN_RESULTS_PARTIAL
;
3315 add_wait_queue(&iscan
->waitq
, &wait
);
3317 prepare_to_wait(&iscan
->waitq
, &wait
, TASK_INTERRUPTIBLE
);
3321 if (kthread_should_stop())
3323 if (iscan
->timer_on
) {
3324 del_timer_sync(&iscan
->timer
);
3325 iscan
->timer_on
= 0;
3328 err
= brcmf_get_iscan_results(iscan
, &status
,
3329 &cfg_priv
->bss_list
);
3330 if (unlikely(err
)) {
3331 status
= BRCMF_SCAN_RESULTS_ABORTED
;
3332 WL_ERR("Abort iscan\n");
3335 el
->handler
[status
](cfg_priv
);
3337 finish_wait(&iscan
->waitq
, &wait
);
3338 if (iscan
->timer_on
) {
3339 del_timer_sync(&iscan
->timer
);
3340 iscan
->timer_on
= 0;
3342 WL_SCAN("ISCAN thread terminated\n");
3347 static void brcmf_iscan_timer(unsigned long data
)
3349 struct brcmf_cfg80211_iscan_ctrl
*iscan
=
3350 (struct brcmf_cfg80211_iscan_ctrl
*)data
;
3353 iscan
->timer_on
= 0;
3354 WL_SCAN("timer expired\n");
3355 brcmf_wakeup_iscan(iscan
);
3359 static s32
brcmf_invoke_iscan(struct brcmf_cfg80211_priv
*cfg_priv
)
3361 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg_priv
);
3363 if (cfg_priv
->iscan_on
&& !iscan
->tsk
) {
3364 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3365 init_waitqueue_head(&iscan
->waitq
);
3366 iscan
->tsk
= kthread_run(brcmf_iscan_thread
, iscan
, "wl_iscan");
3367 if (IS_ERR(iscan
->tsk
)) {
3368 WL_ERR("Could not create iscan thread\n");
3377 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop
*el
)
3379 memset(el
, 0, sizeof(*el
));
3380 el
->handler
[BRCMF_SCAN_RESULTS_SUCCESS
] = brcmf_iscan_done
;
3381 el
->handler
[BRCMF_SCAN_RESULTS_PARTIAL
] = brcmf_iscan_inprogress
;
3382 el
->handler
[BRCMF_SCAN_RESULTS_PENDING
] = brcmf_iscan_pending
;
3383 el
->handler
[BRCMF_SCAN_RESULTS_ABORTED
] = brcmf_iscan_aborted
;
3384 el
->handler
[BRCMF_SCAN_RESULTS_NO_MEM
] = brcmf_iscan_aborted
;
3387 static s32
brcmf_init_iscan(struct brcmf_cfg80211_priv
*cfg_priv
)
3389 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg_priv
);
3392 if (cfg_priv
->iscan_on
) {
3393 iscan
->dev
= cfg_to_ndev(cfg_priv
);
3394 brcmf_init_iscan_eloop(&iscan
->el
);
3395 iscan
->timer_ms
= WL_ISCAN_TIMER_INTERVAL_MS
;
3396 init_timer(&iscan
->timer
);
3397 iscan
->timer
.data
= (unsigned long) iscan
;
3398 iscan
->timer
.function
= brcmf_iscan_timer
;
3399 err
= brcmf_invoke_iscan(cfg_priv
);
3401 iscan
->data
= cfg_priv
;
3407 static s32
wl_init_priv(struct brcmf_cfg80211_priv
*cfg_priv
)
3411 cfg_priv
->scan_request
= NULL
;
3412 #ifndef WL_POWERSAVE_DISABLED
3413 cfg_priv
->pwr_save
= true;
3414 #endif /* WL_POWERSAVE_DISABLED */
3415 cfg_priv
->iscan_on
= true; /* iscan on & off switch.
3416 we enable iscan per default */
3417 cfg_priv
->roam_on
= true; /* roam on & off switch.
3418 we enable roam per default */
3420 cfg_priv
->iscan_kickstart
= false;
3421 cfg_priv
->active_scan
= true; /* we do active scan for
3422 specific scan per default */
3423 cfg_priv
->dongle_up
= false; /* dongle is not up yet */
3424 brcmf_init_eq(cfg_priv
);
3425 err
= brcmf_init_priv_mem(cfg_priv
);
3428 if (unlikely(brcmf_create_event_handler(cfg_priv
)))
3430 brcmf_init_eloop_handler(&cfg_priv
->el
);
3431 mutex_init(&cfg_priv
->usr_sync
);
3432 err
= brcmf_init_iscan(cfg_priv
);
3435 brcmf_init_conf(cfg_priv
->conf
);
3436 brcmf_init_prof(cfg_priv
->profile
);
3437 brcmf_link_down(cfg_priv
);
3442 static void wl_deinit_priv(struct brcmf_cfg80211_priv
*cfg_priv
)
3444 brcmf_destroy_event_handler(cfg_priv
);
3445 cfg_priv
->dongle_up
= false; /* dongle down */
3446 brcmf_flush_eq(cfg_priv
);
3447 brcmf_link_down(cfg_priv
);
3448 brcmf_term_iscan(cfg_priv
);
3449 brcmf_deinit_priv_mem(cfg_priv
);
3452 s32
brcmf_cfg80211_attach(struct net_device
*ndev
, void *data
)
3454 struct wireless_dev
*wdev
;
3455 struct brcmf_cfg80211_priv
*cfg_priv
;
3456 struct brcmf_cfg80211_iface
*ci
;
3459 if (unlikely(!ndev
)) {
3460 WL_ERR("ndev is invalid\n");
3463 cfg80211_dev
= kzalloc(sizeof(struct brcmf_cfg80211_dev
), GFP_KERNEL
);
3464 if (unlikely(!cfg80211_dev
)) {
3465 WL_ERR("wl_cfg80211_dev is invalid\n");
3468 WL_INFO("func %p\n", brcmf_cfg80211_get_sdio_func());
3469 wdev
= brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface
),
3470 &brcmf_cfg80211_get_sdio_func()->dev
);
3474 wdev
->iftype
= brcmf_mode_to_nl80211_iftype(WL_MODE_BSS
);
3475 cfg_priv
= wdev_to_cfg(wdev
);
3476 cfg_priv
->wdev
= wdev
;
3477 cfg_priv
->pub
= data
;
3478 ci
= (struct brcmf_cfg80211_iface
*)&cfg_priv
->ci
;
3479 ci
->cfg_priv
= cfg_priv
;
3480 ndev
->ieee80211_ptr
= wdev
;
3481 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
3482 wdev
->netdev
= ndev
;
3483 err
= wl_init_priv(cfg_priv
);
3484 if (unlikely(err
)) {
3485 WL_ERR("Failed to init iwm_priv (%d)\n", err
);
3486 goto cfg80211_attach_out
;
3488 brcmf_set_drvdata(cfg80211_dev
, ci
);
3492 cfg80211_attach_out
:
3493 brcmf_free_wdev(cfg_priv
);
3497 void brcmf_cfg80211_detach(void)
3499 struct brcmf_cfg80211_priv
*cfg_priv
;
3501 cfg_priv
= WL_PRIV_GET();
3503 wl_deinit_priv(cfg_priv
);
3504 brcmf_free_wdev(cfg_priv
);
3505 brcmf_set_drvdata(cfg80211_dev
, NULL
);
3506 kfree(cfg80211_dev
);
3507 cfg80211_dev
= NULL
;
3508 brcmf_clear_sdio_func();
3511 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv
*cfg_priv
)
3513 wake_up(&cfg_priv
->event_waitq
);
3516 static s32
brcmf_event_handler(void *data
)
3518 struct brcmf_cfg80211_priv
*cfg_priv
=
3519 (struct brcmf_cfg80211_priv
*)data
;
3520 struct sched_param param
= {.sched_priority
= MAX_RT_PRIO
- 1 };
3521 struct brcmf_cfg80211_event_q
*e
;
3522 DECLARE_WAITQUEUE(wait
, current
);
3524 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
3525 allow_signal(SIGTERM
);
3526 add_wait_queue(&cfg_priv
->event_waitq
, &wait
);
3528 prepare_to_wait(&cfg_priv
->event_waitq
, &wait
,
3529 TASK_INTERRUPTIBLE
);
3533 if (kthread_should_stop())
3536 e
= brcmf_deq_event(cfg_priv
);
3538 WL_ERR("event queue empty...\n");
3543 WL_INFO("event type (%d)\n", e
->etype
);
3544 if (cfg_priv
->el
.handler
[e
->etype
])
3545 cfg_priv
->el
.handler
[e
->etype
](cfg_priv
,
3546 cfg_to_ndev(cfg_priv
),
3547 &e
->emsg
, e
->edata
);
3549 WL_INFO("Unknown Event (%d): ignoring\n",
3552 } while ((e
= brcmf_deq_event(cfg_priv
)));
3554 finish_wait(&cfg_priv
->event_waitq
, &wait
);
3555 WL_INFO("was terminated\n");
3560 brcmf_cfg80211_event(struct net_device
*ndev
,
3561 const struct brcmf_event_msg
*e
, void *data
)
3563 u32 event_type
= be32_to_cpu(e
->event_type
);
3564 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
3566 if (likely(!brcmf_enq_event(cfg_priv
, event_type
, e
)))
3567 brcmf_wakeup_event(cfg_priv
);
3570 static void brcmf_init_eq(struct brcmf_cfg80211_priv
*cfg_priv
)
3572 brcmf_init_eq_lock(cfg_priv
);
3573 INIT_LIST_HEAD(&cfg_priv
->eq_list
);
3576 static void brcmf_flush_eq(struct brcmf_cfg80211_priv
*cfg_priv
)
3578 struct brcmf_cfg80211_event_q
*e
;
3580 brcmf_lock_eq(cfg_priv
);
3581 while (!list_empty(&cfg_priv
->eq_list
)) {
3582 e
= list_first_entry(&cfg_priv
->eq_list
,
3583 struct brcmf_cfg80211_event_q
, eq_list
);
3584 list_del(&e
->eq_list
);
3587 brcmf_unlock_eq(cfg_priv
);
3591 * retrieve first queued event from head
3594 static struct brcmf_cfg80211_event_q
*brcmf_deq_event(
3595 struct brcmf_cfg80211_priv
*cfg_priv
)
3597 struct brcmf_cfg80211_event_q
*e
= NULL
;
3599 brcmf_lock_eq(cfg_priv
);
3600 if (likely(!list_empty(&cfg_priv
->eq_list
))) {
3601 e
= list_first_entry(&cfg_priv
->eq_list
,
3602 struct brcmf_cfg80211_event_q
, eq_list
);
3603 list_del(&e
->eq_list
);
3605 brcmf_unlock_eq(cfg_priv
);
3611 ** push event to tail of the queue
3615 brcmf_enq_event(struct brcmf_cfg80211_priv
*cfg_priv
, u32 event
,
3616 const struct brcmf_event_msg
*msg
)
3618 struct brcmf_cfg80211_event_q
*e
;
3621 e
= kzalloc(sizeof(struct brcmf_cfg80211_event_q
), GFP_KERNEL
);
3623 WL_ERR("event alloc failed\n");
3628 memcpy(&e
->emsg
, msg
, sizeof(struct brcmf_event_msg
));
3630 brcmf_lock_eq(cfg_priv
);
3631 list_add_tail(&e
->eq_list
, &cfg_priv
->eq_list
);
3632 brcmf_unlock_eq(cfg_priv
);
3637 static void brcmf_put_event(struct brcmf_cfg80211_event_q
*e
)
3642 void brcmf_cfg80211_sdio_func(void *func
)
3644 cfg80211_sdio_func
= (struct sdio_func
*)func
;
3647 static void brcmf_clear_sdio_func(void)
3649 cfg80211_sdio_func
= NULL
;
3652 struct sdio_func
*brcmf_cfg80211_get_sdio_func(void)
3654 return cfg80211_sdio_func
;
3657 static s32
brcmf_dongle_mode(struct net_device
*ndev
, s32 iftype
)
3663 case NL80211_IFTYPE_MONITOR
:
3664 case NL80211_IFTYPE_WDS
:
3665 WL_ERR("type (%d) : currently we do not support this mode\n",
3669 case NL80211_IFTYPE_ADHOC
:
3672 case NL80211_IFTYPE_STATION
:
3677 WL_ERR("invalid type (%d)\n", iftype
);
3680 infra
= cpu_to_le32(infra
);
3681 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_INFRA
, &infra
, sizeof(infra
));
3682 if (unlikely(err
)) {
3683 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
3690 static s32
brcmf_dongle_eventmsg(struct net_device
*ndev
)
3692 /* Room for "event_msgs" + '\0' + bitvec */
3693 s8 iovbuf
[BRCMF_EVENTING_MASK_LEN
+ 12];
3694 s8 eventmask
[BRCMF_EVENTING_MASK_LEN
];
3697 WL_TRACE("Enter\n");
3699 /* Setup event_msgs */
3700 brcmu_mkiovar("event_msgs", eventmask
, BRCMF_EVENTING_MASK_LEN
, iovbuf
,
3702 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_GET_VAR
, iovbuf
, sizeof(iovbuf
));
3703 if (unlikely(err
)) {
3704 WL_ERR("Get event_msgs error (%d)\n", err
);
3705 goto dongle_eventmsg_out
;
3707 memcpy(eventmask
, iovbuf
, BRCMF_EVENTING_MASK_LEN
);
3709 setbit(eventmask
, BRCMF_E_SET_SSID
);
3710 setbit(eventmask
, BRCMF_E_ROAM
);
3711 setbit(eventmask
, BRCMF_E_PRUNE
);
3712 setbit(eventmask
, BRCMF_E_AUTH
);
3713 setbit(eventmask
, BRCMF_E_REASSOC
);
3714 setbit(eventmask
, BRCMF_E_REASSOC_IND
);
3715 setbit(eventmask
, BRCMF_E_DEAUTH_IND
);
3716 setbit(eventmask
, BRCMF_E_DISASSOC_IND
);
3717 setbit(eventmask
, BRCMF_E_DISASSOC
);
3718 setbit(eventmask
, BRCMF_E_JOIN
);
3719 setbit(eventmask
, BRCMF_E_ASSOC_IND
);
3720 setbit(eventmask
, BRCMF_E_PSK_SUP
);
3721 setbit(eventmask
, BRCMF_E_LINK
);
3722 setbit(eventmask
, BRCMF_E_NDIS_LINK
);
3723 setbit(eventmask
, BRCMF_E_MIC_ERROR
);
3724 setbit(eventmask
, BRCMF_E_PMKID_CACHE
);
3725 setbit(eventmask
, BRCMF_E_TXFAIL
);
3726 setbit(eventmask
, BRCMF_E_JOIN_START
);
3727 setbit(eventmask
, BRCMF_E_SCAN_COMPLETE
);
3729 brcmu_mkiovar("event_msgs", eventmask
, BRCMF_EVENTING_MASK_LEN
, iovbuf
,
3731 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3732 if (unlikely(err
)) {
3733 WL_ERR("Set event_msgs error (%d)\n", err
);
3734 goto dongle_eventmsg_out
;
3737 dongle_eventmsg_out
:
3743 brcmf_dongle_roam(struct net_device
*ndev
, u32 roamvar
, u32 bcn_timeout
)
3751 * Setup timeout if Beacons are lost and roam is
3752 * off to report link down
3755 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout
,
3756 sizeof(bcn_timeout
), iovbuf
, sizeof(iovbuf
));
3757 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_VAR
,
3758 iovbuf
, sizeof(iovbuf
));
3759 if (unlikely(err
)) {
3760 WL_ERR("bcn_timeout error (%d)\n", err
);
3761 goto dongle_rom_out
;
3766 * Enable/Disable built-in roaming to allow supplicant
3767 * to take care of roaming
3769 WL_INFO("Internal Roaming = %s\n", roamvar
? "Off" : "On");
3770 brcmu_mkiovar("roam_off", (char *)&roamvar
,
3771 sizeof(roamvar
), iovbuf
, sizeof(iovbuf
));
3772 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3773 if (unlikely(err
)) {
3774 WL_ERR("roam_off error (%d)\n", err
);
3775 goto dongle_rom_out
;
3778 roamtrigger
[0] = WL_ROAM_TRIGGER_LEVEL
;
3779 roamtrigger
[1] = BRCM_BAND_ALL
;
3780 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_ROAM_TRIGGER
,
3781 (void *)roamtrigger
, sizeof(roamtrigger
));
3782 if (unlikely(err
)) {
3783 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
3784 goto dongle_rom_out
;
3787 roam_delta
[0] = WL_ROAM_DELTA
;
3788 roam_delta
[1] = BRCM_BAND_ALL
;
3789 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_ROAM_DELTA
,
3790 (void *)roam_delta
, sizeof(roam_delta
));
3791 if (unlikely(err
)) {
3792 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err
);
3793 goto dongle_rom_out
;
3801 brcmf_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
3802 s32 scan_unassoc_time
, s32 scan_passive_time
)
3806 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
3807 &scan_assoc_time
, sizeof(scan_assoc_time
));
3809 if (err
== -EOPNOTSUPP
)
3810 WL_INFO("Scan assoc time is not supported\n");
3812 WL_ERR("Scan assoc time error (%d)\n", err
);
3813 goto dongle_scantime_out
;
3815 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
3816 &scan_unassoc_time
, sizeof(scan_unassoc_time
));
3818 if (err
== -EOPNOTSUPP
)
3819 WL_INFO("Scan unassoc time is not supported\n");
3821 WL_ERR("Scan unassoc time error (%d)\n", err
);
3822 goto dongle_scantime_out
;
3825 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
3826 &scan_passive_time
, sizeof(scan_passive_time
));
3828 if (err
== -EOPNOTSUPP
)
3829 WL_INFO("Scan passive time is not supported\n");
3831 WL_ERR("Scan passive time error (%d)\n", err
);
3832 goto dongle_scantime_out
;
3835 dongle_scantime_out
:
3839 s32
brcmf_config_dongle(struct brcmf_cfg80211_priv
*cfg_priv
, bool need_lock
)
3841 struct net_device
*ndev
;
3842 struct wireless_dev
*wdev
;
3846 if (cfg_priv
->dongle_up
)
3849 ndev
= cfg_to_ndev(cfg_priv
);
3850 wdev
= ndev
->ieee80211_ptr
;
3854 brcmf_dongle_scantime(ndev
, WL_SCAN_CHANNEL_TIME
,
3855 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
3857 err
= brcmf_dongle_eventmsg(ndev
);
3859 goto default_conf_out
;
3861 power_mode
= cfg_priv
->pwr_save
? PM_FAST
: PM_OFF
;
3862 power_mode
= cpu_to_le32(power_mode
);
3863 err
= brcmf_dev_ioctl(ndev
, BRCMF_C_SET_PM
,
3864 &power_mode
, sizeof(power_mode
));
3866 goto default_conf_out
;
3867 WL_INFO("power save set to %s\n",
3868 (power_mode
? "enabled" : "disabled"));
3870 err
= brcmf_dongle_roam(ndev
, (cfg_priv
->roam_on
? 0 : 1),
3873 goto default_conf_out
;
3874 err
= brcmf_dongle_mode(ndev
, wdev
->iftype
);
3875 if (unlikely(err
&& err
!= -EINPROGRESS
))
3876 goto default_conf_out
;
3877 err
= brcmf_dongle_probecap(cfg_priv
);
3879 goto default_conf_out
;
3881 /* -EINPROGRESS: Call commit handler */
3887 cfg_priv
->dongle_up
= true;
3893 static s32
wl_update_wiphybands(struct brcmf_cfg80211_priv
*cfg_priv
)
3895 struct wiphy
*wiphy
;
3900 err
= brcmf_dev_ioctl(cfg_to_ndev(cfg_priv
), BRCM_GET_PHYLIST
,
3901 &phy_list
, sizeof(phy_list
));
3902 if (unlikely(err
)) {
3903 WL_ERR("error (%d)\n", err
);
3907 phy
= ((char *)&phy_list
)[1];
3908 WL_INFO("%c phy\n", phy
);
3909 if (phy
== 'n' || phy
== 'a') {
3910 wiphy
= cfg_to_wiphy(cfg_priv
);
3911 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
3917 static s32
__brcmf_cfg80211_up(struct brcmf_cfg80211_priv
*cfg_priv
)
3921 set_bit(WL_STATUS_READY
, &cfg_priv
->status
);
3923 brcmf_debugfs_add_netdev_params(cfg_priv
);
3925 err
= brcmf_config_dongle(cfg_priv
, false);
3929 brcmf_invoke_iscan(cfg_priv
);
3934 static s32
__brcmf_cfg80211_down(struct brcmf_cfg80211_priv
*cfg_priv
)
3937 * While going down, if associated with AP disassociate
3938 * from AP to save power
3940 if ((test_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
) ||
3941 test_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
)) &&
3942 test_bit(WL_STATUS_READY
, &cfg_priv
->status
)) {
3943 WL_INFO("Disassociating from AP");
3944 brcmf_link_down(cfg_priv
);
3946 /* Make sure WPA_Supplicant receives all the event
3947 generated due to DISASSOC call to the fw to keep
3948 the state fw and WPA_Supplicant state consistent
3955 set_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
);
3956 brcmf_term_iscan(cfg_priv
);
3957 if (cfg_priv
->scan_request
) {
3958 cfg80211_scan_done(cfg_priv
->scan_request
, true);
3959 /* May need to perform this to cover rmmod */
3960 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3961 cfg_priv
->scan_request
= NULL
;
3963 clear_bit(WL_STATUS_READY
, &cfg_priv
->status
);
3964 clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
);
3965 clear_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
);
3967 brcmf_debugfs_remove_netdev(cfg_priv
);
3972 s32
brcmf_cfg80211_up(void)
3974 struct brcmf_cfg80211_priv
*cfg_priv
;
3977 cfg_priv
= WL_PRIV_GET();
3978 mutex_lock(&cfg_priv
->usr_sync
);
3979 err
= __brcmf_cfg80211_up(cfg_priv
);
3980 mutex_unlock(&cfg_priv
->usr_sync
);
3985 s32
brcmf_cfg80211_down(void)
3987 struct brcmf_cfg80211_priv
*cfg_priv
;
3990 cfg_priv
= WL_PRIV_GET();
3991 mutex_lock(&cfg_priv
->usr_sync
);
3992 err
= __brcmf_cfg80211_down(cfg_priv
);
3993 mutex_unlock(&cfg_priv
->usr_sync
);
3998 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_priv
*cfg_priv
)
4000 return wl_update_wiphybands(cfg_priv
);
4003 static void *brcmf_read_prof(struct brcmf_cfg80211_priv
*cfg_priv
, s32 item
)
4007 return &cfg_priv
->profile
->sec
;
4009 return &cfg_priv
->profile
->bssid
;
4011 return &cfg_priv
->profile
->ssid
;
4013 WL_ERR("invalid item (%d)\n", item
);
4018 brcmf_update_prof(struct brcmf_cfg80211_priv
*cfg_priv
,
4019 const struct brcmf_event_msg
*e
, void *data
, s32 item
)
4022 struct brcmf_ssid
*ssid
;
4026 ssid
= (struct brcmf_ssid
*) data
;
4027 memset(cfg_priv
->profile
->ssid
.SSID
, 0,
4028 sizeof(cfg_priv
->profile
->ssid
.SSID
));
4029 memcpy(cfg_priv
->profile
->ssid
.SSID
,
4030 ssid
->SSID
, ssid
->SSID_len
);
4031 cfg_priv
->profile
->ssid
.SSID_len
= ssid
->SSID_len
;
4035 memcpy(cfg_priv
->profile
->bssid
, data
, ETH_ALEN
);
4037 memset(cfg_priv
->profile
->bssid
, 0, ETH_ALEN
);
4040 memcpy(&cfg_priv
->profile
->sec
, data
,
4041 sizeof(cfg_priv
->profile
->sec
));
4043 case WL_PROF_BEACONINT
:
4044 cfg_priv
->profile
->beacon_interval
= *(u16
*)data
;
4046 case WL_PROF_DTIMPERIOD
:
4047 cfg_priv
->profile
->dtim_period
= *(u8
*)data
;
4050 WL_ERR("unsupported item (%d)\n", item
);
4058 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv
*cfg_priv
)
4060 return cfg_priv
->conf
->mode
== WL_MODE_IBSS
;
4063 static __used s32
brcmf_add_ie(struct brcmf_cfg80211_priv
*cfg_priv
,
4066 struct brcmf_cfg80211_ie
*ie
= &cfg_priv
->ie
;
4069 if (unlikely(ie
->offset
+ l
+ 2 > WL_TLV_INFO_MAX
)) {
4070 WL_ERR("ei crosses buffer boundary\n");
4073 ie
->buf
[ie
->offset
] = t
;
4074 ie
->buf
[ie
->offset
+ 1] = l
;
4075 memcpy(&ie
->buf
[ie
->offset
+ 2], v
, l
);
4076 ie
->offset
+= l
+ 2;
4081 static void brcmf_link_down(struct brcmf_cfg80211_priv
*cfg_priv
)
4083 struct net_device
*dev
= NULL
;
4086 WL_TRACE("Enter\n");
4088 if (cfg_priv
->link_up
) {
4089 dev
= cfg_to_ndev(cfg_priv
);
4090 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
4091 err
= brcmf_dev_ioctl(dev
, BRCMF_C_DISASSOC
, NULL
, 0);
4093 WL_ERR("WLC_DISASSOC failed (%d)\n", err
);
4094 cfg_priv
->link_up
= false;
4099 static void brcmf_lock_eq(struct brcmf_cfg80211_priv
*cfg_priv
)
4101 spin_lock_irq(&cfg_priv
->eq_lock
);
4104 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv
*cfg_priv
)
4106 spin_unlock_irq(&cfg_priv
->eq_lock
);
4109 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv
*cfg_priv
)
4111 spin_lock_init(&cfg_priv
->eq_lock
);
4114 static void brcmf_delay(u32 ms
)
4116 if (ms
< 1000 / HZ
) {
4124 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev
*dev
, void *data
)
4126 dev
->driver_data
= data
;
4129 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev
*dev
)
4134 data
= dev
->driver_data
;
4138 static void brcmf_set_mpc(struct net_device
*ndev
, int mpc
)
4141 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
4143 if (test_bit(WL_STATUS_READY
, &cfg_priv
->status
)) {
4144 err
= brcmf_dev_intvar_set(ndev
, "mpc", mpc
);
4145 if (unlikely(err
)) {
4146 WL_ERR("fail to set mpc\n");
4149 WL_INFO("MPC : %d\n", mpc
);
4153 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv
*cfg_priv
)
4155 char buf
[10+IFNAMSIZ
];
4159 sprintf(buf
, "netdev:%s", cfg_to_ndev(cfg_priv
)->name
);
4160 cfg_priv
->debugfsdir
= debugfs_create_dir(buf
,
4161 cfg_to_wiphy(cfg_priv
)->debugfsdir
);
4163 fd
= debugfs_create_u16("beacon_int", S_IRUGO
, cfg_priv
->debugfsdir
,
4164 (u16
*)&cfg_priv
->profile
->beacon_interval
);
4170 fd
= debugfs_create_u8("dtim_period", S_IRUGO
, cfg_priv
->debugfsdir
,
4171 (u8
*)&cfg_priv
->profile
->dtim_period
);
4181 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv
*cfg_priv
)
4183 debugfs_remove_recursive(cfg_priv
->debugfsdir
);
4184 cfg_priv
->debugfsdir
= NULL
;