2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/kernel.h>
18 #include <linux/if_arp.h>
19 #include <linux/sched.h>
20 #include <linux/kthread.h>
21 #include <linux/netdevice.h>
22 #include <linux/sched.h>
23 #include <linux/etherdevice.h>
24 #include <linux/wireless.h>
25 #include <linux/ieee80211.h>
26 #include <linux/mmc/sdio_func.h>
27 #include <linux/firmware.h>
28 #include <linux/uaccess.h>
29 #include <net/cfg80211.h>
30 #include <net/rtnetlink.h>
32 #include <brcmu_utils.h>
34 #include <brcmu_wifi.h>
35 #include "dngl_stats.h"
37 #include "wl_cfg80211.h"
39 void sdioh_sdio_set_host_pm_flags(int flag
);
41 static struct sdio_func
*cfg80211_sdio_func
;
42 static struct wl_dev
*wl_cfg80211_dev
;
43 static const u8 ether_bcast
[ETH_ALEN
] = {255, 255, 255, 255, 255, 255};
45 u32 brcmf_dbg_level
= WL_DBG_ERR
;
47 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
48 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
51 ** cfg80211_ops api/callback list
53 static s32
wl_cfg80211_change_iface(struct wiphy
*wiphy
,
54 struct net_device
*ndev
,
55 enum nl80211_iftype type
, u32
*flags
,
56 struct vif_params
*params
);
57 static s32
__wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
58 struct cfg80211_scan_request
*request
,
59 struct cfg80211_ssid
*this_ssid
);
60 static s32
wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
61 struct cfg80211_scan_request
*request
);
62 static s32
wl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
);
63 static s32
wl_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
64 struct cfg80211_ibss_params
*params
);
65 static s32
wl_cfg80211_leave_ibss(struct wiphy
*wiphy
,
66 struct net_device
*dev
);
67 static s32
wl_cfg80211_get_station(struct wiphy
*wiphy
,
68 struct net_device
*dev
, u8
*mac
,
69 struct station_info
*sinfo
);
70 static s32
wl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
71 struct net_device
*dev
, bool enabled
,
73 static s32
wl_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
,
74 struct net_device
*dev
,
76 const struct cfg80211_bitrate_mask
78 static int wl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
79 struct cfg80211_connect_params
*sme
);
80 static s32
wl_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
82 static s32
wl_cfg80211_set_tx_power(struct wiphy
*wiphy
,
83 enum nl80211_tx_power_setting type
,
85 static s32
wl_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
);
86 static s32
wl_cfg80211_config_default_key(struct wiphy
*wiphy
,
87 struct net_device
*dev
, u8 key_idx
,
88 bool unicast
, bool multicast
);
89 static s32
wl_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
90 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
91 struct key_params
*params
);
92 static s32
wl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
93 u8 key_idx
, bool pairwise
, const u8
*mac_addr
);
94 static s32
wl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
95 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
96 void *cookie
, void (*callback
) (void *cookie
,
100 static s32
wl_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
101 struct net_device
*dev
,
103 static s32
wl_cfg80211_resume(struct wiphy
*wiphy
);
104 static s32
wl_cfg80211_suspend(struct wiphy
*wiphy
);
105 static s32
wl_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
106 struct cfg80211_pmksa
*pmksa
);
107 static s32
wl_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
108 struct cfg80211_pmksa
*pmksa
);
109 static s32
wl_cfg80211_flush_pmksa(struct wiphy
*wiphy
,
110 struct net_device
*dev
);
112 ** event & event Q handlers for cfg80211 interfaces
114 static s32
wl_create_event_handler(struct wl_priv
*wl
);
115 static void wl_destroy_event_handler(struct wl_priv
*wl
);
116 static s32
wl_event_handler(void *data
);
117 static void wl_init_eq(struct wl_priv
*wl
);
118 static void wl_flush_eq(struct wl_priv
*wl
);
119 static void wl_lock_eq(struct wl_priv
*wl
);
120 static void wl_unlock_eq(struct wl_priv
*wl
);
121 static void wl_init_eq_lock(struct wl_priv
*wl
);
122 static void wl_init_eloop_handler(struct wl_event_loop
*el
);
123 static struct wl_event_q
*wl_deq_event(struct wl_priv
*wl
);
124 static s32
wl_enq_event(struct wl_priv
*wl
, u32 type
,
125 const wl_event_msg_t
*msg
, void *data
);
126 static void wl_put_event(struct wl_event_q
*e
);
127 static void wl_wakeup_event(struct wl_priv
*wl
);
128 static s32
wl_notify_connect_status(struct wl_priv
*wl
,
129 struct net_device
*ndev
,
130 const wl_event_msg_t
*e
, void *data
);
131 static s32
wl_notify_roaming_status(struct wl_priv
*wl
,
132 struct net_device
*ndev
,
133 const wl_event_msg_t
*e
, void *data
);
134 static s32
wl_notify_scan_status(struct wl_priv
*wl
, struct net_device
*ndev
,
135 const wl_event_msg_t
*e
, void *data
);
136 static s32
wl_bss_connect_done(struct wl_priv
*wl
, struct net_device
*ndev
,
137 const wl_event_msg_t
*e
, void *data
,
139 static s32
wl_bss_roaming_done(struct wl_priv
*wl
, struct net_device
*ndev
,
140 const wl_event_msg_t
*e
, void *data
);
141 static s32
wl_notify_mic_status(struct wl_priv
*wl
, struct net_device
*ndev
,
142 const wl_event_msg_t
*e
, void *data
);
145 ** register/deregister sdio function
147 struct sdio_func
*wl_cfg80211_get_sdio_func(void);
148 static void wl_clear_sdio_func(void);
153 static s32
wl_dev_bufvar_get(struct net_device
*dev
, s8
*name
, s8
*buf
,
155 static __used s32
wl_dev_bufvar_set(struct net_device
*dev
, s8
*name
,
157 static s32
wl_dev_intvar_set(struct net_device
*dev
, s8
*name
, s32 val
);
158 static s32
wl_dev_intvar_get(struct net_device
*dev
, s8
*name
,
160 static s32
wl_dev_ioctl(struct net_device
*dev
, u32 cmd
, void *arg
,
164 ** cfg80211 set_wiphy_params utilities
166 static s32
wl_set_frag(struct net_device
*dev
, u32 frag_threshold
);
167 static s32
wl_set_rts(struct net_device
*dev
, u32 frag_threshold
);
168 static s32
wl_set_retry(struct net_device
*dev
, u32 retry
, bool l
);
171 ** wl profile utilities
173 static s32
wl_update_prof(struct wl_priv
*wl
, const wl_event_msg_t
*e
,
174 void *data
, s32 item
);
175 static void *wl_read_prof(struct wl_priv
*wl
, s32 item
);
176 static void wl_init_prof(struct wl_profile
*prof
);
179 ** cfg80211 connect utilites
181 static s32
wl_set_wpa_version(struct net_device
*dev
,
182 struct cfg80211_connect_params
*sme
);
183 static s32
wl_set_auth_type(struct net_device
*dev
,
184 struct cfg80211_connect_params
*sme
);
185 static s32
wl_set_set_cipher(struct net_device
*dev
,
186 struct cfg80211_connect_params
*sme
);
187 static s32
wl_set_key_mgmt(struct net_device
*dev
,
188 struct cfg80211_connect_params
*sme
);
189 static s32
wl_set_set_sharedkey(struct net_device
*dev
,
190 struct cfg80211_connect_params
*sme
);
191 static s32
wl_get_assoc_ies(struct wl_priv
*wl
);
192 static void wl_clear_assoc_ies(struct wl_priv
*wl
);
193 static void wl_ch_to_chanspec(int ch
,
194 struct wl_join_params
*join_params
, size_t *join_params_size
);
197 ** information element utilities
199 static __used s32
wl_add_ie(struct wl_priv
*wl
, u8 t
, u8 l
, u8
*v
);
200 static s32
wl_mode_to_nl80211_iftype(s32 mode
);
201 static struct wireless_dev
*wl_alloc_wdev(s32 sizeof_iface
,
203 static void wl_free_wdev(struct wl_priv
*wl
);
204 static s32
wl_inform_bss(struct wl_priv
*wl
);
205 static s32
wl_inform_single_bss(struct wl_priv
*wl
, struct wl_bss_info
*bi
);
206 static s32
wl_update_bss_info(struct wl_priv
*wl
);
207 static s32
wl_add_keyext(struct wiphy
*wiphy
, struct net_device
*dev
,
208 u8 key_idx
, const u8
*mac_addr
,
209 struct key_params
*params
);
212 ** key indianess swap utilities
214 static void swap_key_from_BE(struct wl_wsec_key
*key
);
215 static void swap_key_to_BE(struct wl_wsec_key
*key
);
218 ** wl_priv memory init/deinit utilities
220 static s32
wl_init_priv_mem(struct wl_priv
*wl
);
221 static void wl_deinit_priv_mem(struct wl_priv
*wl
);
223 static void wl_delay(u32 ms
);
226 ** store/restore cfg80211 instance data
228 static void wl_set_drvdata(struct wl_dev
*dev
, void *data
);
229 static void *wl_get_drvdata(struct wl_dev
*dev
);
232 ** ibss mode utilities
234 static bool wl_is_ibssmode(struct wl_priv
*wl
);
237 ** dongle up/down , default configuration utilities
239 static bool wl_is_linkdown(struct wl_priv
*wl
, const wl_event_msg_t
*e
);
240 static bool wl_is_linkup(struct wl_priv
*wl
, const wl_event_msg_t
*e
);
241 static bool wl_is_nonetwork(struct wl_priv
*wl
, const wl_event_msg_t
*e
);
242 static void wl_link_down(struct wl_priv
*wl
);
243 static s32
wl_dongle_mode(struct net_device
*ndev
, s32 iftype
);
244 static s32
__wl_cfg80211_up(struct wl_priv
*wl
);
245 static s32
__wl_cfg80211_down(struct wl_priv
*wl
);
246 static s32
wl_dongle_probecap(struct wl_priv
*wl
);
247 static void wl_init_conf(struct wl_conf
*conf
);
250 ** dongle configuration utilities
252 #ifndef EMBEDDED_PLATFORM
253 static s32
wl_dongle_mode(struct net_device
*ndev
, s32 iftype
);
254 static s32
wl_dongle_country(struct net_device
*ndev
, u8 ccode
);
255 static s32
wl_dongle_up(struct net_device
*ndev
, u32 up
);
256 static s32
wl_dongle_power(struct net_device
*ndev
, u32 power_mode
);
257 static s32
wl_dongle_glom(struct net_device
*ndev
, u32 glom
,
259 static s32
wl_dongle_offload(struct net_device
*ndev
, s32 arpoe
,
261 static s32
wl_pattern_atoh(s8
*src
, s8
*dst
);
262 static s32
wl_dongle_filter(struct net_device
*ndev
, u32 filter_mode
);
263 static s32
wl_update_wiphybands(struct wl_priv
*wl
);
264 #endif /* !EMBEDDED_PLATFORM */
266 static s32
wl_dongle_eventmsg(struct net_device
*ndev
);
267 static s32
wl_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
268 s32 scan_unassoc_time
, s32 scan_passive_time
);
269 static s32
wl_config_dongle(struct wl_priv
*wl
, bool need_lock
);
270 static s32
wl_dongle_roam(struct net_device
*ndev
, u32 roamvar
,
276 static void wl_iscan_timer(unsigned long data
);
277 static void wl_term_iscan(struct wl_priv
*wl
);
278 static s32
wl_init_iscan(struct wl_priv
*wl
);
279 static s32
wl_iscan_thread(void *data
);
280 static s32
wl_dev_iovar_setbuf(struct net_device
*dev
, s8
*iovar
,
281 void *param
, s32 paramlen
, void *bufptr
,
283 static s32
wl_dev_iovar_getbuf(struct net_device
*dev
, s8
*iovar
,
284 void *param
, s32 paramlen
, void *bufptr
,
286 static s32
wl_run_iscan(struct wl_iscan_ctrl
*iscan
, struct wlc_ssid
*ssid
,
288 static s32
wl_do_iscan(struct wl_priv
*wl
);
289 static s32
wl_wakeup_iscan(struct wl_iscan_ctrl
*iscan
);
290 static s32
wl_invoke_iscan(struct wl_priv
*wl
);
291 static s32
wl_get_iscan_results(struct wl_iscan_ctrl
*iscan
, u32
*status
,
292 struct wl_scan_results
**bss_list
);
293 static void wl_notify_iscan_complete(struct wl_iscan_ctrl
*iscan
, bool aborted
);
294 static void wl_init_iscan_eloop(struct wl_iscan_eloop
*el
);
295 static s32
wl_iscan_done(struct wl_priv
*wl
);
296 static s32
wl_iscan_pending(struct wl_priv
*wl
);
297 static s32
wl_iscan_inprogress(struct wl_priv
*wl
);
298 static s32
wl_iscan_aborted(struct wl_priv
*wl
);
301 ** fw/nvram downloading handler
303 static void wl_init_fw(struct wl_fw_ctrl
*fw
);
306 * find most significant bit set
308 static __used u32
wl_find_msb(u16 bit16
);
311 * update pmklist to dongle
313 static __used s32
wl_update_pmklist(struct net_device
*dev
,
314 struct wl_pmk_list
*pmk_list
, s32 err
);
316 static void wl_set_mpc(struct net_device
*ndev
, int mpc
);
321 static int wl_debugfs_add_netdev_params(struct wl_priv
*wl
);
322 static void wl_debugfs_remove_netdev(struct wl_priv
*wl
);
324 #define WL_PRIV_GET() \
326 struct wl_iface *ci; \
327 if (unlikely(!(wl_cfg80211_dev && \
328 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
329 WL_ERR("wl_cfg80211_dev is unavailable\n"); \
335 #define CHECK_SYS_UP() \
337 struct wl_priv *wl = wiphy_to_wl(wiphy); \
338 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
339 WL_INFO("device is not ready : status (%d)\n", \
345 extern int dhd_wait_pend8021x(struct net_device
*dev
);
346 #define CHAN2G(_channel, _freq, _flags) { \
347 .band = IEEE80211_BAND_2GHZ, \
348 .center_freq = (_freq), \
349 .hw_value = (_channel), \
351 .max_antenna_gain = 0, \
355 #define CHAN5G(_channel, _flags) { \
356 .band = IEEE80211_BAND_5GHZ, \
357 .center_freq = 5000 + (5 * (_channel)), \
358 .hw_value = (_channel), \
360 .max_antenna_gain = 0, \
364 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
365 #define RATETAB_ENT(_rateid, _flags) \
367 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
368 .hw_value = (_rateid), \
372 static struct ieee80211_rate __wl_rates
[] = {
373 RATETAB_ENT(WLC_RATE_1M
, 0),
374 RATETAB_ENT(WLC_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
375 RATETAB_ENT(WLC_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
376 RATETAB_ENT(WLC_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
377 RATETAB_ENT(WLC_RATE_6M
, 0),
378 RATETAB_ENT(WLC_RATE_9M
, 0),
379 RATETAB_ENT(WLC_RATE_12M
, 0),
380 RATETAB_ENT(WLC_RATE_18M
, 0),
381 RATETAB_ENT(WLC_RATE_24M
, 0),
382 RATETAB_ENT(WLC_RATE_36M
, 0),
383 RATETAB_ENT(WLC_RATE_48M
, 0),
384 RATETAB_ENT(WLC_RATE_54M
, 0),
387 #define wl_a_rates (__wl_rates + 4)
388 #define wl_a_rates_size 8
389 #define wl_g_rates (__wl_rates + 0)
390 #define wl_g_rates_size 12
392 static struct ieee80211_channel __wl_2ghz_channels
[] = {
409 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
410 CHAN5G(34, 0), CHAN5G(36, 0),
411 CHAN5G(38, 0), CHAN5G(40, 0),
412 CHAN5G(42, 0), CHAN5G(44, 0),
413 CHAN5G(46, 0), CHAN5G(48, 0),
414 CHAN5G(52, 0), CHAN5G(56, 0),
415 CHAN5G(60, 0), CHAN5G(64, 0),
416 CHAN5G(100, 0), CHAN5G(104, 0),
417 CHAN5G(108, 0), CHAN5G(112, 0),
418 CHAN5G(116, 0), CHAN5G(120, 0),
419 CHAN5G(124, 0), CHAN5G(128, 0),
420 CHAN5G(132, 0), CHAN5G(136, 0),
421 CHAN5G(140, 0), CHAN5G(149, 0),
422 CHAN5G(153, 0), CHAN5G(157, 0),
423 CHAN5G(161, 0), CHAN5G(165, 0),
424 CHAN5G(184, 0), CHAN5G(188, 0),
425 CHAN5G(192, 0), CHAN5G(196, 0),
426 CHAN5G(200, 0), CHAN5G(204, 0),
427 CHAN5G(208, 0), CHAN5G(212, 0),
431 static struct ieee80211_channel __wl_5ghz_n_channels
[] = {
432 CHAN5G(32, 0), CHAN5G(34, 0),
433 CHAN5G(36, 0), CHAN5G(38, 0),
434 CHAN5G(40, 0), CHAN5G(42, 0),
435 CHAN5G(44, 0), CHAN5G(46, 0),
436 CHAN5G(48, 0), CHAN5G(50, 0),
437 CHAN5G(52, 0), CHAN5G(54, 0),
438 CHAN5G(56, 0), CHAN5G(58, 0),
439 CHAN5G(60, 0), CHAN5G(62, 0),
440 CHAN5G(64, 0), CHAN5G(66, 0),
441 CHAN5G(68, 0), CHAN5G(70, 0),
442 CHAN5G(72, 0), CHAN5G(74, 0),
443 CHAN5G(76, 0), CHAN5G(78, 0),
444 CHAN5G(80, 0), CHAN5G(82, 0),
445 CHAN5G(84, 0), CHAN5G(86, 0),
446 CHAN5G(88, 0), CHAN5G(90, 0),
447 CHAN5G(92, 0), CHAN5G(94, 0),
448 CHAN5G(96, 0), CHAN5G(98, 0),
449 CHAN5G(100, 0), CHAN5G(102, 0),
450 CHAN5G(104, 0), CHAN5G(106, 0),
451 CHAN5G(108, 0), CHAN5G(110, 0),
452 CHAN5G(112, 0), CHAN5G(114, 0),
453 CHAN5G(116, 0), CHAN5G(118, 0),
454 CHAN5G(120, 0), CHAN5G(122, 0),
455 CHAN5G(124, 0), CHAN5G(126, 0),
456 CHAN5G(128, 0), CHAN5G(130, 0),
457 CHAN5G(132, 0), CHAN5G(134, 0),
458 CHAN5G(136, 0), CHAN5G(138, 0),
459 CHAN5G(140, 0), CHAN5G(142, 0),
460 CHAN5G(144, 0), CHAN5G(145, 0),
461 CHAN5G(146, 0), CHAN5G(147, 0),
462 CHAN5G(148, 0), CHAN5G(149, 0),
463 CHAN5G(150, 0), CHAN5G(151, 0),
464 CHAN5G(152, 0), CHAN5G(153, 0),
465 CHAN5G(154, 0), CHAN5G(155, 0),
466 CHAN5G(156, 0), CHAN5G(157, 0),
467 CHAN5G(158, 0), CHAN5G(159, 0),
468 CHAN5G(160, 0), CHAN5G(161, 0),
469 CHAN5G(162, 0), CHAN5G(163, 0),
470 CHAN5G(164, 0), CHAN5G(165, 0),
471 CHAN5G(166, 0), CHAN5G(168, 0),
472 CHAN5G(170, 0), CHAN5G(172, 0),
473 CHAN5G(174, 0), CHAN5G(176, 0),
474 CHAN5G(178, 0), CHAN5G(180, 0),
475 CHAN5G(182, 0), CHAN5G(184, 0),
476 CHAN5G(186, 0), CHAN5G(188, 0),
477 CHAN5G(190, 0), CHAN5G(192, 0),
478 CHAN5G(194, 0), CHAN5G(196, 0),
479 CHAN5G(198, 0), CHAN5G(200, 0),
480 CHAN5G(202, 0), CHAN5G(204, 0),
481 CHAN5G(206, 0), CHAN5G(208, 0),
482 CHAN5G(210, 0), CHAN5G(212, 0),
483 CHAN5G(214, 0), CHAN5G(216, 0),
484 CHAN5G(218, 0), CHAN5G(220, 0),
485 CHAN5G(222, 0), CHAN5G(224, 0),
486 CHAN5G(226, 0), CHAN5G(228, 0),
489 static struct ieee80211_supported_band __wl_band_2ghz
= {
490 .band
= IEEE80211_BAND_2GHZ
,
491 .channels
= __wl_2ghz_channels
,
492 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
493 .bitrates
= wl_g_rates
,
494 .n_bitrates
= wl_g_rates_size
,
497 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
498 .band
= IEEE80211_BAND_5GHZ
,
499 .channels
= __wl_5ghz_a_channels
,
500 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
501 .bitrates
= wl_a_rates
,
502 .n_bitrates
= wl_a_rates_size
,
505 static struct ieee80211_supported_band __wl_band_5ghz_n
= {
506 .band
= IEEE80211_BAND_5GHZ
,
507 .channels
= __wl_5ghz_n_channels
,
508 .n_channels
= ARRAY_SIZE(__wl_5ghz_n_channels
),
509 .bitrates
= wl_a_rates
,
510 .n_bitrates
= wl_a_rates_size
,
513 static const u32 __wl_cipher_suites
[] = {
514 WLAN_CIPHER_SUITE_WEP40
,
515 WLAN_CIPHER_SUITE_WEP104
,
516 WLAN_CIPHER_SUITE_TKIP
,
517 WLAN_CIPHER_SUITE_CCMP
,
518 WLAN_CIPHER_SUITE_AES_CMAC
,
521 static void swap_key_from_BE(struct wl_wsec_key
*key
)
523 key
->index
= cpu_to_le32(key
->index
);
524 key
->len
= cpu_to_le32(key
->len
);
525 key
->algo
= cpu_to_le32(key
->algo
);
526 key
->flags
= cpu_to_le32(key
->flags
);
527 key
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
528 key
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
529 key
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
532 static void swap_key_to_BE(struct wl_wsec_key
*key
)
534 key
->index
= le32_to_cpu(key
->index
);
535 key
->len
= le32_to_cpu(key
->len
);
536 key
->algo
= le32_to_cpu(key
->algo
);
537 key
->flags
= le32_to_cpu(key
->flags
);
538 key
->rxiv
.hi
= le32_to_cpu(key
->rxiv
.hi
);
539 key
->rxiv
.lo
= le16_to_cpu(key
->rxiv
.lo
);
540 key
->iv_initialized
= le32_to_cpu(key
->iv_initialized
);
544 wl_dev_ioctl(struct net_device
*dev
, u32 cmd
, void *arg
, u32 len
)
551 memset(&ioc
, 0, sizeof(ioc
));
555 strcpy(ifr
.ifr_name
, dev
->name
);
556 ifr
.ifr_data
= (caddr_t
)&ioc
;
560 err
= dev
->netdev_ops
->ndo_do_ioctl(dev
, &ifr
, SIOCDEVPRIVATE
);
567 wl_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
568 enum nl80211_iftype type
, u32
*flags
,
569 struct vif_params
*params
)
571 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
572 struct wireless_dev
*wdev
;
580 case NL80211_IFTYPE_MONITOR
:
581 case NL80211_IFTYPE_WDS
:
582 WL_ERR("type (%d) : currently we do not support this type\n",
585 case NL80211_IFTYPE_ADHOC
:
586 wl
->conf
->mode
= WL_MODE_IBSS
;
589 case NL80211_IFTYPE_STATION
:
590 wl
->conf
->mode
= WL_MODE_BSS
;
598 infra
= cpu_to_le32(infra
);
599 err
= wl_dev_ioctl(ndev
, WLC_SET_INFRA
, &infra
, sizeof(infra
));
601 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
604 wdev
= ndev
->ieee80211_ptr
;
608 WL_INFO("IF Type = %s\n",
609 (wl
->conf
->mode
== WL_MODE_IBSS
) ? "Adhoc" : "Infra");
617 static void wl_iscan_prep(struct wl_scan_params
*params
, struct wlc_ssid
*ssid
)
619 memcpy(params
->bssid
, ether_bcast
, ETH_ALEN
);
620 params
->bss_type
= DOT11_BSSTYPE_ANY
;
621 params
->scan_type
= 0;
622 params
->nprobes
= -1;
623 params
->active_time
= -1;
624 params
->passive_time
= -1;
625 params
->home_time
= -1;
626 params
->channel_num
= 0;
628 params
->nprobes
= cpu_to_le32(params
->nprobes
);
629 params
->active_time
= cpu_to_le32(params
->active_time
);
630 params
->passive_time
= cpu_to_le32(params
->passive_time
);
631 params
->home_time
= cpu_to_le32(params
->home_time
);
632 if (ssid
&& ssid
->SSID_len
)
633 memcpy(¶ms
->ssid
, ssid
, sizeof(wlc_ssid_t
));
638 wl_dev_iovar_setbuf(struct net_device
*dev
, s8
* iovar
, void *param
,
639 s32 paramlen
, void *bufptr
, s32 buflen
)
643 iolen
= brcmu_mkiovar(iovar
, param
, paramlen
, bufptr
, buflen
);
646 return wl_dev_ioctl(dev
, WLC_SET_VAR
, bufptr
, iolen
);
650 wl_dev_iovar_getbuf(struct net_device
*dev
, s8
* iovar
, void *param
,
651 s32 paramlen
, void *bufptr
, s32 buflen
)
655 iolen
= brcmu_mkiovar(iovar
, param
, paramlen
, bufptr
, buflen
);
658 return wl_dev_ioctl(dev
, WLC_GET_VAR
, bufptr
, buflen
);
662 wl_run_iscan(struct wl_iscan_ctrl
*iscan
, struct wlc_ssid
*ssid
, u16 action
)
665 (WL_SCAN_PARAMS_FIXED_SIZE
+ offsetof(wl_iscan_params_t
, params
));
666 struct wl_iscan_params
*params
;
669 if (ssid
&& ssid
->SSID_len
)
670 params_size
+= sizeof(struct wlc_ssid
);
671 params
= kzalloc(params_size
, GFP_KERNEL
);
672 if (unlikely(!params
))
674 BUG_ON(params_size
>= WLC_IOCTL_SMLEN
);
676 wl_iscan_prep(¶ms
->params
, ssid
);
678 params
->version
= cpu_to_le32(ISCAN_REQ_VERSION
);
679 params
->action
= cpu_to_le16(action
);
680 params
->scan_duration
= cpu_to_le16(0);
682 /* params_size += offsetof(wl_iscan_params_t, params); */
683 err
= wl_dev_iovar_setbuf(iscan
->dev
, "iscan", params
, params_size
,
684 iscan
->ioctl_buf
, WLC_IOCTL_SMLEN
);
687 WL_INFO("system busy : iscan canceled\n");
689 WL_ERR("error (%d)\n", err
);
696 static s32
wl_do_iscan(struct wl_priv
*wl
)
698 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
699 struct net_device
*ndev
= wl_to_ndev(wl
);
700 struct wlc_ssid ssid
;
704 /* Broadcast scan by default */
705 memset(&ssid
, 0, sizeof(ssid
));
707 iscan
->state
= WL_ISCAN_STATE_SCANING
;
709 passive_scan
= wl
->active_scan
? 0 : 1;
710 err
= wl_dev_ioctl(wl_to_ndev(wl
), WLC_SET_PASSIVE_SCAN
,
711 &passive_scan
, sizeof(passive_scan
));
713 WL_ERR("error (%d)\n", err
);
717 wl
->iscan_kickstart
= true;
718 wl_run_iscan(iscan
, &ssid
, WL_SCAN_ACTION_START
);
719 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
726 __wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
727 struct cfg80211_scan_request
*request
,
728 struct cfg80211_ssid
*this_ssid
)
730 struct wl_priv
*wl
= ndev_to_wl(ndev
);
731 struct cfg80211_ssid
*ssids
;
732 struct wl_scan_req
*sr
= wl_to_sr(wl
);
738 if (unlikely(test_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
739 WL_ERR("Scanning already : status (%d)\n", (int)wl
->status
);
742 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
))) {
743 WL_ERR("Scanning being aborted : status (%d)\n",
747 if (test_bit(WL_STATUS_CONNECTING
, &wl
->status
)) {
748 WL_ERR("Connecting : status (%d)\n",
757 ssids
= request
->ssids
;
758 if (wl
->iscan_on
&& (!ssids
|| !ssids
->ssid_len
))
762 /* we don't do iscan in ibss */
766 wl
->scan_request
= request
;
767 set_bit(WL_STATUS_SCANNING
, &wl
->status
);
769 err
= wl_do_iscan(wl
);
775 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
776 ssids
->ssid
, ssids
->ssid_len
);
777 memset(&sr
->ssid
, 0, sizeof(sr
->ssid
));
779 min_t(u8
, sizeof(sr
->ssid
.SSID
), ssids
->ssid_len
);
780 if (sr
->ssid
.SSID_len
) {
781 memcpy(sr
->ssid
.SSID
, ssids
->ssid
, sr
->ssid
.SSID_len
);
782 sr
->ssid
.SSID_len
= cpu_to_le32(sr
->ssid
.SSID_len
);
785 WL_SCAN("Broadcast scan\n");
788 passive_scan
= wl
->active_scan
? 0 : 1;
789 err
= wl_dev_ioctl(ndev
, WLC_SET_PASSIVE_SCAN
,
790 &passive_scan
, sizeof(passive_scan
));
792 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
796 err
= wl_dev_ioctl(ndev
, WLC_SCAN
, &sr
->ssid
,
800 WL_INFO("system busy : scan for \"%s\" canceled\n",
803 WL_ERR("WLC_SCAN error (%d)\n", err
);
813 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
814 wl
->scan_request
= NULL
;
819 wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
820 struct cfg80211_scan_request
*request
)
828 err
= __wl_cfg80211_scan(wiphy
, ndev
, request
, NULL
);
830 WL_ERR("scan error (%d)\n", err
);
836 static s32
wl_dev_intvar_set(struct net_device
*dev
, s8
*name
, s32 val
)
838 s8 buf
[WLC_IOCTL_SMLEN
];
842 val
= cpu_to_le32(val
);
843 len
= brcmu_mkiovar(name
, (char *)(&val
), sizeof(val
), buf
,
847 err
= wl_dev_ioctl(dev
, WLC_SET_VAR
, buf
, len
);
849 WL_ERR("error (%d)\n", err
);
855 wl_dev_intvar_get(struct net_device
*dev
, s8
*name
, s32
*retval
)
858 s8 buf
[WLC_IOCTL_SMLEN
];
866 brcmu_mkiovar(name
, (char *)(&data_null
), 0, (char *)(&var
),
869 err
= wl_dev_ioctl(dev
, WLC_GET_VAR
, &var
, len
);
871 WL_ERR("error (%d)\n", err
);
873 *retval
= le32_to_cpu(var
.val
);
878 static s32
wl_set_rts(struct net_device
*dev
, u32 rts_threshold
)
882 err
= wl_dev_intvar_set(dev
, "rtsthresh", rts_threshold
);
884 WL_ERR("Error (%d)\n", err
);
889 static s32
wl_set_frag(struct net_device
*dev
, u32 frag_threshold
)
893 err
= wl_dev_intvar_set(dev
, "fragthresh", frag_threshold
);
895 WL_ERR("Error (%d)\n", err
);
900 static s32
wl_set_retry(struct net_device
*dev
, u32 retry
, bool l
)
903 u32 cmd
= (l
? WLC_SET_LRL
: WLC_SET_SRL
);
905 retry
= cpu_to_le32(retry
);
906 err
= wl_dev_ioctl(dev
, cmd
, &retry
, sizeof(retry
));
908 WL_ERR("cmd (%d) , error (%d)\n", cmd
, err
);
914 static s32
wl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
916 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
917 struct net_device
*ndev
= wl_to_ndev(wl
);
923 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
924 (wl
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
925 wl
->conf
->rts_threshold
= wiphy
->rts_threshold
;
926 err
= wl_set_rts(ndev
, wl
->conf
->rts_threshold
);
930 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
931 (wl
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
932 wl
->conf
->frag_threshold
= wiphy
->frag_threshold
;
933 err
= wl_set_frag(ndev
, wl
->conf
->frag_threshold
);
937 if (changed
& WIPHY_PARAM_RETRY_LONG
938 && (wl
->conf
->retry_long
!= wiphy
->retry_long
)) {
939 wl
->conf
->retry_long
= wiphy
->retry_long
;
940 err
= wl_set_retry(ndev
, wl
->conf
->retry_long
, true);
944 if (changed
& WIPHY_PARAM_RETRY_SHORT
945 && (wl
->conf
->retry_short
!= wiphy
->retry_short
)) {
946 wl
->conf
->retry_short
= wiphy
->retry_short
;
947 err
= wl_set_retry(ndev
, wl
->conf
->retry_short
, false);
958 wl_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
959 struct cfg80211_ibss_params
*params
)
961 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
962 struct wl_join_params join_params
;
963 size_t join_params_size
= 0;
972 WL_CONN("SSID: %s\n", params
->ssid
);
974 WL_CONN("SSID: NULL, Not supported\n");
979 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
980 params
->bssid
[0], params
->bssid
[1], params
->bssid
[2],
981 params
->bssid
[3], params
->bssid
[4], params
->bssid
[5]);
983 WL_CONN("No BSSID specified\n");
986 WL_CONN("channel: %d\n", params
->channel
->center_freq
);
988 WL_CONN("no channel specified\n");
990 if (params
->channel_fixed
)
991 WL_CONN("fixed channel required\n");
993 WL_CONN("no fixed channel required\n");
995 if (params
->ie
&& params
->ie_len
)
996 WL_CONN("ie len: %d\n", params
->ie_len
);
998 WL_CONN("no ie specified\n");
1000 if (params
->beacon_interval
)
1001 WL_CONN("beacon interval: %d\n", params
->beacon_interval
);
1003 WL_CONN("no beacon interval specified\n");
1005 if (params
->basic_rates
)
1006 WL_CONN("basic rates: %08X\n", params
->basic_rates
);
1008 WL_CONN("no basic rates specified\n");
1010 if (params
->privacy
)
1011 WL_CONN("privacy required\n");
1013 WL_CONN("no privacy required\n");
1015 /* Configure Privacy for starter */
1016 if (params
->privacy
)
1017 wsec
|= WEP_ENABLED
;
1019 err
= wl_dev_intvar_set(dev
, "wsec", wsec
);
1020 if (unlikely(err
)) {
1021 WL_ERR("wsec failed (%d)\n", err
);
1025 /* Configure Beacon Interval for starter */
1026 if (params
->beacon_interval
)
1027 bcnprd
= cpu_to_le32(params
->beacon_interval
);
1029 bcnprd
= cpu_to_le32(100);
1031 err
= wl_dev_ioctl(dev
, WLC_SET_BCNPRD
, &bcnprd
, sizeof(bcnprd
));
1032 if (unlikely(err
)) {
1033 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err
);
1037 /* Configure required join parameter */
1038 memset(&join_params
, 0, sizeof(wl_join_params_t
));
1041 join_params
.ssid
.SSID_len
=
1042 (params
->ssid_len
> 32) ? 32 : params
->ssid_len
;
1043 memcpy(join_params
.ssid
.SSID
, params
->ssid
, join_params
.ssid
.SSID_len
);
1044 join_params
.ssid
.SSID_len
= cpu_to_le32(join_params
.ssid
.SSID_len
);
1045 join_params_size
= sizeof(join_params
.ssid
);
1046 wl_update_prof(wl
, NULL
, &join_params
.ssid
, WL_PROF_SSID
);
1049 if (params
->bssid
) {
1050 memcpy(join_params
.params
.bssid
, params
->bssid
, ETH_ALEN
);
1052 sizeof(join_params
.ssid
) + WL_ASSOC_PARAMS_FIXED_SIZE
;
1054 memcpy(join_params
.params
.bssid
, ether_bcast
, ETH_ALEN
);
1056 wl_update_prof(wl
, NULL
, &join_params
.params
.bssid
, WL_PROF_BSSID
);
1059 if (params
->channel
) {
1063 ieee80211_frequency_to_channel(
1064 params
->channel
->center_freq
);
1065 if (params
->channel_fixed
) {
1066 /* adding chanspec */
1067 wl_ch_to_chanspec(wl
->channel
,
1068 &join_params
, &join_params_size
);
1071 /* set channel for starter */
1072 target_channel
= cpu_to_le32(wl
->channel
);
1073 err
= wl_dev_ioctl(dev
, WLC_SET_CHANNEL
,
1074 &target_channel
, sizeof(target_channel
));
1075 if (unlikely(err
)) {
1076 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err
);
1082 wl
->ibss_starter
= false;
1085 err
= wl_dev_ioctl(dev
, WLC_SET_SSID
, &join_params
, join_params_size
);
1086 if (unlikely(err
)) {
1087 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1091 set_bit(WL_STATUS_CONNECTING
, &wl
->status
);
1098 static s32
wl_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
1100 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1103 WL_TRACE("Enter\n");
1114 wl_set_wpa_version(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1116 struct wl_priv
*wl
= ndev_to_wl(dev
);
1117 struct wl_security
*sec
;
1121 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1122 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1123 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1124 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1126 val
= WPA_AUTH_DISABLED
;
1127 WL_CONN("setting wpa_auth to 0x%0x\n", val
);
1128 err
= wl_dev_intvar_set(dev
, "wpa_auth", val
);
1129 if (unlikely(err
)) {
1130 WL_ERR("set wpa_auth failed (%d)\n", err
);
1133 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1134 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1139 wl_set_auth_type(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1141 struct wl_priv
*wl
= ndev_to_wl(dev
);
1142 struct wl_security
*sec
;
1146 switch (sme
->auth_type
) {
1147 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1149 WL_CONN("open system\n");
1151 case NL80211_AUTHTYPE_SHARED_KEY
:
1153 WL_CONN("shared key\n");
1155 case NL80211_AUTHTYPE_AUTOMATIC
:
1157 WL_CONN("automatic\n");
1159 case NL80211_AUTHTYPE_NETWORK_EAP
:
1160 WL_CONN("network eap\n");
1163 WL_ERR("invalid auth type (%d)\n", sme
->auth_type
);
1167 err
= wl_dev_intvar_set(dev
, "auth", val
);
1168 if (unlikely(err
)) {
1169 WL_ERR("set auth failed (%d)\n", err
);
1172 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1173 sec
->auth_type
= sme
->auth_type
;
1178 wl_set_set_cipher(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1180 struct wl_priv
*wl
= ndev_to_wl(dev
);
1181 struct wl_security
*sec
;
1186 if (sme
->crypto
.n_ciphers_pairwise
) {
1187 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1188 case WLAN_CIPHER_SUITE_WEP40
:
1189 case WLAN_CIPHER_SUITE_WEP104
:
1192 case WLAN_CIPHER_SUITE_TKIP
:
1193 pval
= TKIP_ENABLED
;
1195 case WLAN_CIPHER_SUITE_CCMP
:
1198 case WLAN_CIPHER_SUITE_AES_CMAC
:
1202 WL_ERR("invalid cipher pairwise (%d)\n",
1203 sme
->crypto
.ciphers_pairwise
[0]);
1207 if (sme
->crypto
.cipher_group
) {
1208 switch (sme
->crypto
.cipher_group
) {
1209 case WLAN_CIPHER_SUITE_WEP40
:
1210 case WLAN_CIPHER_SUITE_WEP104
:
1213 case WLAN_CIPHER_SUITE_TKIP
:
1214 gval
= TKIP_ENABLED
;
1216 case WLAN_CIPHER_SUITE_CCMP
:
1219 case WLAN_CIPHER_SUITE_AES_CMAC
:
1223 WL_ERR("invalid cipher group (%d)\n",
1224 sme
->crypto
.cipher_group
);
1229 WL_CONN("pval (%d) gval (%d)\n", pval
, gval
);
1230 err
= wl_dev_intvar_set(dev
, "wsec", pval
| gval
);
1231 if (unlikely(err
)) {
1232 WL_ERR("error (%d)\n", err
);
1236 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1237 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1238 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1244 wl_set_key_mgmt(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1246 struct wl_priv
*wl
= ndev_to_wl(dev
);
1247 struct wl_security
*sec
;
1251 if (sme
->crypto
.n_akm_suites
) {
1252 err
= wl_dev_intvar_get(dev
, "wpa_auth", &val
);
1253 if (unlikely(err
)) {
1254 WL_ERR("could not get wpa_auth (%d)\n", err
);
1257 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1258 switch (sme
->crypto
.akm_suites
[0]) {
1259 case WLAN_AKM_SUITE_8021X
:
1260 val
= WPA_AUTH_UNSPECIFIED
;
1262 case WLAN_AKM_SUITE_PSK
:
1266 WL_ERR("invalid cipher group (%d)\n",
1267 sme
->crypto
.cipher_group
);
1270 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1271 switch (sme
->crypto
.akm_suites
[0]) {
1272 case WLAN_AKM_SUITE_8021X
:
1273 val
= WPA2_AUTH_UNSPECIFIED
;
1275 case WLAN_AKM_SUITE_PSK
:
1276 val
= WPA2_AUTH_PSK
;
1279 WL_ERR("invalid cipher group (%d)\n",
1280 sme
->crypto
.cipher_group
);
1285 WL_CONN("setting wpa_auth to %d\n", val
);
1286 err
= wl_dev_intvar_set(dev
, "wpa_auth", val
);
1287 if (unlikely(err
)) {
1288 WL_ERR("could not set wpa_auth (%d)\n", err
);
1292 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1293 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1299 wl_set_set_sharedkey(struct net_device
*dev
,
1300 struct cfg80211_connect_params
*sme
)
1302 struct wl_priv
*wl
= ndev_to_wl(dev
);
1303 struct wl_security
*sec
;
1304 struct wl_wsec_key key
;
1308 WL_CONN("key len (%d)\n", sme
->key_len
);
1310 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1311 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1312 sec
->wpa_versions
, sec
->cipher_pairwise
);
1314 (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
|
1315 NL80211_WPA_VERSION_2
))
1316 && (sec
->cipher_pairwise
& (WLAN_CIPHER_SUITE_WEP40
|
1317 WLAN_CIPHER_SUITE_WEP104
))) {
1318 memset(&key
, 0, sizeof(key
));
1319 key
.len
= (u32
) sme
->key_len
;
1320 key
.index
= (u32
) sme
->key_idx
;
1321 if (unlikely(key
.len
> sizeof(key
.data
))) {
1322 WL_ERR("Too long key length (%u)\n", key
.len
);
1325 memcpy(key
.data
, sme
->key
, key
.len
);
1326 key
.flags
= WL_PRIMARY_KEY
;
1327 switch (sec
->cipher_pairwise
) {
1328 case WLAN_CIPHER_SUITE_WEP40
:
1329 key
.algo
= CRYPTO_ALGO_WEP1
;
1331 case WLAN_CIPHER_SUITE_WEP104
:
1332 key
.algo
= CRYPTO_ALGO_WEP128
;
1335 WL_ERR("Invalid algorithm (%d)\n",
1336 sme
->crypto
.ciphers_pairwise
[0]);
1339 /* Set the new key/index */
1340 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1341 key
.len
, key
.index
, key
.algo
);
1342 WL_CONN("key \"%s\"\n", key
.data
);
1343 swap_key_from_BE(&key
);
1344 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
,
1346 if (unlikely(err
)) {
1347 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1350 if (sec
->auth_type
== NL80211_AUTHTYPE_OPEN_SYSTEM
) {
1351 WL_CONN("set auth_type to shared key\n");
1352 val
= 1; /* shared key */
1353 err
= wl_dev_intvar_set(dev
, "auth", val
);
1354 if (unlikely(err
)) {
1355 WL_ERR("set auth failed (%d)\n", err
);
1365 wl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
1366 struct cfg80211_connect_params
*sme
)
1368 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1369 struct ieee80211_channel
*chan
= sme
->channel
;
1370 struct wl_join_params join_params
;
1371 size_t join_params_size
;
1375 WL_TRACE("Enter\n");
1378 if (unlikely(!sme
->ssid
)) {
1379 WL_ERR("Invalid ssid\n");
1385 ieee80211_frequency_to_channel(chan
->center_freq
);
1386 WL_CONN("channel (%d), center_req (%d)\n",
1387 wl
->channel
, chan
->center_freq
);
1391 WL_INFO("ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1393 err
= wl_set_wpa_version(dev
, sme
);
1397 err
= wl_set_auth_type(dev
, sme
);
1401 err
= wl_set_set_cipher(dev
, sme
);
1405 err
= wl_set_key_mgmt(dev
, sme
);
1409 err
= wl_set_set_sharedkey(dev
, sme
);
1413 wl_update_prof(wl
, NULL
, sme
->bssid
, WL_PROF_BSSID
);
1415 ** Join with specific BSSID and cached SSID
1416 ** If SSID is zero join based on BSSID only
1418 memset(&join_params
, 0, sizeof(join_params
));
1419 join_params_size
= sizeof(join_params
.ssid
);
1421 join_params
.ssid
.SSID_len
= min(sizeof(join_params
.ssid
.SSID
), sme
->ssid_len
);
1422 memcpy(&join_params
.ssid
.SSID
, sme
->ssid
, join_params
.ssid
.SSID_len
);
1423 join_params
.ssid
.SSID_len
= cpu_to_le32(join_params
.ssid
.SSID_len
);
1424 wl_update_prof(wl
, NULL
, &join_params
.ssid
, WL_PROF_SSID
);
1427 memcpy(join_params
.params
.bssid
, sme
->bssid
, ETH_ALEN
);
1429 memcpy(join_params
.params
.bssid
, ether_bcast
, ETH_ALEN
);
1431 if (join_params
.ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
) {
1432 WL_CONN("ssid \"%s\", len (%d)\n",
1433 join_params
.ssid
.SSID
, join_params
.ssid
.SSID_len
);
1436 wl_ch_to_chanspec(wl
->channel
, &join_params
, &join_params_size
);
1437 err
= wl_dev_ioctl(dev
, WLC_SET_SSID
, &join_params
, join_params_size
);
1438 if (unlikely(err
)) {
1439 WL_ERR("error (%d)\n", err
);
1442 set_bit(WL_STATUS_CONNECTING
, &wl
->status
);
1449 wl_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
1452 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1456 WL_TRACE("Enter. Reason code = %d\n", reason_code
);
1459 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
1461 scbval
.val
= reason_code
;
1462 memcpy(&scbval
.ea
, wl_read_prof(wl
, WL_PROF_BSSID
), ETH_ALEN
);
1463 scbval
.val
= cpu_to_le32(scbval
.val
);
1464 err
= wl_dev_ioctl(dev
, WLC_DISASSOC
, &scbval
,
1467 WL_ERR("error (%d)\n", err
);
1469 wl
->link_up
= false;
1476 wl_cfg80211_set_tx_power(struct wiphy
*wiphy
,
1477 enum nl80211_tx_power_setting type
, s32 dbm
)
1480 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1481 struct net_device
*ndev
= wl_to_ndev(wl
);
1486 WL_TRACE("Enter\n");
1490 case NL80211_TX_POWER_AUTOMATIC
:
1492 case NL80211_TX_POWER_LIMITED
:
1494 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1499 case NL80211_TX_POWER_FIXED
:
1501 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1507 /* Make sure radio is off or on as far as software is concerned */
1508 disable
= WL_RADIO_SW_DISABLE
<< 16;
1509 disable
= cpu_to_le32(disable
);
1510 err
= wl_dev_ioctl(ndev
, WLC_SET_RADIO
, &disable
, sizeof(disable
));
1512 WL_ERR("WLC_SET_RADIO error (%d)\n", err
);
1517 txpwrmw
= (u16
) dbm
;
1518 err
= wl_dev_intvar_set(ndev
, "qtxpower",
1519 (s32
) (brcmu_mw_to_qdbm(txpwrmw
)));
1521 WL_ERR("qtxpower error (%d)\n", err
);
1522 wl
->conf
->tx_power
= dbm
;
1529 static s32
wl_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
)
1531 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1532 struct net_device
*ndev
= wl_to_ndev(wl
);
1537 WL_TRACE("Enter\n");
1540 err
= wl_dev_intvar_get(ndev
, "qtxpower", &txpwrdbm
);
1541 if (unlikely(err
)) {
1542 WL_ERR("error (%d)\n", err
);
1546 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1547 *dbm
= (s32
) brcmu_qdbm_to_mw(result
);
1555 wl_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1556 u8 key_idx
, bool unicast
, bool multicast
)
1562 WL_TRACE("Enter\n");
1563 WL_CONN("key index (%d)\n", key_idx
);
1566 err
= wl_dev_ioctl(dev
, WLC_GET_WSEC
, &wsec
, sizeof(wsec
));
1567 if (unlikely(err
)) {
1568 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1572 wsec
= le32_to_cpu(wsec
);
1573 if (wsec
& WEP_ENABLED
) {
1574 /* Just select a new current key */
1575 index
= (u32
) key_idx
;
1576 index
= cpu_to_le32(index
);
1577 err
= wl_dev_ioctl(dev
, WLC_SET_KEY_PRIMARY
, &index
,
1580 WL_ERR("error (%d)\n", err
);
1588 wl_add_keyext(struct wiphy
*wiphy
, struct net_device
*dev
,
1589 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1591 struct wl_wsec_key key
;
1594 memset(&key
, 0, sizeof(key
));
1595 key
.index
= (u32
) key_idx
;
1596 /* Instead of bcast for ea address for default wep keys,
1597 driver needs it to be Null */
1598 if (!is_multicast_ether_addr(mac_addr
))
1599 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1600 key
.len
= (u32
) params
->key_len
;
1601 /* check for key index change */
1604 swap_key_from_BE(&key
);
1605 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
));
1606 if (unlikely(err
)) {
1607 WL_ERR("key delete error (%d)\n", err
);
1611 if (key
.len
> sizeof(key
.data
)) {
1612 WL_ERR("Invalid key length (%d)\n", key
.len
);
1616 WL_CONN("Setting the key index %d\n", key
.index
);
1617 memcpy(key
.data
, params
->key
, key
.len
);
1619 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1621 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1622 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1623 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1626 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1627 if (params
->seq
&& params
->seq_len
== 6) {
1630 ivptr
= (u8
*) params
->seq
;
1631 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1632 (ivptr
[3] << 8) | ivptr
[2];
1633 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1634 key
.iv_initialized
= true;
1637 switch (params
->cipher
) {
1638 case WLAN_CIPHER_SUITE_WEP40
:
1639 key
.algo
= CRYPTO_ALGO_WEP1
;
1640 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1642 case WLAN_CIPHER_SUITE_WEP104
:
1643 key
.algo
= CRYPTO_ALGO_WEP128
;
1644 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1646 case WLAN_CIPHER_SUITE_TKIP
:
1647 key
.algo
= CRYPTO_ALGO_TKIP
;
1648 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1650 case WLAN_CIPHER_SUITE_AES_CMAC
:
1651 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1652 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1654 case WLAN_CIPHER_SUITE_CCMP
:
1655 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1656 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1659 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1662 swap_key_from_BE(&key
);
1664 dhd_wait_pend8021x(dev
);
1665 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
));
1666 if (unlikely(err
)) {
1667 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1675 wl_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1676 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1677 struct key_params
*params
)
1679 struct wl_wsec_key key
;
1685 WL_TRACE("Enter\n");
1686 WL_CONN("key index (%d)\n", key_idx
);
1691 return wl_add_keyext(wiphy
, dev
, key_idx
, mac_addr
, params
);
1693 memset(&key
, 0, sizeof(key
));
1695 key
.len
= (u32
) params
->key_len
;
1696 key
.index
= (u32
) key_idx
;
1698 if (unlikely(key
.len
> sizeof(key
.data
))) {
1699 WL_ERR("Too long key length (%u)\n", key
.len
);
1703 memcpy(key
.data
, params
->key
, key
.len
);
1705 key
.flags
= WL_PRIMARY_KEY
;
1706 switch (params
->cipher
) {
1707 case WLAN_CIPHER_SUITE_WEP40
:
1708 key
.algo
= CRYPTO_ALGO_WEP1
;
1709 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1711 case WLAN_CIPHER_SUITE_WEP104
:
1712 key
.algo
= CRYPTO_ALGO_WEP128
;
1713 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1715 case WLAN_CIPHER_SUITE_TKIP
:
1716 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1717 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1718 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1719 key
.algo
= CRYPTO_ALGO_TKIP
;
1720 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1722 case WLAN_CIPHER_SUITE_AES_CMAC
:
1723 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1724 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1726 case WLAN_CIPHER_SUITE_CCMP
:
1727 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1728 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1731 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1736 /* Set the new key/index */
1737 swap_key_from_BE(&key
);
1738 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
));
1739 if (unlikely(err
)) {
1740 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1745 err
= wl_dev_intvar_get(dev
, "wsec", &wsec
);
1746 if (unlikely(err
)) {
1747 WL_ERR("get wsec error (%d)\n", err
);
1750 wsec
&= ~(WEP_ENABLED
);
1752 err
= wl_dev_intvar_set(dev
, "wsec", wsec
);
1753 if (unlikely(err
)) {
1754 WL_ERR("set wsec error (%d)\n", err
);
1758 val
= 1; /* assume shared key. otherwise 0 */
1759 val
= cpu_to_le32(val
);
1760 err
= wl_dev_ioctl(dev
, WLC_SET_AUTH
, &val
, sizeof(val
));
1762 WL_ERR("WLC_SET_AUTH error (%d)\n", err
);
1769 wl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1770 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
1772 struct wl_wsec_key key
;
1777 WL_TRACE("Enter\n");
1779 memset(&key
, 0, sizeof(key
));
1781 key
.index
= (u32
) key_idx
;
1782 key
.flags
= WL_PRIMARY_KEY
;
1783 key
.algo
= CRYPTO_ALGO_OFF
;
1785 WL_CONN("key index (%d)\n", key_idx
);
1786 /* Set the new key/index */
1787 swap_key_from_BE(&key
);
1788 err
= wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
));
1789 if (unlikely(err
)) {
1790 if (err
== -EINVAL
) {
1791 if (key
.index
>= DOT11_MAX_DEFAULT_KEYS
)
1792 /* we ignore this key index in this case */
1793 WL_ERR("invalid key index (%d)\n", key_idx
);
1795 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1797 /* Ignore this error, may happen during DISASSOC */
1803 err
= wl_dev_intvar_get(dev
, "wsec", &wsec
);
1804 if (unlikely(err
)) {
1805 WL_ERR("get wsec error (%d)\n", err
);
1806 /* Ignore this error, may happen during DISASSOC */
1810 wsec
&= ~(WEP_ENABLED
);
1812 err
= wl_dev_intvar_set(dev
, "wsec", wsec
);
1813 if (unlikely(err
)) {
1814 WL_ERR("set wsec error (%d)\n", err
);
1815 /* Ignore this error, may happen during DISASSOC */
1820 val
= 0; /* assume open key. otherwise 1 */
1821 val
= cpu_to_le32(val
);
1822 err
= wl_dev_ioctl(dev
, WLC_SET_AUTH
, &val
, sizeof(val
));
1823 if (unlikely(err
)) {
1824 WL_ERR("WLC_SET_AUTH error (%d)\n", err
);
1825 /* Ignore this error, may happen during DISASSOC */
1834 wl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1835 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
1836 void (*callback
) (void *cookie
, struct key_params
* params
))
1838 struct key_params params
;
1839 struct wl_wsec_key key
;
1840 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1841 struct wl_security
*sec
;
1845 WL_TRACE("Enter\n");
1846 WL_CONN("key index (%d)\n", key_idx
);
1849 memset(&key
, 0, sizeof(key
));
1850 key
.index
= key_idx
;
1851 swap_key_to_BE(&key
);
1852 memset(¶ms
, 0, sizeof(params
));
1853 params
.key_len
= (u8
) min_t(u8
, WLAN_MAX_KEY_LEN
, key
.len
);
1854 memcpy(params
.key
, key
.data
, params
.key_len
);
1856 err
= wl_dev_ioctl(dev
, WLC_GET_WSEC
, &wsec
, sizeof(wsec
));
1857 if (unlikely(err
)) {
1858 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1859 /* Ignore this error, may happen during DISASSOC */
1863 wsec
= le32_to_cpu(wsec
);
1866 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1867 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
1868 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
1869 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1870 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
1871 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
1872 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1876 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
1877 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1880 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
1881 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1884 WL_ERR("Invalid algo (0x%x)\n", wsec
);
1888 callback(cookie
, ¶ms
);
1896 wl_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
1897 struct net_device
*dev
, u8 key_idx
)
1899 WL_INFO("Not supported\n");
1906 wl_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1907 u8
*mac
, struct station_info
*sinfo
)
1909 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1914 u8
*bssid
= wl_read_prof(wl
, WL_PROF_BSSID
);
1916 WL_TRACE("Enter\n");
1920 (memcmp(mac
, bssid
, ETH_ALEN
))) {
1921 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1922 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1923 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5],
1924 bssid
[0], bssid
[1], bssid
[2], bssid
[3],
1925 bssid
[4], bssid
[5]);
1930 /* Report the current tx rate */
1931 err
= wl_dev_ioctl(dev
, WLC_GET_RATE
, &rate
, sizeof(rate
));
1933 WL_ERR("Could not get rate (%d)\n", err
);
1935 rate
= le32_to_cpu(rate
);
1936 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1937 sinfo
->txrate
.legacy
= rate
* 5;
1938 WL_CONN("Rate %d Mbps\n", rate
/ 2);
1941 if (test_bit(WL_STATUS_CONNECTED
, &wl
->status
)) {
1943 err
= wl_dev_ioctl(dev
, WLC_GET_RSSI
, &scb_val
,
1945 if (unlikely(err
)) {
1946 WL_ERR("Could not get rssi (%d)\n", err
);
1948 rssi
= le32_to_cpu(scb_val
.val
);
1949 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1950 sinfo
->signal
= rssi
;
1951 WL_CONN("RSSI %d dBm\n", rssi
);
1960 wl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*dev
,
1961 bool enabled
, s32 timeout
)
1966 WL_TRACE("Enter\n");
1969 pm
= enabled
? PM_FAST
: PM_OFF
;
1970 pm
= cpu_to_le32(pm
);
1971 WL_INFO("power save %s\n", (pm
? "enabled" : "disabled"));
1973 err
= wl_dev_ioctl(dev
, WLC_SET_PM
, &pm
, sizeof(pm
));
1974 if (unlikely(err
)) {
1976 WL_ERR("net_device is not ready yet\n");
1978 WL_ERR("error (%d)\n", err
);
1984 static __used u32
wl_find_msb(u16 bit16
)
1988 if (bit16
& 0xff00) {
2012 wl_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
, struct net_device
*dev
,
2014 const struct cfg80211_bitrate_mask
*mask
)
2016 struct wl_rateset rateset
;
2024 WL_TRACE("Enter\n");
2027 /* addr param is always NULL. ignore it */
2028 /* Get current rateset */
2029 err
= wl_dev_ioctl(dev
, WLC_GET_CURR_RATESET
, &rateset
,
2031 if (unlikely(err
)) {
2032 WL_ERR("could not get current rateset (%d)\n", err
);
2036 rateset
.count
= le32_to_cpu(rateset
.count
);
2038 legacy
= wl_find_msb(mask
->control
[IEEE80211_BAND_2GHZ
].legacy
);
2040 legacy
= wl_find_msb(mask
->control
[IEEE80211_BAND_5GHZ
].legacy
);
2042 val
= wl_g_rates
[legacy
- 1].bitrate
* 100000;
2044 if (val
< rateset
.count
)
2045 /* Select rate by rateset index */
2046 rate
= rateset
.rates
[val
] & 0x7f;
2048 /* Specified rate in bps */
2049 rate
= val
/ 500000;
2051 WL_CONN("rate %d mbps\n", rate
/ 2);
2055 * Set rate override,
2056 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2058 err_bg
= wl_dev_intvar_set(dev
, "bg_rate", rate
);
2059 err_a
= wl_dev_intvar_set(dev
, "a_rate", rate
);
2060 if (unlikely(err_bg
&& err_a
)) {
2061 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg
, err_a
);
2062 err
= err_bg
| err_a
;
2070 static s32
wl_cfg80211_resume(struct wiphy
*wiphy
)
2072 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2073 struct net_device
*ndev
= wl_to_ndev(wl
);
2076 * Check for WL_STATUS_READY before any function call which
2077 * could result is bus access. Don't block the resume for
2078 * any driver error conditions
2080 WL_TRACE("Enter\n");
2082 #if defined(CONFIG_PM_SLEEP)
2083 atomic_set(&dhd_mmc_suspend
, false);
2084 #endif /* defined(CONFIG_PM_SLEEP) */
2086 if (test_bit(WL_STATUS_READY
, &wl
->status
)) {
2087 /* Turn on Watchdog timer */
2088 wl_os_wd_timer(ndev
, dhd_watchdog_ms
);
2089 wl_invoke_iscan(wiphy_to_wl(wiphy
));
2096 static s32
wl_cfg80211_suspend(struct wiphy
*wiphy
)
2098 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2099 struct net_device
*ndev
= wl_to_ndev(wl
);
2101 WL_TRACE("Enter\n");
2104 * Check for WL_STATUS_READY before any function call which
2105 * could result is bus access. Don't block the suspend for
2106 * any driver error conditions
2110 * While going to suspend if associated with AP disassociate
2111 * from AP to save power while system is in suspended state
2113 if (test_bit(WL_STATUS_CONNECTED
, &wl
->status
) &&
2114 test_bit(WL_STATUS_READY
, &wl
->status
)) {
2115 WL_INFO("Disassociating from AP"
2116 " while entering suspend state\n");
2120 * Make sure WPA_Supplicant receives all the event
2121 * generated due to DISASSOC call to the fw to keep
2122 * the state fw and WPA_Supplicant state consistent
2129 set_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
2130 if (test_bit(WL_STATUS_READY
, &wl
->status
))
2133 if (wl
->scan_request
) {
2134 /* Indidate scan abort to cfg80211 layer */
2135 WL_INFO("Terminating scan in progress\n");
2136 cfg80211_scan_done(wl
->scan_request
, true);
2137 wl
->scan_request
= NULL
;
2139 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
2140 clear_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
2141 clear_bit(WL_STATUS_CONNECTING
, &wl
->status
);
2142 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2144 /* Inform SDIO stack not to switch off power to the chip */
2145 sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER
);
2147 /* Turn off watchdog timer */
2148 if (test_bit(WL_STATUS_READY
, &wl
->status
)) {
2149 WL_INFO("Terminate watchdog timer and enable MPC\n");
2150 wl_set_mpc(ndev
, 1);
2151 wl_os_wd_timer(ndev
, 0);
2154 #if defined(CONFIG_PM_SLEEP)
2155 atomic_set(&dhd_mmc_suspend
, true);
2156 #endif /* defined(CONFIG_PM_SLEEP) */
2164 wl_update_pmklist(struct net_device
*dev
, struct wl_pmk_list
*pmk_list
,
2169 WL_CONN("No of elements %d\n", pmk_list
->pmkids
.npmkid
);
2170 for (i
= 0; i
< pmk_list
->pmkids
.npmkid
; i
++) {
2171 WL_CONN("PMKID[%d]: %pM =\n", i
,
2172 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2173 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2174 WL_CONN("%02x\n", pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2178 wl_dev_bufvar_set(dev
, "pmkid_info", (char *)pmk_list
,
2185 wl_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
2186 struct cfg80211_pmksa
*pmksa
)
2188 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2192 WL_TRACE("Enter\n");
2195 for (i
= 0; i
< wl
->pmk_list
->pmkids
.npmkid
; i
++)
2196 if (!memcmp(pmksa
->bssid
, &wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2199 if (i
< WL_NUM_PMKIDS_MAX
) {
2200 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
, pmksa
->bssid
,
2202 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].PMKID
, pmksa
->pmkid
,
2204 if (i
== wl
->pmk_list
->pmkids
.npmkid
)
2205 wl
->pmk_list
->pmkids
.npmkid
++;
2209 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2210 &wl
->pmk_list
->pmkids
.pmkid
[wl
->pmk_list
->pmkids
.npmkid
].BSSID
);
2211 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2213 wl
->pmk_list
->pmkids
.pmkid
[wl
->pmk_list
->pmkids
.npmkid
].
2216 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2223 wl_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
2224 struct cfg80211_pmksa
*pmksa
)
2226 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2227 struct _pmkid_list pmkid
;
2231 WL_TRACE("Enter\n");
2233 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2234 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2236 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2237 &pmkid
.pmkid
[0].BSSID
);
2238 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2239 WL_CONN("%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2241 for (i
= 0; i
< wl
->pmk_list
->pmkids
.npmkid
; i
++)
2243 (pmksa
->bssid
, &wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2247 if ((wl
->pmk_list
->pmkids
.npmkid
> 0)
2248 && (i
< wl
->pmk_list
->pmkids
.npmkid
)) {
2249 memset(&wl
->pmk_list
->pmkids
.pmkid
[i
], 0, sizeof(pmkid_t
));
2250 for (; i
< (wl
->pmk_list
->pmkids
.npmkid
- 1); i
++) {
2251 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2252 &wl
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2254 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2255 &wl
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2258 wl
->pmk_list
->pmkids
.npmkid
--;
2262 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2270 wl_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
)
2272 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2275 WL_TRACE("Enter\n");
2278 memset(wl
->pmk_list
, 0, sizeof(*wl
->pmk_list
));
2279 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2286 static struct cfg80211_ops wl_cfg80211_ops
= {
2287 .change_virtual_intf
= wl_cfg80211_change_iface
,
2288 .scan
= wl_cfg80211_scan
,
2289 .set_wiphy_params
= wl_cfg80211_set_wiphy_params
,
2290 .join_ibss
= wl_cfg80211_join_ibss
,
2291 .leave_ibss
= wl_cfg80211_leave_ibss
,
2292 .get_station
= wl_cfg80211_get_station
,
2293 .set_tx_power
= wl_cfg80211_set_tx_power
,
2294 .get_tx_power
= wl_cfg80211_get_tx_power
,
2295 .add_key
= wl_cfg80211_add_key
,
2296 .del_key
= wl_cfg80211_del_key
,
2297 .get_key
= wl_cfg80211_get_key
,
2298 .set_default_key
= wl_cfg80211_config_default_key
,
2299 .set_default_mgmt_key
= wl_cfg80211_config_default_mgmt_key
,
2300 .set_power_mgmt
= wl_cfg80211_set_power_mgmt
,
2301 .set_bitrate_mask
= wl_cfg80211_set_bitrate_mask
,
2302 .connect
= wl_cfg80211_connect
,
2303 .disconnect
= wl_cfg80211_disconnect
,
2304 .suspend
= wl_cfg80211_suspend
,
2305 .resume
= wl_cfg80211_resume
,
2306 .set_pmksa
= wl_cfg80211_set_pmksa
,
2307 .del_pmksa
= wl_cfg80211_del_pmksa
,
2308 .flush_pmksa
= wl_cfg80211_flush_pmksa
2311 static s32
wl_mode_to_nl80211_iftype(s32 mode
)
2317 return NL80211_IFTYPE_STATION
;
2319 return NL80211_IFTYPE_ADHOC
;
2321 return NL80211_IFTYPE_UNSPECIFIED
;
2327 static struct wireless_dev
*wl_alloc_wdev(s32 sizeof_iface
,
2330 struct wireless_dev
*wdev
;
2333 wdev
= kzalloc(sizeof(*wdev
), GFP_KERNEL
);
2334 if (unlikely(!wdev
)) {
2335 WL_ERR("Could not allocate wireless device\n");
2336 return ERR_PTR(-ENOMEM
);
2339 wiphy_new(&wl_cfg80211_ops
, sizeof(struct wl_priv
) + sizeof_iface
);
2340 if (unlikely(!wdev
->wiphy
)) {
2341 WL_ERR("Couldn not allocate wiphy device\n");
2345 set_wiphy_dev(wdev
->wiphy
, dev
);
2346 wdev
->wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
2347 wdev
->wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
2348 wdev
->wiphy
->interface_modes
=
2349 BIT(NL80211_IFTYPE_STATION
) | BIT(NL80211_IFTYPE_ADHOC
);
2350 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
2351 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
2352 * it as 11a by default.
2353 * This will be updated with
2356 * if phy has 11n capability
2358 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
2359 wdev
->wiphy
->cipher_suites
= __wl_cipher_suites
;
2360 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
2361 #ifndef WL_POWERSAVE_DISABLED
2362 wdev
->wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
2367 wdev
->wiphy
->flags
&= ~WIPHY_FLAG_PS_ON_BY_DEFAULT
;
2368 #endif /* !WL_POWERSAVE_DISABLED */
2369 err
= wiphy_register(wdev
->wiphy
);
2370 if (unlikely(err
< 0)) {
2371 WL_ERR("Couldn not register wiphy device (%d)\n", err
);
2372 goto wiphy_register_out
;
2377 wiphy_free(wdev
->wiphy
);
2382 return ERR_PTR(err
);
2385 static void wl_free_wdev(struct wl_priv
*wl
)
2387 struct wireless_dev
*wdev
= wl_to_wdev(wl
);
2389 if (unlikely(!wdev
)) {
2390 WL_ERR("wdev is invalid\n");
2393 wiphy_unregister(wdev
->wiphy
);
2394 wiphy_free(wdev
->wiphy
);
2396 wl_to_wdev(wl
) = NULL
;
2399 static s32
wl_inform_bss(struct wl_priv
*wl
)
2401 struct wl_scan_results
*bss_list
;
2402 struct wl_bss_info
*bi
= NULL
; /* must be initialized */
2406 bss_list
= wl
->bss_list
;
2407 if (unlikely(bss_list
->version
!= WL_BSS_INFO_VERSION
)) {
2408 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2412 WL_SCAN("scanned AP count (%d)\n", bss_list
->count
);
2413 bi
= next_bss(bss_list
, bi
);
2414 for_each_bss(bss_list
, bi
, i
) {
2415 err
= wl_inform_single_bss(wl
, bi
);
2423 static s32
wl_inform_single_bss(struct wl_priv
*wl
, struct wl_bss_info
*bi
)
2425 struct wiphy
*wiphy
= wl_to_wiphy(wl
);
2426 struct ieee80211_channel
*notify_channel
;
2427 struct cfg80211_bss
*bss
;
2428 struct ieee80211_supported_band
*band
;
2432 u64 notify_timestamp
;
2433 u16 notify_capability
;
2434 u16 notify_interval
;
2436 size_t notify_ielen
;
2439 if (unlikely(le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
)) {
2440 WL_ERR("Bss info is larger than buffer. Discarding\n");
2444 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2445 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2447 if (channel
<= CH_MAX_2G_CHANNEL
)
2448 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2450 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2452 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2453 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2455 notify_timestamp
= jiffies_to_msecs(jiffies
)*1000; /* uSec */
2456 notify_capability
= le16_to_cpu(bi
->capability
);
2457 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2458 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2459 notify_ielen
= le16_to_cpu(bi
->ie_length
);
2460 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2462 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2463 bi
->BSSID
[0], bi
->BSSID
[1], bi
->BSSID
[2],
2464 bi
->BSSID
[3], bi
->BSSID
[4], bi
->BSSID
[5]);
2465 WL_CONN("Channel: %d(%d)\n", channel
, freq
);
2466 WL_CONN("Capability: %X\n", notify_capability
);
2467 WL_CONN("Beacon interval: %d\n", notify_interval
);
2468 WL_CONN("Signal: %d\n", notify_signal
);
2469 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp
);
2471 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2472 notify_timestamp
, notify_capability
, notify_interval
, notify_ie
,
2473 notify_ielen
, notify_signal
, GFP_KERNEL
);
2475 if (unlikely(!bss
)) {
2476 WL_ERR("cfg80211_inform_bss_frame error\n");
2484 wl_inform_ibss(struct wl_priv
*wl
, struct net_device
*dev
, const u8
*bssid
)
2486 struct wiphy
*wiphy
= wl_to_wiphy(wl
);
2487 struct ieee80211_channel
*notify_channel
;
2488 struct wl_bss_info
*bi
= NULL
;
2489 struct ieee80211_supported_band
*band
;
2494 u64 notify_timestamp
;
2495 u16 notify_capability
;
2496 u16 notify_interval
;
2498 size_t notify_ielen
;
2501 WL_TRACE("Enter\n");
2503 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2505 WL_ERR("kzalloc() failed\n");
2510 *(u32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2512 err
= wl_dev_ioctl(dev
, WLC_GET_BSS_INFO
, buf
, WL_BSS_INFO_MAX
);
2513 if (unlikely(err
)) {
2514 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err
);
2518 bi
= (wl_bss_info_t
*)(buf
+ 4);
2520 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2521 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2523 if (channel
<= CH_MAX_2G_CHANNEL
)
2524 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2526 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2528 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2529 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2531 notify_timestamp
= jiffies_to_msecs(jiffies
)*1000; /* uSec */
2532 notify_capability
= le16_to_cpu(bi
->capability
);
2533 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2534 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2535 notify_ielen
= le16_to_cpu(bi
->ie_length
);
2536 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2538 WL_CONN("channel: %d(%d)\n", channel
, freq
);
2539 WL_CONN("capability: %X\n", notify_capability
);
2540 WL_CONN("beacon interval: %d\n", notify_interval
);
2541 WL_CONN("signal: %d\n", notify_signal
);
2542 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp
);
2544 cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2545 notify_timestamp
, notify_capability
, notify_interval
,
2546 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2557 static bool wl_is_linkup(struct wl_priv
*wl
, const wl_event_msg_t
*e
)
2559 u32 event
= be32_to_cpu(e
->event_type
);
2560 u32 status
= be32_to_cpu(e
->status
);
2562 if (event
== WLC_E_SET_SSID
&& status
== WLC_E_STATUS_SUCCESS
) {
2563 WL_CONN("Processing set ssid\n");
2571 static bool wl_is_linkdown(struct wl_priv
*wl
, const wl_event_msg_t
*e
)
2573 u32 event
= be32_to_cpu(e
->event_type
);
2574 u16 flags
= be16_to_cpu(e
->flags
);
2576 if (event
== WLC_E_LINK
&& (!(flags
& WLC_EVENT_MSG_LINK
))) {
2577 WL_CONN("Processing link down\n");
2583 static bool wl_is_nonetwork(struct wl_priv
*wl
, const wl_event_msg_t
*e
)
2585 u32 event
= be32_to_cpu(e
->event_type
);
2586 u32 status
= be32_to_cpu(e
->status
);
2588 if (event
== WLC_E_LINK
&& status
== WLC_E_STATUS_NO_NETWORKS
) {
2589 WL_CONN("Processing Link %s & no network found\n",
2590 be16_to_cpu(e
->flags
) & WLC_EVENT_MSG_LINK
?
2595 if (event
== WLC_E_SET_SSID
&& status
!= WLC_E_STATUS_SUCCESS
) {
2596 WL_CONN("Processing connecting & no network found\n");
2604 wl_notify_connect_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2605 const wl_event_msg_t
*e
, void *data
)
2609 if (wl_is_linkup(wl
, e
)) {
2610 WL_CONN("Linkup\n");
2611 if (wl_is_ibssmode(wl
)) {
2612 wl_update_prof(wl
, NULL
, (void *)e
->addr
,
2614 wl_inform_ibss(wl
, ndev
, e
->addr
);
2615 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
2616 clear_bit(WL_STATUS_CONNECTING
, &wl
->status
);
2617 set_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2619 wl_bss_connect_done(wl
, ndev
, e
, data
, true);
2620 } else if (wl_is_linkdown(wl
, e
)) {
2621 WL_CONN("Linkdown\n");
2622 if (wl_is_ibssmode(wl
)) {
2623 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
2627 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
2629 cfg80211_disconnected(ndev
, 0, NULL
, 0,
2634 wl_init_prof(wl
->profile
);
2635 } else if (wl_is_nonetwork(wl
, e
)) {
2636 if (wl_is_ibssmode(wl
))
2637 clear_bit(WL_STATUS_CONNECTING
, &wl
->status
);
2639 wl_bss_connect_done(wl
, ndev
, e
, data
, false);
2646 wl_notify_roaming_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2647 const wl_event_msg_t
*e
, void *data
)
2650 u32 event
= be32_to_cpu(e
->event_type
);
2651 u32 status
= be32_to_cpu(e
->status
);
2653 if (event
== WLC_E_ROAM
&& status
== WLC_E_STATUS_SUCCESS
) {
2654 if (test_bit(WL_STATUS_CONNECTED
, &wl
->status
))
2655 wl_bss_roaming_done(wl
, ndev
, e
, data
);
2657 wl_bss_connect_done(wl
, ndev
, e
, data
, true);
2664 wl_dev_bufvar_set(struct net_device
*dev
, s8
*name
, s8
*buf
, s32 len
)
2666 struct wl_priv
*wl
= ndev_to_wl(dev
);
2669 buflen
= brcmu_mkiovar(name
, buf
, len
, wl
->ioctl_buf
, WL_IOCTL_LEN_MAX
);
2672 return wl_dev_ioctl(dev
, WLC_SET_VAR
, wl
->ioctl_buf
, buflen
);
2676 wl_dev_bufvar_get(struct net_device
*dev
, s8
*name
, s8
*buf
,
2679 struct wl_priv
*wl
= ndev_to_wl(dev
);
2683 len
= brcmu_mkiovar(name
, NULL
, 0, wl
->ioctl_buf
, WL_IOCTL_LEN_MAX
);
2685 err
= wl_dev_ioctl(dev
, WLC_GET_VAR
, (void *)wl
->ioctl_buf
,
2687 if (unlikely(err
)) {
2688 WL_ERR("error (%d)\n", err
);
2691 memcpy(buf
, wl
->ioctl_buf
, buf_len
);
2696 static s32
wl_get_assoc_ies(struct wl_priv
*wl
)
2698 struct net_device
*ndev
= wl_to_ndev(wl
);
2699 struct wl_assoc_ielen
*assoc_info
;
2700 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2705 wl_clear_assoc_ies(wl
);
2707 err
= wl_dev_bufvar_get(ndev
, "assoc_info", wl
->extra_buf
,
2709 if (unlikely(err
)) {
2710 WL_ERR("could not get assoc info (%d)\n", err
);
2713 assoc_info
= (struct wl_assoc_ielen
*)wl
->extra_buf
;
2714 req_len
= assoc_info
->req_len
;
2715 resp_len
= assoc_info
->resp_len
;
2717 err
= wl_dev_bufvar_get(ndev
, "assoc_req_ies", wl
->extra_buf
,
2719 if (unlikely(err
)) {
2720 WL_ERR("could not get assoc req (%d)\n", err
);
2723 conn_info
->req_ie_len
= req_len
;
2725 kmemdup(wl
->extra_buf
, conn_info
->req_ie_len
, GFP_KERNEL
);
2727 conn_info
->req_ie_len
= 0;
2728 conn_info
->req_ie
= NULL
;
2731 err
= wl_dev_bufvar_get(ndev
, "assoc_resp_ies", wl
->extra_buf
,
2733 if (unlikely(err
)) {
2734 WL_ERR("could not get assoc resp (%d)\n", err
);
2737 conn_info
->resp_ie_len
= resp_len
;
2738 conn_info
->resp_ie
=
2739 kmemdup(wl
->extra_buf
, conn_info
->resp_ie_len
, GFP_KERNEL
);
2741 conn_info
->resp_ie_len
= 0;
2742 conn_info
->resp_ie
= NULL
;
2744 WL_CONN("req len (%d) resp len (%d)\n",
2745 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
2750 static void wl_clear_assoc_ies(struct wl_priv
*wl
)
2752 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2754 kfree(conn_info
->req_ie
);
2755 conn_info
->req_ie
= NULL
;
2756 conn_info
->req_ie_len
= 0;
2757 kfree(conn_info
->resp_ie
);
2758 conn_info
->resp_ie
= NULL
;
2759 conn_info
->resp_ie_len
= 0;
2763 static void wl_ch_to_chanspec(int ch
, struct wl_join_params
*join_params
,
2764 size_t *join_params_size
)
2766 chanspec_t chanspec
= 0;
2769 join_params
->params
.chanspec_num
= 1;
2770 join_params
->params
.chanspec_list
[0] = ch
;
2772 if (join_params
->params
.chanspec_list
[0] <= CH_MAX_2G_CHANNEL
)
2773 chanspec
|= WL_CHANSPEC_BAND_2G
;
2775 chanspec
|= WL_CHANSPEC_BAND_5G
;
2777 chanspec
|= WL_CHANSPEC_BW_20
;
2778 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
2780 *join_params_size
+= WL_ASSOC_PARAMS_FIXED_SIZE
+
2781 join_params
->params
.chanspec_num
* sizeof(chanspec_t
);
2783 join_params
->params
.chanspec_list
[0] &= WL_CHANSPEC_CHAN_MASK
;
2784 join_params
->params
.chanspec_list
[0] |= chanspec
;
2785 join_params
->params
.chanspec_list
[0] =
2786 cpu_to_le16(join_params
->params
.chanspec_list
[0]);
2788 join_params
->params
.chanspec_num
=
2789 cpu_to_le32(join_params
->params
.chanspec_num
);
2791 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
2792 "channel %d, chanspec %#X\n",
2793 join_params
->params
.chanspec_list
[0], ch
, chanspec
);
2797 static s32
wl_update_bss_info(struct wl_priv
*wl
)
2799 struct wl_bss_info
*bi
;
2800 struct wlc_ssid
*ssid
;
2801 struct brcmu_tlv
*tim
;
2802 u16 beacon_interval
;
2808 WL_TRACE("Enter\n");
2809 if (wl_is_ibssmode(wl
))
2812 ssid
= (struct wlc_ssid
*)wl_read_prof(wl
, WL_PROF_SSID
);
2814 *(u32
*)wl
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2815 err
= wl_dev_ioctl(wl_to_ndev(wl
), WLC_GET_BSS_INFO
,
2816 wl
->extra_buf
, WL_EXTRA_BUF_MAX
);
2817 if (unlikely(err
)) {
2818 WL_ERR("Could not get bss info %d\n", err
);
2819 goto update_bss_info_out
;
2822 bi
= (struct wl_bss_info
*)(wl
->extra_buf
+ 4);
2823 err
= wl_inform_single_bss(wl
, bi
);
2825 goto update_bss_info_out
;
2827 ie
= ((u8
*)bi
) + bi
->ie_offset
;
2828 ie_len
= bi
->ie_length
;
2829 beacon_interval
= cpu_to_le16(bi
->beacon_period
);
2831 tim
= brcmu_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2833 dtim_period
= tim
->data
[1];
2836 * active scan was done so we could not get dtim
2837 * information out of probe response.
2838 * so we speficially query dtim information to dongle.
2841 err
= wl_dev_intvar_get(wl_to_ndev(wl
), "dtim_assoc", &var
);
2842 if (unlikely(err
)) {
2843 WL_ERR("wl dtim_assoc failed (%d)\n", err
);
2844 goto update_bss_info_out
;
2846 dtim_period
= (u8
)var
;
2849 wl_update_prof(wl
, NULL
, &beacon_interval
, WL_PROF_BEACONINT
);
2850 wl_update_prof(wl
, NULL
, &dtim_period
, WL_PROF_DTIMPERIOD
);
2852 update_bss_info_out
:
2858 wl_bss_roaming_done(struct wl_priv
*wl
, struct net_device
*ndev
,
2859 const wl_event_msg_t
*e
, void *data
)
2861 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2864 WL_TRACE("Enter\n");
2866 wl_get_assoc_ies(wl
);
2867 wl_update_prof(wl
, NULL
, &e
->addr
, WL_PROF_BSSID
);
2868 wl_update_bss_info(wl
);
2870 cfg80211_roamed(ndev
, NULL
,
2871 (u8
*)wl_read_prof(wl
, WL_PROF_BSSID
),
2872 conn_info
->req_ie
, conn_info
->req_ie_len
,
2873 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
2874 WL_CONN("Report roaming result\n");
2876 set_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2882 wl_bss_connect_done(struct wl_priv
*wl
, struct net_device
*ndev
,
2883 const wl_event_msg_t
*e
, void *data
, bool completed
)
2885 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2888 WL_TRACE("Enter\n");
2890 if (test_and_clear_bit(WL_STATUS_CONNECTING
, &wl
->status
)) {
2892 wl_get_assoc_ies(wl
);
2893 wl_update_prof(wl
, NULL
, &e
->addr
, WL_PROF_BSSID
);
2894 wl_update_bss_info(wl
);
2896 cfg80211_connect_result(ndev
,
2897 (u8
*)wl_read_prof(wl
, WL_PROF_BSSID
),
2899 conn_info
->req_ie_len
,
2901 conn_info
->resp_ie_len
,
2902 completed
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_AUTH_TIMEOUT
,
2905 set_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2906 WL_CONN("Report connect result - connection %s\n",
2907 completed
? "succeeded" : "failed");
2914 wl_notify_mic_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2915 const wl_event_msg_t
*e
, void *data
)
2917 u16 flags
= be16_to_cpu(e
->flags
);
2918 enum nl80211_key_type key_type
;
2921 if (flags
& WLC_EVENT_MSG_GROUP
)
2922 key_type
= NL80211_KEYTYPE_GROUP
;
2924 key_type
= NL80211_KEYTYPE_PAIRWISE
;
2926 cfg80211_michael_mic_failure(ndev
, (u8
*)&e
->addr
, key_type
, -1,
2934 wl_notify_scan_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2935 const wl_event_msg_t
*e
, void *data
)
2937 struct channel_info channel_inform
;
2938 struct wl_scan_results
*bss_list
;
2939 u32 len
= WL_SCAN_BUF_MAX
;
2941 bool scan_abort
= false;
2943 WL_TRACE("Enter\n");
2945 if (wl
->iscan_on
&& wl
->iscan_kickstart
) {
2947 return wl_wakeup_iscan(wl_to_iscan(wl
));
2950 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
2951 WL_ERR("Scan complete while device not scanning\n");
2957 err
= wl_dev_ioctl(ndev
, WLC_GET_CHANNEL
, &channel_inform
,
2958 sizeof(channel_inform
));
2959 if (unlikely(err
)) {
2960 WL_ERR("scan busy (%d)\n", err
);
2964 channel_inform
.scan_channel
= le32_to_cpu(channel_inform
.scan_channel
);
2965 if (unlikely(channel_inform
.scan_channel
)) {
2967 WL_CONN("channel_inform.scan_channel (%d)\n",
2968 channel_inform
.scan_channel
);
2970 wl
->bss_list
= wl
->scan_results
;
2971 bss_list
= wl
->bss_list
;
2972 memset(bss_list
, 0, len
);
2973 bss_list
->buflen
= cpu_to_le32(len
);
2975 err
= wl_dev_ioctl(ndev
, WLC_SCAN_RESULTS
, bss_list
, len
);
2976 if (unlikely(err
)) {
2977 WL_ERR("%s Scan_results error (%d)\n", ndev
->name
, err
);
2982 bss_list
->buflen
= le32_to_cpu(bss_list
->buflen
);
2983 bss_list
->version
= le32_to_cpu(bss_list
->version
);
2984 bss_list
->count
= le32_to_cpu(bss_list
->count
);
2986 err
= wl_inform_bss(wl
);
2993 if (wl
->scan_request
) {
2994 WL_SCAN("calling cfg80211_scan_done\n");
2995 cfg80211_scan_done(wl
->scan_request
, scan_abort
);
2996 wl_set_mpc(ndev
, 1);
2997 wl
->scan_request
= NULL
;
3005 static void wl_init_conf(struct wl_conf
*conf
)
3007 conf
->mode
= (u32
)-1;
3008 conf
->frag_threshold
= (u32
)-1;
3009 conf
->rts_threshold
= (u32
)-1;
3010 conf
->retry_short
= (u32
)-1;
3011 conf
->retry_long
= (u32
)-1;
3012 conf
->tx_power
= -1;
3015 static void wl_init_prof(struct wl_profile
*prof
)
3017 memset(prof
, 0, sizeof(*prof
));
3020 static void wl_init_eloop_handler(struct wl_event_loop
*el
)
3022 memset(el
, 0, sizeof(*el
));
3023 el
->handler
[WLC_E_SCAN_COMPLETE
] = wl_notify_scan_status
;
3024 el
->handler
[WLC_E_LINK
] = wl_notify_connect_status
;
3025 el
->handler
[WLC_E_ROAM
] = wl_notify_roaming_status
;
3026 el
->handler
[WLC_E_MIC_ERROR
] = wl_notify_mic_status
;
3027 el
->handler
[WLC_E_SET_SSID
] = wl_notify_connect_status
;
3030 static s32
wl_init_priv_mem(struct wl_priv
*wl
)
3032 wl
->scan_results
= kzalloc(WL_SCAN_BUF_MAX
, GFP_KERNEL
);
3033 if (unlikely(!wl
->scan_results
)) {
3034 WL_ERR("Scan results alloc failed\n");
3035 goto init_priv_mem_out
;
3037 wl
->conf
= kzalloc(sizeof(*wl
->conf
), GFP_KERNEL
);
3038 if (unlikely(!wl
->conf
)) {
3039 WL_ERR("wl_conf alloc failed\n");
3040 goto init_priv_mem_out
;
3042 wl
->profile
= kzalloc(sizeof(*wl
->profile
), GFP_KERNEL
);
3043 if (unlikely(!wl
->profile
)) {
3044 WL_ERR("wl_profile alloc failed\n");
3045 goto init_priv_mem_out
;
3047 wl
->bss_info
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
3048 if (unlikely(!wl
->bss_info
)) {
3049 WL_ERR("Bss information alloc failed\n");
3050 goto init_priv_mem_out
;
3052 wl
->scan_req_int
= kzalloc(sizeof(*wl
->scan_req_int
), GFP_KERNEL
);
3053 if (unlikely(!wl
->scan_req_int
)) {
3054 WL_ERR("Scan req alloc failed\n");
3055 goto init_priv_mem_out
;
3057 wl
->ioctl_buf
= kzalloc(WL_IOCTL_LEN_MAX
, GFP_KERNEL
);
3058 if (unlikely(!wl
->ioctl_buf
)) {
3059 WL_ERR("Ioctl buf alloc failed\n");
3060 goto init_priv_mem_out
;
3062 wl
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3063 if (unlikely(!wl
->extra_buf
)) {
3064 WL_ERR("Extra buf alloc failed\n");
3065 goto init_priv_mem_out
;
3067 wl
->iscan
= kzalloc(sizeof(*wl
->iscan
), GFP_KERNEL
);
3068 if (unlikely(!wl
->iscan
)) {
3069 WL_ERR("Iscan buf alloc failed\n");
3070 goto init_priv_mem_out
;
3072 wl
->fw
= kzalloc(sizeof(*wl
->fw
), GFP_KERNEL
);
3073 if (unlikely(!wl
->fw
)) {
3074 WL_ERR("fw object alloc failed\n");
3075 goto init_priv_mem_out
;
3077 wl
->pmk_list
= kzalloc(sizeof(*wl
->pmk_list
), GFP_KERNEL
);
3078 if (unlikely(!wl
->pmk_list
)) {
3079 WL_ERR("pmk list alloc failed\n");
3080 goto init_priv_mem_out
;
3086 wl_deinit_priv_mem(wl
);
3091 static void wl_deinit_priv_mem(struct wl_priv
*wl
)
3093 kfree(wl
->scan_results
);
3094 wl
->scan_results
= NULL
;
3095 kfree(wl
->bss_info
);
3096 wl
->bss_info
= NULL
;
3101 kfree(wl
->scan_req_int
);
3102 wl
->scan_req_int
= NULL
;
3103 kfree(wl
->ioctl_buf
);
3104 wl
->ioctl_buf
= NULL
;
3105 kfree(wl
->extra_buf
);
3106 wl
->extra_buf
= NULL
;
3111 kfree(wl
->pmk_list
);
3112 wl
->pmk_list
= NULL
;
3115 static s32
wl_create_event_handler(struct wl_priv
*wl
)
3117 sema_init(&wl
->event_sync
, 0);
3118 wl
->event_tsk
= kthread_run(wl_event_handler
, wl
, "wl_event_handler");
3119 if (IS_ERR(wl
->event_tsk
)) {
3120 wl
->event_tsk
= NULL
;
3121 WL_ERR("failed to create event thread\n");
3127 static void wl_destroy_event_handler(struct wl_priv
*wl
)
3129 if (wl
->event_tsk
) {
3130 send_sig(SIGTERM
, wl
->event_tsk
, 1);
3131 kthread_stop(wl
->event_tsk
);
3132 wl
->event_tsk
= NULL
;
3136 static void wl_term_iscan(struct wl_priv
*wl
)
3138 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
3140 if (wl
->iscan_on
&& iscan
->tsk
) {
3141 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3142 send_sig(SIGTERM
, iscan
->tsk
, 1);
3143 kthread_stop(iscan
->tsk
);
3148 static void wl_notify_iscan_complete(struct wl_iscan_ctrl
*iscan
, bool aborted
)
3150 struct wl_priv
*wl
= iscan_to_wl(iscan
);
3151 struct net_device
*ndev
= wl_to_ndev(wl
);
3153 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
3154 WL_ERR("Scan complete while device not scanning\n");
3157 if (likely(wl
->scan_request
)) {
3158 WL_SCAN("ISCAN Completed scan: %s\n",
3159 aborted
? "Aborted" : "Done");
3160 cfg80211_scan_done(wl
->scan_request
, aborted
);
3161 wl_set_mpc(ndev
, 1);
3162 wl
->scan_request
= NULL
;
3164 wl
->iscan_kickstart
= false;
3167 static s32
wl_wakeup_iscan(struct wl_iscan_ctrl
*iscan
)
3169 if (likely(iscan
->state
!= WL_ISCAN_STATE_IDLE
)) {
3170 WL_SCAN("wake up iscan\n");
3179 wl_get_iscan_results(struct wl_iscan_ctrl
*iscan
, u32
*status
,
3180 struct wl_scan_results
**bss_list
)
3182 struct wl_iscan_results list
;
3183 struct wl_scan_results
*results
;
3184 struct wl_iscan_results
*list_buf
;
3187 memset(iscan
->scan_buf
, 0, WL_ISCAN_BUF_MAX
);
3188 list_buf
= (struct wl_iscan_results
*)iscan
->scan_buf
;
3189 results
= &list_buf
->results
;
3190 results
->buflen
= WL_ISCAN_RESULTS_FIXED_SIZE
;
3191 results
->version
= 0;
3194 memset(&list
, 0, sizeof(list
));
3195 list
.results
.buflen
= cpu_to_le32(WL_ISCAN_BUF_MAX
);
3196 err
= wl_dev_iovar_getbuf(iscan
->dev
, "iscanresults", &list
,
3197 WL_ISCAN_RESULTS_FIXED_SIZE
, iscan
->scan_buf
,
3199 if (unlikely(err
)) {
3200 WL_ERR("error (%d)\n", err
);
3203 results
->buflen
= le32_to_cpu(results
->buflen
);
3204 results
->version
= le32_to_cpu(results
->version
);
3205 results
->count
= le32_to_cpu(results
->count
);
3206 WL_SCAN("results->count = %d\n", results
->count
);
3207 WL_SCAN("results->buflen = %d\n", results
->buflen
);
3208 *status
= le32_to_cpu(list_buf
->status
);
3209 *bss_list
= results
;
3214 static s32
wl_iscan_done(struct wl_priv
*wl
)
3216 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
3219 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3222 wl_notify_iscan_complete(iscan
, false);
3228 static s32
wl_iscan_pending(struct wl_priv
*wl
)
3230 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
3233 /* Reschedule the timer */
3234 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
3235 iscan
->timer_on
= 1;
3240 static s32
wl_iscan_inprogress(struct wl_priv
*wl
)
3242 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
3247 wl_run_iscan(iscan
, NULL
, WL_SCAN_ACTION_CONTINUE
);
3249 /* Reschedule the timer */
3250 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
3251 iscan
->timer_on
= 1;
3256 static s32
wl_iscan_aborted(struct wl_priv
*wl
)
3258 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
3261 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3263 wl_notify_iscan_complete(iscan
, true);
3269 static s32
wl_iscan_thread(void *data
)
3271 struct sched_param param
= {.sched_priority
= MAX_RT_PRIO
- 1 };
3272 struct wl_iscan_ctrl
*iscan
= (struct wl_iscan_ctrl
*)data
;
3273 struct wl_priv
*wl
= iscan_to_wl(iscan
);
3274 struct wl_iscan_eloop
*el
= &iscan
->el
;
3278 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
3279 allow_signal(SIGTERM
);
3280 status
= WL_SCAN_RESULTS_PARTIAL
;
3281 while (likely(!down_interruptible(&iscan
->sync
))) {
3282 if (kthread_should_stop())
3284 if (iscan
->timer_on
) {
3285 del_timer_sync(&iscan
->timer
);
3286 iscan
->timer_on
= 0;
3289 err
= wl_get_iscan_results(iscan
, &status
, &wl
->bss_list
);
3290 if (unlikely(err
)) {
3291 status
= WL_SCAN_RESULTS_ABORTED
;
3292 WL_ERR("Abort iscan\n");
3295 el
->handler
[status
] (wl
);
3297 if (iscan
->timer_on
) {
3298 del_timer_sync(&iscan
->timer
);
3299 iscan
->timer_on
= 0;
3301 WL_SCAN("ISCAN thread terminated\n");
3306 static void wl_iscan_timer(unsigned long data
)
3308 struct wl_iscan_ctrl
*iscan
= (struct wl_iscan_ctrl
*)data
;
3311 iscan
->timer_on
= 0;
3312 WL_SCAN("timer expired\n");
3313 wl_wakeup_iscan(iscan
);
3317 static s32
wl_invoke_iscan(struct wl_priv
*wl
)
3319 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
3322 if (wl
->iscan_on
&& !iscan
->tsk
) {
3323 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3324 sema_init(&iscan
->sync
, 0);
3325 iscan
->tsk
= kthread_run(wl_iscan_thread
, iscan
, "wl_iscan");
3326 if (IS_ERR(iscan
->tsk
)) {
3327 WL_ERR("Could not create iscan thread\n");
3336 static void wl_init_iscan_eloop(struct wl_iscan_eloop
*el
)
3338 memset(el
, 0, sizeof(*el
));
3339 el
->handler
[WL_SCAN_RESULTS_SUCCESS
] = wl_iscan_done
;
3340 el
->handler
[WL_SCAN_RESULTS_PARTIAL
] = wl_iscan_inprogress
;
3341 el
->handler
[WL_SCAN_RESULTS_PENDING
] = wl_iscan_pending
;
3342 el
->handler
[WL_SCAN_RESULTS_ABORTED
] = wl_iscan_aborted
;
3343 el
->handler
[WL_SCAN_RESULTS_NO_MEM
] = wl_iscan_aborted
;
3346 static s32
wl_init_iscan(struct wl_priv
*wl
)
3348 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
3352 iscan
->dev
= wl_to_ndev(wl
);
3353 iscan
->state
= WL_ISCAN_STATE_IDLE
;
3354 wl_init_iscan_eloop(&iscan
->el
);
3355 iscan
->timer_ms
= WL_ISCAN_TIMER_INTERVAL_MS
;
3356 init_timer(&iscan
->timer
);
3357 iscan
->timer
.data
= (unsigned long) iscan
;
3358 iscan
->timer
.function
= wl_iscan_timer
;
3359 sema_init(&iscan
->sync
, 0);
3360 iscan
->tsk
= kthread_run(wl_iscan_thread
, iscan
, "wl_iscan");
3361 if (IS_ERR(iscan
->tsk
)) {
3362 WL_ERR("Could not create iscan thread\n");
3372 static void wl_init_fw(struct wl_fw_ctrl
*fw
)
3374 fw
->status
= 0; /* init fw loading status.
3375 0 means nothing was loaded yet */
3378 static s32
wl_init_priv(struct wl_priv
*wl
)
3380 struct wiphy
*wiphy
= wl_to_wiphy(wl
);
3383 wl
->scan_request
= NULL
;
3384 wl
->pwr_save
= !!(wiphy
->flags
& WIPHY_FLAG_PS_ON_BY_DEFAULT
);
3385 wl
->iscan_on
= true; /* iscan on & off switch.
3386 we enable iscan per default */
3387 wl
->roam_on
= false; /* roam on & off switch.
3388 we enable roam per default */
3390 wl
->iscan_kickstart
= false;
3391 wl
->active_scan
= true; /* we do active scan for
3392 specific scan per default */
3393 wl
->dongle_up
= false; /* dongle is not up yet */
3395 err
= wl_init_priv_mem(wl
);
3398 if (unlikely(wl_create_event_handler(wl
)))
3400 wl_init_eloop_handler(&wl
->el
);
3401 mutex_init(&wl
->usr_sync
);
3402 err
= wl_init_iscan(wl
);
3406 wl_init_conf(wl
->conf
);
3407 wl_init_prof(wl
->profile
);
3413 static void wl_deinit_priv(struct wl_priv
*wl
)
3415 wl_destroy_event_handler(wl
);
3416 wl
->dongle_up
= false; /* dongle down */
3420 wl_deinit_priv_mem(wl
);
3423 s32
wl_cfg80211_attach(struct net_device
*ndev
, void *data
)
3425 struct wireless_dev
*wdev
;
3427 struct wl_iface
*ci
;
3430 if (unlikely(!ndev
)) {
3431 WL_ERR("ndev is invalid\n");
3434 wl_cfg80211_dev
= kzalloc(sizeof(struct wl_dev
), GFP_KERNEL
);
3435 if (unlikely(!wl_cfg80211_dev
)) {
3436 WL_ERR("wl_cfg80211_dev is invalid\n");
3439 WL_INFO("func %p\n", wl_cfg80211_get_sdio_func());
3440 wdev
= wl_alloc_wdev(sizeof(struct wl_iface
), &wl_cfg80211_get_sdio_func()->dev
);
3444 wdev
->iftype
= wl_mode_to_nl80211_iftype(WL_MODE_BSS
);
3445 wl
= wdev_to_wl(wdev
);
3448 ci
= (struct wl_iface
*)wl_to_ci(wl
);
3450 ndev
->ieee80211_ptr
= wdev
;
3451 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
3452 wdev
->netdev
= ndev
;
3453 err
= wl_init_priv(wl
);
3454 if (unlikely(err
)) {
3455 WL_ERR("Failed to init iwm_priv (%d)\n", err
);
3456 goto cfg80211_attach_out
;
3458 wl_set_drvdata(wl_cfg80211_dev
, ci
);
3462 cfg80211_attach_out
:
3467 void wl_cfg80211_detach(void)
3475 wl_set_drvdata(wl_cfg80211_dev
, NULL
);
3476 kfree(wl_cfg80211_dev
);
3477 wl_cfg80211_dev
= NULL
;
3478 wl_clear_sdio_func();
3481 static void wl_wakeup_event(struct wl_priv
*wl
)
3483 up(&wl
->event_sync
);
3486 static s32
wl_event_handler(void *data
)
3488 struct wl_priv
*wl
= (struct wl_priv
*)data
;
3489 struct sched_param param
= {.sched_priority
= MAX_RT_PRIO
- 1 };
3490 struct wl_event_q
*e
;
3492 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
3493 allow_signal(SIGTERM
);
3494 while (likely(!down_interruptible(&wl
->event_sync
))) {
3495 if (kthread_should_stop())
3497 e
= wl_deq_event(wl
);
3499 WL_ERR("event queue empty...\n");
3502 WL_INFO("event type (%d)\n", e
->etype
);
3503 if (wl
->el
.handler
[e
->etype
]) {
3504 wl
->el
.handler
[e
->etype
] (wl
, wl_to_ndev(wl
), &e
->emsg
,
3507 WL_INFO("Unknown Event (%d): ignoring\n", e
->etype
);
3511 WL_INFO("was terminated\n");
3516 wl_cfg80211_event(struct net_device
*ndev
, const wl_event_msg_t
* e
, void *data
)
3518 u32 event_type
= be32_to_cpu(e
->event_type
);
3519 struct wl_priv
*wl
= ndev_to_wl(ndev
);
3521 if (likely(!wl_enq_event(wl
, event_type
, e
, data
)))
3522 wl_wakeup_event(wl
);
3525 static void wl_init_eq(struct wl_priv
*wl
)
3527 wl_init_eq_lock(wl
);
3528 INIT_LIST_HEAD(&wl
->eq_list
);
3531 static void wl_flush_eq(struct wl_priv
*wl
)
3533 struct wl_event_q
*e
;
3536 while (!list_empty(&wl
->eq_list
)) {
3537 e
= list_first_entry(&wl
->eq_list
, struct wl_event_q
, eq_list
);
3538 list_del(&e
->eq_list
);
3545 * retrieve first queued event from head
3548 static struct wl_event_q
*wl_deq_event(struct wl_priv
*wl
)
3550 struct wl_event_q
*e
= NULL
;
3553 if (likely(!list_empty(&wl
->eq_list
))) {
3554 e
= list_first_entry(&wl
->eq_list
, struct wl_event_q
, eq_list
);
3555 list_del(&e
->eq_list
);
3563 ** push event to tail of the queue
3567 wl_enq_event(struct wl_priv
*wl
, u32 event
, const wl_event_msg_t
*msg
,
3570 struct wl_event_q
*e
;
3573 e
= kzalloc(sizeof(struct wl_event_q
), GFP_KERNEL
);
3575 WL_ERR("event alloc failed\n");
3580 memcpy(&e
->emsg
, msg
, sizeof(wl_event_msg_t
));
3584 list_add_tail(&e
->eq_list
, &wl
->eq_list
);
3590 static void wl_put_event(struct wl_event_q
*e
)
3595 void wl_cfg80211_sdio_func(void *func
)
3597 cfg80211_sdio_func
= (struct sdio_func
*)func
;
3600 static void wl_clear_sdio_func(void)
3602 cfg80211_sdio_func
= NULL
;
3605 struct sdio_func
*wl_cfg80211_get_sdio_func(void)
3607 return cfg80211_sdio_func
;
3610 static s32
wl_dongle_mode(struct net_device
*ndev
, s32 iftype
)
3616 case NL80211_IFTYPE_MONITOR
:
3617 case NL80211_IFTYPE_WDS
:
3618 WL_ERR("type (%d) : currently we do not support this mode\n",
3622 case NL80211_IFTYPE_ADHOC
:
3625 case NL80211_IFTYPE_STATION
:
3630 WL_ERR("invalid type (%d)\n", iftype
);
3633 infra
= cpu_to_le32(infra
);
3634 err
= wl_dev_ioctl(ndev
, WLC_SET_INFRA
, &infra
, sizeof(infra
));
3635 if (unlikely(err
)) {
3636 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
3643 #ifndef EMBEDDED_PLATFORM
3644 static s32
wl_dongle_country(struct net_device
*ndev
, u8 ccode
)
3652 static s32
wl_dongle_up(struct net_device
*ndev
, u32 up
)
3656 err
= wl_dev_ioctl(ndev
, WLC_UP
, &up
, sizeof(up
));
3657 if (unlikely(err
)) {
3658 WL_ERR("WLC_UP error (%d)\n", err
);
3663 static s32
wl_dongle_power(struct net_device
*ndev
, u32 power_mode
)
3667 err
= wl_dev_ioctl(ndev
, WLC_SET_PM
, &power_mode
, sizeof(power_mode
));
3668 if (unlikely(err
)) {
3669 WL_ERR("WLC_SET_PM error (%d)\n", err
);
3675 wl_dongle_glom(struct net_device
*ndev
, u32 glom
, u32 dongle_align
)
3677 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3681 /* Match Host and Dongle rx alignment */
3682 brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align
, 4, iovbuf
,
3684 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3685 if (unlikely(err
)) {
3686 WL_ERR("txglomalign error (%d)\n", err
);
3687 goto dongle_glom_out
;
3689 /* disable glom option per default */
3690 brcmu_mkiovar("bus:txglom", (char *)&glom
, 4, iovbuf
, sizeof(iovbuf
));
3691 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3692 if (unlikely(err
)) {
3693 WL_ERR("txglom error (%d)\n", err
);
3694 goto dongle_glom_out
;
3701 wl_dongle_offload(struct net_device
*ndev
, s32 arpoe
, s32 arp_ol
)
3703 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3707 /* Set ARP offload */
3708 brcmu_mkiovar("arpoe", (char *)&arpoe
, 4, iovbuf
, sizeof(iovbuf
));
3709 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3711 if (err
== -EOPNOTSUPP
)
3712 WL_INFO("arpoe is not supported\n");
3714 WL_ERR("arpoe error (%d)\n", err
);
3716 goto dongle_offload_out
;
3718 brcmu_mkiovar("arp_ol", (char *)&arp_ol
, 4, iovbuf
, sizeof(iovbuf
));
3719 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3721 if (err
== -EOPNOTSUPP
)
3722 WL_INFO("arp_ol is not supported\n");
3724 WL_ERR("arp_ol error (%d)\n", err
);
3726 goto dongle_offload_out
;
3733 static s32
wl_pattern_atoh(s8
*src
, s8
*dst
)
3736 if (strncmp(src
, "0x", 2) != 0 && strncmp(src
, "0X", 2) != 0) {
3737 WL_ERR("Mask invalid format. Needs to start with 0x\n");
3740 src
= src
+ 2; /* Skip past 0x */
3741 if (strlen(src
) % 2 != 0) {
3742 WL_ERR("Mask invalid format. Needs to be of even length\n");
3745 for (i
= 0; *src
!= '\0'; i
++) {
3747 strncpy(num
, src
, 2);
3749 dst
[i
] = (u8
) simple_strtoul(num
, NULL
, 16);
3755 static s32
wl_dongle_filter(struct net_device
*ndev
, u32 filter_mode
)
3757 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3760 struct wl_pkt_filter pkt_filter
;
3761 struct wl_pkt_filter
*pkt_filterp
;
3769 /* add a default packet filter pattern */
3770 str
= "pkt_filter_add";
3771 str_len
= strlen(str
);
3772 strncpy(buf
, str
, str_len
);
3773 buf
[str_len
] = '\0';
3774 buf_len
= str_len
+ 1;
3776 pkt_filterp
= (struct wl_pkt_filter
*)(buf
+ str_len
+ 1);
3778 /* Parse packet filter id. */
3779 pkt_filter
.id
= cpu_to_le32(100);
3781 /* Parse filter polarity. */
3782 pkt_filter
.negate_match
= cpu_to_le32(0);
3784 /* Parse filter type. */
3785 pkt_filter
.type
= cpu_to_le32(0);
3787 /* Parse pattern filter offset. */
3788 pkt_filter
.u
.pattern
.offset
= cpu_to_le32(0);
3790 /* Parse pattern filter mask. */
3791 mask_size
= cpu_to_le32(wl_pattern_atoh("0xff",
3792 (char *)pkt_filterp
->u
.pattern
.
3795 /* Parse pattern filter pattern. */
3796 pattern_size
= cpu_to_le32(wl_pattern_atoh("0x00",
3797 (char *)&pkt_filterp
->u
.
3802 if (mask_size
!= pattern_size
) {
3803 WL_ERR("Mask and pattern not the same size\n");
3805 goto dongle_filter_out
;
3808 pkt_filter
.u
.pattern
.size_bytes
= mask_size
;
3809 buf_len
+= WL_PKT_FILTER_FIXED_LEN
;
3810 buf_len
+= (WL_PKT_FILTER_PATTERN_FIXED_LEN
+ 2 * mask_size
);
3812 /* Keep-alive attributes are set in local
3813 * variable (keep_alive_pkt), and
3814 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3815 * guarantee that the buffer is properly aligned.
3817 memcpy((char *)pkt_filterp
, &pkt_filter
,
3818 WL_PKT_FILTER_FIXED_LEN
+ WL_PKT_FILTER_PATTERN_FIXED_LEN
);
3820 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, buf
, buf_len
);
3822 if (err
== -EOPNOTSUPP
) {
3823 WL_INFO("filter not supported\n");
3825 WL_ERR("filter (%d)\n", err
);
3827 goto dongle_filter_out
;
3830 /* set mode to allow pattern */
3831 brcmu_mkiovar("pkt_filter_mode", (char *)&filter_mode
, 4, iovbuf
,
3833 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3835 if (err
== -EOPNOTSUPP
) {
3836 WL_INFO("filter_mode not supported\n");
3838 WL_ERR("filter_mode (%d)\n", err
);
3840 goto dongle_filter_out
;
3846 #endif /* !EMBEDDED_PLATFORM */
3848 static s32
wl_dongle_eventmsg(struct net_device
*ndev
)
3850 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3852 s8 eventmask
[WL_EVENTING_MASK_LEN
];
3855 WL_TRACE("Enter\n");
3857 /* Setup event_msgs */
3858 brcmu_mkiovar("event_msgs", eventmask
, WL_EVENTING_MASK_LEN
, iovbuf
,
3860 err
= wl_dev_ioctl(ndev
, WLC_GET_VAR
, iovbuf
, sizeof(iovbuf
));
3861 if (unlikely(err
)) {
3862 WL_ERR("Get event_msgs error (%d)\n", err
);
3863 goto dongle_eventmsg_out
;
3865 memcpy(eventmask
, iovbuf
, WL_EVENTING_MASK_LEN
);
3867 setbit(eventmask
, WLC_E_SET_SSID
);
3868 setbit(eventmask
, WLC_E_ROAM
);
3869 setbit(eventmask
, WLC_E_PRUNE
);
3870 setbit(eventmask
, WLC_E_AUTH
);
3871 setbit(eventmask
, WLC_E_REASSOC
);
3872 setbit(eventmask
, WLC_E_REASSOC_IND
);
3873 setbit(eventmask
, WLC_E_DEAUTH_IND
);
3874 setbit(eventmask
, WLC_E_DISASSOC_IND
);
3875 setbit(eventmask
, WLC_E_DISASSOC
);
3876 setbit(eventmask
, WLC_E_JOIN
);
3877 setbit(eventmask
, WLC_E_ASSOC_IND
);
3878 setbit(eventmask
, WLC_E_PSK_SUP
);
3879 setbit(eventmask
, WLC_E_LINK
);
3880 setbit(eventmask
, WLC_E_NDIS_LINK
);
3881 setbit(eventmask
, WLC_E_MIC_ERROR
);
3882 setbit(eventmask
, WLC_E_PMKID_CACHE
);
3883 setbit(eventmask
, WLC_E_TXFAIL
);
3884 setbit(eventmask
, WLC_E_JOIN_START
);
3885 setbit(eventmask
, WLC_E_SCAN_COMPLETE
);
3887 brcmu_mkiovar("event_msgs", eventmask
, WL_EVENTING_MASK_LEN
, iovbuf
,
3889 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3890 if (unlikely(err
)) {
3891 WL_ERR("Set event_msgs error (%d)\n", err
);
3892 goto dongle_eventmsg_out
;
3895 dongle_eventmsg_out
:
3901 wl_dongle_roam(struct net_device
*ndev
, u32 roamvar
, u32 bcn_timeout
)
3909 * Setup timeout if Beacons are lost and roam is
3910 * off to report link down
3913 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout
,
3914 sizeof(bcn_timeout
), iovbuf
, sizeof(iovbuf
));
3915 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3916 if (unlikely(err
)) {
3917 WL_ERR("bcn_timeout error (%d)\n", err
);
3918 goto dongle_rom_out
;
3923 * Enable/Disable built-in roaming to allow supplicant
3924 * to take care of roaming
3926 WL_INFO("Internal Roaming = %s\n", roamvar
? "Off" : "On");
3927 brcmu_mkiovar("roam_off", (char *)&roamvar
,
3928 sizeof(roamvar
), iovbuf
, sizeof(iovbuf
));
3929 err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
));
3930 if (unlikely(err
)) {
3931 WL_ERR("roam_off error (%d)\n", err
);
3932 goto dongle_rom_out
;
3935 roamtrigger
[0] = WL_ROAM_TRIGGER_LEVEL
;
3936 roamtrigger
[1] = WLC_BAND_ALL
;
3937 err
= wl_dev_ioctl(ndev
, WLC_SET_ROAM_TRIGGER
,
3938 (void *)roamtrigger
, sizeof(roamtrigger
));
3939 if (unlikely(err
)) {
3940 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
3941 goto dongle_rom_out
;
3944 roam_delta
[0] = WL_ROAM_DELTA
;
3945 roam_delta
[1] = WLC_BAND_ALL
;
3946 err
= wl_dev_ioctl(ndev
, WLC_SET_ROAM_DELTA
,
3947 (void *)roam_delta
, sizeof(roam_delta
));
3948 if (unlikely(err
)) {
3949 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err
);
3950 goto dongle_rom_out
;
3958 wl_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
3959 s32 scan_unassoc_time
, s32 scan_passive_time
)
3963 err
= wl_dev_ioctl(ndev
, WLC_SET_SCAN_CHANNEL_TIME
, &scan_assoc_time
,
3964 sizeof(scan_assoc_time
));
3966 if (err
== -EOPNOTSUPP
)
3967 WL_INFO("Scan assoc time is not supported\n");
3969 WL_ERR("Scan assoc time error (%d)\n", err
);
3970 goto dongle_scantime_out
;
3972 err
= wl_dev_ioctl(ndev
, WLC_SET_SCAN_UNASSOC_TIME
, &scan_unassoc_time
,
3973 sizeof(scan_unassoc_time
));
3975 if (err
== -EOPNOTSUPP
)
3976 WL_INFO("Scan unassoc time is not supported\n");
3978 WL_ERR("Scan unassoc time error (%d)\n", err
);
3979 goto dongle_scantime_out
;
3982 err
= wl_dev_ioctl(ndev
, WLC_SET_SCAN_PASSIVE_TIME
, &scan_passive_time
,
3983 sizeof(scan_passive_time
));
3985 if (err
== -EOPNOTSUPP
)
3986 WL_INFO("Scan passive time is not supported\n");
3988 WL_ERR("Scan passive time error (%d)\n", err
);
3989 goto dongle_scantime_out
;
3992 dongle_scantime_out
:
3996 s32
wl_config_dongle(struct wl_priv
*wl
, bool need_lock
)
3999 #define DHD_SDALIGN 32
4001 struct net_device
*ndev
;
4002 struct wireless_dev
*wdev
;
4008 ndev
= wl_to_ndev(wl
);
4009 wdev
= ndev
->ieee80211_ptr
;
4013 #ifndef EMBEDDED_PLATFORM
4014 err
= wl_dongle_up(ndev
, 0);
4016 goto default_conf_out
;
4017 err
= wl_dongle_country(ndev
, 0);
4019 goto default_conf_out
;
4020 err
= wl_dongle_power(ndev
, PM_FAST
);
4022 goto default_conf_out
;
4023 err
= wl_dongle_glom(ndev
, 0, DHD_SDALIGN
);
4025 goto default_conf_out
;
4027 wl_dongle_offload(ndev
, 1, 0xf);
4028 wl_dongle_filter(ndev
, 1);
4029 #endif /* !EMBEDDED_PLATFORM */
4031 wl_dongle_scantime(ndev
, WL_SCAN_CHANNEL_TIME
,
4032 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
4034 err
= wl_dongle_eventmsg(ndev
);
4036 goto default_conf_out
;
4037 err
= wl_dongle_roam(ndev
, (wl
->roam_on
? 0 : 1), WL_BEACON_TIMEOUT
);
4039 goto default_conf_out
;
4040 err
= wl_dongle_mode(ndev
, wdev
->iftype
);
4041 if (unlikely(err
&& err
!= -EINPROGRESS
))
4042 goto default_conf_out
;
4043 err
= wl_dongle_probecap(wl
);
4045 goto default_conf_out
;
4047 /* -EINPROGRESS: Call commit handler */
4053 wl
->dongle_up
= true;
4059 static s32
wl_update_wiphybands(struct wl_priv
*wl
)
4061 struct wiphy
*wiphy
;
4066 err
= wl_dev_ioctl(wl_to_ndev(wl
), WLC_GET_PHYLIST
, &phy_list
,
4068 if (unlikely(err
)) {
4069 WL_ERR("error (%d)\n", err
);
4073 phy
= ((char *)&phy_list
)[1];
4074 WL_INFO("%c phy\n", phy
);
4075 if (phy
== 'n' || phy
== 'a') {
4076 wiphy
= wl_to_wiphy(wl
);
4077 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
4083 static s32
__wl_cfg80211_up(struct wl_priv
*wl
)
4087 set_bit(WL_STATUS_READY
, &wl
->status
);
4089 wl_debugfs_add_netdev_params(wl
);
4091 err
= wl_config_dongle(wl
, false);
4095 wl_invoke_iscan(wl
);
4100 static s32
__wl_cfg80211_down(struct wl_priv
*wl
)
4102 set_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
4104 if (wl
->scan_request
) {
4105 cfg80211_scan_done(wl
->scan_request
, true);
4106 /* May need to perform this to cover rmmod */
4107 /* wl_set_mpc(wl_to_ndev(wl), 1); */
4108 wl
->scan_request
= NULL
;
4110 clear_bit(WL_STATUS_READY
, &wl
->status
);
4111 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
4112 clear_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
4113 clear_bit(WL_STATUS_CONNECTING
, &wl
->status
);
4114 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
4116 wl_debugfs_remove_netdev(wl
);
4121 s32
wl_cfg80211_up(void)
4127 mutex_lock(&wl
->usr_sync
);
4128 err
= __wl_cfg80211_up(wl
);
4129 mutex_unlock(&wl
->usr_sync
);
4134 s32
wl_cfg80211_down(void)
4140 mutex_lock(&wl
->usr_sync
);
4141 err
= __wl_cfg80211_down(wl
);
4142 mutex_unlock(&wl
->usr_sync
);
4147 static s32
wl_dongle_probecap(struct wl_priv
*wl
)
4151 err
= wl_update_wiphybands(wl
);
4158 static void *wl_read_prof(struct wl_priv
*wl
, s32 item
)
4162 return &wl
->profile
->sec
;
4164 return &wl
->profile
->bssid
;
4166 return &wl
->profile
->ssid
;
4168 WL_ERR("invalid item (%d)\n", item
);
4173 wl_update_prof(struct wl_priv
*wl
, const wl_event_msg_t
*e
, void *data
,
4177 struct wlc_ssid
*ssid
;
4181 ssid
= (wlc_ssid_t
*) data
;
4182 memset(wl
->profile
->ssid
.SSID
, 0,
4183 sizeof(wl
->profile
->ssid
.SSID
));
4184 memcpy(wl
->profile
->ssid
.SSID
, ssid
->SSID
, ssid
->SSID_len
);
4185 wl
->profile
->ssid
.SSID_len
= ssid
->SSID_len
;
4189 memcpy(wl
->profile
->bssid
, data
, ETH_ALEN
);
4191 memset(wl
->profile
->bssid
, 0, ETH_ALEN
);
4194 memcpy(&wl
->profile
->sec
, data
, sizeof(wl
->profile
->sec
));
4196 case WL_PROF_BEACONINT
:
4197 wl
->profile
->beacon_interval
= *(u16
*)data
;
4199 case WL_PROF_DTIMPERIOD
:
4200 wl
->profile
->dtim_period
= *(u8
*)data
;
4203 WL_ERR("unsupported item (%d)\n", item
);
4211 static bool wl_is_ibssmode(struct wl_priv
*wl
)
4213 return wl
->conf
->mode
== WL_MODE_IBSS
;
4216 static __used s32
wl_add_ie(struct wl_priv
*wl
, u8 t
, u8 l
, u8
*v
)
4218 struct wl_ie
*ie
= wl_to_ie(wl
);
4221 if (unlikely(ie
->offset
+ l
+ 2 > WL_TLV_INFO_MAX
)) {
4222 WL_ERR("ei crosses buffer boundary\n");
4225 ie
->buf
[ie
->offset
] = t
;
4226 ie
->buf
[ie
->offset
+ 1] = l
;
4227 memcpy(&ie
->buf
[ie
->offset
+ 2], v
, l
);
4228 ie
->offset
+= l
+ 2;
4234 static void wl_link_down(struct wl_priv
*wl
)
4236 struct net_device
*dev
= NULL
;
4239 WL_TRACE("Enter\n");
4240 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
4243 dev
= wl_to_ndev(wl
);
4244 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
4245 err
= wl_dev_ioctl(dev
, WLC_DISASSOC
, NULL
, 0);
4247 WL_ERR("WLC_DISASSOC failed (%d)\n", err
);
4248 wl
->link_up
= false;
4253 static void wl_lock_eq(struct wl_priv
*wl
)
4255 spin_lock_irq(&wl
->eq_lock
);
4258 static void wl_unlock_eq(struct wl_priv
*wl
)
4260 spin_unlock_irq(&wl
->eq_lock
);
4263 static void wl_init_eq_lock(struct wl_priv
*wl
)
4265 spin_lock_init(&wl
->eq_lock
);
4268 static void wl_delay(u32 ms
)
4270 if (ms
< 1000 / HZ
) {
4278 static void wl_set_drvdata(struct wl_dev
*dev
, void *data
)
4280 dev
->driver_data
= data
;
4283 static void *wl_get_drvdata(struct wl_dev
*dev
)
4285 return dev
->driver_data
;
4288 s32
wl_cfg80211_read_fw(s8
*buf
, u32 size
)
4290 const struct firmware
*fw_entry
;
4295 fw_entry
= wl
->fw
->fw_entry
;
4297 if (fw_entry
->size
< wl
->fw
->ptr
+ size
)
4298 size
= fw_entry
->size
- wl
->fw
->ptr
;
4300 memcpy(buf
, &fw_entry
->data
[wl
->fw
->ptr
], size
);
4301 wl
->fw
->ptr
+= size
;
4305 void wl_cfg80211_release_fw(void)
4310 release_firmware(wl
->fw
->fw_entry
);
4314 void *wl_cfg80211_request_fw(s8
*file_name
)
4317 const struct firmware
*fw_entry
= NULL
;
4320 WL_INFO("file name : \"%s\"\n", file_name
);
4323 if (!test_bit(WL_FW_LOADING_DONE
, &wl
->fw
->status
)) {
4324 err
= request_firmware(&wl
->fw
->fw_entry
, file_name
,
4325 &wl_cfg80211_get_sdio_func()->dev
);
4326 if (unlikely(err
)) {
4327 WL_ERR("Could not download fw (%d)\n", err
);
4330 set_bit(WL_FW_LOADING_DONE
, &wl
->fw
->status
);
4331 fw_entry
= wl
->fw
->fw_entry
;
4333 WL_INFO("fw size (%zd), data (%p)\n",
4334 fw_entry
->size
, fw_entry
->data
);
4336 } else if (!test_bit(WL_NVRAM_LOADING_DONE
, &wl
->fw
->status
)) {
4337 err
= request_firmware(&wl
->fw
->fw_entry
, file_name
,
4338 &wl_cfg80211_get_sdio_func()->dev
);
4339 if (unlikely(err
)) {
4340 WL_ERR("Could not download nvram (%d)\n", err
);
4343 set_bit(WL_NVRAM_LOADING_DONE
, &wl
->fw
->status
);
4344 fw_entry
= wl
->fw
->fw_entry
;
4346 WL_INFO("nvram size (%zd), data (%p)\n",
4347 fw_entry
->size
, fw_entry
->data
);
4350 WL_INFO("Downloading already done. Nothing to do more\n");
4355 if (unlikely(err
)) {
4359 return (void *)fw_entry
->data
;
4362 s8
*wl_cfg80211_get_fwname(void)
4367 strcpy(wl
->fw
->fw_name
, WL_4329_FW_FILE
);
4368 return wl
->fw
->fw_name
;
4371 s8
*wl_cfg80211_get_nvramname(void)
4376 strcpy(wl
->fw
->nvram_name
, WL_4329_NVRAM_FILE
);
4377 return wl
->fw
->nvram_name
;
4380 static void wl_set_mpc(struct net_device
*ndev
, int mpc
)
4383 struct wl_priv
*wl
= ndev_to_wl(ndev
);
4385 if (test_bit(WL_STATUS_READY
, &wl
->status
)) {
4386 err
= wl_dev_intvar_set(ndev
, "mpc", mpc
);
4387 if (unlikely(err
)) {
4388 WL_ERR("fail to set mpc\n");
4391 WL_INFO("MPC : %d\n", mpc
);
4395 static int wl_debugfs_add_netdev_params(struct wl_priv
*wl
)
4397 char buf
[10+IFNAMSIZ
];
4401 sprintf(buf
, "netdev:%s", wl_to_ndev(wl
)->name
);
4402 wl
->debugfsdir
= debugfs_create_dir(buf
, wl_to_wiphy(wl
)->debugfsdir
);
4404 fd
= debugfs_create_u16("beacon_int", S_IRUGO
, wl
->debugfsdir
,
4405 (u16
*)&wl
->profile
->beacon_interval
);
4411 fd
= debugfs_create_u8("dtim_period", S_IRUGO
, wl
->debugfsdir
,
4412 (u8
*)&wl
->profile
->dtim_period
);
4422 static void wl_debugfs_remove_netdev(struct wl_priv
*wl
)
4424 debugfs_remove_recursive(wl
->debugfsdir
);
4425 wl
->debugfsdir
= NULL
;