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>
21 #include <brcmu_utils.h>
23 #include <brcmu_wifi.h>
25 #include <asm/uaccess.h>
27 #include <dngl_stats.h>
30 #include <linux/kthread.h>
31 #include <linux/netdevice.h>
32 #include <linux/sched.h>
33 #include <linux/etherdevice.h>
34 #include <linux/wireless.h>
35 #include <linux/ieee80211.h>
36 #include <net/cfg80211.h>
38 #include <net/rtnetlink.h>
39 #include <linux/mmc/sdio_func.h>
40 #include <linux/firmware.h>
41 #include <wl_cfg80211.h>
43 void sdioh_sdio_set_host_pm_flags(int flag
);
45 static struct sdio_func
*cfg80211_sdio_func
;
46 static struct wl_dev
*wl_cfg80211_dev
;
47 static const u8 ether_bcast
[ETH_ALEN
] = {255, 255, 255, 255, 255, 255};
49 u32 brcmf_dbg_level
= WL_DBG_ERR
;
51 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
52 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
55 ** cfg80211_ops api/callback list
57 static s32
wl_cfg80211_change_iface(struct wiphy
*wiphy
,
58 struct net_device
*ndev
,
59 enum nl80211_iftype type
, u32
*flags
,
60 struct vif_params
*params
);
61 static s32
__wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
62 struct cfg80211_scan_request
*request
,
63 struct cfg80211_ssid
*this_ssid
);
64 static s32
wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
65 struct cfg80211_scan_request
*request
);
66 static s32
wl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
);
67 static s32
wl_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
68 struct cfg80211_ibss_params
*params
);
69 static s32
wl_cfg80211_leave_ibss(struct wiphy
*wiphy
,
70 struct net_device
*dev
);
71 static s32
wl_cfg80211_get_station(struct wiphy
*wiphy
,
72 struct net_device
*dev
, u8
*mac
,
73 struct station_info
*sinfo
);
74 static s32
wl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
75 struct net_device
*dev
, bool enabled
,
77 static s32
wl_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
,
78 struct net_device
*dev
,
80 const struct cfg80211_bitrate_mask
82 static int wl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
83 struct cfg80211_connect_params
*sme
);
84 static s32
wl_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
86 static s32
wl_cfg80211_set_tx_power(struct wiphy
*wiphy
,
87 enum nl80211_tx_power_setting type
,
89 static s32
wl_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
);
90 static s32
wl_cfg80211_config_default_key(struct wiphy
*wiphy
,
91 struct net_device
*dev
, u8 key_idx
,
92 bool unicast
, bool multicast
);
93 static s32
wl_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
94 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
95 struct key_params
*params
);
96 static s32
wl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
97 u8 key_idx
, bool pairwise
, const u8
*mac_addr
);
98 static s32
wl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
99 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
100 void *cookie
, void (*callback
) (void *cookie
,
104 static s32
wl_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
105 struct net_device
*dev
,
107 static s32
wl_cfg80211_resume(struct wiphy
*wiphy
);
108 static s32
wl_cfg80211_suspend(struct wiphy
*wiphy
);
109 static s32
wl_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
110 struct cfg80211_pmksa
*pmksa
);
111 static s32
wl_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
112 struct cfg80211_pmksa
*pmksa
);
113 static s32
wl_cfg80211_flush_pmksa(struct wiphy
*wiphy
,
114 struct net_device
*dev
);
116 ** event & event Q handlers for cfg80211 interfaces
118 static s32
wl_create_event_handler(struct wl_priv
*wl
);
119 static void wl_destroy_event_handler(struct wl_priv
*wl
);
120 static s32
wl_event_handler(void *data
);
121 static void wl_init_eq(struct wl_priv
*wl
);
122 static void wl_flush_eq(struct wl_priv
*wl
);
123 static void wl_lock_eq(struct wl_priv
*wl
);
124 static void wl_unlock_eq(struct wl_priv
*wl
);
125 static void wl_init_eq_lock(struct wl_priv
*wl
);
126 static void wl_init_eloop_handler(struct wl_event_loop
*el
);
127 static struct wl_event_q
*wl_deq_event(struct wl_priv
*wl
);
128 static s32
wl_enq_event(struct wl_priv
*wl
, u32 type
,
129 const wl_event_msg_t
*msg
, void *data
);
130 static void wl_put_event(struct wl_event_q
*e
);
131 static void wl_wakeup_event(struct wl_priv
*wl
);
132 static s32
wl_notify_connect_status(struct wl_priv
*wl
,
133 struct net_device
*ndev
,
134 const wl_event_msg_t
*e
, void *data
);
135 static s32
wl_notify_roaming_status(struct wl_priv
*wl
,
136 struct net_device
*ndev
,
137 const wl_event_msg_t
*e
, void *data
);
138 static s32
wl_notify_scan_status(struct wl_priv
*wl
, struct net_device
*ndev
,
139 const wl_event_msg_t
*e
, void *data
);
140 static s32
wl_bss_connect_done(struct wl_priv
*wl
, struct net_device
*ndev
,
141 const wl_event_msg_t
*e
, void *data
,
143 static s32
wl_bss_roaming_done(struct wl_priv
*wl
, struct net_device
*ndev
,
144 const wl_event_msg_t
*e
, void *data
);
145 static s32
wl_notify_mic_status(struct wl_priv
*wl
, struct net_device
*ndev
,
146 const wl_event_msg_t
*e
, void *data
);
149 ** register/deregister sdio function
151 struct sdio_func
*wl_cfg80211_get_sdio_func(void);
152 static void wl_clear_sdio_func(void);
157 static s32
wl_dev_bufvar_get(struct net_device
*dev
, s8
*name
, s8
*buf
,
159 static __used s32
wl_dev_bufvar_set(struct net_device
*dev
, s8
*name
,
161 static s32
wl_dev_intvar_set(struct net_device
*dev
, s8
*name
, s32 val
);
162 static s32
wl_dev_intvar_get(struct net_device
*dev
, s8
*name
,
164 static s32
wl_dev_ioctl(struct net_device
*dev
, u32 cmd
, void *arg
,
168 ** cfg80211 set_wiphy_params utilities
170 static s32
wl_set_frag(struct net_device
*dev
, u32 frag_threshold
);
171 static s32
wl_set_rts(struct net_device
*dev
, u32 frag_threshold
);
172 static s32
wl_set_retry(struct net_device
*dev
, u32 retry
, bool l
);
175 ** wl profile utilities
177 static s32
wl_update_prof(struct wl_priv
*wl
, const wl_event_msg_t
*e
,
178 void *data
, s32 item
);
179 static void *wl_read_prof(struct wl_priv
*wl
, s32 item
);
180 static void wl_init_prof(struct wl_profile
*prof
);
183 ** cfg80211 connect utilites
185 static s32
wl_set_wpa_version(struct net_device
*dev
,
186 struct cfg80211_connect_params
*sme
);
187 static s32
wl_set_auth_type(struct net_device
*dev
,
188 struct cfg80211_connect_params
*sme
);
189 static s32
wl_set_set_cipher(struct net_device
*dev
,
190 struct cfg80211_connect_params
*sme
);
191 static s32
wl_set_key_mgmt(struct net_device
*dev
,
192 struct cfg80211_connect_params
*sme
);
193 static s32
wl_set_set_sharedkey(struct net_device
*dev
,
194 struct cfg80211_connect_params
*sme
);
195 static s32
wl_get_assoc_ies(struct wl_priv
*wl
);
196 static void wl_clear_assoc_ies(struct wl_priv
*wl
);
197 static void wl_ch_to_chanspec(int ch
,
198 struct wl_join_params
*join_params
, size_t *join_params_size
);
201 ** information element utilities
203 static __used s32
wl_add_ie(struct wl_priv
*wl
, u8 t
, u8 l
, u8
*v
);
204 static s32
wl_mode_to_nl80211_iftype(s32 mode
);
205 static struct wireless_dev
*wl_alloc_wdev(s32 sizeof_iface
,
207 static void wl_free_wdev(struct wl_priv
*wl
);
208 static s32
wl_inform_bss(struct wl_priv
*wl
);
209 static s32
wl_inform_single_bss(struct wl_priv
*wl
, struct wl_bss_info
*bi
);
210 static s32
wl_update_bss_info(struct wl_priv
*wl
);
211 static s32
wl_add_keyext(struct wiphy
*wiphy
, struct net_device
*dev
,
212 u8 key_idx
, const u8
*mac_addr
,
213 struct key_params
*params
);
216 ** key indianess swap utilities
218 static void swap_key_from_BE(struct wl_wsec_key
*key
);
219 static void swap_key_to_BE(struct wl_wsec_key
*key
);
222 ** wl_priv memory init/deinit utilities
224 static s32
wl_init_priv_mem(struct wl_priv
*wl
);
225 static void wl_deinit_priv_mem(struct wl_priv
*wl
);
227 static void wl_delay(u32 ms
);
230 ** store/restore cfg80211 instance data
232 static void wl_set_drvdata(struct wl_dev
*dev
, void *data
);
233 static void *wl_get_drvdata(struct wl_dev
*dev
);
236 ** ibss mode utilities
238 static bool wl_is_ibssmode(struct wl_priv
*wl
);
241 ** dongle up/down , default configuration utilities
243 static bool wl_is_linkdown(struct wl_priv
*wl
, const wl_event_msg_t
*e
);
244 static bool wl_is_linkup(struct wl_priv
*wl
, const wl_event_msg_t
*e
);
245 static bool wl_is_nonetwork(struct wl_priv
*wl
, const wl_event_msg_t
*e
);
246 static void wl_link_down(struct wl_priv
*wl
);
247 static s32
wl_dongle_mode(struct net_device
*ndev
, s32 iftype
);
248 static s32
__wl_cfg80211_up(struct wl_priv
*wl
);
249 static s32
__wl_cfg80211_down(struct wl_priv
*wl
);
250 static s32
wl_dongle_probecap(struct wl_priv
*wl
);
251 static void wl_init_conf(struct wl_conf
*conf
);
254 ** dongle configuration utilities
256 #ifndef EMBEDDED_PLATFORM
257 static s32
wl_dongle_mode(struct net_device
*ndev
, s32 iftype
);
258 static s32
wl_dongle_country(struct net_device
*ndev
, u8 ccode
);
259 static s32
wl_dongle_up(struct net_device
*ndev
, u32 up
);
260 static s32
wl_dongle_power(struct net_device
*ndev
, u32 power_mode
);
261 static s32
wl_dongle_glom(struct net_device
*ndev
, u32 glom
,
263 static s32
wl_dongle_offload(struct net_device
*ndev
, s32 arpoe
,
265 static s32
wl_pattern_atoh(s8
*src
, s8
*dst
);
266 static s32
wl_dongle_filter(struct net_device
*ndev
, u32 filter_mode
);
267 static s32
wl_update_wiphybands(struct wl_priv
*wl
);
268 #endif /* !EMBEDDED_PLATFORM */
270 static s32
wl_dongle_eventmsg(struct net_device
*ndev
);
271 static s32
wl_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
272 s32 scan_unassoc_time
, s32 scan_passive_time
);
273 static s32
wl_config_dongle(struct wl_priv
*wl
, bool need_lock
);
274 static s32
wl_dongle_roam(struct net_device
*ndev
, u32 roamvar
,
280 static void wl_iscan_timer(unsigned long data
);
281 static void wl_term_iscan(struct wl_priv
*wl
);
282 static s32
wl_init_iscan(struct wl_priv
*wl
);
283 static s32
wl_iscan_thread(void *data
);
284 static s32
wl_dev_iovar_setbuf(struct net_device
*dev
, s8
*iovar
,
285 void *param
, s32 paramlen
, void *bufptr
,
287 static s32
wl_dev_iovar_getbuf(struct net_device
*dev
, s8
*iovar
,
288 void *param
, s32 paramlen
, void *bufptr
,
290 static s32
wl_run_iscan(struct wl_iscan_ctrl
*iscan
, struct wlc_ssid
*ssid
,
292 static s32
wl_do_iscan(struct wl_priv
*wl
);
293 static s32
wl_wakeup_iscan(struct wl_iscan_ctrl
*iscan
);
294 static s32
wl_invoke_iscan(struct wl_priv
*wl
);
295 static s32
wl_get_iscan_results(struct wl_iscan_ctrl
*iscan
, u32
*status
,
296 struct wl_scan_results
**bss_list
);
297 static void wl_notify_iscan_complete(struct wl_iscan_ctrl
*iscan
, bool aborted
);
298 static void wl_init_iscan_eloop(struct wl_iscan_eloop
*el
);
299 static s32
wl_iscan_done(struct wl_priv
*wl
);
300 static s32
wl_iscan_pending(struct wl_priv
*wl
);
301 static s32
wl_iscan_inprogress(struct wl_priv
*wl
);
302 static s32
wl_iscan_aborted(struct wl_priv
*wl
);
305 ** fw/nvram downloading handler
307 static void wl_init_fw(struct wl_fw_ctrl
*fw
);
310 * find most significant bit set
312 static __used u32
wl_find_msb(u16 bit16
);
315 * update pmklist to dongle
317 static __used s32
wl_update_pmklist(struct net_device
*dev
,
318 struct wl_pmk_list
*pmk_list
, s32 err
);
320 static void wl_set_mpc(struct net_device
*ndev
, int mpc
);
325 static int wl_debugfs_add_netdev_params(struct wl_priv
*wl
);
326 static void wl_debugfs_remove_netdev(struct wl_priv
*wl
);
328 #define WL_PRIV_GET() \
330 struct wl_iface *ci; \
331 if (unlikely(!(wl_cfg80211_dev && \
332 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
333 WL_ERR("wl_cfg80211_dev is unavailable\n"); \
339 #define CHECK_SYS_UP() \
341 struct wl_priv *wl = wiphy_to_wl(wiphy); \
342 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
343 WL_INFO("device is not ready : status (%d)\n", \
349 extern int dhd_wait_pend8021x(struct net_device
*dev
);
350 #define CHAN2G(_channel, _freq, _flags) { \
351 .band = IEEE80211_BAND_2GHZ, \
352 .center_freq = (_freq), \
353 .hw_value = (_channel), \
355 .max_antenna_gain = 0, \
359 #define CHAN5G(_channel, _flags) { \
360 .band = IEEE80211_BAND_5GHZ, \
361 .center_freq = 5000 + (5 * (_channel)), \
362 .hw_value = (_channel), \
364 .max_antenna_gain = 0, \
368 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
369 #define RATETAB_ENT(_rateid, _flags) \
371 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
372 .hw_value = (_rateid), \
376 static struct ieee80211_rate __wl_rates
[] = {
377 RATETAB_ENT(WLC_RATE_1M
, 0),
378 RATETAB_ENT(WLC_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
379 RATETAB_ENT(WLC_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
380 RATETAB_ENT(WLC_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
381 RATETAB_ENT(WLC_RATE_6M
, 0),
382 RATETAB_ENT(WLC_RATE_9M
, 0),
383 RATETAB_ENT(WLC_RATE_12M
, 0),
384 RATETAB_ENT(WLC_RATE_18M
, 0),
385 RATETAB_ENT(WLC_RATE_24M
, 0),
386 RATETAB_ENT(WLC_RATE_36M
, 0),
387 RATETAB_ENT(WLC_RATE_48M
, 0),
388 RATETAB_ENT(WLC_RATE_54M
, 0),
391 #define wl_a_rates (__wl_rates + 4)
392 #define wl_a_rates_size 8
393 #define wl_g_rates (__wl_rates + 0)
394 #define wl_g_rates_size 12
396 static struct ieee80211_channel __wl_2ghz_channels
[] = {
413 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
414 CHAN5G(34, 0), CHAN5G(36, 0),
415 CHAN5G(38, 0), CHAN5G(40, 0),
416 CHAN5G(42, 0), CHAN5G(44, 0),
417 CHAN5G(46, 0), CHAN5G(48, 0),
418 CHAN5G(52, 0), CHAN5G(56, 0),
419 CHAN5G(60, 0), CHAN5G(64, 0),
420 CHAN5G(100, 0), CHAN5G(104, 0),
421 CHAN5G(108, 0), CHAN5G(112, 0),
422 CHAN5G(116, 0), CHAN5G(120, 0),
423 CHAN5G(124, 0), CHAN5G(128, 0),
424 CHAN5G(132, 0), CHAN5G(136, 0),
425 CHAN5G(140, 0), CHAN5G(149, 0),
426 CHAN5G(153, 0), CHAN5G(157, 0),
427 CHAN5G(161, 0), CHAN5G(165, 0),
428 CHAN5G(184, 0), CHAN5G(188, 0),
429 CHAN5G(192, 0), CHAN5G(196, 0),
430 CHAN5G(200, 0), CHAN5G(204, 0),
431 CHAN5G(208, 0), CHAN5G(212, 0),
435 static struct ieee80211_channel __wl_5ghz_n_channels
[] = {
436 CHAN5G(32, 0), CHAN5G(34, 0),
437 CHAN5G(36, 0), CHAN5G(38, 0),
438 CHAN5G(40, 0), CHAN5G(42, 0),
439 CHAN5G(44, 0), CHAN5G(46, 0),
440 CHAN5G(48, 0), CHAN5G(50, 0),
441 CHAN5G(52, 0), CHAN5G(54, 0),
442 CHAN5G(56, 0), CHAN5G(58, 0),
443 CHAN5G(60, 0), CHAN5G(62, 0),
444 CHAN5G(64, 0), CHAN5G(66, 0),
445 CHAN5G(68, 0), CHAN5G(70, 0),
446 CHAN5G(72, 0), CHAN5G(74, 0),
447 CHAN5G(76, 0), CHAN5G(78, 0),
448 CHAN5G(80, 0), CHAN5G(82, 0),
449 CHAN5G(84, 0), CHAN5G(86, 0),
450 CHAN5G(88, 0), CHAN5G(90, 0),
451 CHAN5G(92, 0), CHAN5G(94, 0),
452 CHAN5G(96, 0), CHAN5G(98, 0),
453 CHAN5G(100, 0), CHAN5G(102, 0),
454 CHAN5G(104, 0), CHAN5G(106, 0),
455 CHAN5G(108, 0), CHAN5G(110, 0),
456 CHAN5G(112, 0), CHAN5G(114, 0),
457 CHAN5G(116, 0), CHAN5G(118, 0),
458 CHAN5G(120, 0), CHAN5G(122, 0),
459 CHAN5G(124, 0), CHAN5G(126, 0),
460 CHAN5G(128, 0), CHAN5G(130, 0),
461 CHAN5G(132, 0), CHAN5G(134, 0),
462 CHAN5G(136, 0), CHAN5G(138, 0),
463 CHAN5G(140, 0), CHAN5G(142, 0),
464 CHAN5G(144, 0), CHAN5G(145, 0),
465 CHAN5G(146, 0), CHAN5G(147, 0),
466 CHAN5G(148, 0), CHAN5G(149, 0),
467 CHAN5G(150, 0), CHAN5G(151, 0),
468 CHAN5G(152, 0), CHAN5G(153, 0),
469 CHAN5G(154, 0), CHAN5G(155, 0),
470 CHAN5G(156, 0), CHAN5G(157, 0),
471 CHAN5G(158, 0), CHAN5G(159, 0),
472 CHAN5G(160, 0), CHAN5G(161, 0),
473 CHAN5G(162, 0), CHAN5G(163, 0),
474 CHAN5G(164, 0), CHAN5G(165, 0),
475 CHAN5G(166, 0), CHAN5G(168, 0),
476 CHAN5G(170, 0), CHAN5G(172, 0),
477 CHAN5G(174, 0), CHAN5G(176, 0),
478 CHAN5G(178, 0), CHAN5G(180, 0),
479 CHAN5G(182, 0), CHAN5G(184, 0),
480 CHAN5G(186, 0), CHAN5G(188, 0),
481 CHAN5G(190, 0), CHAN5G(192, 0),
482 CHAN5G(194, 0), CHAN5G(196, 0),
483 CHAN5G(198, 0), CHAN5G(200, 0),
484 CHAN5G(202, 0), CHAN5G(204, 0),
485 CHAN5G(206, 0), CHAN5G(208, 0),
486 CHAN5G(210, 0), CHAN5G(212, 0),
487 CHAN5G(214, 0), CHAN5G(216, 0),
488 CHAN5G(218, 0), CHAN5G(220, 0),
489 CHAN5G(222, 0), CHAN5G(224, 0),
490 CHAN5G(226, 0), CHAN5G(228, 0),
493 static struct ieee80211_supported_band __wl_band_2ghz
= {
494 .band
= IEEE80211_BAND_2GHZ
,
495 .channels
= __wl_2ghz_channels
,
496 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
497 .bitrates
= wl_g_rates
,
498 .n_bitrates
= wl_g_rates_size
,
501 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
502 .band
= IEEE80211_BAND_5GHZ
,
503 .channels
= __wl_5ghz_a_channels
,
504 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
505 .bitrates
= wl_a_rates
,
506 .n_bitrates
= wl_a_rates_size
,
509 static struct ieee80211_supported_band __wl_band_5ghz_n
= {
510 .band
= IEEE80211_BAND_5GHZ
,
511 .channels
= __wl_5ghz_n_channels
,
512 .n_channels
= ARRAY_SIZE(__wl_5ghz_n_channels
),
513 .bitrates
= wl_a_rates
,
514 .n_bitrates
= wl_a_rates_size
,
517 static const u32 __wl_cipher_suites
[] = {
518 WLAN_CIPHER_SUITE_WEP40
,
519 WLAN_CIPHER_SUITE_WEP104
,
520 WLAN_CIPHER_SUITE_TKIP
,
521 WLAN_CIPHER_SUITE_CCMP
,
522 WLAN_CIPHER_SUITE_AES_CMAC
,
525 static void swap_key_from_BE(struct wl_wsec_key
*key
)
527 key
->index
= cpu_to_le32(key
->index
);
528 key
->len
= cpu_to_le32(key
->len
);
529 key
->algo
= cpu_to_le32(key
->algo
);
530 key
->flags
= cpu_to_le32(key
->flags
);
531 key
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
532 key
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
533 key
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
536 static void swap_key_to_BE(struct wl_wsec_key
*key
)
538 key
->index
= le32_to_cpu(key
->index
);
539 key
->len
= le32_to_cpu(key
->len
);
540 key
->algo
= le32_to_cpu(key
->algo
);
541 key
->flags
= le32_to_cpu(key
->flags
);
542 key
->rxiv
.hi
= le32_to_cpu(key
->rxiv
.hi
);
543 key
->rxiv
.lo
= le16_to_cpu(key
->rxiv
.lo
);
544 key
->iv_initialized
= le32_to_cpu(key
->iv_initialized
);
548 wl_dev_ioctl(struct net_device
*dev
, u32 cmd
, void *arg
, u32 len
)
555 memset(&ioc
, 0, sizeof(ioc
));
559 strcpy(ifr
.ifr_name
, dev
->name
);
560 ifr
.ifr_data
= (caddr_t
)&ioc
;
564 err
= dev
->netdev_ops
->ndo_do_ioctl(dev
, &ifr
, SIOCDEVPRIVATE
);
571 wl_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
572 enum nl80211_iftype type
, u32
*flags
,
573 struct vif_params
*params
)
575 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
576 struct wireless_dev
*wdev
;
584 case NL80211_IFTYPE_MONITOR
:
585 case NL80211_IFTYPE_WDS
:
586 WL_ERR("type (%d) : currently we do not support this type\n",
589 case NL80211_IFTYPE_ADHOC
:
590 wl
->conf
->mode
= WL_MODE_IBSS
;
593 case NL80211_IFTYPE_STATION
:
594 wl
->conf
->mode
= WL_MODE_BSS
;
602 infra
= cpu_to_le32(infra
);
603 err
= wl_dev_ioctl(ndev
, WLC_SET_INFRA
, &infra
, sizeof(infra
));
605 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
608 wdev
= ndev
->ieee80211_ptr
;
612 WL_INFO("IF Type = %s\n",
613 (wl
->conf
->mode
== WL_MODE_IBSS
) ? "Adhoc" : "Infra");
621 static void wl_iscan_prep(struct wl_scan_params
*params
, struct wlc_ssid
*ssid
)
623 memcpy(params
->bssid
, ether_bcast
, ETH_ALEN
);
624 params
->bss_type
= DOT11_BSSTYPE_ANY
;
625 params
->scan_type
= 0;
626 params
->nprobes
= -1;
627 params
->active_time
= -1;
628 params
->passive_time
= -1;
629 params
->home_time
= -1;
630 params
->channel_num
= 0;
632 params
->nprobes
= cpu_to_le32(params
->nprobes
);
633 params
->active_time
= cpu_to_le32(params
->active_time
);
634 params
->passive_time
= cpu_to_le32(params
->passive_time
);
635 params
->home_time
= cpu_to_le32(params
->home_time
);
636 if (ssid
&& ssid
->SSID_len
)
637 memcpy(¶ms
->ssid
, ssid
, sizeof(wlc_ssid_t
));
642 wl_dev_iovar_setbuf(struct net_device
*dev
, s8
* iovar
, void *param
,
643 s32 paramlen
, void *bufptr
, s32 buflen
)
647 iolen
= brcmu_mkiovar(iovar
, param
, paramlen
, bufptr
, buflen
);
650 return wl_dev_ioctl(dev
, WLC_SET_VAR
, bufptr
, iolen
);
654 wl_dev_iovar_getbuf(struct net_device
*dev
, s8
* iovar
, void *param
,
655 s32 paramlen
, void *bufptr
, s32 buflen
)
659 iolen
= brcmu_mkiovar(iovar
, param
, paramlen
, bufptr
, buflen
);
662 return wl_dev_ioctl(dev
, WLC_GET_VAR
, bufptr
, buflen
);
666 wl_run_iscan(struct wl_iscan_ctrl
*iscan
, struct wlc_ssid
*ssid
, u16 action
)
669 (WL_SCAN_PARAMS_FIXED_SIZE
+ offsetof(wl_iscan_params_t
, params
));
670 struct wl_iscan_params
*params
;
673 if (ssid
&& ssid
->SSID_len
)
674 params_size
+= sizeof(struct wlc_ssid
);
675 params
= kzalloc(params_size
, GFP_KERNEL
);
676 if (unlikely(!params
))
678 BUG_ON(params_size
>= WLC_IOCTL_SMLEN
);
680 wl_iscan_prep(¶ms
->params
, ssid
);
682 params
->version
= cpu_to_le32(ISCAN_REQ_VERSION
);
683 params
->action
= cpu_to_le16(action
);
684 params
->scan_duration
= cpu_to_le16(0);
686 /* params_size += offsetof(wl_iscan_params_t, params); */
687 err
= wl_dev_iovar_setbuf(iscan
->dev
, "iscan", params
, params_size
,
688 iscan
->ioctl_buf
, WLC_IOCTL_SMLEN
);
691 WL_INFO("system busy : iscan canceled\n");
693 WL_ERR("error (%d)\n", err
);
700 static s32
wl_do_iscan(struct wl_priv
*wl
)
702 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
703 struct net_device
*ndev
= wl_to_ndev(wl
);
704 struct wlc_ssid ssid
;
708 /* Broadcast scan by default */
709 memset(&ssid
, 0, sizeof(ssid
));
711 iscan
->state
= WL_ISCAN_STATE_SCANING
;
713 passive_scan
= wl
->active_scan
? 0 : 1;
714 err
= wl_dev_ioctl(wl_to_ndev(wl
), WLC_SET_PASSIVE_SCAN
,
715 &passive_scan
, sizeof(passive_scan
));
717 WL_ERR("error (%d)\n", err
);
721 wl
->iscan_kickstart
= true;
722 wl_run_iscan(iscan
, &ssid
, WL_SCAN_ACTION_START
);
723 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
730 __wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
731 struct cfg80211_scan_request
*request
,
732 struct cfg80211_ssid
*this_ssid
)
734 struct wl_priv
*wl
= ndev_to_wl(ndev
);
735 struct cfg80211_ssid
*ssids
;
736 struct wl_scan_req
*sr
= wl_to_sr(wl
);
742 if (unlikely(test_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
743 WL_ERR("Scanning already : status (%d)\n", (int)wl
->status
);
746 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
))) {
747 WL_ERR("Scanning being aborted : status (%d)\n",
751 if (test_bit(WL_STATUS_CONNECTING
, &wl
->status
)) {
752 WL_ERR("Connecting : status (%d)\n",
761 ssids
= request
->ssids
;
762 if (wl
->iscan_on
&& (!ssids
|| !ssids
->ssid_len
))
766 /* we don't do iscan in ibss */
770 wl
->scan_request
= request
;
771 set_bit(WL_STATUS_SCANNING
, &wl
->status
);
773 err
= wl_do_iscan(wl
);
779 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
780 ssids
->ssid
, ssids
->ssid_len
);
781 memset(&sr
->ssid
, 0, sizeof(sr
->ssid
));
783 min_t(u8
, sizeof(sr
->ssid
.SSID
), ssids
->ssid_len
);
784 if (sr
->ssid
.SSID_len
) {
785 memcpy(sr
->ssid
.SSID
, ssids
->ssid
, sr
->ssid
.SSID_len
);
786 sr
->ssid
.SSID_len
= cpu_to_le32(sr
->ssid
.SSID_len
);
789 WL_SCAN("Broadcast scan\n");
792 passive_scan
= wl
->active_scan
? 0 : 1;
793 err
= wl_dev_ioctl(ndev
, WLC_SET_PASSIVE_SCAN
,
794 &passive_scan
, sizeof(passive_scan
));
796 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
800 err
= wl_dev_ioctl(ndev
, WLC_SCAN
, &sr
->ssid
,
804 WL_INFO("system busy : scan for \"%s\" canceled\n",
807 WL_ERR("WLC_SCAN error (%d)\n", err
);
817 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
818 wl
->scan_request
= NULL
;
823 wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
824 struct cfg80211_scan_request
*request
)
832 err
= __wl_cfg80211_scan(wiphy
, ndev
, request
, NULL
);
834 WL_ERR("scan error (%d)\n", err
);
840 static s32
wl_dev_intvar_set(struct net_device
*dev
, s8
*name
, s32 val
)
842 s8 buf
[WLC_IOCTL_SMLEN
];
846 val
= cpu_to_le32(val
);
847 len
= brcmu_mkiovar(name
, (char *)(&val
), sizeof(val
), buf
,
851 err
= wl_dev_ioctl(dev
, WLC_SET_VAR
, buf
, len
);
853 WL_ERR("error (%d)\n", err
);
859 wl_dev_intvar_get(struct net_device
*dev
, s8
*name
, s32
*retval
)
862 s8 buf
[WLC_IOCTL_SMLEN
];
870 brcmu_mkiovar(name
, (char *)(&data_null
), 0, (char *)(&var
),
873 err
= wl_dev_ioctl(dev
, WLC_GET_VAR
, &var
, len
);
875 WL_ERR("error (%d)\n", err
);
877 *retval
= le32_to_cpu(var
.val
);
882 static s32
wl_set_rts(struct net_device
*dev
, u32 rts_threshold
)
886 err
= wl_dev_intvar_set(dev
, "rtsthresh", rts_threshold
);
888 WL_ERR("Error (%d)\n", err
);
893 static s32
wl_set_frag(struct net_device
*dev
, u32 frag_threshold
)
897 err
= wl_dev_intvar_set(dev
, "fragthresh", frag_threshold
);
899 WL_ERR("Error (%d)\n", err
);
904 static s32
wl_set_retry(struct net_device
*dev
, u32 retry
, bool l
)
907 u32 cmd
= (l
? WLC_SET_LRL
: WLC_SET_SRL
);
909 retry
= cpu_to_le32(retry
);
910 err
= wl_dev_ioctl(dev
, cmd
, &retry
, sizeof(retry
));
912 WL_ERR("cmd (%d) , error (%d)\n", cmd
, err
);
918 static s32
wl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
920 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
921 struct net_device
*ndev
= wl_to_ndev(wl
);
927 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
928 (wl
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
929 wl
->conf
->rts_threshold
= wiphy
->rts_threshold
;
930 err
= wl_set_rts(ndev
, wl
->conf
->rts_threshold
);
934 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
935 (wl
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
936 wl
->conf
->frag_threshold
= wiphy
->frag_threshold
;
937 err
= wl_set_frag(ndev
, wl
->conf
->frag_threshold
);
941 if (changed
& WIPHY_PARAM_RETRY_LONG
942 && (wl
->conf
->retry_long
!= wiphy
->retry_long
)) {
943 wl
->conf
->retry_long
= wiphy
->retry_long
;
944 err
= wl_set_retry(ndev
, wl
->conf
->retry_long
, true);
948 if (changed
& WIPHY_PARAM_RETRY_SHORT
949 && (wl
->conf
->retry_short
!= wiphy
->retry_short
)) {
950 wl
->conf
->retry_short
= wiphy
->retry_short
;
951 err
= wl_set_retry(ndev
, wl
->conf
->retry_short
, false);
962 wl_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
963 struct cfg80211_ibss_params
*params
)
965 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
966 struct wl_join_params join_params
;
967 size_t join_params_size
= 0;
976 WL_CONN("SSID: %s\n", params
->ssid
);
978 WL_CONN("SSID: NULL, Not supported\n");
983 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
984 params
->bssid
[0], params
->bssid
[1], params
->bssid
[2],
985 params
->bssid
[3], params
->bssid
[4], params
->bssid
[5]);
987 WL_CONN("No BSSID specified\n");
990 WL_CONN("channel: %d\n", params
->channel
->center_freq
);
992 WL_CONN("no channel specified\n");
994 if (params
->channel_fixed
)
995 WL_CONN("fixed channel required\n");
997 WL_CONN("no fixed channel required\n");
999 if (params
->ie
&& params
->ie_len
)
1000 WL_CONN("ie len: %d\n", params
->ie_len
);
1002 WL_CONN("no ie specified\n");
1004 if (params
->beacon_interval
)
1005 WL_CONN("beacon interval: %d\n", params
->beacon_interval
);
1007 WL_CONN("no beacon interval specified\n");
1009 if (params
->basic_rates
)
1010 WL_CONN("basic rates: %08X\n", params
->basic_rates
);
1012 WL_CONN("no basic rates specified\n");
1014 if (params
->privacy
)
1015 WL_CONN("privacy required\n");
1017 WL_CONN("no privacy required\n");
1019 /* Configure Privacy for starter */
1020 if (params
->privacy
)
1021 wsec
|= WEP_ENABLED
;
1023 err
= wl_dev_intvar_set(dev
, "wsec", wsec
);
1024 if (unlikely(err
)) {
1025 WL_ERR("wsec failed (%d)\n", err
);
1029 /* Configure Beacon Interval for starter */
1030 if (params
->beacon_interval
)
1031 bcnprd
= cpu_to_le32(params
->beacon_interval
);
1033 bcnprd
= cpu_to_le32(100);
1035 err
= wl_dev_ioctl(dev
, WLC_SET_BCNPRD
, &bcnprd
, sizeof(bcnprd
));
1036 if (unlikely(err
)) {
1037 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err
);
1041 /* Configure required join parameter */
1042 memset(&join_params
, 0, sizeof(wl_join_params_t
));
1045 join_params
.ssid
.SSID_len
=
1046 (params
->ssid_len
> 32) ? 32 : params
->ssid_len
;
1047 memcpy(join_params
.ssid
.SSID
, params
->ssid
, join_params
.ssid
.SSID_len
);
1048 join_params
.ssid
.SSID_len
= cpu_to_le32(join_params
.ssid
.SSID_len
);
1049 join_params_size
= sizeof(join_params
.ssid
);
1050 wl_update_prof(wl
, NULL
, &join_params
.ssid
, WL_PROF_SSID
);
1053 if (params
->bssid
) {
1054 memcpy(join_params
.params
.bssid
, params
->bssid
, ETH_ALEN
);
1056 sizeof(join_params
.ssid
) + WL_ASSOC_PARAMS_FIXED_SIZE
;
1058 memcpy(join_params
.params
.bssid
, ether_bcast
, ETH_ALEN
);
1060 wl_update_prof(wl
, NULL
, &join_params
.params
.bssid
, WL_PROF_BSSID
);
1063 if (params
->channel
) {
1067 ieee80211_frequency_to_channel(
1068 params
->channel
->center_freq
);
1069 if (params
->channel_fixed
) {
1070 /* adding chanspec */
1071 wl_ch_to_chanspec(wl
->channel
,
1072 &join_params
, &join_params_size
);
1075 /* set channel for starter */
1076 target_channel
= cpu_to_le32(wl
->channel
);
1077 err
= wl_dev_ioctl(dev
, WLC_SET_CHANNEL
,
1078 &target_channel
, sizeof(target_channel
));
1079 if (unlikely(err
)) {
1080 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err
);
1086 wl
->ibss_starter
= false;
1089 err
= wl_dev_ioctl(dev
, WLC_SET_SSID
, &join_params
, join_params_size
);
1090 if (unlikely(err
)) {
1091 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1095 set_bit(WL_STATUS_CONNECTING
, &wl
->status
);
1102 static s32
wl_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
1104 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1107 WL_TRACE("Enter\n");
1118 wl_set_wpa_version(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1120 struct wl_priv
*wl
= ndev_to_wl(dev
);
1121 struct wl_security
*sec
;
1125 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1126 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1127 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1128 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1130 val
= WPA_AUTH_DISABLED
;
1131 WL_CONN("setting wpa_auth to 0x%0x\n", val
);
1132 err
= wl_dev_intvar_set(dev
, "wpa_auth", val
);
1133 if (unlikely(err
)) {
1134 WL_ERR("set wpa_auth failed (%d)\n", err
);
1137 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1138 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1143 wl_set_auth_type(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1145 struct wl_priv
*wl
= ndev_to_wl(dev
);
1146 struct wl_security
*sec
;
1150 switch (sme
->auth_type
) {
1151 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1153 WL_CONN("open system\n");
1155 case NL80211_AUTHTYPE_SHARED_KEY
:
1157 WL_CONN("shared key\n");
1159 case NL80211_AUTHTYPE_AUTOMATIC
:
1161 WL_CONN("automatic\n");
1163 case NL80211_AUTHTYPE_NETWORK_EAP
:
1164 WL_CONN("network eap\n");
1167 WL_ERR("invalid auth type (%d)\n", sme
->auth_type
);
1171 err
= wl_dev_intvar_set(dev
, "auth", val
);
1172 if (unlikely(err
)) {
1173 WL_ERR("set auth failed (%d)\n", err
);
1176 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1177 sec
->auth_type
= sme
->auth_type
;
1182 wl_set_set_cipher(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1184 struct wl_priv
*wl
= ndev_to_wl(dev
);
1185 struct wl_security
*sec
;
1190 if (sme
->crypto
.n_ciphers_pairwise
) {
1191 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1192 case WLAN_CIPHER_SUITE_WEP40
:
1193 case WLAN_CIPHER_SUITE_WEP104
:
1196 case WLAN_CIPHER_SUITE_TKIP
:
1197 pval
= TKIP_ENABLED
;
1199 case WLAN_CIPHER_SUITE_CCMP
:
1202 case WLAN_CIPHER_SUITE_AES_CMAC
:
1206 WL_ERR("invalid cipher pairwise (%d)\n",
1207 sme
->crypto
.ciphers_pairwise
[0]);
1211 if (sme
->crypto
.cipher_group
) {
1212 switch (sme
->crypto
.cipher_group
) {
1213 case WLAN_CIPHER_SUITE_WEP40
:
1214 case WLAN_CIPHER_SUITE_WEP104
:
1217 case WLAN_CIPHER_SUITE_TKIP
:
1218 gval
= TKIP_ENABLED
;
1220 case WLAN_CIPHER_SUITE_CCMP
:
1223 case WLAN_CIPHER_SUITE_AES_CMAC
:
1227 WL_ERR("invalid cipher group (%d)\n",
1228 sme
->crypto
.cipher_group
);
1233 WL_CONN("pval (%d) gval (%d)\n", pval
, gval
);
1234 err
= wl_dev_intvar_set(dev
, "wsec", pval
| gval
);
1235 if (unlikely(err
)) {
1236 WL_ERR("error (%d)\n", err
);
1240 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1241 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1242 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1248 wl_set_key_mgmt(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1250 struct wl_priv
*wl
= ndev_to_wl(dev
);
1251 struct wl_security
*sec
;
1255 if (sme
->crypto
.n_akm_suites
) {
1256 err
= wl_dev_intvar_get(dev
, "wpa_auth", &val
);
1257 if (unlikely(err
)) {
1258 WL_ERR("could not get wpa_auth (%d)\n", err
);
1261 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1262 switch (sme
->crypto
.akm_suites
[0]) {
1263 case WLAN_AKM_SUITE_8021X
:
1264 val
= WPA_AUTH_UNSPECIFIED
;
1266 case WLAN_AKM_SUITE_PSK
:
1270 WL_ERR("invalid cipher group (%d)\n",
1271 sme
->crypto
.cipher_group
);
1274 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1275 switch (sme
->crypto
.akm_suites
[0]) {
1276 case WLAN_AKM_SUITE_8021X
:
1277 val
= WPA2_AUTH_UNSPECIFIED
;
1279 case WLAN_AKM_SUITE_PSK
:
1280 val
= WPA2_AUTH_PSK
;
1283 WL_ERR("invalid cipher group (%d)\n",
1284 sme
->crypto
.cipher_group
);
1289 WL_CONN("setting wpa_auth to %d\n", val
);
1290 err
= wl_dev_intvar_set(dev
, "wpa_auth", val
);
1291 if (unlikely(err
)) {
1292 WL_ERR("could not set wpa_auth (%d)\n", err
);
1296 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1297 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1303 wl_set_set_sharedkey(struct net_device
*dev
,
1304 struct cfg80211_connect_params
*sme
)
1306 struct wl_priv
*wl
= ndev_to_wl(dev
);
1307 struct wl_security
*sec
;
1308 struct wl_wsec_key key
;
1312 WL_CONN("key len (%d)\n", sme
->key_len
);
1314 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1315 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1316 sec
->wpa_versions
, sec
->cipher_pairwise
);
1318 (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
|
1319 NL80211_WPA_VERSION_2
))
1320 && (sec
->cipher_pairwise
& (WLAN_CIPHER_SUITE_WEP40
|
1321 WLAN_CIPHER_SUITE_WEP104
))) {
1322 memset(&key
, 0, sizeof(key
));
1323 key
.len
= (u32
) sme
->key_len
;
1324 key
.index
= (u32
) sme
->key_idx
;
1325 if (unlikely(key
.len
> sizeof(key
.data
))) {
1326 WL_ERR("Too long key length (%u)\n", key
.len
);
1329 memcpy(key
.data
, sme
->key
, key
.len
);
1330 key
.flags
= WL_PRIMARY_KEY
;
1331 switch (sec
->cipher_pairwise
) {
1332 case WLAN_CIPHER_SUITE_WEP40
:
1333 key
.algo
= CRYPTO_ALGO_WEP1
;
1335 case WLAN_CIPHER_SUITE_WEP104
:
1336 key
.algo
= CRYPTO_ALGO_WEP128
;
1339 WL_ERR("Invalid algorithm (%d)\n",
1340 sme
->crypto
.ciphers_pairwise
[0]);
1343 /* Set the new key/index */
1344 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1345 key
.len
, key
.index
, key
.algo
);
1346 WL_CONN("key \"%s\"\n", key
.data
);
1347 swap_key_from_BE(&key
);
1348 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
,
1350 if (unlikely(err
)) {
1351 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1354 if (sec
->auth_type
== NL80211_AUTHTYPE_OPEN_SYSTEM
) {
1355 WL_CONN("set auth_type to shared key\n");
1356 val
= 1; /* shared key */
1357 err
= wl_dev_intvar_set(dev
, "auth", val
);
1358 if (unlikely(err
)) {
1359 WL_ERR("set auth failed (%d)\n", err
);
1369 wl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
1370 struct cfg80211_connect_params
*sme
)
1372 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1373 struct ieee80211_channel
*chan
= sme
->channel
;
1374 struct wl_join_params join_params
;
1375 size_t join_params_size
;
1379 WL_TRACE("Enter\n");
1382 if (unlikely(!sme
->ssid
)) {
1383 WL_ERR("Invalid ssid\n");
1389 ieee80211_frequency_to_channel(chan
->center_freq
);
1390 WL_CONN("channel (%d), center_req (%d)\n",
1391 wl
->channel
, chan
->center_freq
);
1395 WL_INFO("ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1397 err
= wl_set_wpa_version(dev
, sme
);
1401 err
= wl_set_auth_type(dev
, sme
);
1405 err
= wl_set_set_cipher(dev
, sme
);
1409 err
= wl_set_key_mgmt(dev
, sme
);
1413 err
= wl_set_set_sharedkey(dev
, sme
);
1417 wl_update_prof(wl
, NULL
, sme
->bssid
, WL_PROF_BSSID
);
1419 ** Join with specific BSSID and cached SSID
1420 ** If SSID is zero join based on BSSID only
1422 memset(&join_params
, 0, sizeof(join_params
));
1423 join_params_size
= sizeof(join_params
.ssid
);
1425 join_params
.ssid
.SSID_len
= min(sizeof(join_params
.ssid
.SSID
), sme
->ssid_len
);
1426 memcpy(&join_params
.ssid
.SSID
, sme
->ssid
, join_params
.ssid
.SSID_len
);
1427 join_params
.ssid
.SSID_len
= cpu_to_le32(join_params
.ssid
.SSID_len
);
1428 wl_update_prof(wl
, NULL
, &join_params
.ssid
, WL_PROF_SSID
);
1431 memcpy(join_params
.params
.bssid
, sme
->bssid
, ETH_ALEN
);
1433 memcpy(join_params
.params
.bssid
, ether_bcast
, ETH_ALEN
);
1435 if (join_params
.ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
) {
1436 WL_CONN("ssid \"%s\", len (%d)\n",
1437 join_params
.ssid
.SSID
, join_params
.ssid
.SSID_len
);
1440 wl_ch_to_chanspec(wl
->channel
, &join_params
, &join_params_size
);
1441 err
= wl_dev_ioctl(dev
, WLC_SET_SSID
, &join_params
, join_params_size
);
1442 if (unlikely(err
)) {
1443 WL_ERR("error (%d)\n", err
);
1446 set_bit(WL_STATUS_CONNECTING
, &wl
->status
);
1453 wl_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
1456 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1460 WL_TRACE("Enter. Reason code = %d\n", reason_code
);
1463 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
1465 scbval
.val
= reason_code
;
1466 memcpy(&scbval
.ea
, wl_read_prof(wl
, WL_PROF_BSSID
), ETH_ALEN
);
1467 scbval
.val
= cpu_to_le32(scbval
.val
);
1468 err
= wl_dev_ioctl(dev
, WLC_DISASSOC
, &scbval
,
1471 WL_ERR("error (%d)\n", err
);
1473 wl
->link_up
= false;
1480 wl_cfg80211_set_tx_power(struct wiphy
*wiphy
,
1481 enum nl80211_tx_power_setting type
, s32 dbm
)
1484 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1485 struct net_device
*ndev
= wl_to_ndev(wl
);
1490 WL_TRACE("Enter\n");
1494 case NL80211_TX_POWER_AUTOMATIC
:
1496 case NL80211_TX_POWER_LIMITED
:
1498 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1503 case NL80211_TX_POWER_FIXED
:
1505 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1511 /* Make sure radio is off or on as far as software is concerned */
1512 disable
= WL_RADIO_SW_DISABLE
<< 16;
1513 disable
= cpu_to_le32(disable
);
1514 err
= wl_dev_ioctl(ndev
, WLC_SET_RADIO
, &disable
, sizeof(disable
));
1516 WL_ERR("WLC_SET_RADIO error (%d)\n", err
);
1521 txpwrmw
= (u16
) dbm
;
1522 err
= wl_dev_intvar_set(ndev
, "qtxpower",
1523 (s32
) (brcmu_mw_to_qdbm(txpwrmw
)));
1525 WL_ERR("qtxpower error (%d)\n", err
);
1526 wl
->conf
->tx_power
= dbm
;
1533 static s32
wl_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
)
1535 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1536 struct net_device
*ndev
= wl_to_ndev(wl
);
1541 WL_TRACE("Enter\n");
1544 err
= wl_dev_intvar_get(ndev
, "qtxpower", &txpwrdbm
);
1545 if (unlikely(err
)) {
1546 WL_ERR("error (%d)\n", err
);
1550 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1551 *dbm
= (s32
) brcmu_qdbm_to_mw(result
);
1559 wl_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1560 u8 key_idx
, bool unicast
, bool multicast
)
1566 WL_TRACE("Enter\n");
1567 WL_CONN("key index (%d)\n", key_idx
);
1570 err
= wl_dev_ioctl(dev
, WLC_GET_WSEC
, &wsec
, sizeof(wsec
));
1571 if (unlikely(err
)) {
1572 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1576 wsec
= le32_to_cpu(wsec
);
1577 if (wsec
& WEP_ENABLED
) {
1578 /* Just select a new current key */
1579 index
= (u32
) key_idx
;
1580 index
= cpu_to_le32(index
);
1581 err
= wl_dev_ioctl(dev
, WLC_SET_KEY_PRIMARY
, &index
,
1584 WL_ERR("error (%d)\n", err
);
1592 wl_add_keyext(struct wiphy
*wiphy
, struct net_device
*dev
,
1593 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1595 struct wl_wsec_key key
;
1598 memset(&key
, 0, sizeof(key
));
1599 key
.index
= (u32
) key_idx
;
1600 /* Instead of bcast for ea address for default wep keys,
1601 driver needs it to be Null */
1602 if (!is_multicast_ether_addr(mac_addr
))
1603 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1604 key
.len
= (u32
) params
->key_len
;
1605 /* check for key index change */
1608 swap_key_from_BE(&key
);
1609 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
));
1610 if (unlikely(err
)) {
1611 WL_ERR("key delete error (%d)\n", err
);
1615 if (key
.len
> sizeof(key
.data
)) {
1616 WL_ERR("Invalid key length (%d)\n", key
.len
);
1620 WL_CONN("Setting the key index %d\n", key
.index
);
1621 memcpy(key
.data
, params
->key
, key
.len
);
1623 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1625 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1626 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1627 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1630 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1631 if (params
->seq
&& params
->seq_len
== 6) {
1634 ivptr
= (u8
*) params
->seq
;
1635 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1636 (ivptr
[3] << 8) | ivptr
[2];
1637 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1638 key
.iv_initialized
= true;
1641 switch (params
->cipher
) {
1642 case WLAN_CIPHER_SUITE_WEP40
:
1643 key
.algo
= CRYPTO_ALGO_WEP1
;
1644 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1646 case WLAN_CIPHER_SUITE_WEP104
:
1647 key
.algo
= CRYPTO_ALGO_WEP128
;
1648 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1650 case WLAN_CIPHER_SUITE_TKIP
:
1651 key
.algo
= CRYPTO_ALGO_TKIP
;
1652 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1654 case WLAN_CIPHER_SUITE_AES_CMAC
:
1655 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1656 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1658 case WLAN_CIPHER_SUITE_CCMP
:
1659 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1660 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1663 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1666 swap_key_from_BE(&key
);
1668 dhd_wait_pend8021x(dev
);
1669 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
));
1670 if (unlikely(err
)) {
1671 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1679 wl_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1680 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1681 struct key_params
*params
)
1683 struct wl_wsec_key key
;
1689 WL_TRACE("Enter\n");
1690 WL_CONN("key index (%d)\n", key_idx
);
1695 return wl_add_keyext(wiphy
, dev
, key_idx
, mac_addr
, params
);
1697 memset(&key
, 0, sizeof(key
));
1699 key
.len
= (u32
) params
->key_len
;
1700 key
.index
= (u32
) key_idx
;
1702 if (unlikely(key
.len
> sizeof(key
.data
))) {
1703 WL_ERR("Too long key length (%u)\n", key
.len
);
1707 memcpy(key
.data
, params
->key
, key
.len
);
1709 key
.flags
= WL_PRIMARY_KEY
;
1710 switch (params
->cipher
) {
1711 case WLAN_CIPHER_SUITE_WEP40
:
1712 key
.algo
= CRYPTO_ALGO_WEP1
;
1713 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1715 case WLAN_CIPHER_SUITE_WEP104
:
1716 key
.algo
= CRYPTO_ALGO_WEP128
;
1717 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1719 case WLAN_CIPHER_SUITE_TKIP
:
1720 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1721 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1722 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1723 key
.algo
= CRYPTO_ALGO_TKIP
;
1724 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1726 case WLAN_CIPHER_SUITE_AES_CMAC
:
1727 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1728 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1730 case WLAN_CIPHER_SUITE_CCMP
:
1731 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1732 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1735 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1740 /* Set the new key/index */
1741 swap_key_from_BE(&key
);
1742 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
));
1743 if (unlikely(err
)) {
1744 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1749 err
= wl_dev_intvar_get(dev
, "wsec", &wsec
);
1750 if (unlikely(err
)) {
1751 WL_ERR("get wsec error (%d)\n", err
);
1754 wsec
&= ~(WEP_ENABLED
);
1756 err
= wl_dev_intvar_set(dev
, "wsec", wsec
);
1757 if (unlikely(err
)) {
1758 WL_ERR("set wsec error (%d)\n", err
);
1762 val
= 1; /* assume shared key. otherwise 0 */
1763 val
= cpu_to_le32(val
);
1764 err
= wl_dev_ioctl(dev
, WLC_SET_AUTH
, &val
, sizeof(val
));
1766 WL_ERR("WLC_SET_AUTH error (%d)\n", err
);
1773 wl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1774 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
1776 struct wl_wsec_key key
;
1781 WL_TRACE("Enter\n");
1783 memset(&key
, 0, sizeof(key
));
1785 key
.index
= (u32
) key_idx
;
1786 key
.flags
= WL_PRIMARY_KEY
;
1787 key
.algo
= CRYPTO_ALGO_OFF
;
1789 WL_CONN("key index (%d)\n", key_idx
);
1790 /* Set the new key/index */
1791 swap_key_from_BE(&key
);
1792 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
));
1793 if (unlikely(err
)) {
1794 if (err
== -EINVAL
) {
1795 if (key
.index
>= DOT11_MAX_DEFAULT_KEYS
)
1796 /* we ignore this key index in this case */
1797 WL_ERR("invalid key index (%d)\n", key_idx
);
1799 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1801 /* Ignore this error, may happen during DISASSOC */
1807 err
= wl_dev_intvar_get(dev
, "wsec", &wsec
);
1808 if (unlikely(err
)) {
1809 WL_ERR("get wsec error (%d)\n", err
);
1810 /* Ignore this error, may happen during DISASSOC */
1814 wsec
&= ~(WEP_ENABLED
);
1816 err
= wl_dev_intvar_set(dev
, "wsec", wsec
);
1817 if (unlikely(err
)) {
1818 WL_ERR("set wsec error (%d)\n", err
);
1819 /* Ignore this error, may happen during DISASSOC */
1824 val
= 0; /* assume open key. otherwise 1 */
1825 val
= cpu_to_le32(val
);
1826 err
= wl_dev_ioctl(dev
, WLC_SET_AUTH
, &val
, sizeof(val
));
1827 if (unlikely(err
)) {
1828 WL_ERR("WLC_SET_AUTH error (%d)\n", err
);
1829 /* Ignore this error, may happen during DISASSOC */
1838 wl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1839 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
1840 void (*callback
) (void *cookie
, struct key_params
* params
))
1842 struct key_params params
;
1843 struct wl_wsec_key key
;
1844 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1845 struct wl_security
*sec
;
1849 WL_TRACE("Enter\n");
1850 WL_CONN("key index (%d)\n", key_idx
);
1853 memset(&key
, 0, sizeof(key
));
1854 key
.index
= key_idx
;
1855 swap_key_to_BE(&key
);
1856 memset(¶ms
, 0, sizeof(params
));
1857 params
.key_len
= (u8
) min_t(u8
, WLAN_MAX_KEY_LEN
, key
.len
);
1858 memcpy(params
.key
, key
.data
, params
.key_len
);
1860 err
= wl_dev_ioctl(dev
, WLC_GET_WSEC
, &wsec
, sizeof(wsec
));
1861 if (unlikely(err
)) {
1862 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1863 /* Ignore this error, may happen during DISASSOC */
1867 wsec
= le32_to_cpu(wsec
);
1870 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1871 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
1872 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
1873 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1874 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
1875 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
1876 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1880 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
1881 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1884 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
1885 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1888 WL_ERR("Invalid algo (0x%x)\n", wsec
);
1892 callback(cookie
, ¶ms
);
1900 wl_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
1901 struct net_device
*dev
, u8 key_idx
)
1903 WL_INFO("Not supported\n");
1910 wl_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1911 u8
*mac
, struct station_info
*sinfo
)
1913 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1918 u8
*bssid
= wl_read_prof(wl
, WL_PROF_BSSID
);
1920 WL_TRACE("Enter\n");
1924 (memcmp(mac
, bssid
, ETH_ALEN
))) {
1925 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1926 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1927 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5],
1928 bssid
[0], bssid
[1], bssid
[2], bssid
[3],
1929 bssid
[4], bssid
[5]);
1934 /* Report the current tx rate */
1935 err
= wl_dev_ioctl(dev
, WLC_GET_RATE
, &rate
, sizeof(rate
));
1937 WL_ERR("Could not get rate (%d)\n", err
);
1939 rate
= le32_to_cpu(rate
);
1940 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1941 sinfo
->txrate
.legacy
= rate
* 5;
1942 WL_CONN("Rate %d Mbps\n", rate
/ 2);
1945 if (test_bit(WL_STATUS_CONNECTED
, &wl
->status
)) {
1947 err
= wl_dev_ioctl(dev
, WLC_GET_RSSI
, &scb_val
,
1949 if (unlikely(err
)) {
1950 WL_ERR("Could not get rssi (%d)\n", err
);
1952 rssi
= le32_to_cpu(scb_val
.val
);
1953 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1954 sinfo
->signal
= rssi
;
1955 WL_CONN("RSSI %d dBm\n", rssi
);
1964 wl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*dev
,
1965 bool enabled
, s32 timeout
)
1970 WL_TRACE("Enter\n");
1973 pm
= enabled
? PM_FAST
: PM_OFF
;
1974 pm
= cpu_to_le32(pm
);
1975 WL_INFO("power save %s\n", (pm
? "enabled" : "disabled"));
1977 err
= wl_dev_ioctl(dev
, WLC_SET_PM
, &pm
, sizeof(pm
));
1978 if (unlikely(err
)) {
1980 WL_ERR("net_device is not ready yet\n");
1982 WL_ERR("error (%d)\n", err
);
1988 static __used u32
wl_find_msb(u16 bit16
)
1992 if (bit16
& 0xff00) {
2016 wl_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
, struct net_device
*dev
,
2018 const struct cfg80211_bitrate_mask
*mask
)
2020 struct wl_rateset rateset
;
2028 WL_TRACE("Enter\n");
2031 /* addr param is always NULL. ignore it */
2032 /* Get current rateset */
2033 err
= wl_dev_ioctl(dev
, WLC_GET_CURR_RATESET
, &rateset
,
2035 if (unlikely(err
)) {
2036 WL_ERR("could not get current rateset (%d)\n", err
);
2040 rateset
.count
= le32_to_cpu(rateset
.count
);
2042 legacy
= wl_find_msb(mask
->control
[IEEE80211_BAND_2GHZ
].legacy
);
2044 legacy
= wl_find_msb(mask
->control
[IEEE80211_BAND_5GHZ
].legacy
);
2046 val
= wl_g_rates
[legacy
- 1].bitrate
* 100000;
2048 if (val
< rateset
.count
)
2049 /* Select rate by rateset index */
2050 rate
= rateset
.rates
[val
] & 0x7f;
2052 /* Specified rate in bps */
2053 rate
= val
/ 500000;
2055 WL_CONN("rate %d mbps\n", rate
/ 2);
2059 * Set rate override,
2060 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2062 err_bg
= wl_dev_intvar_set(dev
, "bg_rate", rate
);
2063 err_a
= wl_dev_intvar_set(dev
, "a_rate", rate
);
2064 if (unlikely(err_bg
&& err_a
)) {
2065 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg
, err_a
);
2066 err
= err_bg
| err_a
;
2074 static s32
wl_cfg80211_resume(struct wiphy
*wiphy
)
2076 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2077 struct net_device
*ndev
= wl_to_ndev(wl
);
2080 * Check for WL_STATUS_READY before any function call which
2081 * could result is bus access. Don't block the resume for
2082 * any driver error conditions
2084 WL_TRACE("Enter\n");
2086 #if defined(CONFIG_PM_SLEEP)
2087 atomic_set(&dhd_mmc_suspend
, false);
2088 #endif /* defined(CONFIG_PM_SLEEP) */
2090 if (test_bit(WL_STATUS_READY
, &wl
->status
)) {
2091 /* Turn on Watchdog timer */
2092 wl_os_wd_timer(ndev
, dhd_watchdog_ms
);
2093 wl_invoke_iscan(wiphy_to_wl(wiphy
));
2100 static s32
wl_cfg80211_suspend(struct wiphy
*wiphy
)
2102 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2103 struct net_device
*ndev
= wl_to_ndev(wl
);
2105 WL_TRACE("Enter\n");
2108 * Check for WL_STATUS_READY before any function call which
2109 * could result is bus access. Don't block the suspend for
2110 * any driver error conditions
2114 * While going to suspend if associated with AP disassociate
2115 * from AP to save power while system is in suspended state
2117 if (test_bit(WL_STATUS_CONNECTED
, &wl
->status
) &&
2118 test_bit(WL_STATUS_READY
, &wl
->status
)) {
2119 WL_INFO("Disassociating from AP"
2120 " while entering suspend state\n");
2124 * Make sure WPA_Supplicant receives all the event
2125 * generated due to DISASSOC call to the fw to keep
2126 * the state fw and WPA_Supplicant state consistent
2133 set_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
2134 if (test_bit(WL_STATUS_READY
, &wl
->status
))
2137 if (wl
->scan_request
) {
2138 /* Indidate scan abort to cfg80211 layer */
2139 WL_INFO("Terminating scan in progress\n");
2140 cfg80211_scan_done(wl
->scan_request
, true);
2141 wl
->scan_request
= NULL
;
2143 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
2144 clear_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
2145 clear_bit(WL_STATUS_CONNECTING
, &wl
->status
);
2146 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2148 /* Inform SDIO stack not to switch off power to the chip */
2149 sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER
);
2151 /* Turn off watchdog timer */
2152 if (test_bit(WL_STATUS_READY
, &wl
->status
)) {
2153 WL_INFO("Terminate watchdog timer and enable MPC\n");
2154 wl_set_mpc(ndev
, 1);
2155 wl_os_wd_timer(ndev
, 0);
2158 #if defined(CONFIG_PM_SLEEP)
2159 atomic_set(&dhd_mmc_suspend
, true);
2160 #endif /* defined(CONFIG_PM_SLEEP) */
2168 wl_update_pmklist(struct net_device
*dev
, struct wl_pmk_list
*pmk_list
,
2173 WL_CONN("No of elements %d\n", pmk_list
->pmkids
.npmkid
);
2174 for (i
= 0; i
< pmk_list
->pmkids
.npmkid
; i
++) {
2175 WL_CONN("PMKID[%d]: %pM =\n", i
,
2176 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2177 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2178 WL_CONN("%02x\n", pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2182 wl_dev_bufvar_set(dev
, "pmkid_info", (char *)pmk_list
,
2189 wl_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
2190 struct cfg80211_pmksa
*pmksa
)
2192 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2196 WL_TRACE("Enter\n");
2199 for (i
= 0; i
< wl
->pmk_list
->pmkids
.npmkid
; i
++)
2200 if (!memcmp(pmksa
->bssid
, &wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2203 if (i
< WL_NUM_PMKIDS_MAX
) {
2204 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
, pmksa
->bssid
,
2206 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].PMKID
, pmksa
->pmkid
,
2208 if (i
== wl
->pmk_list
->pmkids
.npmkid
)
2209 wl
->pmk_list
->pmkids
.npmkid
++;
2213 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2214 &wl
->pmk_list
->pmkids
.pmkid
[wl
->pmk_list
->pmkids
.npmkid
].BSSID
);
2215 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2217 wl
->pmk_list
->pmkids
.pmkid
[wl
->pmk_list
->pmkids
.npmkid
].
2220 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2227 wl_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
2228 struct cfg80211_pmksa
*pmksa
)
2230 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2231 struct _pmkid_list pmkid
;
2235 WL_TRACE("Enter\n");
2237 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2238 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2240 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2241 &pmkid
.pmkid
[0].BSSID
);
2242 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2243 WL_CONN("%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2245 for (i
= 0; i
< wl
->pmk_list
->pmkids
.npmkid
; i
++)
2247 (pmksa
->bssid
, &wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2251 if ((wl
->pmk_list
->pmkids
.npmkid
> 0)
2252 && (i
< wl
->pmk_list
->pmkids
.npmkid
)) {
2253 memset(&wl
->pmk_list
->pmkids
.pmkid
[i
], 0, sizeof(pmkid_t
));
2254 for (; i
< (wl
->pmk_list
->pmkids
.npmkid
- 1); i
++) {
2255 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2256 &wl
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2258 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2259 &wl
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2262 wl
->pmk_list
->pmkids
.npmkid
--;
2266 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2274 wl_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
)
2276 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2279 WL_TRACE("Enter\n");
2282 memset(wl
->pmk_list
, 0, sizeof(*wl
->pmk_list
));
2283 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2290 static struct cfg80211_ops wl_cfg80211_ops
= {
2291 .change_virtual_intf
= wl_cfg80211_change_iface
,
2292 .scan
= wl_cfg80211_scan
,
2293 .set_wiphy_params
= wl_cfg80211_set_wiphy_params
,
2294 .join_ibss
= wl_cfg80211_join_ibss
,
2295 .leave_ibss
= wl_cfg80211_leave_ibss
,
2296 .get_station
= wl_cfg80211_get_station
,
2297 .set_tx_power
= wl_cfg80211_set_tx_power
,
2298 .get_tx_power
= wl_cfg80211_get_tx_power
,
2299 .add_key
= wl_cfg80211_add_key
,
2300 .del_key
= wl_cfg80211_del_key
,
2301 .get_key
= wl_cfg80211_get_key
,
2302 .set_default_key
= wl_cfg80211_config_default_key
,
2303 .set_default_mgmt_key
= wl_cfg80211_config_default_mgmt_key
,
2304 .set_power_mgmt
= wl_cfg80211_set_power_mgmt
,
2305 .set_bitrate_mask
= wl_cfg80211_set_bitrate_mask
,
2306 .connect
= wl_cfg80211_connect
,
2307 .disconnect
= wl_cfg80211_disconnect
,
2308 .suspend
= wl_cfg80211_suspend
,
2309 .resume
= wl_cfg80211_resume
,
2310 .set_pmksa
= wl_cfg80211_set_pmksa
,
2311 .del_pmksa
= wl_cfg80211_del_pmksa
,
2312 .flush_pmksa
= wl_cfg80211_flush_pmksa
2315 static s32
wl_mode_to_nl80211_iftype(s32 mode
)
2321 return NL80211_IFTYPE_STATION
;
2323 return NL80211_IFTYPE_ADHOC
;
2325 return NL80211_IFTYPE_UNSPECIFIED
;
2331 static struct wireless_dev
*wl_alloc_wdev(s32 sizeof_iface
,
2334 struct wireless_dev
*wdev
;
2337 wdev
= kzalloc(sizeof(*wdev
), GFP_KERNEL
);
2338 if (unlikely(!wdev
)) {
2339 WL_ERR("Could not allocate wireless device\n");
2340 return ERR_PTR(-ENOMEM
);
2343 wiphy_new(&wl_cfg80211_ops
, sizeof(struct wl_priv
) + sizeof_iface
);
2344 if (unlikely(!wdev
->wiphy
)) {
2345 WL_ERR("Couldn not allocate wiphy device\n");
2349 set_wiphy_dev(wdev
->wiphy
, dev
);
2350 wdev
->wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
2351 wdev
->wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
2352 wdev
->wiphy
->interface_modes
=
2353 BIT(NL80211_IFTYPE_STATION
) | BIT(NL80211_IFTYPE_ADHOC
);
2354 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
2355 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
2356 * it as 11a by default.
2357 * This will be updated with
2360 * if phy has 11n capability
2362 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
2363 wdev
->wiphy
->cipher_suites
= __wl_cipher_suites
;
2364 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
2365 #ifndef WL_POWERSAVE_DISABLED
2366 wdev
->wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
2371 wdev
->wiphy
->flags
&= ~WIPHY_FLAG_PS_ON_BY_DEFAULT
;
2372 #endif /* !WL_POWERSAVE_DISABLED */
2373 err
= wiphy_register(wdev
->wiphy
);
2374 if (unlikely(err
< 0)) {
2375 WL_ERR("Couldn not register wiphy device (%d)\n", err
);
2376 goto wiphy_register_out
;
2381 wiphy_free(wdev
->wiphy
);
2386 return ERR_PTR(err
);
2389 static void wl_free_wdev(struct wl_priv
*wl
)
2391 struct wireless_dev
*wdev
= wl_to_wdev(wl
);
2393 if (unlikely(!wdev
)) {
2394 WL_ERR("wdev is invalid\n");
2397 wiphy_unregister(wdev
->wiphy
);
2398 wiphy_free(wdev
->wiphy
);
2400 wl_to_wdev(wl
) = NULL
;
2403 static s32
wl_inform_bss(struct wl_priv
*wl
)
2405 struct wl_scan_results
*bss_list
;
2406 struct wl_bss_info
*bi
= NULL
; /* must be initialized */
2410 bss_list
= wl
->bss_list
;
2411 if (unlikely(bss_list
->version
!= WL_BSS_INFO_VERSION
)) {
2412 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2416 WL_SCAN("scanned AP count (%d)\n", bss_list
->count
);
2417 bi
= next_bss(bss_list
, bi
);
2418 for_each_bss(bss_list
, bi
, i
) {
2419 err
= wl_inform_single_bss(wl
, bi
);
2427 static s32
wl_inform_single_bss(struct wl_priv
*wl
, struct wl_bss_info
*bi
)
2429 struct wiphy
*wiphy
= wl_to_wiphy(wl
);
2430 struct ieee80211_channel
*notify_channel
;
2431 struct cfg80211_bss
*bss
;
2432 struct ieee80211_supported_band
*band
;
2436 u64 notify_timestamp
;
2437 u16 notify_capability
;
2438 u16 notify_interval
;
2440 size_t notify_ielen
;
2443 if (unlikely(le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
)) {
2444 WL_ERR("Bss info is larger than buffer. Discarding\n");
2448 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2449 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2451 if (channel
<= CH_MAX_2G_CHANNEL
)
2452 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2454 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2456 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2457 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2459 notify_timestamp
= jiffies_to_msecs(jiffies
)*1000; /* uSec */
2460 notify_capability
= le16_to_cpu(bi
->capability
);
2461 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2462 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2463 notify_ielen
= le16_to_cpu(bi
->ie_length
);
2464 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2466 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2467 bi
->BSSID
[0], bi
->BSSID
[1], bi
->BSSID
[2],
2468 bi
->BSSID
[3], bi
->BSSID
[4], bi
->BSSID
[5]);
2469 WL_CONN("Channel: %d(%d)\n", channel
, freq
);
2470 WL_CONN("Capability: %X\n", notify_capability
);
2471 WL_CONN("Beacon interval: %d\n", notify_interval
);
2472 WL_CONN("Signal: %d\n", notify_signal
);
2473 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp
);
2475 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2476 notify_timestamp
, notify_capability
, notify_interval
, notify_ie
,
2477 notify_ielen
, notify_signal
, GFP_KERNEL
);
2479 if (unlikely(!bss
)) {
2480 WL_ERR("cfg80211_inform_bss_frame error\n");
2488 wl_inform_ibss(struct wl_priv
*wl
, struct net_device
*dev
, const u8
*bssid
)
2490 struct wiphy
*wiphy
= wl_to_wiphy(wl
);
2491 struct ieee80211_channel
*notify_channel
;
2492 struct wl_bss_info
*bi
= NULL
;
2493 struct ieee80211_supported_band
*band
;
2498 u64 notify_timestamp
;
2499 u16 notify_capability
;
2500 u16 notify_interval
;
2502 size_t notify_ielen
;
2505 WL_TRACE("Enter\n");
2507 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2509 WL_ERR("kzalloc() failed\n");
2514 *(u32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2516 err
= wl_dev_ioctl(dev
, WLC_GET_BSS_INFO
, buf
, WL_BSS_INFO_MAX
);
2517 if (unlikely(err
)) {
2518 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err
);
2522 bi
= (wl_bss_info_t
*)(buf
+ 4);
2524 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2525 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2527 if (channel
<= CH_MAX_2G_CHANNEL
)
2528 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2530 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2532 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2533 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2535 notify_timestamp
= jiffies_to_msecs(jiffies
)*1000; /* uSec */
2536 notify_capability
= le16_to_cpu(bi
->capability
);
2537 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2538 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2539 notify_ielen
= le16_to_cpu(bi
->ie_length
);
2540 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2542 WL_CONN("channel: %d(%d)\n", channel
, freq
);
2543 WL_CONN("capability: %X\n", notify_capability
);
2544 WL_CONN("beacon interval: %d\n", notify_interval
);
2545 WL_CONN("signal: %d\n", notify_signal
);
2546 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp
);
2548 cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2549 notify_timestamp
, notify_capability
, notify_interval
,
2550 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2561 static bool wl_is_linkup(struct wl_priv
*wl
, const wl_event_msg_t
*e
)
2563 u32 event
= be32_to_cpu(e
->event_type
);
2564 u32 status
= be32_to_cpu(e
->status
);
2566 if (event
== WLC_E_SET_SSID
&& status
== WLC_E_STATUS_SUCCESS
) {
2567 WL_CONN("Processing set ssid\n");
2575 static bool wl_is_linkdown(struct wl_priv
*wl
, const wl_event_msg_t
*e
)
2577 u32 event
= be32_to_cpu(e
->event_type
);
2578 u16 flags
= be16_to_cpu(e
->flags
);
2580 if (event
== WLC_E_LINK
&& (!(flags
& WLC_EVENT_MSG_LINK
))) {
2581 WL_CONN("Processing link down\n");
2587 static bool wl_is_nonetwork(struct wl_priv
*wl
, const wl_event_msg_t
*e
)
2589 u32 event
= be32_to_cpu(e
->event_type
);
2590 u32 status
= be32_to_cpu(e
->status
);
2592 if (event
== WLC_E_LINK
&& status
== WLC_E_STATUS_NO_NETWORKS
) {
2593 WL_CONN("Processing Link %s & no network found\n",
2594 be16_to_cpu(e
->flags
) & WLC_EVENT_MSG_LINK
?
2599 if (event
== WLC_E_SET_SSID
&& status
!= WLC_E_STATUS_SUCCESS
) {
2600 WL_CONN("Processing connecting & no network found\n");
2608 wl_notify_connect_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2609 const wl_event_msg_t
*e
, void *data
)
2613 if (wl_is_linkup(wl
, e
)) {
2614 WL_CONN("Linkup\n");
2615 if (wl_is_ibssmode(wl
)) {
2616 wl_update_prof(wl
, NULL
, (void *)e
->addr
,
2618 wl_inform_ibss(wl
, ndev
, e
->addr
);
2619 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
2620 clear_bit(WL_STATUS_CONNECTING
, &wl
->status
);
2621 set_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2623 wl_bss_connect_done(wl
, ndev
, e
, data
, true);
2624 } else if (wl_is_linkdown(wl
, e
)) {
2625 WL_CONN("Linkdown\n");
2626 if (wl_is_ibssmode(wl
)) {
2627 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
2631 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
2633 cfg80211_disconnected(ndev
, 0, NULL
, 0,
2638 wl_init_prof(wl
->profile
);
2639 } else if (wl_is_nonetwork(wl
, e
)) {
2640 if (wl_is_ibssmode(wl
))
2641 clear_bit(WL_STATUS_CONNECTING
, &wl
->status
);
2643 wl_bss_connect_done(wl
, ndev
, e
, data
, false);
2650 wl_notify_roaming_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2651 const wl_event_msg_t
*e
, void *data
)
2654 u32 event
= be32_to_cpu(e
->event_type
);
2655 u32 status
= be32_to_cpu(e
->status
);
2657 if (event
== WLC_E_ROAM
&& status
== WLC_E_STATUS_SUCCESS
) {
2658 if (test_bit(WL_STATUS_CONNECTED
, &wl
->status
))
2659 wl_bss_roaming_done(wl
, ndev
, e
, data
);
2661 wl_bss_connect_done(wl
, ndev
, e
, data
, true);
2668 wl_dev_bufvar_set(struct net_device
*dev
, s8
*name
, s8
*buf
, s32 len
)
2670 struct wl_priv
*wl
= ndev_to_wl(dev
);
2673 buflen
= brcmu_mkiovar(name
, buf
, len
, wl
->ioctl_buf
, WL_IOCTL_LEN_MAX
);
2676 return wl_dev_ioctl(dev
, WLC_SET_VAR
, wl
->ioctl_buf
, buflen
);
2680 wl_dev_bufvar_get(struct net_device
*dev
, s8
*name
, s8
*buf
,
2683 struct wl_priv
*wl
= ndev_to_wl(dev
);
2687 len
= brcmu_mkiovar(name
, NULL
, 0, wl
->ioctl_buf
, WL_IOCTL_LEN_MAX
);
2689 err
= wl_dev_ioctl(dev
, WLC_GET_VAR
, (void *)wl
->ioctl_buf
,
2691 if (unlikely(err
)) {
2692 WL_ERR("error (%d)\n", err
);
2695 memcpy(buf
, wl
->ioctl_buf
, buf_len
);
2700 static s32
wl_get_assoc_ies(struct wl_priv
*wl
)
2702 struct net_device
*ndev
= wl_to_ndev(wl
);
2703 struct wl_assoc_ielen
*assoc_info
;
2704 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2709 wl_clear_assoc_ies(wl
);
2711 err
= wl_dev_bufvar_get(ndev
, "assoc_info", wl
->extra_buf
,
2713 if (unlikely(err
)) {
2714 WL_ERR("could not get assoc info (%d)\n", err
);
2717 assoc_info
= (struct wl_assoc_ielen
*)wl
->extra_buf
;
2718 req_len
= assoc_info
->req_len
;
2719 resp_len
= assoc_info
->resp_len
;
2721 err
= wl_dev_bufvar_get(ndev
, "assoc_req_ies", wl
->extra_buf
,
2723 if (unlikely(err
)) {
2724 WL_ERR("could not get assoc req (%d)\n", err
);
2727 conn_info
->req_ie_len
= req_len
;
2729 kmemdup(wl
->extra_buf
, conn_info
->req_ie_len
, GFP_KERNEL
);
2731 conn_info
->req_ie_len
= 0;
2732 conn_info
->req_ie
= NULL
;
2735 err
= wl_dev_bufvar_get(ndev
, "assoc_resp_ies", wl
->extra_buf
,
2737 if (unlikely(err
)) {
2738 WL_ERR("could not get assoc resp (%d)\n", err
);
2741 conn_info
->resp_ie_len
= resp_len
;
2742 conn_info
->resp_ie
=
2743 kmemdup(wl
->extra_buf
, conn_info
->resp_ie_len
, GFP_KERNEL
);
2745 conn_info
->resp_ie_len
= 0;
2746 conn_info
->resp_ie
= NULL
;
2748 WL_CONN("req len (%d) resp len (%d)\n",
2749 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
2754 static void wl_clear_assoc_ies(struct wl_priv
*wl
)
2756 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2758 kfree(conn_info
->req_ie
);
2759 conn_info
->req_ie
= NULL
;
2760 conn_info
->req_ie_len
= 0;
2761 kfree(conn_info
->resp_ie
);
2762 conn_info
->resp_ie
= NULL
;
2763 conn_info
->resp_ie_len
= 0;
2767 static void wl_ch_to_chanspec(int ch
, struct wl_join_params
*join_params
,
2768 size_t *join_params_size
)
2770 chanspec_t chanspec
= 0;
2773 join_params
->params
.chanspec_num
= 1;
2774 join_params
->params
.chanspec_list
[0] = ch
;
2776 if (join_params
->params
.chanspec_list
[0] <= CH_MAX_2G_CHANNEL
)
2777 chanspec
|= WL_CHANSPEC_BAND_2G
;
2779 chanspec
|= WL_CHANSPEC_BAND_5G
;
2781 chanspec
|= WL_CHANSPEC_BW_20
;
2782 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
2784 *join_params_size
+= WL_ASSOC_PARAMS_FIXED_SIZE
+
2785 join_params
->params
.chanspec_num
* sizeof(chanspec_t
);
2787 join_params
->params
.chanspec_list
[0] &= WL_CHANSPEC_CHAN_MASK
;
2788 join_params
->params
.chanspec_list
[0] |= chanspec
;
2789 join_params
->params
.chanspec_list
[0] =
2790 cpu_to_le16(join_params
->params
.chanspec_list
[0]);
2792 join_params
->params
.chanspec_num
=
2793 cpu_to_le32(join_params
->params
.chanspec_num
);
2795 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2796 "channel %d, chanspec %#X\n",
2797 join_params
->params
.chanspec_list
[0], ch
, chanspec
);
2801 static s32
wl_update_bss_info(struct wl_priv
*wl
)
2803 struct wl_bss_info
*bi
;
2804 struct wlc_ssid
*ssid
;
2805 struct brcmu_tlv
*tim
;
2806 u16 beacon_interval
;
2812 WL_TRACE("Enter\n");
2813 if (wl_is_ibssmode(wl
))
2816 ssid
= (struct wlc_ssid
*)wl_read_prof(wl
, WL_PROF_SSID
);
2818 *(u32
*)wl
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2819 err
= wl_dev_ioctl(wl_to_ndev(wl
), WLC_GET_BSS_INFO
,
2820 wl
->extra_buf
, WL_EXTRA_BUF_MAX
);
2821 if (unlikely(err
)) {
2822 WL_ERR("Could not get bss info %d\n", err
);
2823 goto update_bss_info_out
;
2826 bi
= (struct wl_bss_info
*)(wl
->extra_buf
+ 4);
2827 err
= wl_inform_single_bss(wl
, bi
);
2829 goto update_bss_info_out
;
2831 ie
= ((u8
*)bi
) + bi
->ie_offset
;
2832 ie_len
= bi
->ie_length
;
2833 beacon_interval
= cpu_to_le16(bi
->beacon_period
);
2835 tim
= brcmu_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2837 dtim_period
= tim
->data
[1];
2840 * active scan was done so we could not get dtim
2841 * information out of probe response.
2842 * so we speficially query dtim information to dongle.
2845 err
= wl_dev_intvar_get(wl_to_ndev(wl
), "dtim_assoc", &var
);
2846 if (unlikely(err
)) {
2847 WL_ERR("wl dtim_assoc failed (%d)\n", err
);
2848 goto update_bss_info_out
;
2850 dtim_period
= (u8
)var
;
2853 wl_update_prof(wl
, NULL
, &beacon_interval
, WL_PROF_BEACONINT
);
2854 wl_update_prof(wl
, NULL
, &dtim_period
, WL_PROF_DTIMPERIOD
);
2856 update_bss_info_out
:
2862 wl_bss_roaming_done(struct wl_priv
*wl
, struct net_device
*ndev
,
2863 const wl_event_msg_t
*e
, void *data
)
2865 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2868 WL_TRACE("Enter\n");
2870 wl_get_assoc_ies(wl
);
2871 wl_update_prof(wl
, NULL
, &e
->addr
, WL_PROF_BSSID
);
2872 wl_update_bss_info(wl
);
2874 cfg80211_roamed(ndev
, NULL
,
2875 (u8
*)wl_read_prof(wl
, WL_PROF_BSSID
),
2876 conn_info
->req_ie
, conn_info
->req_ie_len
,
2877 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
2878 WL_CONN("Report roaming result\n");
2880 set_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2886 wl_bss_connect_done(struct wl_priv
*wl
, struct net_device
*ndev
,
2887 const wl_event_msg_t
*e
, void *data
, bool completed
)
2889 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2892 WL_TRACE("Enter\n");
2894 if (test_and_clear_bit(WL_STATUS_CONNECTING
, &wl
->status
)) {
2896 wl_get_assoc_ies(wl
);
2897 wl_update_prof(wl
, NULL
, &e
->addr
, WL_PROF_BSSID
);
2898 wl_update_bss_info(wl
);
2900 cfg80211_connect_result(ndev
,
2901 (u8
*)wl_read_prof(wl
, WL_PROF_BSSID
),
2903 conn_info
->req_ie_len
,
2905 conn_info
->resp_ie_len
,
2906 completed
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_AUTH_TIMEOUT
,
2909 set_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2910 WL_CONN("Report connect result - connection %s\n",
2911 completed
? "succeeded" : "failed");
2918 wl_notify_mic_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2919 const wl_event_msg_t
*e
, void *data
)
2921 u16 flags
= be16_to_cpu(e
->flags
);
2922 enum nl80211_key_type key_type
;
2925 if (flags
& WLC_EVENT_MSG_GROUP
)
2926 key_type
= NL80211_KEYTYPE_GROUP
;
2928 key_type
= NL80211_KEYTYPE_PAIRWISE
;
2930 cfg80211_michael_mic_failure(ndev
, (u8
*)&e
->addr
, key_type
, -1,
2938 wl_notify_scan_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2939 const wl_event_msg_t
*e
, void *data
)
2941 struct channel_info channel_inform
;
2942 struct wl_scan_results
*bss_list
;
2943 u32 len
= WL_SCAN_BUF_MAX
;
2945 bool scan_abort
= false;
2947 WL_TRACE("Enter\n");
2949 if (wl
->iscan_on
&& wl
->iscan_kickstart
) {
2951 return wl_wakeup_iscan(wl_to_iscan(wl
));
2954 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
2955 WL_ERR("Scan complete while device not scanning\n");
2961 err
= wl_dev_ioctl(ndev
, WLC_GET_CHANNEL
, &channel_inform
,
2962 sizeof(channel_inform
));
2963 if (unlikely(err
)) {
2964 WL_ERR("scan busy (%d)\n", err
);
2968 channel_inform
.scan_channel
= le32_to_cpu(channel_inform
.scan_channel
);
2969 if (unlikely(channel_inform
.scan_channel
)) {
2971 WL_CONN("channel_inform.scan_channel (%d)\n",
2972 channel_inform
.scan_channel
);
2974 wl
->bss_list
= wl
->scan_results
;
2975 bss_list
= wl
->bss_list
;
2976 memset(bss_list
, 0, len
);
2977 bss_list
->buflen
= cpu_to_le32(len
);
2979 err
= wl_dev_ioctl(ndev
, WLC_SCAN_RESULTS
, bss_list
, len
);
2980 if (unlikely(err
)) {
2981 WL_ERR("%s Scan_results error (%d)\n", ndev
->name
, err
);
2986 bss_list
->buflen
= le32_to_cpu(bss_list
->buflen
);
2987 bss_list
->version
= le32_to_cpu(bss_list
->version
);
2988 bss_list
->count
= le32_to_cpu(bss_list
->count
);
2990 err
= wl_inform_bss(wl
);
2997 if (wl
->scan_request
) {
2998 WL_SCAN("calling cfg80211_scan_done\n");
2999 cfg80211_scan_done(wl
->scan_request
, scan_abort
);
3000 wl_set_mpc(ndev
, 1);
3001 wl
->scan_request
= NULL
;
3009 static void wl_init_conf(struct wl_conf
*conf
)
3011 conf
->mode
= (u32
)-1;
3012 conf
->frag_threshold
= (u32
)-1;
3013 conf
->rts_threshold
= (u32
)-1;
3014 conf
->retry_short
= (u32
)-1;
3015 conf
->retry_long
= (u32
)-1;
3016 conf
->tx_power
= -1;
3019 static void wl_init_prof(struct wl_profile
*prof
)
3021 memset(prof
, 0, sizeof(*prof
));
3024 static void wl_init_eloop_handler(struct wl_event_loop
*el
)
3026 memset(el
, 0, sizeof(*el
));
3027 el
->handler
[WLC_E_SCAN_COMPLETE
] = wl_notify_scan_status
;
3028 el
->handler
[WLC_E_LINK
] = wl_notify_connect_status
;
3029 el
->handler
[WLC_E_ROAM
] = wl_notify_roaming_status
;
3030 el
->handler
[WLC_E_MIC_ERROR
] = wl_notify_mic_status
;
3031 el
->handler
[WLC_E_SET_SSID
] = wl_notify_connect_status
;
3034 static s32
wl_init_priv_mem(struct wl_priv
*wl
)
3036 wl
->scan_results
= kzalloc(WL_SCAN_BUF_MAX
, GFP_KERNEL
);
3037 if (unlikely(!wl
->scan_results
)) {
3038 WL_ERR("Scan results alloc failed\n");
3039 goto init_priv_mem_out
;
3041 wl
->conf
= kzalloc(sizeof(*wl
->conf
), GFP_KERNEL
);
3042 if (unlikely(!wl
->conf
)) {
3043 WL_ERR("wl_conf alloc failed\n");
3044 goto init_priv_mem_out
;
3046 wl
->profile
= kzalloc(sizeof(*wl
->profile
), GFP_KERNEL
);
3047 if (unlikely(!wl
->profile
)) {
3048 WL_ERR("wl_profile alloc failed\n");
3049 goto init_priv_mem_out
;
3051 wl
->bss_info
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
3052 if (unlikely(!wl
->bss_info
)) {
3053 WL_ERR("Bss information alloc failed\n");
3054 goto init_priv_mem_out
;
3056 wl
->scan_req_int
= kzalloc(sizeof(*wl
->scan_req_int
), GFP_KERNEL
);
3057 if (unlikely(!wl
->scan_req_int
)) {
3058 WL_ERR("Scan req alloc failed\n");
3059 goto init_priv_mem_out
;
3061 wl
->ioctl_buf
= kzalloc(WL_IOCTL_LEN_MAX
, GFP_KERNEL
);
3062 if (unlikely(!wl
->ioctl_buf
)) {
3063 WL_ERR("Ioctl buf alloc failed\n");
3064 goto init_priv_mem_out
;
3066 wl
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3067 if (unlikely(!wl
->extra_buf
)) {
3068 WL_ERR("Extra buf alloc failed\n");
3069 goto init_priv_mem_out
;
3071 wl
->iscan
= kzalloc(sizeof(*wl
->iscan
), GFP_KERNEL
);
3072 if (unlikely(!wl
->iscan
)) {
3073 WL_ERR("Iscan buf alloc failed\n");
3074 goto init_priv_mem_out
;
3076 wl
->fw
= kzalloc(sizeof(*wl
->fw
), GFP_KERNEL
);
3077 if (unlikely(!wl
->fw
)) {
3078 WL_ERR("fw object alloc failed\n");
3079 goto init_priv_mem_out
;
3081 wl
->pmk_list
= kzalloc(sizeof(*wl
->pmk_list
), GFP_KERNEL
);
3082 if (unlikely(!wl
->pmk_list
)) {
3083 WL_ERR("pmk list alloc failed\n");
3084 goto init_priv_mem_out
;
3090 wl_deinit_priv_mem(wl
);
3095 static void wl_deinit_priv_mem(struct wl_priv
*wl
)
3097 kfree(wl
->scan_results
);
3098 wl
->scan_results
= NULL
;
3099 kfree(wl
->bss_info
);
3100 wl
->bss_info
= NULL
;
3105 kfree(wl
->scan_req_int
);
3106 wl
->scan_req_int
= NULL
;
3107 kfree(wl
->ioctl_buf
);
3108 wl
->ioctl_buf
= NULL
;
3109 kfree(wl
->extra_buf
);
3110 wl
->extra_buf
= NULL
;
3115 kfree(wl
->pmk_list
);
3116 wl
->pmk_list
= NULL
;
3119 static s32
wl_create_event_handler(struct wl_priv
*wl
)
3121 sema_init(&wl
->event_sync
, 0);
3122 wl
->event_tsk
= kthread_run(wl_event_handler
, wl
, "wl_event_handler");
3123 if (IS_ERR(wl
->event_tsk
)) {
3124 wl
->event_tsk
= NULL
;
3125 WL_ERR("failed to create event thread\n");
3131 static void wl_destroy_event_handler(struct wl_priv
*wl
)
3133 if (wl
->event_tsk
) {
3134 send_sig(SIGTERM
, wl
->event_tsk
, 1);
3135 kthread_stop(wl
->event_tsk
);
3136 wl
->event_tsk
= NULL
;
3140 static void wl_term_iscan(struct wl_priv
*wl
)
3142 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
3144 if (wl
->iscan_on
&& iscan
->tsk
) {
3145 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3146 send_sig(SIGTERM
, iscan
->tsk
, 1);
3147 kthread_stop(iscan
->tsk
);
3152 static void wl_notify_iscan_complete(struct wl_iscan_ctrl
*iscan
, bool aborted
)
3154 struct wl_priv
*wl
= iscan_to_wl(iscan
);
3155 struct net_device
*ndev
= wl_to_ndev(wl
);
3157 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
3158 WL_ERR("Scan complete while device not scanning\n");
3161 if (likely(wl
->scan_request
)) {
3162 WL_SCAN("ISCAN Completed scan: %s\n",
3163 aborted
? "Aborted" : "Done");
3164 cfg80211_scan_done(wl
->scan_request
, aborted
);
3165 wl_set_mpc(ndev
, 1);
3166 wl
->scan_request
= NULL
;
3168 wl
->iscan_kickstart
= false;
3171 static s32
wl_wakeup_iscan(struct wl_iscan_ctrl
*iscan
)
3173 if (likely(iscan
->state
!= WL_ISCAN_STATE_IDLE
)) {
3174 WL_SCAN("wake up iscan\n");
3183 wl_get_iscan_results(struct wl_iscan_ctrl
*iscan
, u32
*status
,
3184 struct wl_scan_results
**bss_list
)
3186 struct wl_iscan_results list
;
3187 struct wl_scan_results
*results
;
3188 struct wl_iscan_results
*list_buf
;
3191 memset(iscan
->scan_buf
, 0, WL_ISCAN_BUF_MAX
);
3192 list_buf
= (struct wl_iscan_results
*)iscan
->scan_buf
;
3193 results
= &list_buf
->results
;
3194 results
->buflen
= WL_ISCAN_RESULTS_FIXED_SIZE
;
3195 results
->version
= 0;
3198 memset(&list
, 0, sizeof(list
));
3199 list
.results
.buflen
= cpu_to_le32(WL_ISCAN_BUF_MAX
);
3200 err
= wl_dev_iovar_getbuf(iscan
->dev
, "iscanresults", &list
,
3201 WL_ISCAN_RESULTS_FIXED_SIZE
, iscan
->scan_buf
,
3203 if (unlikely(err
)) {
3204 WL_ERR("error (%d)\n", err
);
3207 results
->buflen
= le32_to_cpu(results
->buflen
);
3208 results
->version
= le32_to_cpu(results
->version
);
3209 results
->count
= le32_to_cpu(results
->count
);
3210 WL_SCAN("results->count = %d\n", results
->count
);
3211 WL_SCAN("results->buflen = %d\n", results
->buflen
);
3212 *status
= le32_to_cpu(list_buf
->status
);
3213 *bss_list
= results
;
3218 static s32
wl_iscan_done(struct wl_priv
*wl
)
3220 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
3223 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3226 wl_notify_iscan_complete(iscan
, false);
3232 static s32
wl_iscan_pending(struct wl_priv
*wl
)
3234 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
3237 /* Reschedule the timer */
3238 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
3239 iscan
->timer_on
= 1;
3244 static s32
wl_iscan_inprogress(struct wl_priv
*wl
)
3246 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
3251 wl_run_iscan(iscan
, NULL
, WL_SCAN_ACTION_CONTINUE
);
3253 /* Reschedule the timer */
3254 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
3255 iscan
->timer_on
= 1;
3260 static s32
wl_iscan_aborted(struct wl_priv
*wl
)
3262 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
3265 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3267 wl_notify_iscan_complete(iscan
, true);
3273 static s32
wl_iscan_thread(void *data
)
3275 struct sched_param param
= {.sched_priority
= MAX_RT_PRIO
- 1 };
3276 struct wl_iscan_ctrl
*iscan
= (struct wl_iscan_ctrl
*)data
;
3277 struct wl_priv
*wl
= iscan_to_wl(iscan
);
3278 struct wl_iscan_eloop
*el
= &iscan
->el
;
3282 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
3283 allow_signal(SIGTERM
);
3284 status
= WL_SCAN_RESULTS_PARTIAL
;
3285 while (likely(!down_interruptible(&iscan
->sync
))) {
3286 if (kthread_should_stop())
3288 if (iscan
->timer_on
) {
3289 del_timer_sync(&iscan
->timer
);
3290 iscan
->timer_on
= 0;
3293 err
= wl_get_iscan_results(iscan
, &status
, &wl
->bss_list
);
3294 if (unlikely(err
)) {
3295 status
= WL_SCAN_RESULTS_ABORTED
;
3296 WL_ERR("Abort iscan\n");
3299 el
->handler
[status
] (wl
);
3301 if (iscan
->timer_on
) {
3302 del_timer_sync(&iscan
->timer
);
3303 iscan
->timer_on
= 0;
3305 WL_SCAN("ISCAN thread terminated\n");
3310 static void wl_iscan_timer(unsigned long data
)
3312 struct wl_iscan_ctrl
*iscan
= (struct wl_iscan_ctrl
*)data
;
3315 iscan
->timer_on
= 0;
3316 WL_SCAN("timer expired\n");
3317 wl_wakeup_iscan(iscan
);
3321 static s32
wl_invoke_iscan(struct wl_priv
*wl
)
3323 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
3326 if (wl
->iscan_on
&& !iscan
->tsk
) {
3327 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3328 sema_init(&iscan
->sync
, 0);
3329 iscan
->tsk
= kthread_run(wl_iscan_thread
, iscan
, "wl_iscan");
3330 if (IS_ERR(iscan
->tsk
)) {
3331 WL_ERR("Could not create iscan thread\n");
3340 static void wl_init_iscan_eloop(struct wl_iscan_eloop
*el
)
3342 memset(el
, 0, sizeof(*el
));
3343 el
->handler
[WL_SCAN_RESULTS_SUCCESS
] = wl_iscan_done
;
3344 el
->handler
[WL_SCAN_RESULTS_PARTIAL
] = wl_iscan_inprogress
;
3345 el
->handler
[WL_SCAN_RESULTS_PENDING
] = wl_iscan_pending
;
3346 el
->handler
[WL_SCAN_RESULTS_ABORTED
] = wl_iscan_aborted
;
3347 el
->handler
[WL_SCAN_RESULTS_NO_MEM
] = wl_iscan_aborted
;
3350 static s32
wl_init_iscan(struct wl_priv
*wl
)
3352 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
3356 iscan
->dev
= wl_to_ndev(wl
);
3357 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3358 wl_init_iscan_eloop(&iscan
->el
);
3359 iscan
->timer_ms
= WL_ISCAN_TIMER_INTERVAL_MS
;
3360 init_timer(&iscan
->timer
);
3361 iscan
->timer
.data
= (unsigned long) iscan
;
3362 iscan
->timer
.function
= wl_iscan_timer
;
3363 sema_init(&iscan
->sync
, 0);
3364 iscan
->tsk
= kthread_run(wl_iscan_thread
, iscan
, "wl_iscan");
3365 if (IS_ERR(iscan
->tsk
)) {
3366 WL_ERR("Could not create iscan thread\n");
3376 static void wl_init_fw(struct wl_fw_ctrl
*fw
)
3378 fw
->status
= 0; /* init fw loading status.
3379 0 means nothing was loaded yet */
3382 static s32
wl_init_priv(struct wl_priv
*wl
)
3384 struct wiphy
*wiphy
= wl_to_wiphy(wl
);
3387 wl
->scan_request
= NULL
;
3388 wl
->pwr_save
= !!(wiphy
->flags
& WIPHY_FLAG_PS_ON_BY_DEFAULT
);
3389 wl
->iscan_on
= true; /* iscan on & off switch.
3390 we enable iscan per default */
3391 wl
->roam_on
= false; /* roam on & off switch.
3392 we enable roam per default */
3394 wl
->iscan_kickstart
= false;
3395 wl
->active_scan
= true; /* we do active scan for
3396 specific scan per default */
3397 wl
->dongle_up
= false; /* dongle is not up yet */
3399 err
= wl_init_priv_mem(wl
);
3402 if (unlikely(wl_create_event_handler(wl
)))
3404 wl_init_eloop_handler(&wl
->el
);
3405 mutex_init(&wl
->usr_sync
);
3406 err
= wl_init_iscan(wl
);
3410 wl_init_conf(wl
->conf
);
3411 wl_init_prof(wl
->profile
);
3417 static void wl_deinit_priv(struct wl_priv
*wl
)
3419 wl_destroy_event_handler(wl
);
3420 wl
->dongle_up
= false; /* dongle down */
3424 wl_deinit_priv_mem(wl
);
3427 s32
wl_cfg80211_attach(struct net_device
*ndev
, void *data
)
3429 struct wireless_dev
*wdev
;
3431 struct wl_iface
*ci
;
3434 if (unlikely(!ndev
)) {
3435 WL_ERR("ndev is invalid\n");
3438 wl_cfg80211_dev
= kzalloc(sizeof(struct wl_dev
), GFP_KERNEL
);
3439 if (unlikely(!wl_cfg80211_dev
)) {
3440 WL_ERR("wl_cfg80211_dev is invalid\n");
3443 WL_INFO("func %p\n", wl_cfg80211_get_sdio_func());
3444 wdev
= wl_alloc_wdev(sizeof(struct wl_iface
), &wl_cfg80211_get_sdio_func()->dev
);
3448 wdev
->iftype
= wl_mode_to_nl80211_iftype(WL_MODE_BSS
);
3449 wl
= wdev_to_wl(wdev
);
3452 ci
= (struct wl_iface
*)wl_to_ci(wl
);
3454 ndev
->ieee80211_ptr
= wdev
;
3455 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
3456 wdev
->netdev
= ndev
;
3457 err
= wl_init_priv(wl
);
3458 if (unlikely(err
)) {
3459 WL_ERR("Failed to init iwm_priv (%d)\n", err
);
3460 goto cfg80211_attach_out
;
3462 wl_set_drvdata(wl_cfg80211_dev
, ci
);
3466 cfg80211_attach_out
:
3471 void wl_cfg80211_detach(void)
3479 wl_set_drvdata(wl_cfg80211_dev
, NULL
);
3480 kfree(wl_cfg80211_dev
);
3481 wl_cfg80211_dev
= NULL
;
3482 wl_clear_sdio_func();
3485 static void wl_wakeup_event(struct wl_priv
*wl
)
3487 up(&wl
->event_sync
);
3490 static s32
wl_event_handler(void *data
)
3492 struct wl_priv
*wl
= (struct wl_priv
*)data
;
3493 struct sched_param param
= {.sched_priority
= MAX_RT_PRIO
- 1 };
3494 struct wl_event_q
*e
;
3496 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
3497 allow_signal(SIGTERM
);
3498 while (likely(!down_interruptible(&wl
->event_sync
))) {
3499 if (kthread_should_stop())
3501 e
= wl_deq_event(wl
);
3503 WL_ERR("event queue empty...\n");
3506 WL_INFO("event type (%d)\n", e
->etype
);
3507 if (wl
->el
.handler
[e
->etype
]) {
3508 wl
->el
.handler
[e
->etype
] (wl
, wl_to_ndev(wl
), &e
->emsg
,
3511 WL_INFO("Unknown Event (%d): ignoring\n", e
->etype
);
3515 WL_INFO("was terminated\n");
3520 wl_cfg80211_event(struct net_device
*ndev
, const wl_event_msg_t
* e
, void *data
)
3522 u32 event_type
= be32_to_cpu(e
->event_type
);
3523 struct wl_priv
*wl
= ndev_to_wl(ndev
);
3525 if (likely(!wl_enq_event(wl
, event_type
, e
, data
)))
3526 wl_wakeup_event(wl
);
3529 static void wl_init_eq(struct wl_priv
*wl
)
3531 wl_init_eq_lock(wl
);
3532 INIT_LIST_HEAD(&wl
->eq_list
);
3535 static void wl_flush_eq(struct wl_priv
*wl
)
3537 struct wl_event_q
*e
;
3540 while (!list_empty(&wl
->eq_list
)) {
3541 e
= list_first_entry(&wl
->eq_list
, struct wl_event_q
, eq_list
);
3542 list_del(&e
->eq_list
);
3549 * retrieve first queued event from head
3552 static struct wl_event_q
*wl_deq_event(struct wl_priv
*wl
)
3554 struct wl_event_q
*e
= NULL
;
3557 if (likely(!list_empty(&wl
->eq_list
))) {
3558 e
= list_first_entry(&wl
->eq_list
, struct wl_event_q
, eq_list
);
3559 list_del(&e
->eq_list
);
3567 ** push event to tail of the queue
3571 wl_enq_event(struct wl_priv
*wl
, u32 event
, const wl_event_msg_t
*msg
,
3574 struct wl_event_q
*e
;
3577 e
= kzalloc(sizeof(struct wl_event_q
), GFP_KERNEL
);
3579 WL_ERR("event alloc failed\n");
3584 memcpy(&e
->emsg
, msg
, sizeof(wl_event_msg_t
));
3588 list_add_tail(&e
->eq_list
, &wl
->eq_list
);
3594 static void wl_put_event(struct wl_event_q
*e
)
3599 void wl_cfg80211_sdio_func(void *func
)
3601 cfg80211_sdio_func
= (struct sdio_func
*)func
;
3604 static void wl_clear_sdio_func(void)
3606 cfg80211_sdio_func
= NULL
;
3609 struct sdio_func
*wl_cfg80211_get_sdio_func(void)
3611 return cfg80211_sdio_func
;
3614 static s32
wl_dongle_mode(struct net_device
*ndev
, s32 iftype
)
3620 case NL80211_IFTYPE_MONITOR
:
3621 case NL80211_IFTYPE_WDS
:
3622 WL_ERR("type (%d) : currently we do not support this mode\n",
3626 case NL80211_IFTYPE_ADHOC
:
3629 case NL80211_IFTYPE_STATION
:
3634 WL_ERR("invalid type (%d)\n", iftype
);
3637 infra
= cpu_to_le32(infra
);
3638 err
= wl_dev_ioctl(ndev
, WLC_SET_INFRA
, &infra
, sizeof(infra
));
3639 if (unlikely(err
)) {
3640 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
3647 #ifndef EMBEDDED_PLATFORM
3648 static s32
wl_dongle_country(struct net_device
*ndev
, u8 ccode
)
3656 static s32
wl_dongle_up(struct net_device
*ndev
, u32 up
)
3660 err
= wl_dev_ioctl(ndev
, WLC_UP
, &up
, sizeof(up
));
3661 if (unlikely(err
)) {
3662 WL_ERR("WLC_UP error (%d)\n", err
);
3667 static s32
wl_dongle_power(struct net_device
*ndev
, u32 power_mode
)
3671 err
= wl_dev_ioctl(ndev
, WLC_SET_PM
, &power_mode
, sizeof(power_mode
));
3672 if (unlikely(err
)) {
3673 WL_ERR("WLC_SET_PM error (%d)\n", err
);
3679 wl_dongle_glom(struct net_device
*ndev
, u32 glom
, u32 dongle_align
)
3681 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3685 /* Match Host and Dongle rx alignment */
3686 brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align
, 4, iovbuf
,
3688 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3689 if (unlikely(err
)) {
3690 WL_ERR("txglomalign error (%d)\n", err
);
3691 goto dongle_glom_out
;
3693 /* disable glom option per default */
3694 brcmu_mkiovar("bus:txglom", (char *)&glom
, 4, iovbuf
, sizeof(iovbuf
));
3695 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3696 if (unlikely(err
)) {
3697 WL_ERR("txglom error (%d)\n", err
);
3698 goto dongle_glom_out
;
3705 wl_dongle_offload(struct net_device
*ndev
, s32 arpoe
, s32 arp_ol
)
3707 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3711 /* Set ARP offload */
3712 brcmu_mkiovar("arpoe", (char *)&arpoe
, 4, iovbuf
, sizeof(iovbuf
));
3713 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3715 if (err
== -EOPNOTSUPP
)
3716 WL_INFO("arpoe is not supported\n");
3718 WL_ERR("arpoe error (%d)\n", err
);
3720 goto dongle_offload_out
;
3722 brcmu_mkiovar("arp_ol", (char *)&arp_ol
, 4, iovbuf
, sizeof(iovbuf
));
3723 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3725 if (err
== -EOPNOTSUPP
)
3726 WL_INFO("arp_ol is not supported\n");
3728 WL_ERR("arp_ol error (%d)\n", err
);
3730 goto dongle_offload_out
;
3737 static s32
wl_pattern_atoh(s8
*src
, s8
*dst
)
3740 if (strncmp(src
, "0x", 2) != 0 && strncmp(src
, "0X", 2) != 0) {
3741 WL_ERR("Mask invalid format. Needs to start with 0x\n");
3744 src
= src
+ 2; /* Skip past 0x */
3745 if (strlen(src
) % 2 != 0) {
3746 WL_ERR("Mask invalid format. Needs to be of even length\n");
3749 for (i
= 0; *src
!= '\0'; i
++) {
3751 strncpy(num
, src
, 2);
3753 dst
[i
] = (u8
) simple_strtoul(num
, NULL
, 16);
3759 static s32
wl_dongle_filter(struct net_device
*ndev
, u32 filter_mode
)
3761 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3764 struct wl_pkt_filter pkt_filter
;
3765 struct wl_pkt_filter
*pkt_filterp
;
3773 /* add a default packet filter pattern */
3774 str
= "pkt_filter_add";
3775 str_len
= strlen(str
);
3776 strncpy(buf
, str
, str_len
);
3777 buf
[str_len
] = '\0';
3778 buf_len
= str_len
+ 1;
3780 pkt_filterp
= (struct wl_pkt_filter
*)(buf
+ str_len
+ 1);
3782 /* Parse packet filter id. */
3783 pkt_filter
.id
= cpu_to_le32(100);
3785 /* Parse filter polarity. */
3786 pkt_filter
.negate_match
= cpu_to_le32(0);
3788 /* Parse filter type. */
3789 pkt_filter
.type
= cpu_to_le32(0);
3791 /* Parse pattern filter offset. */
3792 pkt_filter
.u
.pattern
.offset
= cpu_to_le32(0);
3794 /* Parse pattern filter mask. */
3795 mask_size
= cpu_to_le32(wl_pattern_atoh("0xff",
3796 (char *)pkt_filterp
->u
.pattern
.
3799 /* Parse pattern filter pattern. */
3800 pattern_size
= cpu_to_le32(wl_pattern_atoh("0x00",
3801 (char *)&pkt_filterp
->u
.
3806 if (mask_size
!= pattern_size
) {
3807 WL_ERR("Mask and pattern not the same size\n");
3809 goto dongle_filter_out
;
3812 pkt_filter
.u
.pattern
.size_bytes
= mask_size
;
3813 buf_len
+= WL_PKT_FILTER_FIXED_LEN
;
3814 buf_len
+= (WL_PKT_FILTER_PATTERN_FIXED_LEN
+ 2 * mask_size
);
3816 /* Keep-alive attributes are set in local
3817 * variable (keep_alive_pkt), and
3818 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3819 * guarantee that the buffer is properly aligned.
3821 memcpy((char *)pkt_filterp
, &pkt_filter
,
3822 WL_PKT_FILTER_FIXED_LEN
+ WL_PKT_FILTER_PATTERN_FIXED_LEN
);
3824 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, buf
, buf_len
);
3826 if (err
== -EOPNOTSUPP
) {
3827 WL_INFO("filter not supported\n");
3829 WL_ERR("filter (%d)\n", err
);
3831 goto dongle_filter_out
;
3834 /* set mode to allow pattern */
3835 brcmu_mkiovar("pkt_filter_mode", (char *)&filter_mode
, 4, iovbuf
,
3837 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3839 if (err
== -EOPNOTSUPP
) {
3840 WL_INFO("filter_mode not supported\n");
3842 WL_ERR("filter_mode (%d)\n", err
);
3844 goto dongle_filter_out
;
3850 #endif /* !EMBEDDED_PLATFORM */
3852 static s32
wl_dongle_eventmsg(struct net_device
*ndev
)
3854 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3856 s8 eventmask
[WL_EVENTING_MASK_LEN
];
3859 WL_TRACE("Enter\n");
3861 /* Setup event_msgs */
3862 brcmu_mkiovar("event_msgs", eventmask
, WL_EVENTING_MASK_LEN
, iovbuf
,
3864 err
= wl_dev_ioctl(ndev
, WLC_GET_VAR
, iovbuf
, sizeof(iovbuf
));
3865 if (unlikely(err
)) {
3866 WL_ERR("Get event_msgs error (%d)\n", err
);
3867 goto dongle_eventmsg_out
;
3869 memcpy(eventmask
, iovbuf
, WL_EVENTING_MASK_LEN
);
3871 setbit(eventmask
, WLC_E_SET_SSID
);
3872 setbit(eventmask
, WLC_E_ROAM
);
3873 setbit(eventmask
, WLC_E_PRUNE
);
3874 setbit(eventmask
, WLC_E_AUTH
);
3875 setbit(eventmask
, WLC_E_REASSOC
);
3876 setbit(eventmask
, WLC_E_REASSOC_IND
);
3877 setbit(eventmask
, WLC_E_DEAUTH_IND
);
3878 setbit(eventmask
, WLC_E_DISASSOC_IND
);
3879 setbit(eventmask
, WLC_E_DISASSOC
);
3880 setbit(eventmask
, WLC_E_JOIN
);
3881 setbit(eventmask
, WLC_E_ASSOC_IND
);
3882 setbit(eventmask
, WLC_E_PSK_SUP
);
3883 setbit(eventmask
, WLC_E_LINK
);
3884 setbit(eventmask
, WLC_E_NDIS_LINK
);
3885 setbit(eventmask
, WLC_E_MIC_ERROR
);
3886 setbit(eventmask
, WLC_E_PMKID_CACHE
);
3887 setbit(eventmask
, WLC_E_TXFAIL
);
3888 setbit(eventmask
, WLC_E_JOIN_START
);
3889 setbit(eventmask
, WLC_E_SCAN_COMPLETE
);
3891 brcmu_mkiovar("event_msgs", eventmask
, WL_EVENTING_MASK_LEN
, iovbuf
,
3893 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3894 if (unlikely(err
)) {
3895 WL_ERR("Set event_msgs error (%d)\n", err
);
3896 goto dongle_eventmsg_out
;
3899 dongle_eventmsg_out
:
3905 wl_dongle_roam(struct net_device
*ndev
, u32 roamvar
, u32 bcn_timeout
)
3913 * Setup timeout if Beacons are lost and roam is
3914 * off to report link down
3917 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout
,
3918 sizeof(bcn_timeout
), iovbuf
, sizeof(iovbuf
));
3919 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3920 if (unlikely(err
)) {
3921 WL_ERR("bcn_timeout error (%d)\n", err
);
3922 goto dongle_rom_out
;
3927 * Enable/Disable built-in roaming to allow supplicant
3928 * to take care of roaming
3930 WL_INFO("Internal Roaming = %s\n", roamvar
? "Off" : "On");
3931 brcmu_mkiovar("roam_off", (char *)&roamvar
,
3932 sizeof(roamvar
), iovbuf
, sizeof(iovbuf
));
3933 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3934 if (unlikely(err
)) {
3935 WL_ERR("roam_off error (%d)\n", err
);
3936 goto dongle_rom_out
;
3939 roamtrigger
[0] = WL_ROAM_TRIGGER_LEVEL
;
3940 roamtrigger
[1] = WLC_BAND_ALL
;
3941 err
= wl_dev_ioctl(ndev
, WLC_SET_ROAM_TRIGGER
,
3942 (void *)roamtrigger
, sizeof(roamtrigger
));
3943 if (unlikely(err
)) {
3944 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
3945 goto dongle_rom_out
;
3948 roam_delta
[0] = WL_ROAM_DELTA
;
3949 roam_delta
[1] = WLC_BAND_ALL
;
3950 err
= wl_dev_ioctl(ndev
, WLC_SET_ROAM_DELTA
,
3951 (void *)roam_delta
, sizeof(roam_delta
));
3952 if (unlikely(err
)) {
3953 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err
);
3954 goto dongle_rom_out
;
3962 wl_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
3963 s32 scan_unassoc_time
, s32 scan_passive_time
)
3967 err
= wl_dev_ioctl(ndev
, WLC_SET_SCAN_CHANNEL_TIME
, &scan_assoc_time
,
3968 sizeof(scan_assoc_time
));
3970 if (err
== -EOPNOTSUPP
)
3971 WL_INFO("Scan assoc time is not supported\n");
3973 WL_ERR("Scan assoc time error (%d)\n", err
);
3974 goto dongle_scantime_out
;
3976 err
= wl_dev_ioctl(ndev
, WLC_SET_SCAN_UNASSOC_TIME
, &scan_unassoc_time
,
3977 sizeof(scan_unassoc_time
));
3979 if (err
== -EOPNOTSUPP
)
3980 WL_INFO("Scan unassoc time is not supported\n");
3982 WL_ERR("Scan unassoc time error (%d)\n", err
);
3983 goto dongle_scantime_out
;
3986 err
= wl_dev_ioctl(ndev
, WLC_SET_SCAN_PASSIVE_TIME
, &scan_passive_time
,
3987 sizeof(scan_passive_time
));
3989 if (err
== -EOPNOTSUPP
)
3990 WL_INFO("Scan passive time is not supported\n");
3992 WL_ERR("Scan passive time error (%d)\n", err
);
3993 goto dongle_scantime_out
;
3996 dongle_scantime_out
:
4000 s32
wl_config_dongle(struct wl_priv
*wl
, bool need_lock
)
4003 #define DHD_SDALIGN 32
4005 struct net_device
*ndev
;
4006 struct wireless_dev
*wdev
;
4012 ndev
= wl_to_ndev(wl
);
4013 wdev
= ndev
->ieee80211_ptr
;
4017 #ifndef EMBEDDED_PLATFORM
4018 err
= wl_dongle_up(ndev
, 0);
4020 goto default_conf_out
;
4021 err
= wl_dongle_country(ndev
, 0);
4023 goto default_conf_out
;
4024 err
= wl_dongle_power(ndev
, PM_FAST
);
4026 goto default_conf_out
;
4027 err
= wl_dongle_glom(ndev
, 0, DHD_SDALIGN
);
4029 goto default_conf_out
;
4031 wl_dongle_offload(ndev
, 1, 0xf);
4032 wl_dongle_filter(ndev
, 1);
4033 #endif /* !EMBEDDED_PLATFORM */
4035 wl_dongle_scantime(ndev
, WL_SCAN_CHANNEL_TIME
,
4036 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
4038 err
= wl_dongle_eventmsg(ndev
);
4040 goto default_conf_out
;
4041 err
= wl_dongle_roam(ndev
, (wl
->roam_on
? 0 : 1), WL_BEACON_TIMEOUT
);
4043 goto default_conf_out
;
4044 err
= wl_dongle_mode(ndev
, wdev
->iftype
);
4045 if (unlikely(err
&& err
!= -EINPROGRESS
))
4046 goto default_conf_out
;
4047 err
= wl_dongle_probecap(wl
);
4049 goto default_conf_out
;
4051 /* -EINPROGRESS: Call commit handler */
4057 wl
->dongle_up
= true;
4063 static s32
wl_update_wiphybands(struct wl_priv
*wl
)
4065 struct wiphy
*wiphy
;
4070 err
= wl_dev_ioctl(wl_to_ndev(wl
), WLC_GET_PHYLIST
, &phy_list
,
4072 if (unlikely(err
)) {
4073 WL_ERR("error (%d)\n", err
);
4077 phy
= ((char *)&phy_list
)[1];
4078 WL_INFO("%c phy\n", phy
);
4079 if (phy
== 'n' || phy
== 'a') {
4080 wiphy
= wl_to_wiphy(wl
);
4081 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
4087 static s32
__wl_cfg80211_up(struct wl_priv
*wl
)
4091 set_bit(WL_STATUS_READY
, &wl
->status
);
4093 wl_debugfs_add_netdev_params(wl
);
4095 err
= wl_config_dongle(wl
, false);
4099 wl_invoke_iscan(wl
);
4104 static s32
__wl_cfg80211_down(struct wl_priv
*wl
)
4106 set_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
4108 if (wl
->scan_request
) {
4109 cfg80211_scan_done(wl
->scan_request
, true);
4110 /* May need to perform this to cover rmmod */
4111 /* wl_set_mpc(wl_to_ndev(wl), 1); */
4112 wl
->scan_request
= NULL
;
4114 clear_bit(WL_STATUS_READY
, &wl
->status
);
4115 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
4116 clear_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
4117 clear_bit(WL_STATUS_CONNECTING
, &wl
->status
);
4118 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
4120 wl_debugfs_remove_netdev(wl
);
4125 s32
wl_cfg80211_up(void)
4131 mutex_lock(&wl
->usr_sync
);
4132 err
= __wl_cfg80211_up(wl
);
4133 mutex_unlock(&wl
->usr_sync
);
4138 s32
wl_cfg80211_down(void)
4144 mutex_lock(&wl
->usr_sync
);
4145 err
= __wl_cfg80211_down(wl
);
4146 mutex_unlock(&wl
->usr_sync
);
4151 static s32
wl_dongle_probecap(struct wl_priv
*wl
)
4155 err
= wl_update_wiphybands(wl
);
4162 static void *wl_read_prof(struct wl_priv
*wl
, s32 item
)
4166 return &wl
->profile
->sec
;
4168 return &wl
->profile
->bssid
;
4170 return &wl
->profile
->ssid
;
4172 WL_ERR("invalid item (%d)\n", item
);
4177 wl_update_prof(struct wl_priv
*wl
, const wl_event_msg_t
*e
, void *data
,
4181 struct wlc_ssid
*ssid
;
4185 ssid
= (wlc_ssid_t
*) data
;
4186 memset(wl
->profile
->ssid
.SSID
, 0,
4187 sizeof(wl
->profile
->ssid
.SSID
));
4188 memcpy(wl
->profile
->ssid
.SSID
, ssid
->SSID
, ssid
->SSID_len
);
4189 wl
->profile
->ssid
.SSID_len
= ssid
->SSID_len
;
4193 memcpy(wl
->profile
->bssid
, data
, ETH_ALEN
);
4195 memset(wl
->profile
->bssid
, 0, ETH_ALEN
);
4198 memcpy(&wl
->profile
->sec
, data
, sizeof(wl
->profile
->sec
));
4200 case WL_PROF_BEACONINT
:
4201 wl
->profile
->beacon_interval
= *(u16
*)data
;
4203 case WL_PROF_DTIMPERIOD
:
4204 wl
->profile
->dtim_period
= *(u8
*)data
;
4207 WL_ERR("unsupported item (%d)\n", item
);
4215 static bool wl_is_ibssmode(struct wl_priv
*wl
)
4217 return wl
->conf
->mode
== WL_MODE_IBSS
;
4220 static __used s32
wl_add_ie(struct wl_priv
*wl
, u8 t
, u8 l
, u8
*v
)
4222 struct wl_ie
*ie
= wl_to_ie(wl
);
4225 if (unlikely(ie
->offset
+ l
+ 2 > WL_TLV_INFO_MAX
)) {
4226 WL_ERR("ei crosses buffer boundary\n");
4229 ie
->buf
[ie
->offset
] = t
;
4230 ie
->buf
[ie
->offset
+ 1] = l
;
4231 memcpy(&ie
->buf
[ie
->offset
+ 2], v
, l
);
4232 ie
->offset
+= l
+ 2;
4238 static void wl_link_down(struct wl_priv
*wl
)
4240 struct net_device
*dev
= NULL
;
4243 WL_TRACE("Enter\n");
4244 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
4247 dev
= wl_to_ndev(wl
);
4248 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
4249 err
= wl_dev_ioctl(dev
, WLC_DISASSOC
, NULL
, 0);
4251 WL_ERR("WLC_DISASSOC failed (%d)\n", err
);
4252 wl
->link_up
= false;
4257 static void wl_lock_eq(struct wl_priv
*wl
)
4259 spin_lock_irq(&wl
->eq_lock
);
4262 static void wl_unlock_eq(struct wl_priv
*wl
)
4264 spin_unlock_irq(&wl
->eq_lock
);
4267 static void wl_init_eq_lock(struct wl_priv
*wl
)
4269 spin_lock_init(&wl
->eq_lock
);
4272 static void wl_delay(u32 ms
)
4274 if (ms
< 1000 / HZ
) {
4282 static void wl_set_drvdata(struct wl_dev
*dev
, void *data
)
4284 dev
->driver_data
= data
;
4287 static void *wl_get_drvdata(struct wl_dev
*dev
)
4289 return dev
->driver_data
;
4292 s32
wl_cfg80211_read_fw(s8
*buf
, u32 size
)
4294 const struct firmware
*fw_entry
;
4299 fw_entry
= wl
->fw
->fw_entry
;
4301 if (fw_entry
->size
< wl
->fw
->ptr
+ size
)
4302 size
= fw_entry
->size
- wl
->fw
->ptr
;
4304 memcpy(buf
, &fw_entry
->data
[wl
->fw
->ptr
], size
);
4305 wl
->fw
->ptr
+= size
;
4309 void wl_cfg80211_release_fw(void)
4314 release_firmware(wl
->fw
->fw_entry
);
4318 void *wl_cfg80211_request_fw(s8
*file_name
)
4321 const struct firmware
*fw_entry
= NULL
;
4324 WL_INFO("file name : \"%s\"\n", file_name
);
4327 if (!test_bit(WL_FW_LOADING_DONE
, &wl
->fw
->status
)) {
4328 err
= request_firmware(&wl
->fw
->fw_entry
, file_name
,
4329 &wl_cfg80211_get_sdio_func()->dev
);
4330 if (unlikely(err
)) {
4331 WL_ERR("Could not download fw (%d)\n", err
);
4334 set_bit(WL_FW_LOADING_DONE
, &wl
->fw
->status
);
4335 fw_entry
= wl
->fw
->fw_entry
;
4337 WL_INFO("fw size (%zd), data (%p)\n",
4338 fw_entry
->size
, fw_entry
->data
);
4340 } else if (!test_bit(WL_NVRAM_LOADING_DONE
, &wl
->fw
->status
)) {
4341 err
= request_firmware(&wl
->fw
->fw_entry
, file_name
,
4342 &wl_cfg80211_get_sdio_func()->dev
);
4343 if (unlikely(err
)) {
4344 WL_ERR("Could not download nvram (%d)\n", err
);
4347 set_bit(WL_NVRAM_LOADING_DONE
, &wl
->fw
->status
);
4348 fw_entry
= wl
->fw
->fw_entry
;
4350 WL_INFO("nvram size (%zd), data (%p)\n",
4351 fw_entry
->size
, fw_entry
->data
);
4354 WL_INFO("Downloading already done. Nothing to do more\n");
4359 if (unlikely(err
)) {
4363 return (void *)fw_entry
->data
;
4366 s8
*wl_cfg80211_get_fwname(void)
4371 strcpy(wl
->fw
->fw_name
, WL_4329_FW_FILE
);
4372 return wl
->fw
->fw_name
;
4375 s8
*wl_cfg80211_get_nvramname(void)
4380 strcpy(wl
->fw
->nvram_name
, WL_4329_NVRAM_FILE
);
4381 return wl
->fw
->nvram_name
;
4384 static void wl_set_mpc(struct net_device
*ndev
, int mpc
)
4387 struct wl_priv
*wl
= ndev_to_wl(ndev
);
4389 if (test_bit(WL_STATUS_READY
, &wl
->status
)) {
4390 err
= wl_dev_intvar_set(ndev
, "mpc", mpc
);
4391 if (unlikely(err
)) {
4392 WL_ERR("fail to set mpc\n");
4395 WL_INFO("MPC : %d\n", mpc
);
4399 static int wl_debugfs_add_netdev_params(struct wl_priv
*wl
)
4401 char buf
[10+IFNAMSIZ
];
4405 sprintf(buf
, "netdev:%s", wl_to_ndev(wl
)->name
);
4406 wl
->debugfsdir
= debugfs_create_dir(buf
, wl_to_wiphy(wl
)->debugfsdir
);
4408 fd
= debugfs_create_u16("beacon_int", S_IRUGO
, wl
->debugfsdir
,
4409 (u16
*)&wl
->profile
->beacon_interval
);
4415 fd
= debugfs_create_u8("dtim_period", S_IRUGO
, wl
->debugfsdir
,
4416 (u8
*)&wl
->profile
->dtim_period
);
4426 static void wl_debugfs_remove_netdev(struct wl_priv
*wl
)
4428 debugfs_remove_recursive(wl
->debugfsdir
);
4429 wl
->debugfsdir
= NULL
;