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.
22 #include <bcmendian.h>
23 #include <proto/ethernet.h>
25 #include <linux/if_arp.h>
26 #include <asm/uaccess.h>
28 #include <dngl_stats.h>
33 #include <proto/ethernet.h>
34 #include <dngl_stats.h>
37 #include <linux/kernel.h>
38 #include <linux/netdevice.h>
39 #include <linux/sched.h>
40 #include <linux/etherdevice.h>
41 #include <linux/wireless.h>
42 #include <linux/ieee80211.h>
43 #include <net/cfg80211.h>
45 #include <net/rtnetlink.h>
46 #include <linux/mmc/sdio_func.h>
47 #include <linux/firmware.h>
48 #include <wl_cfg80211.h>
50 static struct sdio_func
*cfg80211_sdio_func
;
51 static struct wl_dev
*wl_cfg80211_dev
;
53 uint32 wl_dbg_level
= WL_DBG_ERR
| WL_DBG_INFO
;
55 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
56 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
59 ** cfg80211_ops api/callback list
61 static int32
wl_cfg80211_change_iface(struct wiphy
*wiphy
,
62 struct net_device
*ndev
,
63 enum nl80211_iftype type
, uint32
*flags
,
64 struct vif_params
*params
);
65 static int32
__wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
66 struct cfg80211_scan_request
*request
,
67 struct cfg80211_ssid
*this_ssid
);
68 static int32
wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
69 struct cfg80211_scan_request
*request
);
70 static int32
wl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, uint32 changed
);
71 static int32
wl_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
72 struct cfg80211_ibss_params
*params
);
73 static int32
wl_cfg80211_leave_ibss(struct wiphy
*wiphy
,
74 struct net_device
*dev
);
75 static int32
wl_cfg80211_get_station(struct wiphy
*wiphy
,
76 struct net_device
*dev
, u8
*mac
,
77 struct station_info
*sinfo
);
78 static int32
wl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
79 struct net_device
*dev
, bool enabled
,
81 static int32
wl_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
,
82 struct net_device
*dev
,
84 const struct cfg80211_bitrate_mask
86 static int wl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
87 struct cfg80211_connect_params
*sme
);
88 static int32
wl_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
90 static int32
wl_cfg80211_set_tx_power(struct wiphy
*wiphy
,
91 enum nl80211_tx_power_setting type
,
93 static int32
wl_cfg80211_get_tx_power(struct wiphy
*wiphy
, int32
*dbm
);
94 static int32
wl_cfg80211_config_default_key(struct wiphy
*wiphy
,
95 struct net_device
*dev
,
97 static int32
wl_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
98 u8 key_idx
, const u8
*mac_addr
,
99 struct key_params
*params
);
100 static int32
wl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
101 u8 key_idx
, const u8
*mac_addr
);
102 static int32
wl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
103 u8 key_idx
, const u8
*mac_addr
,
104 void *cookie
, void (*callback
) (void *cookie
,
108 static int32
wl_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
109 struct net_device
*dev
,
111 static int32
wl_cfg80211_resume(struct wiphy
*wiphy
);
112 static int32
wl_cfg80211_suspend(struct wiphy
*wiphy
);
113 static int32
wl_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
114 struct cfg80211_pmksa
*pmksa
);
115 static int32
wl_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
116 struct cfg80211_pmksa
*pmksa
);
117 static int32
wl_cfg80211_flush_pmksa(struct wiphy
*wiphy
,
118 struct net_device
*dev
);
120 ** event & event Q handlers for cfg80211 interfaces
122 static int32
wl_create_event_handler(struct wl_priv
*wl
);
123 static void wl_destroy_event_handler(struct wl_priv
*wl
);
124 static int32
wl_event_handler(void *data
);
125 static void wl_init_eq(struct wl_priv
*wl
);
126 static void wl_flush_eq(struct wl_priv
*wl
);
127 static void wl_lock_eq(struct wl_priv
*wl
);
128 static void wl_unlock_eq(struct wl_priv
*wl
);
129 static void wl_init_eq_lock(struct wl_priv
*wl
);
130 static void wl_init_eloop_handler(struct wl_event_loop
*el
);
131 static struct wl_event_q
*wl_deq_event(struct wl_priv
*wl
);
132 static int32
wl_enq_event(struct wl_priv
*wl
, uint32 type
,
133 const wl_event_msg_t
*msg
, void *data
);
134 static void wl_put_event(struct wl_event_q
*e
);
135 static void wl_wakeup_event(struct wl_priv
*wl
);
136 static int32
wl_notify_connect_status(struct wl_priv
*wl
,
137 struct net_device
*ndev
,
138 const wl_event_msg_t
*e
, void *data
);
139 static int32
wl_notify_roaming_status(struct wl_priv
*wl
,
140 struct net_device
*ndev
,
141 const wl_event_msg_t
*e
, void *data
);
142 static int32
wl_notify_scan_status(struct wl_priv
*wl
, struct net_device
*ndev
,
143 const wl_event_msg_t
*e
, void *data
);
144 static int32
wl_bss_connect_done(struct wl_priv
*wl
, struct net_device
*ndev
,
145 const wl_event_msg_t
*e
, void *data
);
146 static int32
wl_bss_roaming_done(struct wl_priv
*wl
, struct net_device
*ndev
,
147 const wl_event_msg_t
*e
, void *data
);
148 static int32
wl_notify_mic_status(struct wl_priv
*wl
, struct net_device
*ndev
,
149 const wl_event_msg_t
*e
, void *data
);
152 ** register/deregister sdio function
154 struct sdio_func
*wl_cfg80211_get_sdio_func(void);
155 static void wl_clear_sdio_func(void);
160 static int32
wl_dev_bufvar_get(struct net_device
*dev
, s8
*name
, s8
*buf
,
162 static __used int32
wl_dev_bufvar_set(struct net_device
*dev
, s8
*name
,
164 static int32
wl_dev_intvar_set(struct net_device
*dev
, s8
*name
, int32 val
);
165 static int32
wl_dev_intvar_get(struct net_device
*dev
, s8
*name
,
167 static int32
wl_dev_ioctl(struct net_device
*dev
, uint32 cmd
, void *arg
,
171 ** cfg80211 set_wiphy_params utilities
173 static int32
wl_set_frag(struct net_device
*dev
, uint32 frag_threshold
);
174 static int32
wl_set_rts(struct net_device
*dev
, uint32 frag_threshold
);
175 static int32
wl_set_retry(struct net_device
*dev
, uint32 retry
, bool l
);
178 ** wl profile utilities
180 static int32
wl_update_prof(struct wl_priv
*wl
, const wl_event_msg_t
*e
,
181 void *data
, int32 item
);
182 static void *wl_read_prof(struct wl_priv
*wl
, int32 item
);
183 static void wl_init_prof(struct wl_profile
*prof
);
186 ** cfg80211 connect utilites
188 static int32
wl_set_wpa_version(struct net_device
*dev
,
189 struct cfg80211_connect_params
*sme
);
190 static int32
wl_set_auth_type(struct net_device
*dev
,
191 struct cfg80211_connect_params
*sme
);
192 static int32
wl_set_set_cipher(struct net_device
*dev
,
193 struct cfg80211_connect_params
*sme
);
194 static int32
wl_set_key_mgmt(struct net_device
*dev
,
195 struct cfg80211_connect_params
*sme
);
196 static int32
wl_set_set_sharedkey(struct net_device
*dev
,
197 struct cfg80211_connect_params
*sme
);
198 static int32
wl_get_assoc_ies(struct wl_priv
*wl
);
201 ** information element utilities
203 static void wl_rst_ie(struct wl_priv
*wl
);
204 static int32
wl_add_ie(struct wl_priv
*wl
, u8 t
, u8 l
, u8
*v
);
205 static int32
wl_mrg_ie(struct wl_priv
*wl
, u8
*ie_stream
, uint16 ie_size
);
206 static int32
wl_cp_ie(struct wl_priv
*wl
, u8
*dst
, uint16 dst_size
);
207 static uint32
wl_get_ielen(struct wl_priv
*wl
);
209 static int32
wl_mode_to_nl80211_iftype(int32 mode
);
211 static struct wireless_dev
*wl_alloc_wdev(int32 sizeof_iface
,
213 static void wl_free_wdev(struct wl_priv
*wl
);
215 static int32
wl_inform_bss(struct wl_priv
*wl
);
216 static int32
wl_inform_single_bss(struct wl_priv
*wl
, struct wl_bss_info
*bi
);
217 static int32
wl_update_bss_info(struct wl_priv
*wl
);
219 static int32
wl_add_keyext(struct wiphy
*wiphy
, struct net_device
*dev
,
220 u8 key_idx
, const u8
*mac_addr
,
221 struct key_params
*params
);
224 ** key indianess swap utilities
226 static void swap_key_from_BE(struct wl_wsec_key
*key
);
227 static void swap_key_to_BE(struct wl_wsec_key
*key
);
230 ** wl_priv memory init/deinit utilities
232 static int32
wl_init_priv_mem(struct wl_priv
*wl
);
233 static void wl_deinit_priv_mem(struct wl_priv
*wl
);
235 static void wl_delay(uint32 ms
);
238 ** store/restore cfg80211 instance data
240 static void wl_set_drvdata(struct wl_dev
*dev
, void *data
);
241 static void *wl_get_drvdata(struct wl_dev
*dev
);
244 ** ibss mode utilities
246 static bool wl_is_ibssmode(struct wl_priv
*wl
);
247 static bool wl_is_ibssstarter(struct wl_priv
*wl
);
250 ** dongle up/down , default configuration utilities
252 static bool wl_is_linkdown(struct wl_priv
*wl
, const wl_event_msg_t
*e
);
253 static bool wl_is_linkup(struct wl_priv
*wl
, const wl_event_msg_t
*e
);
254 static void wl_link_up(struct wl_priv
*wl
);
255 static void wl_link_down(struct wl_priv
*wl
);
256 static int32
wl_dongle_mode(struct net_device
*ndev
, int32 iftype
);
257 static int32
__wl_cfg80211_up(struct wl_priv
*wl
);
258 static int32
__wl_cfg80211_down(struct wl_priv
*wl
);
259 static int32
wl_dongle_probecap(struct wl_priv
*wl
);
260 static void wl_init_conf(struct wl_conf
*conf
);
263 ** dongle configuration utilities
265 #ifndef EMBEDDED_PLATFORM
266 static int32
wl_dongle_mode(struct net_device
*ndev
, int32 iftype
);
267 static int32
wl_dongle_country(struct net_device
*ndev
, u8 ccode
);
268 static int32
wl_dongle_up(struct net_device
*ndev
, uint32 up
);
269 static int32
wl_dongle_power(struct net_device
*ndev
, uint32 power_mode
);
270 static int32
wl_dongle_glom(struct net_device
*ndev
, uint32 glom
,
271 uint32 dongle_align
);
272 static int32
wl_dongle_roam(struct net_device
*ndev
, uint32 roamvar
,
274 static int32
wl_dongle_eventmsg(struct net_device
*ndev
);
275 static int32
wl_dongle_scantime(struct net_device
*ndev
, int32 scan_assoc_time
,
276 int32 scan_unassoc_time
);
277 static int32
wl_dongle_offload(struct net_device
*ndev
, int32 arpoe
,
279 static int32
wl_pattern_atoh(s8
*src
, s8
*dst
);
280 static int32
wl_dongle_filter(struct net_device
*ndev
, uint32 filter_mode
);
281 static int32
wl_update_wiphybands(struct wl_priv
*wl
);
282 #endif /* !EMBEDDED_PLATFORM */
283 static int32
wl_config_dongle(struct wl_priv
*wl
, bool need_lock
);
288 static void wl_iscan_timer(unsigned long data
);
289 static void wl_term_iscan(struct wl_priv
*wl
);
290 static int32
wl_init_iscan(struct wl_priv
*wl
);
291 static int32
wl_iscan_thread(void *data
);
292 static int32
wl_dev_iovar_setbuf(struct net_device
*dev
, s8
*iovar
,
293 void *param
, int32 paramlen
, void *bufptr
,
295 static int32
wl_dev_iovar_getbuf(struct net_device
*dev
, s8
*iovar
,
296 void *param
, int32 paramlen
, void *bufptr
,
298 static int32
wl_run_iscan(struct wl_iscan_ctrl
*iscan
, struct wlc_ssid
*ssid
,
300 static int32
wl_do_iscan(struct wl_priv
*wl
);
301 static int32
wl_wakeup_iscan(struct wl_iscan_ctrl
*iscan
);
302 static int32
wl_invoke_iscan(struct wl_priv
*wl
);
303 static int32
wl_get_iscan_results(struct wl_iscan_ctrl
*iscan
, uint32
*status
,
304 struct wl_scan_results
**bss_list
);
305 static void wl_notify_iscan_complete(struct wl_iscan_ctrl
*iscan
, bool aborted
);
306 static void wl_init_iscan_eloop(struct wl_iscan_eloop
*el
);
307 static int32
wl_iscan_done(struct wl_priv
*wl
);
308 static int32
wl_iscan_pending(struct wl_priv
*wl
);
309 static int32
wl_iscan_inprogress(struct wl_priv
*wl
);
310 static int32
wl_iscan_aborted(struct wl_priv
*wl
);
313 ** fw/nvram downloading handler
315 static void wl_init_fw(struct wl_fw_ctrl
*fw
);
318 * find most significant bit set
320 static __used uint32
wl_find_msb(uint16 bit16
);
323 * update pmklist to dongle
325 static __used int32
wl_update_pmklist(struct net_device
*dev
,
326 struct wl_pmk_list
*pmk_list
, int32 err
);
328 #define WL_PRIV_GET() \
330 struct wl_iface *ci; \
331 if (unlikely(!(wl_cfg80211_dev && \
332 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
333 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
339 #define CHECK_SYS_UP() \
341 struct wl_priv *wl = wiphy_to_wl(wiphy); \
342 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
343 WL_INFO(("device is not ready : status (%d)\n", \
349 extern int dhd_wait_pend8021x(struct net_device
*dev
);
351 #if (WL_DBG_LEVEL > 0)
352 #define WL_DBG_ESTR_MAX 32
353 static s8 wl_dbg_estr
[][WL_DBG_ESTR_MAX
] = {
354 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
355 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
356 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
357 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
358 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
359 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
360 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
362 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
364 "RADIO", "PSM_WATCHDOG",
366 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
367 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
368 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
370 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
372 #endif /* WL_DBG_LEVEL */
374 #define CHAN2G(_channel, _freq, _flags) { \
375 .band = IEEE80211_BAND_2GHZ, \
376 .center_freq = (_freq), \
377 .hw_value = (_channel), \
379 .max_antenna_gain = 0, \
383 #define CHAN5G(_channel, _flags) { \
384 .band = IEEE80211_BAND_5GHZ, \
385 .center_freq = 5000 + (5 * (_channel)), \
386 .hw_value = (_channel), \
388 .max_antenna_gain = 0, \
392 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
393 #define RATETAB_ENT(_rateid, _flags) \
395 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
396 .hw_value = (_rateid), \
400 static struct ieee80211_rate __wl_rates
[] = {
401 RATETAB_ENT(WLC_RATE_1M
, 0),
402 RATETAB_ENT(WLC_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
403 RATETAB_ENT(WLC_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
404 RATETAB_ENT(WLC_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
405 RATETAB_ENT(WLC_RATE_6M
, 0),
406 RATETAB_ENT(WLC_RATE_9M
, 0),
407 RATETAB_ENT(WLC_RATE_12M
, 0),
408 RATETAB_ENT(WLC_RATE_18M
, 0),
409 RATETAB_ENT(WLC_RATE_24M
, 0),
410 RATETAB_ENT(WLC_RATE_36M
, 0),
411 RATETAB_ENT(WLC_RATE_48M
, 0),
412 RATETAB_ENT(WLC_RATE_54M
, 0),
415 #define wl_a_rates (__wl_rates + 4)
416 #define wl_a_rates_size 8
417 #define wl_g_rates (__wl_rates + 0)
418 #define wl_g_rates_size 12
420 static struct ieee80211_channel __wl_2ghz_channels
[] = {
437 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
438 CHAN5G(34, 0), CHAN5G(36, 0),
439 CHAN5G(38, 0), CHAN5G(40, 0),
440 CHAN5G(42, 0), CHAN5G(44, 0),
441 CHAN5G(46, 0), CHAN5G(48, 0),
442 CHAN5G(52, 0), CHAN5G(56, 0),
443 CHAN5G(60, 0), CHAN5G(64, 0),
444 CHAN5G(100, 0), CHAN5G(104, 0),
445 CHAN5G(108, 0), CHAN5G(112, 0),
446 CHAN5G(116, 0), CHAN5G(120, 0),
447 CHAN5G(124, 0), CHAN5G(128, 0),
448 CHAN5G(132, 0), CHAN5G(136, 0),
449 CHAN5G(140, 0), CHAN5G(149, 0),
450 CHAN5G(153, 0), CHAN5G(157, 0),
451 CHAN5G(161, 0), CHAN5G(165, 0),
452 CHAN5G(184, 0), CHAN5G(188, 0),
453 CHAN5G(192, 0), CHAN5G(196, 0),
454 CHAN5G(200, 0), CHAN5G(204, 0),
455 CHAN5G(208, 0), CHAN5G(212, 0),
459 static struct ieee80211_channel __wl_5ghz_n_channels
[] = {
460 CHAN5G(32, 0), CHAN5G(34, 0),
461 CHAN5G(36, 0), CHAN5G(38, 0),
462 CHAN5G(40, 0), CHAN5G(42, 0),
463 CHAN5G(44, 0), CHAN5G(46, 0),
464 CHAN5G(48, 0), CHAN5G(50, 0),
465 CHAN5G(52, 0), CHAN5G(54, 0),
466 CHAN5G(56, 0), CHAN5G(58, 0),
467 CHAN5G(60, 0), CHAN5G(62, 0),
468 CHAN5G(64, 0), CHAN5G(66, 0),
469 CHAN5G(68, 0), CHAN5G(70, 0),
470 CHAN5G(72, 0), CHAN5G(74, 0),
471 CHAN5G(76, 0), CHAN5G(78, 0),
472 CHAN5G(80, 0), CHAN5G(82, 0),
473 CHAN5G(84, 0), CHAN5G(86, 0),
474 CHAN5G(88, 0), CHAN5G(90, 0),
475 CHAN5G(92, 0), CHAN5G(94, 0),
476 CHAN5G(96, 0), CHAN5G(98, 0),
477 CHAN5G(100, 0), CHAN5G(102, 0),
478 CHAN5G(104, 0), CHAN5G(106, 0),
479 CHAN5G(108, 0), CHAN5G(110, 0),
480 CHAN5G(112, 0), CHAN5G(114, 0),
481 CHAN5G(116, 0), CHAN5G(118, 0),
482 CHAN5G(120, 0), CHAN5G(122, 0),
483 CHAN5G(124, 0), CHAN5G(126, 0),
484 CHAN5G(128, 0), CHAN5G(130, 0),
485 CHAN5G(132, 0), CHAN5G(134, 0),
486 CHAN5G(136, 0), CHAN5G(138, 0),
487 CHAN5G(140, 0), CHAN5G(142, 0),
488 CHAN5G(144, 0), CHAN5G(145, 0),
489 CHAN5G(146, 0), CHAN5G(147, 0),
490 CHAN5G(148, 0), CHAN5G(149, 0),
491 CHAN5G(150, 0), CHAN5G(151, 0),
492 CHAN5G(152, 0), CHAN5G(153, 0),
493 CHAN5G(154, 0), CHAN5G(155, 0),
494 CHAN5G(156, 0), CHAN5G(157, 0),
495 CHAN5G(158, 0), CHAN5G(159, 0),
496 CHAN5G(160, 0), CHAN5G(161, 0),
497 CHAN5G(162, 0), CHAN5G(163, 0),
498 CHAN5G(164, 0), CHAN5G(165, 0),
499 CHAN5G(166, 0), CHAN5G(168, 0),
500 CHAN5G(170, 0), CHAN5G(172, 0),
501 CHAN5G(174, 0), CHAN5G(176, 0),
502 CHAN5G(178, 0), CHAN5G(180, 0),
503 CHAN5G(182, 0), CHAN5G(184, 0),
504 CHAN5G(186, 0), CHAN5G(188, 0),
505 CHAN5G(190, 0), CHAN5G(192, 0),
506 CHAN5G(194, 0), CHAN5G(196, 0),
507 CHAN5G(198, 0), CHAN5G(200, 0),
508 CHAN5G(202, 0), CHAN5G(204, 0),
509 CHAN5G(206, 0), CHAN5G(208, 0),
510 CHAN5G(210, 0), CHAN5G(212, 0),
511 CHAN5G(214, 0), CHAN5G(216, 0),
512 CHAN5G(218, 0), CHAN5G(220, 0),
513 CHAN5G(222, 0), CHAN5G(224, 0),
514 CHAN5G(226, 0), CHAN5G(228, 0),
517 static struct ieee80211_supported_band __wl_band_2ghz
= {
518 .band
= IEEE80211_BAND_2GHZ
,
519 .channels
= __wl_2ghz_channels
,
520 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
521 .bitrates
= wl_g_rates
,
522 .n_bitrates
= wl_g_rates_size
,
525 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
526 .band
= IEEE80211_BAND_5GHZ
,
527 .channels
= __wl_5ghz_a_channels
,
528 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
529 .bitrates
= wl_a_rates
,
530 .n_bitrates
= wl_a_rates_size
,
533 static struct ieee80211_supported_band __wl_band_5ghz_n
= {
534 .band
= IEEE80211_BAND_5GHZ
,
535 .channels
= __wl_5ghz_n_channels
,
536 .n_channels
= ARRAY_SIZE(__wl_5ghz_n_channels
),
537 .bitrates
= wl_a_rates
,
538 .n_bitrates
= wl_a_rates_size
,
541 static const uint32 __wl_cipher_suites
[] = {
542 WLAN_CIPHER_SUITE_WEP40
,
543 WLAN_CIPHER_SUITE_WEP104
,
544 WLAN_CIPHER_SUITE_TKIP
,
545 WLAN_CIPHER_SUITE_CCMP
,
546 WLAN_CIPHER_SUITE_AES_CMAC
,
549 static void swap_key_from_BE(struct wl_wsec_key
*key
)
551 key
->index
= htod32(key
->index
);
552 key
->len
= htod32(key
->len
);
553 key
->algo
= htod32(key
->algo
);
554 key
->flags
= htod32(key
->flags
);
555 key
->rxiv
.hi
= htod32(key
->rxiv
.hi
);
556 key
->rxiv
.lo
= htod16(key
->rxiv
.lo
);
557 key
->iv_initialized
= htod32(key
->iv_initialized
);
560 static void swap_key_to_BE(struct wl_wsec_key
*key
)
562 key
->index
= dtoh32(key
->index
);
563 key
->len
= dtoh32(key
->len
);
564 key
->algo
= dtoh32(key
->algo
);
565 key
->flags
= dtoh32(key
->flags
);
566 key
->rxiv
.hi
= dtoh32(key
->rxiv
.hi
);
567 key
->rxiv
.lo
= dtoh16(key
->rxiv
.lo
);
568 key
->iv_initialized
= dtoh32(key
->iv_initialized
);
572 wl_dev_ioctl(struct net_device
*dev
, uint32 cmd
, void *arg
, uint32 len
)
579 memset(&ioc
, 0, sizeof(ioc
));
583 strcpy(ifr
.ifr_name
, dev
->name
);
584 ifr
.ifr_data
= (caddr_t
)&ioc
;
588 err
= dev
->netdev_ops
->ndo_do_ioctl(dev
, &ifr
, SIOCDEVPRIVATE
);
595 wl_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
596 enum nl80211_iftype type
, uint32
*flags
,
597 struct vif_params
*params
)
599 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
600 struct wireless_dev
*wdev
;
607 case NL80211_IFTYPE_MONITOR
:
608 case NL80211_IFTYPE_WDS
:
609 WL_ERR(("type (%d) : currently we do not support this type\n",
612 case NL80211_IFTYPE_ADHOC
:
613 wl
->conf
->mode
= WL_MODE_IBSS
;
615 case NL80211_IFTYPE_STATION
:
616 wl
->conf
->mode
= WL_MODE_BSS
;
622 infra
= htod32(infra
);
624 wdev
= ndev
->ieee80211_ptr
;
626 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev
->name
, ap
, infra
));
628 ((err
= wl_dev_ioctl(ndev
, WLC_SET_INFRA
, &infra
, sizeof(infra
))))
630 unlikely((err
= wl_dev_ioctl(ndev
, WLC_SET_AP
, &ap
, sizeof(ap
))))) {
631 WL_ERR(("Error (%d)\n", err
));
634 /* -EINPROGRESS: Call commit handler */
638 static void wl_iscan_prep(struct wl_scan_params
*params
, struct wlc_ssid
*ssid
)
640 memcpy(¶ms
->bssid
, ðer_bcast
, ETHER_ADDR_LEN
);
641 params
->bss_type
= DOT11_BSSTYPE_ANY
;
642 params
->scan_type
= 0;
643 params
->nprobes
= -1;
644 params
->active_time
= -1;
645 params
->passive_time
= -1;
646 params
->home_time
= -1;
647 params
->channel_num
= 0;
649 params
->nprobes
= htod32(params
->nprobes
);
650 params
->active_time
= htod32(params
->active_time
);
651 params
->passive_time
= htod32(params
->passive_time
);
652 params
->home_time
= htod32(params
->home_time
);
653 if (ssid
&& ssid
->SSID_len
)
654 memcpy(¶ms
->ssid
, ssid
, sizeof(wlc_ssid_t
));
659 wl_dev_iovar_setbuf(struct net_device
*dev
, s8
* iovar
, void *param
,
660 int32 paramlen
, void *bufptr
, int32 buflen
)
664 iolen
= bcm_mkiovar(iovar
, param
, paramlen
, bufptr
, buflen
);
665 BUG_ON(unlikely(!iolen
));
667 return wl_dev_ioctl(dev
, WLC_SET_VAR
, bufptr
, iolen
);
671 wl_dev_iovar_getbuf(struct net_device
*dev
, s8
* iovar
, void *param
,
672 int32 paramlen
, void *bufptr
, int32 buflen
)
676 iolen
= bcm_mkiovar(iovar
, param
, paramlen
, bufptr
, buflen
);
677 BUG_ON(unlikely(!iolen
));
679 return wl_dev_ioctl(dev
, WLC_GET_VAR
, bufptr
, buflen
);
683 wl_run_iscan(struct wl_iscan_ctrl
*iscan
, struct wlc_ssid
*ssid
, uint16 action
)
686 (WL_SCAN_PARAMS_FIXED_SIZE
+ OFFSETOF(wl_iscan_params_t
, params
));
687 struct wl_iscan_params
*params
;
690 if (ssid
&& ssid
->SSID_len
)
691 params_size
+= sizeof(struct wlc_ssid
);
692 params
= (struct wl_iscan_params
*)kzalloc(params_size
, GFP_KERNEL
);
693 if (unlikely(!params
))
695 memset(params
, 0, params_size
);
696 BUG_ON(unlikely(params_size
>= WLC_IOCTL_SMLEN
));
698 wl_iscan_prep(¶ms
->params
, ssid
);
700 params
->version
= htod32(ISCAN_REQ_VERSION
);
701 params
->action
= htod16(action
);
702 params
->scan_duration
= htod16(0);
704 /* params_size += OFFSETOF(wl_iscan_params_t, params); */
707 wl_dev_iovar_setbuf(iscan
->dev
, "iscan", params
, params_size
,
708 iscan
->ioctl_buf
, WLC_IOCTL_SMLEN
)))) {
710 WL_INFO(("system busy : iscan canceled\n"));
712 WL_ERR(("error (%d)\n", err
));
719 static int32
wl_do_iscan(struct wl_priv
*wl
)
721 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
722 struct wlc_ssid ssid
;
725 /* Broadcast scan by default */
726 memset(&ssid
, 0, sizeof(ssid
));
728 iscan
->state
= WL_ISCAN_STATE_SCANING
;
730 if (wl
->active_scan
) {
731 int32 passive_scan
= 0;
732 /* make it active scan */
735 wl_dev_ioctl(wl_to_ndev(wl
), WLC_SET_PASSIVE_SCAN
,
736 &passive_scan
, sizeof(passive_scan
))))) {
737 WL_DBG(("error (%d)\n", err
));
741 wl
->iscan_kickstart
= TRUE
;
742 wl_run_iscan(iscan
, &ssid
, WL_SCAN_ACTION_START
);
743 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
750 __wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
751 struct cfg80211_scan_request
*request
,
752 struct cfg80211_ssid
*this_ssid
)
754 struct wl_priv
*wl
= ndev_to_wl(ndev
);
755 struct cfg80211_ssid
*ssids
;
756 struct wl_scan_req
*sr
= wl_to_sr(wl
);
761 if (unlikely(test_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
762 WL_ERR(("Scanning already : status (%d)\n", (int)wl
->status
));
765 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
))) {
766 WL_ERR(("Scanning being aborted : status (%d)\n",
773 if (request
) { /* scan bss */
774 ssids
= request
->ssids
;
775 if (wl
->iscan_on
&& (!ssids
|| !ssids
->ssid_len
)) { /* for
777 * ssids->ssid_len has
778 * non-zero(ssid string)
780 * Otherwise this is 0.
781 * we do not iscan for
782 * specific scan request
786 } else { /* scan in ibss */
787 /* we don't do iscan in ibss */
790 wl
->scan_request
= request
;
791 set_bit(WL_STATUS_SCANNING
, &wl
->status
);
793 if (likely(!(err
= wl_do_iscan(wl
))))
798 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
799 ssids
->ssid
, ssids
->ssid_len
));
800 memset(&sr
->ssid
, 0, sizeof(sr
->ssid
));
802 MIN(sizeof(sr
->ssid
.SSID
), ssids
->ssid_len
);
803 if (sr
->ssid
.SSID_len
) {
804 memcpy(sr
->ssid
.SSID
, ssids
->ssid
, sr
->ssid
.SSID_len
);
805 sr
->ssid
.SSID_len
= htod32(sr
->ssid
.SSID_len
);
806 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
807 sr
->ssid
.SSID
, sr
->ssid
.SSID_len
));
810 WL_DBG(("Broadcast scan\n"));
812 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr
->ssid
.SSID_len
));
813 if (wl
->active_scan
) {
814 int32 pssive_scan
= 0;
815 /* make it active scan */
818 wl_dev_ioctl(ndev
, WLC_SET_PASSIVE_SCAN
,
820 sizeof(pssive_scan
))))) {
821 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n",
827 wl_dev_ioctl(ndev
, WLC_SCAN
, &sr
->ssid
,
828 sizeof(sr
->ssid
)))) {
830 WL_INFO(("system busy : scan for \"%s\" "
831 "canceled\n", sr
->ssid
.SSID
));
833 WL_ERR(("WLC_SCAN error (%d)\n", err
));
842 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
843 wl
->scan_request
= NULL
;
848 wl_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
849 struct cfg80211_scan_request
*request
)
854 if (unlikely((err
= __wl_cfg80211_scan(wiphy
, ndev
, request
, NULL
)))) {
855 WL_DBG(("scan error (%d)\n", err
));
862 static int32
wl_dev_intvar_set(struct net_device
*dev
, s8
*name
, int32 val
)
864 s8 buf
[WLC_IOCTL_SMLEN
];
869 len
= bcm_mkiovar(name
, (char *)(&val
), sizeof(val
), buf
, sizeof(buf
));
870 BUG_ON(unlikely(!len
));
872 if (unlikely((err
= wl_dev_ioctl(dev
, WLC_SET_VAR
, buf
, len
)))) {
873 WL_ERR(("error (%d)\n", err
));
880 wl_dev_intvar_get(struct net_device
*dev
, s8
*name
, int32
*retval
)
883 s8 buf
[WLC_IOCTL_SMLEN
];
891 bcm_mkiovar(name
, (char *)(&data_null
), 0, (char *)(&var
),
893 BUG_ON(unlikely(!len
));
894 if (unlikely((err
= wl_dev_ioctl(dev
, WLC_GET_VAR
, &var
, len
)))) {
895 WL_ERR(("error (%d)\n", err
));
897 *retval
= dtoh32(var
.val
);
902 static int32
wl_set_rts(struct net_device
*dev
, uint32 rts_threshold
)
907 ((err
= wl_dev_intvar_set(dev
, "rtsthresh", rts_threshold
)))) {
908 WL_ERR(("Error (%d)\n", err
));
914 static int32
wl_set_frag(struct net_device
*dev
, uint32 frag_threshold
)
919 ((err
= wl_dev_intvar_set(dev
, "fragthresh", frag_threshold
)))) {
920 WL_ERR(("Error (%d)\n", err
));
926 static int32
wl_set_retry(struct net_device
*dev
, uint32 retry
, bool l
)
929 uint32 cmd
= (l
? WLC_SET_LRL
: WLC_SET_SRL
);
931 retry
= htod32(retry
);
932 if (unlikely((err
= wl_dev_ioctl(dev
, cmd
, &retry
, sizeof(retry
))))) {
933 WL_ERR(("cmd (%d) , error (%d)\n", cmd
, err
));
939 static int32
wl_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, uint32 changed
)
941 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
942 struct net_device
*ndev
= wl_to_ndev(wl
);
946 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
947 (wl
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
948 wl
->conf
->rts_threshold
= wiphy
->rts_threshold
;
949 if (!(err
= wl_set_rts(ndev
, wl
->conf
->rts_threshold
)))
952 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
953 (wl
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
954 wl
->conf
->frag_threshold
= wiphy
->frag_threshold
;
955 if (!(err
= wl_set_frag(ndev
, wl
->conf
->frag_threshold
)))
958 if (changed
& WIPHY_PARAM_RETRY_LONG
959 && (wl
->conf
->retry_long
!= wiphy
->retry_long
)) {
960 wl
->conf
->retry_long
= wiphy
->retry_long
;
961 if (!(err
= wl_set_retry(ndev
, wl
->conf
->retry_long
, TRUE
)))
964 if (changed
& WIPHY_PARAM_RETRY_SHORT
965 && (wl
->conf
->retry_short
!= wiphy
->retry_short
)) {
966 wl
->conf
->retry_short
= wiphy
->retry_short
;
967 if (!(err
= wl_set_retry(ndev
, wl
->conf
->retry_short
, FALSE
))) {
976 wl_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
977 struct cfg80211_ibss_params
*params
)
979 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
980 struct cfg80211_bss
*bss
;
981 struct ieee80211_channel
*chan
;
982 struct wl_join_params join_params
;
983 struct cfg80211_ssid ssid
;
984 int32 scan_retry
= 0;
989 WL_ERR(("Invalid bssid\n"));
992 bss
= cfg80211_get_ibss(wiphy
, NULL
, params
->ssid
, params
->ssid_len
);
994 memcpy(ssid
.ssid
, params
->ssid
, params
->ssid_len
);
995 ssid
.ssid_len
= params
->ssid_len
;
998 (__wl_cfg80211_scan(wiphy
, dev
, NULL
, &ssid
) ==
1004 } while (++scan_retry
< WL_SCAN_RETRY_MAX
);
1005 rtnl_unlock(); /* to allow scan_inform to paropagate
1006 to cfg80211 plane */
1007 schedule_timeout_interruptible(4 * HZ
); /* wait 4 secons
1008 till scan done.... */
1010 bss
= cfg80211_get_ibss(wiphy
, NULL
,
1011 params
->ssid
, params
->ssid_len
);
1014 wl
->ibss_starter
= FALSE
;
1015 WL_DBG(("Found IBSS\n"));
1017 wl
->ibss_starter
= TRUE
;
1019 if ((chan
= params
->channel
))
1020 wl
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
1022 ** Join with specific BSSID and cached SSID
1023 ** If SSID is zero join based on BSSID only
1025 memset(&join_params
, 0, sizeof(join_params
));
1026 memcpy((void *)join_params
.ssid
.SSID
, (void *)params
->ssid
,
1028 join_params
.ssid
.SSID_len
= htod32(params
->ssid_len
);
1030 memcpy(&join_params
.params
.bssid
, params
->bssid
,
1033 memset(&join_params
.params
.bssid
, 0, ETHER_ADDR_LEN
);
1037 wl_dev_ioctl(dev
, WLC_SET_SSID
, &join_params
,
1038 sizeof(join_params
))))) {
1039 WL_ERR(("Error (%d)\n", err
));
1045 static int32
wl_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
1047 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1057 wl_set_wpa_version(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1059 struct wl_priv
*wl
= ndev_to_wl(dev
);
1060 struct wl_security
*sec
;
1064 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1065 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1066 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1067 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1069 val
= WPA_AUTH_DISABLED
;
1070 WL_DBG(("setting wpa_auth to 0x%0x\n", val
));
1071 if (unlikely((err
= wl_dev_intvar_set(dev
, "wpa_auth", val
)))) {
1072 WL_ERR(("set wpa_auth failed (%d)\n", err
));
1075 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1076 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1081 wl_set_auth_type(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1083 struct wl_priv
*wl
= ndev_to_wl(dev
);
1084 struct wl_security
*sec
;
1088 switch (sme
->auth_type
) {
1089 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1091 WL_DBG(("open system\n"));
1093 case NL80211_AUTHTYPE_SHARED_KEY
:
1095 WL_DBG(("shared key\n"));
1097 case NL80211_AUTHTYPE_AUTOMATIC
:
1099 WL_DBG(("automatic\n"));
1101 case NL80211_AUTHTYPE_NETWORK_EAP
:
1102 WL_DBG(("network eap\n"));
1105 WL_ERR(("invalid auth type (%d)\n", sme
->auth_type
));
1109 if (unlikely((err
= wl_dev_intvar_set(dev
, "auth", val
)))) {
1110 WL_ERR(("set auth failed (%d)\n", err
));
1113 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1114 sec
->auth_type
= sme
->auth_type
;
1119 wl_set_set_cipher(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1121 struct wl_priv
*wl
= ndev_to_wl(dev
);
1122 struct wl_security
*sec
;
1127 if (sme
->crypto
.n_ciphers_pairwise
) {
1128 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1129 case WLAN_CIPHER_SUITE_WEP40
:
1130 case WLAN_CIPHER_SUITE_WEP104
:
1133 case WLAN_CIPHER_SUITE_TKIP
:
1134 pval
= TKIP_ENABLED
;
1136 case WLAN_CIPHER_SUITE_CCMP
:
1139 case WLAN_CIPHER_SUITE_AES_CMAC
:
1143 WL_ERR(("invalid cipher pairwise (%d)\n",
1144 sme
->crypto
.ciphers_pairwise
[0]));
1148 if (sme
->crypto
.cipher_group
) {
1149 switch (sme
->crypto
.cipher_group
) {
1150 case WLAN_CIPHER_SUITE_WEP40
:
1151 case WLAN_CIPHER_SUITE_WEP104
:
1154 case WLAN_CIPHER_SUITE_TKIP
:
1155 gval
= TKIP_ENABLED
;
1157 case WLAN_CIPHER_SUITE_CCMP
:
1160 case WLAN_CIPHER_SUITE_AES_CMAC
:
1164 WL_ERR(("invalid cipher group (%d)\n",
1165 sme
->crypto
.cipher_group
));
1170 WL_DBG(("pval (%d) gval (%d)\n", pval
, gval
));
1171 if (unlikely((err
= wl_dev_intvar_set(dev
, "wsec", pval
| gval
)))) {
1172 WL_ERR(("error (%d)\n", err
));
1176 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1177 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1178 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1184 wl_set_key_mgmt(struct net_device
*dev
, struct cfg80211_connect_params
*sme
)
1186 struct wl_priv
*wl
= ndev_to_wl(dev
);
1187 struct wl_security
*sec
;
1191 if (sme
->crypto
.n_akm_suites
) {
1192 if (unlikely((err
= wl_dev_intvar_get(dev
, "wpa_auth", &val
)))) {
1193 WL_ERR(("could not get wpa_auth (%d)\n", err
));
1196 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1197 switch (sme
->crypto
.akm_suites
[0]) {
1198 case WLAN_AKM_SUITE_8021X
:
1199 val
= WPA_AUTH_UNSPECIFIED
;
1201 case WLAN_AKM_SUITE_PSK
:
1205 WL_ERR(("invalid cipher group (%d)\n",
1206 sme
->crypto
.cipher_group
));
1209 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1210 switch (sme
->crypto
.akm_suites
[0]) {
1211 case WLAN_AKM_SUITE_8021X
:
1212 val
= WPA2_AUTH_UNSPECIFIED
;
1214 case WLAN_AKM_SUITE_PSK
:
1215 val
= WPA2_AUTH_PSK
;
1218 WL_ERR(("invalid cipher group (%d)\n",
1219 sme
->crypto
.cipher_group
));
1224 WL_DBG(("setting wpa_auth to %d\n", val
));
1225 if (unlikely((err
= wl_dev_intvar_set(dev
, "wpa_auth", val
)))) {
1226 WL_ERR(("could not set wpa_auth (%d)\n", err
));
1230 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1231 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1237 wl_set_set_sharedkey(struct net_device
*dev
,
1238 struct cfg80211_connect_params
*sme
)
1240 struct wl_priv
*wl
= ndev_to_wl(dev
);
1241 struct wl_security
*sec
;
1242 struct wl_wsec_key key
;
1246 WL_DBG(("key len (%d)\n", sme
->key_len
));
1248 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1249 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1250 sec
->wpa_versions
, sec
->cipher_pairwise
));
1252 (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
|
1253 NL80211_WPA_VERSION_2
))
1254 && (sec
->cipher_pairwise
& (WLAN_CIPHER_SUITE_WEP40
|
1255 WLAN_CIPHER_SUITE_WEP104
))) {
1256 memset(&key
, 0, sizeof(key
));
1257 key
.len
= (uint32
) sme
->key_len
;
1258 key
.index
= (uint32
) sme
->key_idx
;
1259 if (unlikely(key
.len
> sizeof(key
.data
))) {
1260 WL_ERR(("Too long key length (%u)\n", key
.len
));
1263 memcpy(key
.data
, sme
->key
, key
.len
);
1264 key
.flags
= WL_PRIMARY_KEY
;
1265 switch (sec
->cipher_pairwise
) {
1266 case WLAN_CIPHER_SUITE_WEP40
:
1267 key
.algo
= CRYPTO_ALGO_WEP1
;
1269 case WLAN_CIPHER_SUITE_WEP104
:
1270 key
.algo
= CRYPTO_ALGO_WEP128
;
1273 WL_ERR(("Invalid algorithm (%d)\n",
1274 sme
->crypto
.ciphers_pairwise
[0]));
1277 /* Set the new key/index */
1278 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1279 key
.len
, key
.index
, key
.algo
));
1280 WL_DBG(("key \"%s\"\n", key
.data
));
1281 swap_key_from_BE(&key
);
1284 wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
,
1286 WL_ERR(("WLC_SET_KEY error (%d)\n", err
));
1289 if (sec
->auth_type
== NL80211_AUTHTYPE_OPEN_SYSTEM
) {
1290 WL_DBG(("set auth_type to shared key\n"));
1291 val
= 1; /* shared key */
1294 wl_dev_intvar_set(dev
, "auth", val
)))) {
1295 WL_ERR(("set auth failed (%d)\n", err
));
1305 wl_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
1306 struct cfg80211_connect_params
*sme
)
1308 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1309 struct ieee80211_channel
*chan
= sme
->channel
;
1310 struct wlc_ssid ssid
;
1314 if (unlikely(!sme
->ssid
)) {
1315 WL_ERR(("Invalid ssid\n"));
1319 wl
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
1320 WL_DBG(("channel (%d), center_req (%d)\n", wl
->channel
,
1321 chan
->center_freq
));
1323 WL_DBG(("ie (%p), ie_len (%d)\n", sme
->ie
, sme
->ie_len
));
1324 if (unlikely((err
= wl_set_wpa_version(dev
, sme
))))
1327 if (unlikely((err
= wl_set_auth_type(dev
, sme
))))
1330 if (unlikely((err
= wl_set_set_cipher(dev
, sme
))))
1333 if (unlikely((err
= wl_set_key_mgmt(dev
, sme
))))
1336 if (unlikely((err
= wl_set_set_sharedkey(dev
, sme
))))
1339 wl_update_prof(wl
, NULL
, sme
->bssid
, WL_PROF_BSSID
);
1341 ** Join with specific BSSID and cached SSID
1342 ** If SSID is zero join based on BSSID only
1344 memset(&ssid
, 0, sizeof(ssid
));
1345 ssid
.SSID_len
= MIN(sizeof(ssid
.SSID
), sme
->ssid_len
);
1346 memcpy(ssid
.SSID
, sme
->ssid
, ssid
.SSID_len
);
1347 ssid
.SSID_len
= htod32(ssid
.SSID_len
);
1348 wl_update_prof(wl
, NULL
, &ssid
, WL_PROF_SSID
);
1349 if (ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
) {
1350 WL_DBG(("ssid \"%s\", len (%d)\n", ssid
.SSID
, ssid
.SSID_len
));
1353 ((err
= wl_dev_ioctl(dev
, WLC_SET_SSID
, &ssid
, sizeof(ssid
))))) {
1354 WL_ERR(("error (%d)\n", err
));
1357 set_bit(WL_STATUS_CONNECTING
, &wl
->status
);
1363 wl_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
1366 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1371 WL_DBG(("Reason %d\n", reason_code
));
1373 if (likely((act
= *(bool *) wl_read_prof(wl
, WL_PROF_ACT
)))) {
1374 scbval
.val
= reason_code
;
1375 memcpy(&scbval
.ea
, &wl
->bssid
, ETHER_ADDR_LEN
);
1376 scbval
.val
= htod32(scbval
.val
);
1377 if (unlikely((err
= wl_dev_ioctl(dev
, WLC_DISASSOC
, &scbval
,
1378 sizeof(scb_val_t
))))) {
1379 WL_ERR(("error (%d)\n", err
));
1388 wl_cfg80211_set_tx_power(struct wiphy
*wiphy
,
1389 enum nl80211_tx_power_setting type
, int32 dbm
)
1392 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1393 struct net_device
*ndev
= wl_to_ndev(wl
);
1400 case NL80211_TX_POWER_AUTOMATIC
:
1402 case NL80211_TX_POWER_LIMITED
:
1404 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1408 case NL80211_TX_POWER_FIXED
:
1410 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1415 /* Make sure radio is off or on as far as software is concerned */
1416 disable
= WL_RADIO_SW_DISABLE
<< 16;
1417 disable
= htod32(disable
);
1420 wl_dev_ioctl(ndev
, WLC_SET_RADIO
, &disable
, sizeof(disable
))))) {
1421 WL_ERR(("WLC_SET_RADIO error (%d)\n", err
));
1428 txpwrmw
= (uint16
) dbm
;
1429 if (unlikely((err
= wl_dev_intvar_set(ndev
, "qtxpower",
1430 (int32
) (bcm_mw_to_qdbm
1432 WL_ERR(("qtxpower error (%d)\n", err
));
1435 wl
->conf
->tx_power
= dbm
;
1440 static int32
wl_cfg80211_get_tx_power(struct wiphy
*wiphy
, int32
*dbm
)
1442 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1443 struct net_device
*ndev
= wl_to_ndev(wl
);
1449 if (unlikely((err
= wl_dev_intvar_get(ndev
, "qtxpower", &txpwrdbm
)))) {
1450 WL_ERR(("error (%d)\n", err
));
1453 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1454 *dbm
= (int32
) bcm_qdbm_to_mw(result
);
1460 wl_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1467 WL_DBG(("key index (%d)\n", key_idx
));
1471 (err
= wl_dev_ioctl(dev
, WLC_GET_WSEC
, &wsec
, sizeof(wsec
)))) {
1472 WL_ERR(("WLC_GET_WSEC error (%d)\n", err
));
1475 wsec
= dtoh32(wsec
);
1476 if (wsec
& WEP_ENABLED
) {
1477 /* Just select a new current key */
1478 index
= (uint32
) key_idx
;
1479 index
= htod32(index
);
1480 if (unlikely((err
= wl_dev_ioctl(dev
, WLC_SET_KEY_PRIMARY
,
1481 &index
, sizeof(index
))))) {
1482 WL_ERR(("error (%d)\n", err
));
1489 wl_add_keyext(struct wiphy
*wiphy
, struct net_device
*dev
,
1490 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1492 struct wl_wsec_key key
;
1495 memset(&key
, 0, sizeof(key
));
1496 key
.index
= (uint32
) key_idx
;
1497 /* Instead of bcast for ea address for default wep keys,
1498 driver needs it to be Null */
1499 if (!ETHER_ISMULTI(mac_addr
))
1500 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETHER_ADDR_LEN
);
1501 key
.len
= (uint32
) params
->key_len
;
1502 /* check for key index change */
1505 swap_key_from_BE(&key
);
1508 wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
))))) {
1509 WL_ERR(("key delete error (%d)\n", err
));
1513 if (key
.len
> sizeof(key
.data
)) {
1514 WL_ERR(("Invalid key length (%d)\n", key
.len
));
1518 WL_DBG(("Setting the key index %d\n", key
.index
));
1519 memcpy(key
.data
, params
->key
, key
.len
);
1521 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1523 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1524 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1525 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1528 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1529 if (params
->seq
&& params
->seq_len
== 6) {
1532 ivptr
= (u8
*) params
->seq
;
1533 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1534 (ivptr
[3] << 8) | ivptr
[2];
1535 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1536 key
.iv_initialized
= TRUE
;
1539 switch (params
->cipher
) {
1540 case WLAN_CIPHER_SUITE_WEP40
:
1541 key
.algo
= CRYPTO_ALGO_WEP1
;
1542 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1544 case WLAN_CIPHER_SUITE_WEP104
:
1545 key
.algo
= CRYPTO_ALGO_WEP128
;
1546 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1548 case WLAN_CIPHER_SUITE_TKIP
:
1549 key
.algo
= CRYPTO_ALGO_TKIP
;
1550 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1552 case WLAN_CIPHER_SUITE_AES_CMAC
:
1553 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1554 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1556 case WLAN_CIPHER_SUITE_CCMP
:
1557 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1558 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1561 WL_ERR(("Invalid cipher (0x%x)\n", params
->cipher
));
1564 swap_key_from_BE(&key
);
1566 dhd_wait_pend8021x(dev
);
1569 wl_dev_ioctl(dev
, WLC_SET_KEY
, &key
, sizeof(key
))))) {
1570 WL_ERR(("WLC_SET_KEY error (%d)\n", err
));
1578 wl_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1579 u8 key_idx
, const u8
*mac_addr
,
1580 struct key_params
*params
)
1582 struct wl_wsec_key key
;
1587 WL_DBG(("key index (%d)\n", key_idx
));
1591 return wl_add_keyext(wiphy
, dev
, key_idx
, mac_addr
, params
);
1592 memset(&key
, 0, sizeof(key
));
1594 key
.len
= (uint32
) params
->key_len
;
1595 key
.index
= (uint32
) key_idx
;
1597 if (unlikely(key
.len
> sizeof(key
.data
))) {
1598 WL_ERR(("Too long key length (%u)\n", key
.len
));
1601 memcpy(key
.data
, params
->key
, key
.len
);
1603 key
.flags
= WL_PRIMARY_KEY
;
1604 switch (params
->cipher
) {
1605 case WLAN_CIPHER_SUITE_WEP40
:
1606 key
.algo
= CRYPTO_ALGO_WEP1
;
1607 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1609 case WLAN_CIPHER_SUITE_WEP104
:
1610 key
.algo
= CRYPTO_ALGO_WEP128
;
1611 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1613 case WLAN_CIPHER_SUITE_TKIP
:
1614 key
.algo
= CRYPTO_ALGO_TKIP
;
1615 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1617 case WLAN_CIPHER_SUITE_AES_CMAC
:
1618 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1619 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1621 case WLAN_CIPHER_SUITE_CCMP
:
1622 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1623 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1626 WL_ERR(("Invalid cipher (0x%x)\n", params
->cipher
));
1630 /* Set the new key/index */
1631 swap_key_from_BE(&key
);
1632 if (unlikely((err
= wl_dev_ioctl(dev
, WLC_SET_KEY
,
1633 &key
, sizeof(key
))))) {
1634 WL_ERR(("WLC_SET_KEY error (%d)\n", err
));
1639 if (unlikely((err
= wl_dev_intvar_get(dev
, "wsec", &wsec
)))) {
1640 WL_ERR(("get wsec error (%d)\n", err
));
1643 wsec
&= ~(WEP_ENABLED
);
1645 if (unlikely((err
= wl_dev_intvar_set(dev
, "wsec", wsec
)))) {
1646 WL_ERR(("set wsec error (%d)\n", err
));
1650 val
= 1; /* assume shared key. otherwise 0 */
1653 ((err
= wl_dev_ioctl(dev
, WLC_SET_AUTH
, &val
, sizeof(val
))))) {
1654 WL_ERR(("WLC_SET_AUTH error (%d)\n", err
));
1661 wl_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1662 u8 key_idx
, const u8
*mac_addr
)
1664 struct wl_wsec_key key
;
1670 memset(&key
, 0, sizeof(key
));
1672 key
.index
= (uint32
) key_idx
;
1673 key
.flags
= WL_PRIMARY_KEY
;
1674 key
.algo
= CRYPTO_ALGO_OFF
;
1676 WL_DBG(("key index (%d)\n", key_idx
));
1677 /* Set the new key/index */
1678 swap_key_from_BE(&key
);
1679 if (unlikely((err
= wl_dev_ioctl(dev
, WLC_SET_KEY
,
1680 &key
, sizeof(key
))))) {
1681 if (err
== -EINVAL
) {
1682 if (key
.index
>= DOT11_MAX_DEFAULT_KEYS
) {
1683 /* we ignore this key index in this case */
1684 WL_DBG(("invalid key index (%d)\n", key_idx
));
1687 WL_ERR(("WLC_SET_KEY error (%d)\n", err
));
1693 if (unlikely((err
= wl_dev_intvar_get(dev
, "wsec", &wsec
)))) {
1694 WL_ERR(("get wsec error (%d)\n", err
));
1697 wsec
&= ~(WEP_ENABLED
);
1699 if (unlikely((err
= wl_dev_intvar_set(dev
, "wsec", wsec
)))) {
1700 WL_ERR(("set wsec error (%d)\n", err
));
1704 val
= 0; /* assume open key. otherwise 1 */
1707 ((err
= wl_dev_ioctl(dev
, WLC_SET_AUTH
, &val
, sizeof(val
))))) {
1708 WL_ERR(("WLC_SET_AUTH error (%d)\n", err
));
1715 wl_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1716 u8 key_idx
, const u8
*mac_addr
, void *cookie
,
1717 void (*callback
) (void *cookie
, struct key_params
* params
))
1719 struct key_params params
;
1720 struct wl_wsec_key key
;
1721 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1722 struct wl_security
*sec
;
1726 WL_DBG(("key index (%d)\n", key_idx
));
1729 memset(&key
, 0, sizeof(key
));
1730 key
.index
= key_idx
;
1731 swap_key_to_BE(&key
);
1732 memset(¶ms
, 0, sizeof(params
));
1733 params
.key_len
= (u8
) MIN(DOT11_MAX_KEY_SIZE
, key
.len
);
1734 memcpy(params
.key
, key
.data
, params
.key_len
);
1737 (err
= wl_dev_ioctl(dev
, WLC_GET_WSEC
, &wsec
, sizeof(wsec
)))) {
1738 WL_ERR(("WLC_GET_WSEC error (%d)\n", err
));
1741 wsec
= dtoh32(wsec
);
1744 sec
= wl_read_prof(wl
, WL_PROF_SEC
);
1745 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
1746 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
1747 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1748 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
1749 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
1750 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1754 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
1755 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1758 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
1759 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1762 WL_ERR(("Invalid algo (0x%x)\n", wsec
));
1766 callback(cookie
, ¶ms
);
1771 wl_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
1772 struct net_device
*dev
, u8 key_idx
)
1774 WL_INFO(("Not supported\n"));
1780 wl_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1781 u8
*mac
, struct station_info
*sinfo
)
1783 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1791 (memcmp(mac
, wl_read_prof(wl
, WL_PROF_BSSID
), ETHER_ADDR_LEN
))) {
1792 WL_ERR(("Wrong Mac address\n"));
1796 /* Report the current tx rate */
1797 if ((err
= wl_dev_ioctl(dev
, WLC_GET_RATE
, &rate
, sizeof(rate
)))) {
1798 WL_ERR(("Could not get rate (%d)\n", err
));
1800 rate
= dtoh32(rate
);
1801 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1802 sinfo
->txrate
.legacy
= rate
* 5;
1803 WL_DBG(("Rate %d Mbps\n", (rate
/ 2)));
1806 if (test_bit(WL_STATUS_CONNECTED
, &wl
->status
)) {
1810 wl_dev_ioctl(dev
, WLC_GET_RSSI
, &scb_val
,
1811 sizeof(scb_val_t
)))) {
1812 WL_ERR(("Could not get rssi (%d)\n", err
));
1815 rssi
= dtoh32(scb_val
.val
);
1816 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1817 sinfo
->signal
= rssi
;
1818 WL_DBG(("RSSI %d dBm\n", rssi
));
1825 wl_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*dev
,
1826 bool enabled
, int32 timeout
)
1832 pm
= enabled
? PM_FAST
: PM_OFF
;
1834 WL_DBG(("power save %s\n", (pm
? "enabled" : "disabled")));
1835 if (unlikely((err
= wl_dev_ioctl(dev
, WLC_SET_PM
, &pm
, sizeof(pm
))))) {
1837 WL_DBG(("net_device is not ready yet\n"));
1839 WL_ERR(("error (%d)\n", err
));
1845 static __used uint32
wl_find_msb(uint16 bit16
)
1849 if (bit16
& 0xff00) {
1873 wl_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
, struct net_device
*dev
,
1875 const struct cfg80211_bitrate_mask
*mask
)
1877 struct wl_rateset rateset
;
1886 /* addr param is always NULL. ignore it */
1887 /* Get current rateset */
1888 if (unlikely((err
= wl_dev_ioctl(dev
, WLC_GET_CURR_RATESET
, &rateset
,
1889 sizeof(rateset
))))) {
1890 WL_ERR(("could not get current rateset (%d)\n", err
));
1894 rateset
.count
= dtoh32(rateset
.count
);
1896 if (!(legacy
= wl_find_msb(mask
->control
[IEEE80211_BAND_2GHZ
].legacy
)))
1897 legacy
= wl_find_msb(mask
->control
[IEEE80211_BAND_5GHZ
].legacy
);
1899 val
= wl_g_rates
[legacy
- 1].bitrate
* 100000;
1901 if (val
< rateset
.count
) {
1902 /* Select rate by rateset index */
1903 rate
= rateset
.rates
[val
] & 0x7f;
1905 /* Specified rate in bps */
1906 rate
= val
/ 500000;
1909 WL_DBG(("rate %d mbps\n", (rate
/ 2)));
1913 * Set rate override,
1914 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1916 err_bg
= wl_dev_intvar_set(dev
, "bg_rate", rate
);
1917 err_a
= wl_dev_intvar_set(dev
, "a_rate", rate
);
1918 if (unlikely(err_bg
&& err_a
)) {
1919 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg
, err_a
));
1920 return err_bg
| err_a
;
1926 static int32
wl_cfg80211_resume(struct wiphy
*wiphy
)
1931 wl_invoke_iscan(wiphy_to_wl(wiphy
));
1936 static int32
wl_cfg80211_suspend(struct wiphy
*wiphy
)
1938 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1943 set_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
1945 if (wl
->scan_request
) {
1946 cfg80211_scan_done(wl
->scan_request
, TRUE
); /* TRUE means
1948 wl
->scan_request
= NULL
;
1950 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
1951 clear_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
1957 wl_update_pmklist(struct net_device
*dev
, struct wl_pmk_list
*pmk_list
,
1960 s8 eabuf
[ETHER_ADDR_STR_LEN
];
1963 memset(eabuf
, 0, ETHER_ADDR_STR_LEN
);
1965 WL_DBG(("No of elements %d\n", pmk_list
->pmkids
.npmkid
));
1966 for (i
= 0; i
< pmk_list
->pmkids
.npmkid
; i
++) {
1967 WL_DBG(("PMKID[%d]: %s =\n", i
,
1968 bcm_ether_ntoa(&pmk_list
->pmkids
.pmkid
[i
].BSSID
,
1970 for (j
= 0; j
< WPA2_PMKID_LEN
; j
++) {
1971 WL_DBG(("%02x\n", pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]));
1975 err
= wl_dev_bufvar_set(dev
, "pmkid_info", (char *)pmk_list
,
1983 wl_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
1984 struct cfg80211_pmksa
*pmksa
)
1986 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
1987 s8 eabuf
[ETHER_ADDR_STR_LEN
];
1992 memset(eabuf
, 0, ETHER_ADDR_STR_LEN
);
1993 for (i
= 0; i
< wl
->pmk_list
->pmkids
.npmkid
; i
++)
1994 if (!memcmp(pmksa
->bssid
, &wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
1997 if (i
< WL_NUM_PMKIDS_MAX
) {
1998 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
, pmksa
->bssid
,
2000 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].PMKID
, pmksa
->pmkid
,
2002 if (i
== wl
->pmk_list
->pmkids
.npmkid
)
2003 wl
->pmk_list
->pmkids
.npmkid
++;
2007 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %s =\n",
2008 bcm_ether_ntoa(&wl
->pmk_list
->pmkids
.
2009 pmkid
[wl
->pmk_list
->pmkids
.npmkid
].BSSID
,
2011 for (i
= 0; i
< WPA2_PMKID_LEN
; i
++) {
2013 wl
->pmk_list
->pmkids
.pmkid
[wl
->pmk_list
->pmkids
.npmkid
].
2017 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2023 wl_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
2024 struct cfg80211_pmksa
*pmksa
)
2026 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2027 s8 eabuf
[ETHER_ADDR_STR_LEN
];
2028 struct _pmkid_list pmkid
;
2033 memset(eabuf
, 0, ETHER_ADDR_STR_LEN
);
2034 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETHER_ADDR_LEN
);
2035 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WPA2_PMKID_LEN
);
2037 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %s =\n",
2038 bcm_ether_ntoa(&pmkid
.pmkid
[0].BSSID
, eabuf
)));
2039 for (i
= 0; i
< WPA2_PMKID_LEN
; i
++) {
2040 WL_DBG(("%02x\n", pmkid
.pmkid
[0].PMKID
[i
]));
2043 for (i
= 0; i
< wl
->pmk_list
->pmkids
.npmkid
; i
++)
2045 (pmksa
->bssid
, &wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2049 if ((wl
->pmk_list
->pmkids
.npmkid
> 0)
2050 && (i
< wl
->pmk_list
->pmkids
.npmkid
)) {
2051 memset(&wl
->pmk_list
->pmkids
.pmkid
[i
], 0, sizeof(pmkid_t
));
2052 for (; i
< (wl
->pmk_list
->pmkids
.npmkid
- 1); i
++) {
2053 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2054 &wl
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2056 memcpy(&wl
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2057 &wl
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2060 wl
->pmk_list
->pmkids
.npmkid
--;
2065 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2072 wl_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
)
2074 struct wl_priv
*wl
= wiphy_to_wl(wiphy
);
2078 memset(wl
->pmk_list
, 0, sizeof(*wl
->pmk_list
));
2079 err
= wl_update_pmklist(dev
, wl
->pmk_list
, err
);
2084 static struct cfg80211_ops wl_cfg80211_ops
= {
2085 .change_virtual_intf
= wl_cfg80211_change_iface
,
2086 .scan
= wl_cfg80211_scan
,
2087 .set_wiphy_params
= wl_cfg80211_set_wiphy_params
,
2088 .join_ibss
= wl_cfg80211_join_ibss
,
2089 .leave_ibss
= wl_cfg80211_leave_ibss
,
2090 .get_station
= wl_cfg80211_get_station
,
2091 .set_tx_power
= wl_cfg80211_set_tx_power
,
2092 .get_tx_power
= wl_cfg80211_get_tx_power
,
2093 .add_key
= wl_cfg80211_add_key
,
2094 .del_key
= wl_cfg80211_del_key
,
2095 .get_key
= wl_cfg80211_get_key
,
2096 .set_default_key
= wl_cfg80211_config_default_key
,
2097 .set_default_mgmt_key
= wl_cfg80211_config_default_mgmt_key
,
2098 .set_power_mgmt
= wl_cfg80211_set_power_mgmt
,
2099 .set_bitrate_mask
= wl_cfg80211_set_bitrate_mask
,
2100 .connect
= wl_cfg80211_connect
,
2101 .disconnect
= wl_cfg80211_disconnect
,
2102 .suspend
= wl_cfg80211_suspend
,
2103 .resume
= wl_cfg80211_resume
,
2104 .set_pmksa
= wl_cfg80211_set_pmksa
,
2105 .del_pmksa
= wl_cfg80211_del_pmksa
,
2106 .flush_pmksa
= wl_cfg80211_flush_pmksa
2109 static int32
wl_mode_to_nl80211_iftype(int32 mode
)
2115 return NL80211_IFTYPE_STATION
;
2117 return NL80211_IFTYPE_ADHOC
;
2119 return NL80211_IFTYPE_UNSPECIFIED
;
2125 static struct wireless_dev
*wl_alloc_wdev(int32 sizeof_iface
,
2128 struct wireless_dev
*wdev
;
2131 wdev
= kzalloc(sizeof(*wdev
), GFP_KERNEL
);
2132 if (unlikely(!wdev
)) {
2133 WL_ERR(("Could not allocate wireless device\n"));
2134 return ERR_PTR(-ENOMEM
);
2137 wiphy_new(&wl_cfg80211_ops
, sizeof(struct wl_priv
) + sizeof_iface
);
2138 if (unlikely(!wdev
->wiphy
)) {
2139 WL_ERR(("Couldn not allocate wiphy device\n"));
2143 set_wiphy_dev(wdev
->wiphy
, dev
);
2144 wdev
->wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
2145 wdev
->wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
2146 wdev
->wiphy
->interface_modes
=
2147 BIT(NL80211_IFTYPE_STATION
) | BIT(NL80211_IFTYPE_ADHOC
);
2148 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
2149 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
2150 * it as 11a by default.
2151 * This will be updated with
2154 * if phy has 11n capability
2156 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
2157 wdev
->wiphy
->cipher_suites
= __wl_cipher_suites
;
2158 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
2159 #ifndef WL_POWERSAVE_DISABLED
2160 wdev
->wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
2165 wdev
->wiphy
->flags
&= ~WIPHY_FLAG_PS_ON_BY_DEFAULT
;
2166 #endif /* !WL_POWERSAVE_DISABLED */
2167 if (unlikely(((err
= wiphy_register(wdev
->wiphy
)) < 0))) {
2168 WL_ERR(("Couldn not register wiphy device (%d)\n", err
));
2169 goto wiphy_register_out
;
2174 wiphy_free(wdev
->wiphy
);
2179 return ERR_PTR(err
);
2182 static void wl_free_wdev(struct wl_priv
*wl
)
2184 struct wireless_dev
*wdev
= wl_to_wdev(wl
);
2186 if (unlikely(!wdev
)) {
2187 WL_ERR(("wdev is invalid\n"));
2190 wiphy_unregister(wdev
->wiphy
);
2191 wiphy_free(wdev
->wiphy
);
2193 wl_to_wdev(wl
) = NULL
;
2196 static int32
wl_inform_bss(struct wl_priv
*wl
)
2198 struct wl_scan_results
*bss_list
;
2199 struct wl_bss_info
*bi
= NULL
; /* must be initialized */
2203 bss_list
= wl
->bss_list
;
2204 if (unlikely(bss_list
->version
!= WL_BSS_INFO_VERSION
)) {
2205 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2206 bss_list
->version
));
2209 WL_DBG(("scanned AP count (%d)\n", bss_list
->count
));
2210 bi
= next_bss(bss_list
, bi
);
2211 for_each_bss(bss_list
, bi
, i
) {
2212 if (unlikely(err
= wl_inform_single_bss(wl
, bi
)))
2218 static int32
wl_inform_single_bss(struct wl_priv
*wl
, struct wl_bss_info
*bi
)
2220 struct wiphy
*wiphy
= wl_to_wiphy(wl
);
2221 struct ieee80211_mgmt
*mgmt
;
2222 struct ieee80211_channel
*channel
;
2223 struct ieee80211_supported_band
*band
;
2224 struct wl_cfg80211_bss_info
*notif_bss_info
;
2225 struct wl_scan_req
*sr
= wl_to_sr(wl
);
2230 if (unlikely(dtoh32(bi
->length
) > WL_BSS_INFO_MAX
)) {
2231 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2235 kzalloc(sizeof(*notif_bss_info
) + sizeof(*mgmt
) - sizeof(u8
) +
2236 WL_BSS_INFO_MAX
, GFP_KERNEL
);
2237 if (unlikely(!notif_bss_info
)) {
2238 WL_ERR(("notif_bss_info alloc failed\n"));
2241 mgmt
= (struct ieee80211_mgmt
*)notif_bss_info
->frame_buf
;
2242 notif_bss_info
->channel
= CHSPEC_CHANNEL(bi
->chanspec
);
2243 if (notif_bss_info
->channel
<= CH_MAX_2G_CHANNEL
)
2244 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2246 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2247 notif_bss_info
->rssi
= bi
->RSSI
;
2248 memcpy(mgmt
->bssid
, &bi
->BSSID
, ETHER_ADDR_LEN
);
2249 if (!memcmp(bi
->SSID
, sr
->ssid
.SSID
, bi
->SSID_len
)) {
2250 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
2251 IEEE80211_STYPE_PROBE_RESP
);
2253 mgmt
->u
.probe_resp
.timestamp
= 0;
2254 mgmt
->u
.probe_resp
.beacon_int
= cpu_to_le16(bi
->beacon_period
);
2255 mgmt
->u
.probe_resp
.capab_info
= cpu_to_le16(bi
->capability
);
2257 wl_add_ie(wl
, WLAN_EID_SSID
, bi
->SSID_len
, bi
->SSID
);
2258 wl_add_ie(wl
, WLAN_EID_SUPP_RATES
, bi
->rateset
.count
,
2260 wl_mrg_ie(wl
, ((u8
*) bi
) + bi
->ie_offset
, bi
->ie_length
);
2261 wl_cp_ie(wl
, mgmt
->u
.probe_resp
.variable
, WL_BSS_INFO_MAX
-
2262 offsetof(struct wl_cfg80211_bss_info
, frame_buf
));
2263 notif_bss_info
->frame_len
=
2264 offsetof(struct ieee80211_mgmt
,
2265 u
.probe_resp
.variable
) + wl_get_ielen(wl
);
2266 freq
= ieee80211_channel_to_frequency(notif_bss_info
->channel
);
2267 channel
= ieee80211_get_channel(wiphy
, freq
);
2269 WL_DBG(("SSID : \"%s\", rssi (%d), capability : 0x04%x\n", bi
->SSID
,
2270 notif_bss_info
->rssi
, mgmt
->u
.probe_resp
.capab_info
));
2272 signal
= notif_bss_info
->rssi
* 100;
2273 if (unlikely(!cfg80211_inform_bss_frame(wiphy
, channel
, mgmt
,
2275 (notif_bss_info
->frame_len
),
2276 signal
, GFP_KERNEL
))) {
2277 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2278 kfree(notif_bss_info
);
2281 kfree(notif_bss_info
);
2286 static bool wl_is_linkup(struct wl_priv
*wl
, const wl_event_msg_t
*e
)
2288 uint32 event
= ntoh32(e
->event_type
);
2289 uint16 flags
= ntoh16(e
->flags
);
2291 if (event
== WLC_E_JOIN
|| event
== WLC_E_ASSOC_IND
2292 || event
== WLC_E_REASSOC_IND
) {
2294 } else if (event
== WLC_E_LINK
) {
2295 if (flags
& WLC_EVENT_MSG_LINK
) {
2296 if (wl_is_ibssmode(wl
)) {
2297 if (wl_is_ibssstarter(wl
)) {
2308 static bool wl_is_linkdown(struct wl_priv
*wl
, const wl_event_msg_t
*e
)
2310 uint32 event
= ntoh32(e
->event_type
);
2311 uint16 flags
= ntoh16(e
->flags
);
2313 if (event
== WLC_E_DEAUTH_IND
|| event
== WLC_E_DISASSOC_IND
) {
2315 } else if (event
== WLC_E_LINK
) {
2316 if (!(flags
& WLC_EVENT_MSG_LINK
))
2324 wl_notify_connect_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2325 const wl_event_msg_t
*e
, void *data
)
2330 if (wl_is_linkup(wl
, e
)) {
2332 if (wl_is_ibssmode(wl
)) {
2333 cfg80211_ibss_joined(ndev
, (s8
*)&e
->addr
,
2335 WL_DBG(("joined in IBSS network\n"));
2337 wl_bss_connect_done(wl
, ndev
, e
, data
);
2338 WL_DBG(("joined in BSS network \"%s\"\n",
2339 ((struct wlc_ssid
*)
2340 wl_read_prof(wl
, WL_PROF_SSID
))->SSID
));
2343 wl_update_prof(wl
, e
, &act
, WL_PROF_ACT
);
2344 } else if (wl_is_linkdown(wl
, e
)) {
2345 cfg80211_disconnected(ndev
, 0, NULL
, 0, GFP_KERNEL
);
2346 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2348 wl_init_prof(wl
->profile
);
2355 wl_notify_roaming_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2356 const wl_event_msg_t
*e
, void *data
)
2361 wl_bss_roaming_done(wl
, ndev
, e
, data
);
2363 wl_update_prof(wl
, e
, &act
, WL_PROF_ACT
);
2369 wl_dev_bufvar_set(struct net_device
*dev
, s8
*name
, s8
*buf
, int32 len
)
2371 struct wl_priv
*wl
= ndev_to_wl(dev
);
2374 buflen
= bcm_mkiovar(name
, buf
, len
, wl
->ioctl_buf
, WL_IOCTL_LEN_MAX
);
2375 BUG_ON(unlikely(!buflen
));
2377 return wl_dev_ioctl(dev
, WLC_SET_VAR
, wl
->ioctl_buf
, buflen
);
2381 wl_dev_bufvar_get(struct net_device
*dev
, s8
*name
, s8
*buf
,
2384 struct wl_priv
*wl
= ndev_to_wl(dev
);
2388 len
= bcm_mkiovar(name
, NULL
, 0, wl
->ioctl_buf
, WL_IOCTL_LEN_MAX
);
2389 BUG_ON(unlikely(!len
));
2392 wl_dev_ioctl(dev
, WLC_GET_VAR
, (void *)wl
->ioctl_buf
,
2393 WL_IOCTL_LEN_MAX
)))) {
2394 WL_ERR(("error (%d)\n", err
));
2397 memcpy(buf
, wl
->ioctl_buf
, buf_len
);
2402 static int32
wl_get_assoc_ies(struct wl_priv
*wl
)
2404 struct net_device
*ndev
= wl_to_ndev(wl
);
2405 struct wl_assoc_ielen
*assoc_info
;
2406 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2411 if (unlikely(err
= wl_dev_bufvar_get(ndev
, "assoc_info", wl
->extra_buf
,
2412 WL_ASSOC_INFO_MAX
))) {
2413 WL_ERR(("could not get assoc info (%d)\n", err
));
2416 assoc_info
= (struct wl_assoc_ielen
*)wl
->extra_buf
;
2417 req_len
= assoc_info
->req_len
;
2418 resp_len
= assoc_info
->resp_len
;
2422 wl_dev_bufvar_get(ndev
, "assoc_req_ies", wl
->extra_buf
,
2423 WL_ASSOC_INFO_MAX
))) {
2424 WL_ERR(("could not get assoc req (%d)\n", err
));
2427 conn_info
->req_ie_len
= req_len
;
2429 kmemdup(wl
->extra_buf
, conn_info
->req_ie_len
, GFP_KERNEL
);
2431 conn_info
->req_ie_len
= 0;
2432 conn_info
->req_ie
= NULL
;
2437 wl_dev_bufvar_get(ndev
, "assoc_resp_ies", wl
->extra_buf
,
2438 WL_ASSOC_INFO_MAX
))) {
2439 WL_ERR(("could not get assoc resp (%d)\n", err
));
2442 conn_info
->resp_ie_len
= resp_len
;
2443 conn_info
->resp_ie
=
2444 kmemdup(wl
->extra_buf
, conn_info
->resp_ie_len
, GFP_KERNEL
);
2446 conn_info
->resp_ie_len
= 0;
2447 conn_info
->resp_ie
= NULL
;
2449 WL_DBG(("req len (%d) resp len (%d)\n", conn_info
->req_ie_len
,
2450 conn_info
->resp_ie_len
));
2455 static int32
wl_update_bss_info(struct wl_priv
*wl
)
2457 struct cfg80211_bss
*bss
;
2458 struct wl_bss_info
*bi
;
2459 struct wlc_ssid
*ssid
;
2462 if (wl_is_ibssmode(wl
))
2465 ssid
= (struct wlc_ssid
*)wl_read_prof(wl
, WL_PROF_SSID
);
2467 cfg80211_get_bss(wl_to_wiphy(wl
), NULL
, (s8
*)&wl
->bssid
,
2468 ssid
->SSID
, ssid
->SSID_len
, WLAN_CAPABILITY_ESS
,
2469 WLAN_CAPABILITY_ESS
);
2472 if (unlikely(!bss
)) {
2473 WL_DBG(("Could not find the AP\n"));
2474 *(uint32
*) wl
->extra_buf
= htod32(WL_EXTRA_BUF_MAX
);
2477 wl_dev_ioctl(wl_to_ndev(wl
), WLC_GET_BSS_INFO
,
2478 wl
->extra_buf
, WL_EXTRA_BUF_MAX
))) {
2479 WL_ERR(("Could not get bss info %d\n", err
));
2480 goto update_bss_info_out
;
2482 bi
= (struct wl_bss_info
*)(wl
->extra_buf
+ 4);
2483 if (unlikely(memcmp(&bi
->BSSID
, &wl
->bssid
, ETHER_ADDR_LEN
))) {
2485 goto update_bss_info_out
;
2487 if (unlikely((err
= wl_inform_single_bss(wl
, bi
))))
2488 goto update_bss_info_out
;
2490 WL_DBG(("Found the AP in the list - "
2491 "BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
2492 bss
->bssid
[0], bss
->bssid
[1], bss
->bssid
[2],
2493 bss
->bssid
[3], bss
->bssid
[4], bss
->bssid
[5]));
2494 cfg80211_put_bss(bss
);
2497 update_bss_info_out
:
2503 wl_bss_roaming_done(struct wl_priv
*wl
, struct net_device
*ndev
,
2504 const wl_event_msg_t
*e
, void *data
)
2506 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2509 wl_get_assoc_ies(wl
);
2510 memcpy(&wl
->bssid
, &e
->addr
, ETHER_ADDR_LEN
);
2511 wl_update_bss_info(wl
);
2512 cfg80211_roamed(ndev
,
2514 conn_info
->req_ie
, conn_info
->req_ie_len
,
2515 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
2516 WL_DBG(("Report roaming result\n"));
2518 set_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2524 wl_bss_connect_done(struct wl_priv
*wl
, struct net_device
*ndev
,
2525 const wl_event_msg_t
*e
, void *data
)
2527 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
2530 wl_get_assoc_ies(wl
);
2531 memcpy(&wl
->bssid
, &e
->addr
, ETHER_ADDR_LEN
);
2532 wl_update_bss_info(wl
);
2533 if (test_and_clear_bit(WL_STATUS_CONNECTING
, &wl
->status
)) {
2534 cfg80211_connect_result(ndev
,
2537 conn_info
->req_ie_len
,
2539 conn_info
->resp_ie_len
,
2540 WLAN_STATUS_SUCCESS
, GFP_KERNEL
);
2541 WL_DBG(("Report connect result\n"));
2543 cfg80211_roamed(ndev
,
2545 conn_info
->req_ie
, conn_info
->req_ie_len
,
2546 conn_info
->resp_ie
, conn_info
->resp_ie_len
,
2548 WL_DBG(("Report roaming result\n"));
2550 set_bit(WL_STATUS_CONNECTED
, &wl
->status
);
2556 wl_notify_mic_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2557 const wl_event_msg_t
*e
, void *data
)
2559 uint16 flags
= ntoh16(e
->flags
);
2560 enum nl80211_key_type key_type
;
2563 if (flags
& WLC_EVENT_MSG_GROUP
)
2564 key_type
= NL80211_KEYTYPE_GROUP
;
2566 key_type
= NL80211_KEYTYPE_PAIRWISE
;
2568 cfg80211_michael_mic_failure(ndev
, (u8
*)&e
->addr
, key_type
, -1,
2576 wl_notify_scan_status(struct wl_priv
*wl
, struct net_device
*ndev
,
2577 const wl_event_msg_t
*e
, void *data
)
2579 struct channel_info channel_inform
;
2580 struct wl_scan_results
*bss_list
;
2581 uint32 len
= WL_SCAN_BUF_MAX
;
2584 if (wl
->iscan_on
&& wl
->iscan_kickstart
)
2585 return wl_wakeup_iscan(wl_to_iscan(wl
));
2587 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
2588 WL_ERR(("Scan complete while device not scanning\n"));
2591 if (unlikely(!wl
->scan_request
)) {
2594 if (unlikely((err
= wl_dev_ioctl(ndev
, WLC_GET_CHANNEL
, &channel_inform
,
2595 sizeof(channel_inform
))))) {
2596 WL_ERR(("scan busy (%d)\n", err
));
2599 channel_inform
.scan_channel
= dtoh32(channel_inform
.scan_channel
);
2600 if (unlikely(channel_inform
.scan_channel
)) {
2602 WL_DBG(("channel_inform.scan_channel (%d)\n",
2603 channel_inform
.scan_channel
));
2605 wl
->bss_list
= wl
->scan_results
;
2606 bss_list
= wl
->bss_list
;
2607 memset(bss_list
, 0, len
);
2608 bss_list
->buflen
= htod32(len
);
2610 ((err
= wl_dev_ioctl(ndev
, WLC_SCAN_RESULTS
, bss_list
, len
)))) {
2611 WL_ERR(("%s Scan_results error (%d)\n", ndev
->name
, err
));
2615 bss_list
->buflen
= dtoh32(bss_list
->buflen
);
2616 bss_list
->version
= dtoh32(bss_list
->version
);
2617 bss_list
->count
= dtoh32(bss_list
->count
);
2619 if ((err
= wl_inform_bss(wl
)))
2623 if (wl
->scan_request
) {
2624 cfg80211_scan_done(wl
->scan_request
, FALSE
);
2625 wl
->scan_request
= NULL
;
2631 static void wl_init_conf(struct wl_conf
*conf
)
2633 conf
->mode
= (uint32
)-1;
2634 conf
->frag_threshold
= (uint32
)-1;
2635 conf
->rts_threshold
= (uint32
)-1;
2636 conf
->retry_short
= (uint32
)-1;
2637 conf
->retry_long
= (uint32
)-1;
2638 conf
->tx_power
= -1;
2641 static void wl_init_prof(struct wl_profile
*prof
)
2643 memset(prof
, 0, sizeof(*prof
));
2646 static void wl_init_eloop_handler(struct wl_event_loop
*el
)
2648 memset(el
, 0, sizeof(*el
));
2649 el
->handler
[WLC_E_SCAN_COMPLETE
] = wl_notify_scan_status
;
2650 el
->handler
[WLC_E_JOIN
] = wl_notify_connect_status
;
2651 el
->handler
[WLC_E_LINK
] = wl_notify_connect_status
;
2652 el
->handler
[WLC_E_DEAUTH_IND
] = wl_notify_connect_status
;
2653 el
->handler
[WLC_E_DISASSOC_IND
] = wl_notify_connect_status
;
2654 el
->handler
[WLC_E_ASSOC_IND
] = wl_notify_connect_status
;
2655 el
->handler
[WLC_E_REASSOC_IND
] = wl_notify_connect_status
;
2656 el
->handler
[WLC_E_ROAM
] = wl_notify_roaming_status
;
2657 el
->handler
[WLC_E_MIC_ERROR
] = wl_notify_mic_status
;
2660 static int32
wl_init_priv_mem(struct wl_priv
*wl
)
2662 wl
->scan_results
= (void *)kzalloc(WL_SCAN_BUF_MAX
, GFP_KERNEL
);
2663 if (unlikely(!wl
->scan_results
)) {
2664 WL_ERR(("Scan results alloc failed\n"));
2665 goto init_priv_mem_out
;
2667 wl
->conf
= (void *)kzalloc(sizeof(*wl
->conf
), GFP_KERNEL
);
2668 if (unlikely(!wl
->conf
)) {
2669 WL_ERR(("wl_conf alloc failed\n"));
2670 goto init_priv_mem_out
;
2672 wl
->profile
= (void *)kzalloc(sizeof(*wl
->profile
), GFP_KERNEL
);
2673 if (unlikely(!wl
->profile
)) {
2674 WL_ERR(("wl_profile alloc failed\n"));
2675 goto init_priv_mem_out
;
2677 wl
->bss_info
= (void *)kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2678 if (unlikely(!wl
->bss_info
)) {
2679 WL_ERR(("Bss information alloc failed\n"));
2680 goto init_priv_mem_out
;
2683 (void *)kzalloc(sizeof(*wl
->scan_req_int
), GFP_KERNEL
);
2684 if (unlikely(!wl
->scan_req_int
)) {
2685 WL_ERR(("Scan req alloc failed\n"));
2686 goto init_priv_mem_out
;
2688 wl
->ioctl_buf
= (void *)kzalloc(WL_IOCTL_LEN_MAX
, GFP_KERNEL
);
2689 if (unlikely(!wl
->ioctl_buf
)) {
2690 WL_ERR(("Ioctl buf alloc failed\n"));
2691 goto init_priv_mem_out
;
2693 wl
->extra_buf
= (void *)kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
2694 if (unlikely(!wl
->extra_buf
)) {
2695 WL_ERR(("Extra buf alloc failed\n"));
2696 goto init_priv_mem_out
;
2698 wl
->iscan
= (void *)kzalloc(sizeof(*wl
->iscan
), GFP_KERNEL
);
2699 if (unlikely(!wl
->iscan
)) {
2700 WL_ERR(("Iscan buf alloc failed\n"));
2701 goto init_priv_mem_out
;
2703 wl
->fw
= (void *)kzalloc(sizeof(*wl
->fw
), GFP_KERNEL
);
2704 if (unlikely(!wl
->fw
)) {
2705 WL_ERR(("fw object alloc failed\n"));
2706 goto init_priv_mem_out
;
2708 wl
->pmk_list
= (void *)kzalloc(sizeof(*wl
->pmk_list
), GFP_KERNEL
);
2709 if (unlikely(!wl
->pmk_list
)) {
2710 WL_ERR(("pmk list alloc failed\n"));
2711 goto init_priv_mem_out
;
2717 wl_deinit_priv_mem(wl
);
2722 static void wl_deinit_priv_mem(struct wl_priv
*wl
)
2724 kfree(wl
->scan_results
);
2725 wl
->scan_results
= NULL
;
2726 kfree(wl
->bss_info
);
2727 wl
->bss_info
= NULL
;
2732 kfree(wl
->scan_req_int
);
2733 wl
->scan_req_int
= NULL
;
2734 kfree(wl
->ioctl_buf
);
2735 wl
->ioctl_buf
= NULL
;
2736 kfree(wl
->extra_buf
);
2737 wl
->extra_buf
= NULL
;
2742 kfree(wl
->pmk_list
);
2743 wl
->pmk_list
= NULL
;
2746 static int32
wl_create_event_handler(struct wl_priv
*wl
)
2748 sema_init(&wl
->event_sync
, 0);
2749 init_completion(&wl
->event_exit
);
2751 (((wl
->event_pid
= kernel_thread(wl_event_handler
, wl
, 0)) < 0))) {
2752 WL_ERR(("failed to create event thread\n"));
2755 WL_DBG(("pid %d\n", wl
->event_pid
));
2759 static void wl_destroy_event_handler(struct wl_priv
*wl
)
2761 if (wl
->event_pid
>= 0) {
2762 KILL_PROC(wl
->event_pid
, SIGTERM
);
2763 wait_for_completion(&wl
->event_exit
);
2767 static void wl_term_iscan(struct wl_priv
*wl
)
2769 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
2771 if (wl
->iscan_on
&& iscan
->pid
>= 0) {
2772 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2773 KILL_PROC(iscan
->pid
, SIGTERM
);
2774 wait_for_completion(&iscan
->exited
);
2779 static void wl_notify_iscan_complete(struct wl_iscan_ctrl
*iscan
, bool aborted
)
2781 struct wl_priv
*wl
= iscan_to_wl(iscan
);
2783 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING
, &wl
->status
))) {
2784 WL_ERR(("Scan complete while device not scanning\n"));
2787 if (likely(wl
->scan_request
)) {
2788 cfg80211_scan_done(wl
->scan_request
, aborted
);
2789 wl
->scan_request
= NULL
;
2791 wl
->iscan_kickstart
= FALSE
;
2794 static int32
wl_wakeup_iscan(struct wl_iscan_ctrl
*iscan
)
2796 if (likely(iscan
->state
!= WL_ISCAN_STATE_IDLE
)) {
2797 WL_DBG(("wake up iscan\n"));
2806 wl_get_iscan_results(struct wl_iscan_ctrl
*iscan
, uint32
*status
,
2807 struct wl_scan_results
**bss_list
)
2809 struct wl_iscan_results list
;
2810 struct wl_scan_results
*results
;
2811 struct wl_iscan_results
*list_buf
;
2814 memset(iscan
->scan_buf
, 0, WL_ISCAN_BUF_MAX
);
2815 list_buf
= (struct wl_iscan_results
*)iscan
->scan_buf
;
2816 results
= &list_buf
->results
;
2817 results
->buflen
= WL_ISCAN_RESULTS_FIXED_SIZE
;
2818 results
->version
= 0;
2821 memset(&list
, 0, sizeof(list
));
2822 list
.results
.buflen
= htod32(WL_ISCAN_BUF_MAX
);
2823 if (unlikely((err
= wl_dev_iovar_getbuf(iscan
->dev
,
2826 WL_ISCAN_RESULTS_FIXED_SIZE
,
2828 WL_ISCAN_BUF_MAX
)))) {
2829 WL_ERR(("error (%d)\n", err
));
2832 results
->buflen
= dtoh32(results
->buflen
);
2833 results
->version
= dtoh32(results
->version
);
2834 results
->count
= dtoh32(results
->count
);
2835 WL_DBG(("results->count = %d\n", results
->count
));
2836 WL_DBG(("results->buflen = %d\n", results
->buflen
));
2837 *status
= dtoh32(list_buf
->status
);
2838 *bss_list
= results
;
2843 static int32
wl_iscan_done(struct wl_priv
*wl
)
2845 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
2848 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2851 wl_notify_iscan_complete(iscan
, FALSE
);
2857 static int32
wl_iscan_pending(struct wl_priv
*wl
)
2859 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
2862 /* Reschedule the timer */
2863 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
2864 iscan
->timer_on
= 1;
2869 static int32
wl_iscan_inprogress(struct wl_priv
*wl
)
2871 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
2876 wl_run_iscan(iscan
, NULL
, WL_SCAN_ACTION_CONTINUE
);
2878 /* Reschedule the timer */
2879 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
2880 iscan
->timer_on
= 1;
2885 static int32
wl_iscan_aborted(struct wl_priv
*wl
)
2887 struct wl_iscan_ctrl
*iscan
= wl
->iscan
;
2890 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2892 wl_notify_iscan_complete(iscan
, TRUE
);
2898 static int32
wl_iscan_thread(void *data
)
2900 struct sched_param param
= {.sched_priority
= MAX_RT_PRIO
- 1 };
2901 struct wl_iscan_ctrl
*iscan
= (struct wl_iscan_ctrl
*)data
;
2902 struct wl_priv
*wl
= iscan_to_wl(iscan
);
2903 struct wl_iscan_eloop
*el
= &iscan
->el
;
2907 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
2908 status
= WL_SCAN_RESULTS_PARTIAL
;
2909 while (likely(!down_interruptible(&iscan
->sync
))) {
2910 if (iscan
->timer_on
) {
2911 del_timer_sync(&iscan
->timer
);
2912 iscan
->timer_on
= 0;
2917 wl_get_iscan_results(iscan
, &status
, &wl
->bss_list
)))) {
2918 status
= WL_SCAN_RESULTS_ABORTED
;
2919 WL_ERR(("Abort iscan\n"));
2922 el
->handler
[status
] (wl
);
2924 if (iscan
->timer_on
) {
2925 del_timer_sync(&iscan
->timer
);
2926 iscan
->timer_on
= 0;
2928 complete_and_exit(&iscan
->exited
, 0);
2933 static void wl_iscan_timer(unsigned long data
)
2935 struct wl_iscan_ctrl
*iscan
= (struct wl_iscan_ctrl
*)data
;
2938 iscan
->timer_on
= 0;
2939 WL_DBG(("timer expired\n"));
2940 wl_wakeup_iscan(iscan
);
2944 static int32
wl_invoke_iscan(struct wl_priv
*wl
)
2946 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
2949 if (wl
->iscan_on
&& iscan
->pid
< 0) {
2950 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2951 sema_init(&iscan
->sync
, 0);
2952 init_completion(&iscan
->exited
);
2953 iscan
->pid
= kernel_thread(wl_iscan_thread
, iscan
, 0);
2954 if (unlikely(iscan
->pid
< 0)) {
2955 WL_ERR(("Could not create iscan thread\n"));
2963 static void wl_init_iscan_eloop(struct wl_iscan_eloop
*el
)
2965 memset(el
, 0, sizeof(*el
));
2966 el
->handler
[WL_SCAN_RESULTS_SUCCESS
] = wl_iscan_done
;
2967 el
->handler
[WL_SCAN_RESULTS_PARTIAL
] = wl_iscan_inprogress
;
2968 el
->handler
[WL_SCAN_RESULTS_PENDING
] = wl_iscan_pending
;
2969 el
->handler
[WL_SCAN_RESULTS_ABORTED
] = wl_iscan_aborted
;
2970 el
->handler
[WL_SCAN_RESULTS_NO_MEM
] = wl_iscan_aborted
;
2973 static int32
wl_init_iscan(struct wl_priv
*wl
)
2975 struct wl_iscan_ctrl
*iscan
= wl_to_iscan(wl
);
2979 iscan
->dev
= wl_to_ndev(wl
);
2980 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2981 wl_init_iscan_eloop(&iscan
->el
);
2982 iscan
->timer_ms
= WL_ISCAN_TIMER_INTERVAL_MS
;
2983 init_timer(&iscan
->timer
);
2984 iscan
->timer
.data
= (unsigned long) iscan
;
2985 iscan
->timer
.function
= wl_iscan_timer
;
2986 sema_init(&iscan
->sync
, 0);
2987 init_completion(&iscan
->exited
);
2988 iscan
->pid
= kernel_thread(wl_iscan_thread
, iscan
, 0);
2989 if (unlikely(iscan
->pid
< 0)) {
2990 WL_ERR(("Could not create iscan thread\n"));
2999 static void wl_init_fw(struct wl_fw_ctrl
*fw
)
3001 fw
->status
= 0; /* init fw loading status.
3002 0 means nothing was loaded yet */
3005 static int32
wl_init_priv(struct wl_priv
*wl
)
3007 struct wiphy
*wiphy
= wl_to_wiphy(wl
);
3010 wl
->scan_request
= NULL
;
3011 wl
->pwr_save
= !!(wiphy
->flags
& WIPHY_FLAG_PS_ON_BY_DEFAULT
);
3012 #ifndef WL_ISCAN_DISABLED
3013 wl
->iscan_on
= TRUE
; /* iscan on & off switch.
3014 we enable iscan per default */
3016 wl
->iscan_on
= FALSE
;
3017 #endif /* WL_ISCAN_DISABLED */
3018 #ifndef WL_ROAM_DISABLED
3019 wl
->roam_on
= TRUE
; /* roam on & off switch.
3020 we enable roam per default */
3022 wl
->roam_on
= FALSE
;
3023 #endif /* WL_ROAM_DISABLED */
3025 wl
->iscan_kickstart
= FALSE
;
3026 wl
->active_scan
= TRUE
; /* we do active scan for
3027 specific scan per default */
3028 wl
->dongle_up
= FALSE
; /* dongle is not up yet */
3030 if (unlikely((err
= wl_init_priv_mem(wl
))))
3032 if (unlikely(wl_create_event_handler(wl
)))
3034 wl_init_eloop_handler(&wl
->el
);
3035 mutex_init(&wl
->usr_sync
);
3036 if (unlikely((err
= wl_init_iscan(wl
))))
3039 wl_init_conf(wl
->conf
);
3040 wl_init_prof(wl
->profile
);
3046 static void wl_deinit_priv(struct wl_priv
*wl
)
3048 wl_destroy_event_handler(wl
);
3049 wl
->dongle_up
= FALSE
; /* dongle down */
3053 wl_deinit_priv_mem(wl
);
3056 int32
wl_cfg80211_attach(struct net_device
*ndev
, void *data
)
3058 struct wireless_dev
*wdev
;
3060 struct wl_iface
*ci
;
3063 if (unlikely(!ndev
)) {
3064 WL_ERR(("ndev is invaild\n"));
3067 wl_cfg80211_dev
= kzalloc(sizeof(struct wl_dev
), GFP_KERNEL
);
3068 if (unlikely(!wl_cfg80211_dev
)) {
3069 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3072 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
3073 wdev
= wl_alloc_wdev(sizeof(struct wl_iface
), &wl_cfg80211_get_sdio_func()->dev
);
3074 if (unlikely(IS_ERR(wdev
)))
3077 wdev
->iftype
= wl_mode_to_nl80211_iftype(WL_MODE_BSS
);
3078 wl
= wdev_to_wl(wdev
);
3081 ci
= (struct wl_iface
*)wl_to_ci(wl
);
3083 ndev
->ieee80211_ptr
= wdev
;
3084 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
3085 wdev
->netdev
= ndev
;
3086 if (unlikely((err
= wl_init_priv(wl
)))) {
3087 WL_ERR(("Failed to init iwm_priv (%d)\n", err
));
3088 goto cfg80211_attach_out
;
3090 wl_set_drvdata(wl_cfg80211_dev
, ci
);
3091 set_bit(WL_STATUS_READY
, &wl
->status
);
3095 cfg80211_attach_out
:
3100 void wl_cfg80211_detach(void)
3108 wl_set_drvdata(wl_cfg80211_dev
, NULL
);
3109 kfree(wl_cfg80211_dev
);
3110 wl_cfg80211_dev
= NULL
;
3111 wl_clear_sdio_func();
3114 static void wl_wakeup_event(struct wl_priv
*wl
)
3116 up(&wl
->event_sync
);
3119 static int32
wl_event_handler(void *data
)
3121 struct wl_priv
*wl
= (struct wl_priv
*)data
;
3122 struct sched_param param
= {.sched_priority
= MAX_RT_PRIO
- 1 };
3123 struct wl_event_q
*e
;
3125 sched_setscheduler(current
, SCHED_FIFO
, ¶m
);
3126 while (likely(!down_interruptible(&wl
->event_sync
))) {
3127 if (unlikely(!(e
= wl_deq_event(wl
)))) {
3128 WL_ERR(("eqeue empty..\n"));
3131 WL_DBG(("event type (%d)\n", e
->etype
));
3132 if (wl
->el
.handler
[e
->etype
]) {
3133 wl
->el
.handler
[e
->etype
] (wl
, wl_to_ndev(wl
), &e
->emsg
,
3136 WL_DBG(("Unknown Event (%d): ignoring\n", e
->etype
));
3140 complete_and_exit(&wl
->event_exit
, 0);
3144 wl_cfg80211_event(struct net_device
*ndev
, const wl_event_msg_t
* e
, void *data
)
3146 uint32 event_type
= ntoh32(e
->event_type
);
3147 struct wl_priv
*wl
= ndev_to_wl(ndev
);
3148 #if (WL_DBG_LEVEL > 0)
3149 s8
*estr
= (event_type
<= sizeof(wl_dbg_estr
) / WL_DBG_ESTR_MAX
- 1) ?
3150 wl_dbg_estr
[event_type
] : (s8
*) "Unknown";
3151 #endif /* (WL_DBG_LEVEL > 0) */
3152 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type
, estr
));
3153 if (likely(!wl_enq_event(wl
, event_type
, e
, data
)))
3154 wl_wakeup_event(wl
);
3157 static void wl_init_eq(struct wl_priv
*wl
)
3159 wl_init_eq_lock(wl
);
3160 INIT_LIST_HEAD(&wl
->eq_list
);
3163 static void wl_flush_eq(struct wl_priv
*wl
)
3165 struct wl_event_q
*e
;
3168 while (!list_empty(&wl
->eq_list
)) {
3169 e
= list_first_entry(&wl
->eq_list
, struct wl_event_q
, eq_list
);
3170 list_del(&e
->eq_list
);
3177 * retrieve first queued event from head
3180 static struct wl_event_q
*wl_deq_event(struct wl_priv
*wl
)
3182 struct wl_event_q
*e
= NULL
;
3185 if (likely(!list_empty(&wl
->eq_list
))) {
3186 e
= list_first_entry(&wl
->eq_list
, struct wl_event_q
, eq_list
);
3187 list_del(&e
->eq_list
);
3195 ** push event to tail of the queue
3199 wl_enq_event(struct wl_priv
*wl
, uint32 event
, const wl_event_msg_t
*msg
,
3202 struct wl_event_q
*e
;
3205 if (unlikely(!(e
= kzalloc(sizeof(struct wl_event_q
), GFP_KERNEL
)))) {
3206 WL_ERR(("event alloc failed\n"));
3211 memcpy(&e
->emsg
, msg
, sizeof(wl_event_msg_t
));
3215 list_add_tail(&e
->eq_list
, &wl
->eq_list
);
3221 static void wl_put_event(struct wl_event_q
*e
)
3226 void wl_cfg80211_sdio_func(void *func
)
3228 cfg80211_sdio_func
= (struct sdio_func
*)func
;
3231 static void wl_clear_sdio_func(void)
3233 cfg80211_sdio_func
= NULL
;
3236 struct sdio_func
*wl_cfg80211_get_sdio_func(void)
3238 return cfg80211_sdio_func
;
3241 static int32
wl_dongle_mode(struct net_device
*ndev
, int32 iftype
)
3248 case NL80211_IFTYPE_MONITOR
:
3249 case NL80211_IFTYPE_WDS
:
3250 WL_ERR(("type (%d) : currently we do not support this mode\n",
3254 case NL80211_IFTYPE_ADHOC
:
3256 case NL80211_IFTYPE_STATION
:
3261 WL_ERR(("invalid type (%d)\n", iftype
));
3264 infra
= htod32(infra
);
3266 WL_DBG(("%s ap (%d), infra (%d)\n", ndev
->name
, ap
, infra
));
3268 (err
= wl_dev_ioctl(ndev
, WLC_SET_INFRA
, &infra
, sizeof(infra
)))
3270 (err
= wl_dev_ioctl(ndev
, WLC_SET_AP
, &ap
, sizeof(ap
)))) {
3271 WL_ERR(("WLC_SET_INFRA error (%d)\n", err
));
3275 return -EINPROGRESS
;
3278 #ifndef EMBEDDED_PLATFORM
3279 static int32
wl_dongle_country(struct net_device
*ndev
, u8 ccode
)
3287 static int32
wl_dongle_up(struct net_device
*ndev
, uint32 up
)
3291 if (unlikely(err
= wl_dev_ioctl(ndev
, WLC_UP
, &up
, sizeof(up
)))) {
3292 WL_ERR(("WLC_UP error (%d)\n", err
));
3297 static int32
wl_dongle_power(struct net_device
*ndev
, uint32 power_mode
)
3303 wl_dev_ioctl(ndev
, WLC_SET_PM
, &power_mode
, sizeof(power_mode
)))) {
3304 WL_ERR(("WLC_SET_PM error (%d)\n", err
));
3310 wl_dongle_glom(struct net_device
*ndev
, uint32 glom
, uint32 dongle_align
)
3312 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3316 /* Match Host and Dongle rx alignment */
3317 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align
, 4, iovbuf
,
3320 (err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3321 WL_ERR(("txglomalign error (%d)\n", err
));
3322 goto dongle_glom_out
;
3324 /* disable glom option per default */
3325 bcm_mkiovar("bus:txglom", (char *)&glom
, 4, iovbuf
, sizeof(iovbuf
));
3327 (err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3328 WL_ERR(("txglom error (%d)\n", err
));
3329 goto dongle_glom_out
;
3336 wl_dongle_roam(struct net_device
*ndev
, uint32 roamvar
, uint32 bcn_timeout
)
3338 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3342 /* Setup timeout if Beacons are lost and roam is
3343 off to report link down */
3345 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout
, 4, iovbuf
,
3349 wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3350 WL_ERR(("bcn_timeout error (%d)\n", err
));
3351 goto dongle_rom_out
;
3354 /* Enable/Disable built-in roaming to allow supplicant
3355 to take care of roaming */
3356 bcm_mkiovar("roam_off", (char *)&roamvar
, 4, iovbuf
, sizeof(iovbuf
));
3358 (err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3359 WL_ERR(("roam_off error (%d)\n", err
));
3360 goto dongle_rom_out
;
3366 static int32
wl_dongle_eventmsg(struct net_device
*ndev
)
3369 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3371 s8 eventmask
[WL_EVENTING_MASK_LEN
];
3374 /* Setup event_msgs */
3375 bcm_mkiovar("event_msgs", eventmask
, WL_EVENTING_MASK_LEN
, iovbuf
,
3378 (err
= wl_dev_ioctl(ndev
, WLC_GET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3379 WL_ERR(("Get event_msgs error (%d)\n", err
));
3380 goto dongle_eventmsg_out
;
3382 memcpy(eventmask
, iovbuf
, WL_EVENTING_MASK_LEN
);
3384 setbit(eventmask
, WLC_E_SET_SSID
);
3385 setbit(eventmask
, WLC_E_PRUNE
);
3386 setbit(eventmask
, WLC_E_AUTH
);
3387 setbit(eventmask
, WLC_E_REASSOC
);
3388 setbit(eventmask
, WLC_E_REASSOC_IND
);
3389 setbit(eventmask
, WLC_E_DEAUTH_IND
);
3390 setbit(eventmask
, WLC_E_DISASSOC_IND
);
3391 setbit(eventmask
, WLC_E_DISASSOC
);
3392 setbit(eventmask
, WLC_E_JOIN
);
3393 setbit(eventmask
, WLC_E_ASSOC_IND
);
3394 setbit(eventmask
, WLC_E_PSK_SUP
);
3395 setbit(eventmask
, WLC_E_LINK
);
3396 setbit(eventmask
, WLC_E_NDIS_LINK
);
3397 setbit(eventmask
, WLC_E_MIC_ERROR
);
3398 setbit(eventmask
, WLC_E_PMKID_CACHE
);
3399 setbit(eventmask
, WLC_E_TXFAIL
);
3400 setbit(eventmask
, WLC_E_JOIN_START
);
3401 setbit(eventmask
, WLC_E_SCAN_COMPLETE
);
3403 bcm_mkiovar("event_msgs", eventmask
, WL_EVENTING_MASK_LEN
, iovbuf
,
3406 (err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3407 WL_ERR(("Set event_msgs error (%d)\n", err
));
3408 goto dongle_eventmsg_out
;
3411 dongle_eventmsg_out
:
3416 wl_dongle_scantime(struct net_device
*ndev
, int32 scan_assoc_time
,
3417 int32 scan_unassoc_time
)
3422 wl_dev_ioctl(ndev
, WLC_SET_SCAN_CHANNEL_TIME
, &scan_assoc_time
,
3423 sizeof(scan_assoc_time
)))) {
3424 if (err
== -EOPNOTSUPP
) {
3425 WL_INFO(("Scan assoc time is not supported\n"));
3427 WL_ERR(("Scan assoc time error (%d)\n", err
));
3429 goto dongle_scantime_out
;
3432 wl_dev_ioctl(ndev
, WLC_SET_SCAN_UNASSOC_TIME
, &scan_unassoc_time
,
3433 sizeof(scan_unassoc_time
)))) {
3434 if (err
== -EOPNOTSUPP
) {
3435 WL_INFO(("Scan unassoc time is not supported\n"));
3437 WL_ERR(("Scan unassoc time error (%d)\n", err
));
3439 goto dongle_scantime_out
;
3442 dongle_scantime_out
:
3447 wl_dongle_offload(struct net_device
*ndev
, int32 arpoe
, int32 arp_ol
)
3449 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3453 /* Set ARP offload */
3454 bcm_mkiovar("arpoe", (char *)&arpoe
, 4, iovbuf
, sizeof(iovbuf
));
3455 if ((err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3456 if (err
== -EOPNOTSUPP
)
3457 WL_INFO(("arpoe is not supported\n"));
3459 WL_ERR(("arpoe error (%d)\n", err
));
3461 goto dongle_offload_out
;
3463 bcm_mkiovar("arp_ol", (char *)&arp_ol
, 4, iovbuf
, sizeof(iovbuf
));
3464 if ((err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3465 if (err
== -EOPNOTSUPP
)
3466 WL_INFO(("arp_ol is not supported\n"));
3468 WL_ERR(("arp_ol error (%d)\n", err
));
3470 goto dongle_offload_out
;
3477 static int32
wl_pattern_atoh(s8
*src
, s8
*dst
)
3479 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
3481 if (strncmp(src
, "0x", 2) != 0 && strncmp(src
, "0X", 2) != 0) {
3482 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3485 src
= src
+ 2; /* Skip past 0x */
3486 if (strlen(src
) % 2 != 0) {
3487 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3490 for (i
= 0; *src
!= '\0'; i
++) {
3492 strncpy(num
, src
, 2);
3494 dst
[i
] = (u8
) strtoul(num
, NULL
, 16);
3500 static int32
wl_dongle_filter(struct net_device
*ndev
, uint32 filter_mode
)
3502 s8 iovbuf
[WL_EVENTING_MASK_LEN
+ 12]; /* Room for "event_msgs" +
3505 struct wl_pkt_filter pkt_filter
;
3506 struct wl_pkt_filter
*pkt_filterp
;
3510 uint32 pattern_size
;
3514 /* add a default packet filter pattern */
3515 str
= "pkt_filter_add";
3516 str_len
= strlen(str
);
3517 strncpy(buf
, str
, str_len
);
3518 buf
[str_len
] = '\0';
3519 buf_len
= str_len
+ 1;
3521 pkt_filterp
= (struct wl_pkt_filter
*)(buf
+ str_len
+ 1);
3523 /* Parse packet filter id. */
3524 pkt_filter
.id
= htod32(100);
3526 /* Parse filter polarity. */
3527 pkt_filter
.negate_match
= htod32(0);
3529 /* Parse filter type. */
3530 pkt_filter
.type
= htod32(0);
3532 /* Parse pattern filter offset. */
3533 pkt_filter
.u
.pattern
.offset
= htod32(0);
3535 /* Parse pattern filter mask. */
3536 mask_size
= htod32(wl_pattern_atoh("0xff",
3537 (char *)pkt_filterp
->u
.pattern
.
3540 /* Parse pattern filter pattern. */
3541 pattern_size
= htod32(wl_pattern_atoh("0x00",
3542 (char *)&pkt_filterp
->u
.pattern
.
3543 mask_and_pattern
[mask_size
]));
3545 if (mask_size
!= pattern_size
) {
3546 WL_ERR(("Mask and pattern not the same size\n"));
3548 goto dongle_filter_out
;
3551 pkt_filter
.u
.pattern
.size_bytes
= mask_size
;
3552 buf_len
+= WL_PKT_FILTER_FIXED_LEN
;
3553 buf_len
+= (WL_PKT_FILTER_PATTERN_FIXED_LEN
+ 2 * mask_size
);
3555 /* Keep-alive attributes are set in local
3556 * variable (keep_alive_pkt), and
3557 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3558 * guarantee that the buffer is properly aligned.
3560 memcpy((char *)pkt_filterp
, &pkt_filter
,
3561 WL_PKT_FILTER_FIXED_LEN
+ WL_PKT_FILTER_PATTERN_FIXED_LEN
);
3563 if ((err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, buf
, buf_len
))) {
3564 if (err
== -EOPNOTSUPP
) {
3565 WL_INFO(("filter not supported\n"));
3567 WL_ERR(("filter (%d)\n", err
));
3569 goto dongle_filter_out
;
3572 /* set mode to allow pattern */
3573 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode
, 4, iovbuf
,
3575 if ((err
= wl_dev_ioctl(ndev
, WLC_SET_VAR
, iovbuf
, sizeof(iovbuf
)))) {
3576 if (err
== -EOPNOTSUPP
) {
3577 WL_INFO(("filter_mode not supported\n"));
3579 WL_ERR(("filter_mode (%d)\n", err
));
3581 goto dongle_filter_out
;
3587 #endif /* !EMBEDDED_PLATFORM */
3589 int32
wl_config_dongle(struct wl_priv
*wl
, bool need_lock
)
3592 #define DHD_SDALIGN 32
3594 struct net_device
*ndev
;
3595 struct wireless_dev
*wdev
;
3601 ndev
= wl_to_ndev(wl
);
3602 wdev
= ndev
->ieee80211_ptr
;
3606 #ifndef EMBEDDED_PLATFORM
3607 if (unlikely((err
= wl_dongle_up(ndev
, 0))))
3608 goto default_conf_out
;
3609 if (unlikely((err
= wl_dongle_country(ndev
, 0))))
3610 goto default_conf_out
;
3611 if (unlikely((err
= wl_dongle_power(ndev
, PM_FAST
))))
3612 goto default_conf_out
;
3613 if (unlikely((err
= wl_dongle_glom(ndev
, 0, DHD_SDALIGN
))))
3614 goto default_conf_out
;
3615 if (unlikely((err
= wl_dongle_roam(ndev
, (wl
->roam_on
? 0 : 1), 3))))
3616 goto default_conf_out
;
3617 if (unlikely((err
= wl_dongle_eventmsg(ndev
))))
3618 goto default_conf_out
;
3620 wl_dongle_scantime(ndev
, 40, 80);
3621 wl_dongle_offload(ndev
, 1, 0xf);
3622 wl_dongle_filter(ndev
, 1);
3623 #endif /* !EMBEDDED_PLATFORM */
3625 err
= wl_dongle_mode(ndev
, wdev
->iftype
);
3626 if (unlikely(err
&& err
!= -EINPROGRESS
))
3627 goto default_conf_out
;
3628 if (unlikely((err
= wl_dongle_probecap(wl
))))
3629 goto default_conf_out
;
3631 /* -EINPROGRESS: Call commit handler */
3637 wl
->dongle_up
= TRUE
;
3643 static int32
wl_update_wiphybands(struct wl_priv
*wl
)
3645 struct wiphy
*wiphy
;
3652 wl_dev_ioctl(wl_to_ndev(wl
), WLC_GET_PHYLIST
, &phy_list
,
3653 sizeof(phy_list
)))) {
3654 WL_ERR(("error (%d)\n", err
));
3658 phy
= ((char *)&phy_list
)[1];
3659 WL_DBG(("%c phy\n", phy
));
3660 if (phy
== 'n' || phy
== 'a') {
3661 wiphy
= wl_to_wiphy(wl
);
3662 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
3668 static int32
__wl_cfg80211_up(struct wl_priv
*wl
)
3672 if (unlikely(err
= wl_config_dongle(wl
, FALSE
)))
3675 wl_invoke_iscan(wl
);
3676 set_bit(WL_STATUS_READY
, &wl
->status
);
3680 static int32
__wl_cfg80211_down(struct wl_priv
*wl
)
3684 /* Check if cfg80211 interface is already down */
3685 if (!test_bit(WL_STATUS_READY
, &wl
->status
))
3686 return err
; /* it is even not ready */
3688 set_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
3690 if (wl
->scan_request
) {
3691 cfg80211_scan_done(wl
->scan_request
, TRUE
); /* TRUE
3693 wl
->scan_request
= NULL
;
3695 clear_bit(WL_STATUS_READY
, &wl
->status
);
3696 clear_bit(WL_STATUS_SCANNING
, &wl
->status
);
3697 clear_bit(WL_STATUS_SCAN_ABORTING
, &wl
->status
);
3698 clear_bit(WL_STATUS_CONNECTED
, &wl
->status
);
3703 int32
wl_cfg80211_up(void)
3709 mutex_lock(&wl
->usr_sync
);
3710 err
= __wl_cfg80211_up(wl
);
3711 mutex_unlock(&wl
->usr_sync
);
3716 int32
wl_cfg80211_down(void)
3722 mutex_lock(&wl
->usr_sync
);
3723 err
= __wl_cfg80211_down(wl
);
3724 mutex_unlock(&wl
->usr_sync
);
3729 static int32
wl_dongle_probecap(struct wl_priv
*wl
)
3733 if (unlikely((err
= wl_update_wiphybands(wl
))))
3739 static void *wl_read_prof(struct wl_priv
*wl
, int32 item
)
3743 return &wl
->profile
->sec
;
3745 return &wl
->profile
->active
;
3747 return &wl
->profile
->bssid
;
3749 return &wl
->profile
->ssid
;
3751 WL_ERR(("invalid item (%d)\n", item
));
3756 wl_update_prof(struct wl_priv
*wl
, const wl_event_msg_t
*e
, void *data
,
3760 struct wlc_ssid
*ssid
;
3764 ssid
= (wlc_ssid_t
*) data
;
3765 memset(wl
->profile
->ssid
.SSID
, 0,
3766 sizeof(wl
->profile
->ssid
.SSID
));
3767 memcpy(wl
->profile
->ssid
.SSID
, ssid
->SSID
, ssid
->SSID_len
);
3768 wl
->profile
->ssid
.SSID_len
= ssid
->SSID_len
;
3772 memcpy(wl
->profile
->bssid
, data
, ETHER_ADDR_LEN
);
3774 memset(wl
->profile
->bssid
, 0, ETHER_ADDR_LEN
);
3777 memcpy(&wl
->profile
->sec
, data
, sizeof(wl
->profile
->sec
));
3780 wl
->profile
->active
= *(bool *) data
;
3783 WL_ERR(("unsupported item (%d)\n", item
));
3791 void wl_cfg80211_dbg_level(uint32 level
)
3793 wl_dbg_level
= level
;
3796 static bool wl_is_ibssmode(struct wl_priv
*wl
)
3798 return wl
->conf
->mode
== WL_MODE_IBSS
;
3801 static bool wl_is_ibssstarter(struct wl_priv
*wl
)
3803 return wl
->ibss_starter
;
3806 static void wl_rst_ie(struct wl_priv
*wl
)
3808 struct wl_ie
*ie
= wl_to_ie(wl
);
3813 static int32
wl_add_ie(struct wl_priv
*wl
, u8 t
, u8 l
, u8
*v
)
3815 struct wl_ie
*ie
= wl_to_ie(wl
);
3818 if (unlikely(ie
->offset
+ l
+ 2 > WL_TLV_INFO_MAX
)) {
3819 WL_ERR(("ei crosses buffer boundary\n"));
3822 ie
->buf
[ie
->offset
] = t
;
3823 ie
->buf
[ie
->offset
+ 1] = l
;
3824 memcpy(&ie
->buf
[ie
->offset
+ 2], v
, l
);
3825 ie
->offset
+= l
+ 2;
3830 static int32
wl_mrg_ie(struct wl_priv
*wl
, u8
*ie_stream
, uint16 ie_size
)
3832 struct wl_ie
*ie
= wl_to_ie(wl
);
3835 if (unlikely(ie
->offset
+ ie_size
> WL_TLV_INFO_MAX
)) {
3836 WL_ERR(("ei_stream crosses buffer boundary\n"));
3839 memcpy(&ie
->buf
[ie
->offset
], ie_stream
, ie_size
);
3840 ie
->offset
+= ie_size
;
3845 static int32
wl_cp_ie(struct wl_priv
*wl
, u8
*dst
, uint16 dst_size
)
3847 struct wl_ie
*ie
= wl_to_ie(wl
);
3850 if (unlikely(ie
->offset
> dst_size
)) {
3851 WL_ERR(("dst_size is not enough\n"));
3854 memcpy(dst
, &ie
->buf
[0], ie
->offset
);
3859 static uint32
wl_get_ielen(struct wl_priv
*wl
)
3861 struct wl_ie
*ie
= wl_to_ie(wl
);
3866 static void wl_link_up(struct wl_priv
*wl
)
3871 static void wl_link_down(struct wl_priv
*wl
)
3873 struct wl_connect_info
*conn_info
= wl_to_conn(wl
);
3875 wl
->link_up
= FALSE
;
3876 kfree(conn_info
->req_ie
);
3877 conn_info
->req_ie
= NULL
;
3878 conn_info
->req_ie_len
= 0;
3879 kfree(conn_info
->resp_ie
);
3880 conn_info
->resp_ie
= NULL
;
3881 conn_info
->resp_ie_len
= 0;
3884 static void wl_lock_eq(struct wl_priv
*wl
)
3886 spin_lock_irq(&wl
->eq_lock
);
3889 static void wl_unlock_eq(struct wl_priv
*wl
)
3891 spin_unlock_irq(&wl
->eq_lock
);
3894 static void wl_init_eq_lock(struct wl_priv
*wl
)
3896 spin_lock_init(&wl
->eq_lock
);
3899 static void wl_delay(uint32 ms
)
3901 if (ms
< 1000 / HZ
) {
3909 static void wl_set_drvdata(struct wl_dev
*dev
, void *data
)
3911 dev
->driver_data
= data
;
3914 static void *wl_get_drvdata(struct wl_dev
*dev
)
3916 return dev
->driver_data
;
3919 int32
wl_cfg80211_read_fw(s8
*buf
, uint32 size
)
3921 const struct firmware
*fw_entry
;
3926 fw_entry
= wl
->fw
->fw_entry
;
3928 if (fw_entry
->size
< wl
->fw
->ptr
+ size
)
3929 size
= fw_entry
->size
- wl
->fw
->ptr
;
3931 memcpy(buf
, &fw_entry
->data
[wl
->fw
->ptr
], size
);
3932 wl
->fw
->ptr
+= size
;
3936 void wl_cfg80211_release_fw(void)
3941 release_firmware(wl
->fw
->fw_entry
);
3945 void *wl_cfg80211_request_fw(s8
*file_name
)
3948 const struct firmware
*fw_entry
= NULL
;
3951 WL_DBG(("file name : \"%s\"\n", file_name
));
3954 if (!test_bit(WL_FW_LOADING_DONE
, &wl
->fw
->status
)) {
3957 request_firmware(&wl
->fw
->fw_entry
, file_name
,
3958 &wl_cfg80211_get_sdio_func()->dev
))) {
3959 WL_ERR(("Could not download fw (%d)\n", err
));
3962 set_bit(WL_FW_LOADING_DONE
, &wl
->fw
->status
);
3963 fw_entry
= wl
->fw
->fw_entry
;
3965 WL_DBG(("fw size (%d), data (%p)\n", fw_entry
->size
,
3968 } else if (!test_bit(WL_NVRAM_LOADING_DONE
, &wl
->fw
->status
)) {
3971 request_firmware(&wl
->fw
->fw_entry
, file_name
,
3972 &wl_cfg80211_get_sdio_func()->dev
))) {
3973 WL_ERR(("Could not download nvram (%d)\n", err
));
3976 set_bit(WL_NVRAM_LOADING_DONE
, &wl
->fw
->status
);
3977 fw_entry
= wl
->fw
->fw_entry
;
3979 WL_DBG(("nvram size (%d), data (%p)\n", fw_entry
->size
,
3983 WL_DBG(("Downloading already done. Nothing to do more\n"));
3988 if (unlikely(err
)) {
3992 return (void *)fw_entry
->data
;
3995 s8
*wl_cfg80211_get_fwname(void)
4000 strcpy(wl
->fw
->fw_name
, WL_4329_FW_FILE
);
4001 return wl
->fw
->fw_name
;
4004 s8
*wl_cfg80211_get_nvramname(void)
4009 strcpy(wl
->fw
->nvram_name
, WL_4329_NVRAM_FILE
);
4010 return wl
->fw
->nvram_name
;