2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/kernel.h>
18 #include <linux/if_arp.h>
23 #include <bcmendian.h>
24 #include <proto/ethernet.h>
26 #include <asm/uaccess.h>
28 #include <dngl_stats.h>
33 #include <proto/ethernet.h>
34 #include <dngl_stats.h>
37 #include <linux/kthread.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 u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
55 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
56 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
59 ** cfg80211_ops api/callback list
61 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
62 struct net_device *ndev,
63 enum nl80211_iftype type, u32 *flags,
64 struct vif_params *params);
65 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
66 struct cfg80211_scan_request *request,
67 struct cfg80211_ssid *this_ssid);
68 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
69 struct cfg80211_scan_request *request);
70 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
71 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
72 struct cfg80211_ibss_params *params);
73 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
74 struct net_device *dev);
75 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
76 struct net_device *dev, u8 *mac,
77 struct station_info *sinfo);
78 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
79 struct net_device *dev, bool enabled,
81 static s32 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 s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
90 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
91 enum nl80211_tx_power_setting type,
93 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
94 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
95 struct net_device *dev,
97 static s32 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 s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
101 u8 key_idx, const u8 *mac_addr);
102 static s32 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 s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
109 struct net_device *dev,
111 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
112 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
113 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
114 struct cfg80211_pmksa *pmksa);
115 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
116 struct cfg80211_pmksa *pmksa);
117 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
118 struct net_device *dev);
120 ** event & event Q handlers for cfg80211 interfaces
122 static s32 wl_create_event_handler(struct wl_priv *wl);
123 static void wl_destroy_event_handler(struct wl_priv *wl);
124 static s32 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 s32 wl_enq_event(struct wl_priv *wl, u32 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 s32 wl_notify_connect_status(struct wl_priv *wl,
137 struct net_device *ndev,
138 const wl_event_msg_t *e, void *data);
139 static s32 wl_notify_roaming_status(struct wl_priv *wl,
140 struct net_device *ndev,
141 const wl_event_msg_t *e, void *data);
142 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
143 const wl_event_msg_t *e, void *data);
144 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
145 const wl_event_msg_t *e, void *data,
147 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
148 const wl_event_msg_t *e, void *data);
149 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
150 const wl_event_msg_t *e, void *data);
153 ** register/deregister sdio function
155 struct sdio_func *wl_cfg80211_get_sdio_func(void);
156 static void wl_clear_sdio_func(void);
161 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
163 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
165 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
166 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
168 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
172 ** cfg80211 set_wiphy_params utilities
174 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
175 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
176 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
179 ** wl profile utilities
181 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
182 void *data, s32 item);
183 static void *wl_read_prof(struct wl_priv *wl, s32 item);
184 static void wl_init_prof(struct wl_profile *prof);
187 ** cfg80211 connect utilites
189 static s32 wl_set_wpa_version(struct net_device *dev,
190 struct cfg80211_connect_params *sme);
191 static s32 wl_set_auth_type(struct net_device *dev,
192 struct cfg80211_connect_params *sme);
193 static s32 wl_set_set_cipher(struct net_device *dev,
194 struct cfg80211_connect_params *sme);
195 static s32 wl_set_key_mgmt(struct net_device *dev,
196 struct cfg80211_connect_params *sme);
197 static s32 wl_set_set_sharedkey(struct net_device *dev,
198 struct cfg80211_connect_params *sme);
199 static s32 wl_get_assoc_ies(struct wl_priv *wl);
200 static void wl_ch_to_chanspec(int ch,
201 struct wl_join_params *join_params, size_t *join_params_size);
204 ** information element utilities
206 static void wl_rst_ie(struct wl_priv *wl);
207 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
208 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
209 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
210 static u32 wl_get_ielen(struct wl_priv *wl);
212 static s32 wl_mode_to_nl80211_iftype(s32 mode);
214 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
216 static void wl_free_wdev(struct wl_priv *wl);
218 static s32 wl_inform_bss(struct wl_priv *wl);
219 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
220 static s32 wl_update_bss_info(struct wl_priv *wl);
222 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
223 u8 key_idx, const u8 *mac_addr,
224 struct key_params *params);
227 ** key indianess swap utilities
229 static void swap_key_from_BE(struct wl_wsec_key *key);
230 static void swap_key_to_BE(struct wl_wsec_key *key);
233 ** wl_priv memory init/deinit utilities
235 static s32 wl_init_priv_mem(struct wl_priv *wl);
236 static void wl_deinit_priv_mem(struct wl_priv *wl);
238 static void wl_delay(u32 ms);
241 ** store/restore cfg80211 instance data
243 static void wl_set_drvdata(struct wl_dev *dev, void *data);
244 static void *wl_get_drvdata(struct wl_dev *dev);
247 ** ibss mode utilities
249 static bool wl_is_ibssmode(struct wl_priv *wl);
250 static bool wl_is_ibssstarter(struct wl_priv *wl);
253 ** dongle up/down , default configuration utilities
255 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
256 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
257 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
258 static void wl_link_up(struct wl_priv *wl);
259 static void wl_link_down(struct wl_priv *wl);
260 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
261 static s32 __wl_cfg80211_up(struct wl_priv *wl);
262 static s32 __wl_cfg80211_down(struct wl_priv *wl);
263 static s32 wl_dongle_probecap(struct wl_priv *wl);
264 static void wl_init_conf(struct wl_conf *conf);
267 ** dongle configuration utilities
269 #ifndef EMBEDDED_PLATFORM
270 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
271 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
272 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
273 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
274 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
276 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
278 static s32 wl_dongle_eventmsg(struct net_device *ndev);
279 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
280 s32 scan_unassoc_time);
281 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
283 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
284 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
285 static s32 wl_update_wiphybands(struct wl_priv *wl);
286 #endif /* !EMBEDDED_PLATFORM */
287 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
292 static void wl_iscan_timer(unsigned long data);
293 static void wl_term_iscan(struct wl_priv *wl);
294 static s32 wl_init_iscan(struct wl_priv *wl);
295 static s32 wl_iscan_thread(void *data);
296 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
297 void *param, s32 paramlen, void *bufptr,
299 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
300 void *param, s32 paramlen, void *bufptr,
302 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
304 static s32 wl_do_iscan(struct wl_priv *wl);
305 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
306 static s32 wl_invoke_iscan(struct wl_priv *wl);
307 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
308 struct wl_scan_results **bss_list);
309 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
310 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
311 static s32 wl_iscan_done(struct wl_priv *wl);
312 static s32 wl_iscan_pending(struct wl_priv *wl);
313 static s32 wl_iscan_inprogress(struct wl_priv *wl);
314 static s32 wl_iscan_aborted(struct wl_priv *wl);
317 ** fw/nvram downloading handler
319 static void wl_init_fw(struct wl_fw_ctrl *fw);
322 * find most significant bit set
324 static __used u32 wl_find_msb(u16 bit16);
327 * update pmklist to dongle
329 static __used s32 wl_update_pmklist(struct net_device *dev,
330 struct wl_pmk_list *pmk_list, s32 err);
332 static void wl_set_mpc(struct net_device *ndev, int mpc);
337 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
338 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
340 #define WL_PRIV_GET() \
342 struct wl_iface *ci; \
343 if (unlikely(!(wl_cfg80211_dev && \
344 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
345 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
351 #define CHECK_SYS_UP() \
353 struct wl_priv *wl = wiphy_to_wl(wiphy); \
354 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
355 WL_INFO(("device is not ready : status (%d)\n", \
361 extern int dhd_wait_pend8021x(struct net_device *dev);
363 #if (WL_DBG_LEVEL > 0)
364 #define WL_DBG_ESTR_MAX 32
365 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
366 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
367 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
368 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
369 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
370 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
371 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
372 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
374 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
376 "RADIO", "PSM_WATCHDOG",
378 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
379 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
380 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
382 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
384 #endif /* WL_DBG_LEVEL */
386 #define CHAN2G(_channel, _freq, _flags) { \
387 .band = IEEE80211_BAND_2GHZ, \
388 .center_freq = (_freq), \
389 .hw_value = (_channel), \
391 .max_antenna_gain = 0, \
395 #define CHAN5G(_channel, _flags) { \
396 .band = IEEE80211_BAND_5GHZ, \
397 .center_freq = 5000 + (5 * (_channel)), \
398 .hw_value = (_channel), \
400 .max_antenna_gain = 0, \
404 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
405 #define RATETAB_ENT(_rateid, _flags) \
407 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
408 .hw_value = (_rateid), \
412 static struct ieee80211_rate __wl_rates[] = {
413 RATETAB_ENT(WLC_RATE_1M, 0),
414 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
415 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
416 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
417 RATETAB_ENT(WLC_RATE_6M, 0),
418 RATETAB_ENT(WLC_RATE_9M, 0),
419 RATETAB_ENT(WLC_RATE_12M, 0),
420 RATETAB_ENT(WLC_RATE_18M, 0),
421 RATETAB_ENT(WLC_RATE_24M, 0),
422 RATETAB_ENT(WLC_RATE_36M, 0),
423 RATETAB_ENT(WLC_RATE_48M, 0),
424 RATETAB_ENT(WLC_RATE_54M, 0),
427 #define wl_a_rates (__wl_rates + 4)
428 #define wl_a_rates_size 8
429 #define wl_g_rates (__wl_rates + 0)
430 #define wl_g_rates_size 12
432 static struct ieee80211_channel __wl_2ghz_channels[] = {
449 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
450 CHAN5G(34, 0), CHAN5G(36, 0),
451 CHAN5G(38, 0), CHAN5G(40, 0),
452 CHAN5G(42, 0), CHAN5G(44, 0),
453 CHAN5G(46, 0), CHAN5G(48, 0),
454 CHAN5G(52, 0), CHAN5G(56, 0),
455 CHAN5G(60, 0), CHAN5G(64, 0),
456 CHAN5G(100, 0), CHAN5G(104, 0),
457 CHAN5G(108, 0), CHAN5G(112, 0),
458 CHAN5G(116, 0), CHAN5G(120, 0),
459 CHAN5G(124, 0), CHAN5G(128, 0),
460 CHAN5G(132, 0), CHAN5G(136, 0),
461 CHAN5G(140, 0), CHAN5G(149, 0),
462 CHAN5G(153, 0), CHAN5G(157, 0),
463 CHAN5G(161, 0), CHAN5G(165, 0),
464 CHAN5G(184, 0), CHAN5G(188, 0),
465 CHAN5G(192, 0), CHAN5G(196, 0),
466 CHAN5G(200, 0), CHAN5G(204, 0),
467 CHAN5G(208, 0), CHAN5G(212, 0),
471 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
472 CHAN5G(32, 0), CHAN5G(34, 0),
473 CHAN5G(36, 0), CHAN5G(38, 0),
474 CHAN5G(40, 0), CHAN5G(42, 0),
475 CHAN5G(44, 0), CHAN5G(46, 0),
476 CHAN5G(48, 0), CHAN5G(50, 0),
477 CHAN5G(52, 0), CHAN5G(54, 0),
478 CHAN5G(56, 0), CHAN5G(58, 0),
479 CHAN5G(60, 0), CHAN5G(62, 0),
480 CHAN5G(64, 0), CHAN5G(66, 0),
481 CHAN5G(68, 0), CHAN5G(70, 0),
482 CHAN5G(72, 0), CHAN5G(74, 0),
483 CHAN5G(76, 0), CHAN5G(78, 0),
484 CHAN5G(80, 0), CHAN5G(82, 0),
485 CHAN5G(84, 0), CHAN5G(86, 0),
486 CHAN5G(88, 0), CHAN5G(90, 0),
487 CHAN5G(92, 0), CHAN5G(94, 0),
488 CHAN5G(96, 0), CHAN5G(98, 0),
489 CHAN5G(100, 0), CHAN5G(102, 0),
490 CHAN5G(104, 0), CHAN5G(106, 0),
491 CHAN5G(108, 0), CHAN5G(110, 0),
492 CHAN5G(112, 0), CHAN5G(114, 0),
493 CHAN5G(116, 0), CHAN5G(118, 0),
494 CHAN5G(120, 0), CHAN5G(122, 0),
495 CHAN5G(124, 0), CHAN5G(126, 0),
496 CHAN5G(128, 0), CHAN5G(130, 0),
497 CHAN5G(132, 0), CHAN5G(134, 0),
498 CHAN5G(136, 0), CHAN5G(138, 0),
499 CHAN5G(140, 0), CHAN5G(142, 0),
500 CHAN5G(144, 0), CHAN5G(145, 0),
501 CHAN5G(146, 0), CHAN5G(147, 0),
502 CHAN5G(148, 0), CHAN5G(149, 0),
503 CHAN5G(150, 0), CHAN5G(151, 0),
504 CHAN5G(152, 0), CHAN5G(153, 0),
505 CHAN5G(154, 0), CHAN5G(155, 0),
506 CHAN5G(156, 0), CHAN5G(157, 0),
507 CHAN5G(158, 0), CHAN5G(159, 0),
508 CHAN5G(160, 0), CHAN5G(161, 0),
509 CHAN5G(162, 0), CHAN5G(163, 0),
510 CHAN5G(164, 0), CHAN5G(165, 0),
511 CHAN5G(166, 0), CHAN5G(168, 0),
512 CHAN5G(170, 0), CHAN5G(172, 0),
513 CHAN5G(174, 0), CHAN5G(176, 0),
514 CHAN5G(178, 0), CHAN5G(180, 0),
515 CHAN5G(182, 0), CHAN5G(184, 0),
516 CHAN5G(186, 0), CHAN5G(188, 0),
517 CHAN5G(190, 0), CHAN5G(192, 0),
518 CHAN5G(194, 0), CHAN5G(196, 0),
519 CHAN5G(198, 0), CHAN5G(200, 0),
520 CHAN5G(202, 0), CHAN5G(204, 0),
521 CHAN5G(206, 0), CHAN5G(208, 0),
522 CHAN5G(210, 0), CHAN5G(212, 0),
523 CHAN5G(214, 0), CHAN5G(216, 0),
524 CHAN5G(218, 0), CHAN5G(220, 0),
525 CHAN5G(222, 0), CHAN5G(224, 0),
526 CHAN5G(226, 0), CHAN5G(228, 0),
529 static struct ieee80211_supported_band __wl_band_2ghz = {
530 .band = IEEE80211_BAND_2GHZ,
531 .channels = __wl_2ghz_channels,
532 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
533 .bitrates = wl_g_rates,
534 .n_bitrates = wl_g_rates_size,
537 static struct ieee80211_supported_band __wl_band_5ghz_a = {
538 .band = IEEE80211_BAND_5GHZ,
539 .channels = __wl_5ghz_a_channels,
540 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
541 .bitrates = wl_a_rates,
542 .n_bitrates = wl_a_rates_size,
545 static struct ieee80211_supported_band __wl_band_5ghz_n = {
546 .band = IEEE80211_BAND_5GHZ,
547 .channels = __wl_5ghz_n_channels,
548 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
549 .bitrates = wl_a_rates,
550 .n_bitrates = wl_a_rates_size,
553 static const u32 __wl_cipher_suites[] = {
554 WLAN_CIPHER_SUITE_WEP40,
555 WLAN_CIPHER_SUITE_WEP104,
556 WLAN_CIPHER_SUITE_TKIP,
557 WLAN_CIPHER_SUITE_CCMP,
558 WLAN_CIPHER_SUITE_AES_CMAC,
561 static void swap_key_from_BE(struct wl_wsec_key *key)
563 key->index = htod32(key->index);
564 key->len = htod32(key->len);
565 key->algo = htod32(key->algo);
566 key->flags = htod32(key->flags);
567 key->rxiv.hi = htod32(key->rxiv.hi);
568 key->rxiv.lo = htod16(key->rxiv.lo);
569 key->iv_initialized = htod32(key->iv_initialized);
572 static void swap_key_to_BE(struct wl_wsec_key *key)
574 key->index = dtoh32(key->index);
575 key->len = dtoh32(key->len);
576 key->algo = dtoh32(key->algo);
577 key->flags = dtoh32(key->flags);
578 key->rxiv.hi = dtoh32(key->rxiv.hi);
579 key->rxiv.lo = dtoh16(key->rxiv.lo);
580 key->iv_initialized = dtoh32(key->iv_initialized);
584 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
591 memset(&ioc, 0, sizeof(ioc));
595 strcpy(ifr.ifr_name, dev->name);
596 ifr.ifr_data = (caddr_t)&ioc;
600 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
607 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
608 enum nl80211_iftype type, u32 *flags,
609 struct vif_params *params)
611 struct wl_priv *wl = wiphy_to_wl(wiphy);
612 struct wireless_dev *wdev;
619 case NL80211_IFTYPE_MONITOR:
620 case NL80211_IFTYPE_WDS:
621 WL_ERR(("type (%d) : currently we do not support this type\n",
624 case NL80211_IFTYPE_ADHOC:
625 wl->conf->mode = WL_MODE_IBSS;
627 case NL80211_IFTYPE_STATION:
628 wl->conf->mode = WL_MODE_BSS;
634 infra = htod32(infra);
636 wdev = ndev->ieee80211_ptr;
638 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
639 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
641 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
644 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
646 WL_ERR(("WLC_SET_AP error (%d)\n", err));
650 /* -EINPROGRESS: Call commit handler */
654 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
656 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
657 params->bss_type = DOT11_BSSTYPE_ANY;
658 params->scan_type = 0;
659 params->nprobes = -1;
660 params->active_time = -1;
661 params->passive_time = -1;
662 params->home_time = -1;
663 params->channel_num = 0;
665 params->nprobes = htod32(params->nprobes);
666 params->active_time = htod32(params->active_time);
667 params->passive_time = htod32(params->passive_time);
668 params->home_time = htod32(params->home_time);
669 if (ssid && ssid->SSID_len)
670 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
675 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
676 s32 paramlen, void *bufptr, s32 buflen)
680 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
681 BUG_ON(unlikely(!iolen));
683 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
687 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
688 s32 paramlen, void *bufptr, s32 buflen)
692 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
693 BUG_ON(unlikely(!iolen));
695 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
699 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
702 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
703 struct wl_iscan_params *params;
706 if (ssid && ssid->SSID_len)
707 params_size += sizeof(struct wlc_ssid);
708 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
709 if (unlikely(!params))
711 memset(params, 0, params_size);
712 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
714 wl_iscan_prep(¶ms->params, ssid);
716 params->version = htod32(ISCAN_REQ_VERSION);
717 params->action = htod16(action);
718 params->scan_duration = htod16(0);
720 /* params_size += offsetof(wl_iscan_params_t, params); */
721 err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
722 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
725 WL_INFO(("system busy : iscan canceled\n"));
727 WL_ERR(("error (%d)\n", err));
734 static s32 wl_do_iscan(struct wl_priv *wl)
736 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
737 struct net_device *ndev = wl_to_ndev(wl);
738 struct wlc_ssid ssid;
742 /* Broadcast scan by default */
743 memset(&ssid, 0, sizeof(ssid));
745 iscan->state = WL_ISCAN_STATE_SCANING;
747 passive_scan = wl->active_scan ? 0 : 1;
748 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
749 &passive_scan, sizeof(passive_scan));
751 WL_DBG(("error (%d)\n", err));
755 wl->iscan_kickstart = true;
756 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
757 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
764 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
765 struct cfg80211_scan_request *request,
766 struct cfg80211_ssid *this_ssid)
768 struct wl_priv *wl = ndev_to_wl(ndev);
769 struct cfg80211_ssid *ssids;
770 struct wl_scan_req *sr = wl_to_sr(wl);
776 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
777 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
780 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
781 WL_ERR(("Scanning being aborted : status (%d)\n",
788 if (request) { /* scan bss */
789 ssids = request->ssids;
790 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) { /* for
792 * ssids->ssid_len has
793 * non-zero(ssid string)
795 * Otherwise this is 0.
796 * we do not iscan for
797 * specific scan request
801 } else { /* scan in ibss */
802 /* we don't do iscan in ibss */
805 wl->scan_request = request;
806 set_bit(WL_STATUS_SCANNING, &wl->status);
808 err = wl_do_iscan(wl);
814 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
815 ssids->ssid, ssids->ssid_len));
816 memset(&sr->ssid, 0, sizeof(sr->ssid));
818 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
819 if (sr->ssid.SSID_len) {
820 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
821 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
822 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
823 sr->ssid.SSID, sr->ssid.SSID_len));
826 WL_DBG(("Broadcast scan\n"));
828 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
829 passive_scan = wl->active_scan ? 0 : 1;
830 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
831 &passive_scan, sizeof(passive_scan));
833 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
837 err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
841 WL_INFO(("system busy : scan for \"%s\" "
842 "canceled\n", sr->ssid.SSID));
844 WL_ERR(("WLC_SCAN error (%d)\n", err));
854 clear_bit(WL_STATUS_SCANNING, &wl->status);
855 wl->scan_request = NULL;
860 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
861 struct cfg80211_scan_request *request)
866 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
868 WL_DBG(("scan error (%d)\n", err));
875 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
877 s8 buf[WLC_IOCTL_SMLEN];
882 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
883 BUG_ON(unlikely(!len));
885 err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
887 WL_ERR(("error (%d)\n", err));
894 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
897 s8 buf[WLC_IOCTL_SMLEN];
905 bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
907 BUG_ON(unlikely(!len));
908 err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
910 WL_ERR(("error (%d)\n", err));
912 *retval = dtoh32(var.val);
917 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
921 err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
923 WL_ERR(("Error (%d)\n", err));
929 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
933 err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
935 WL_ERR(("Error (%d)\n", err));
941 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
944 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
946 retry = htod32(retry);
947 err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
949 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
955 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
957 struct wl_priv *wl = wiphy_to_wl(wiphy);
958 struct net_device *ndev = wl_to_ndev(wl);
962 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
963 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
964 wl->conf->rts_threshold = wiphy->rts_threshold;
965 err = wl_set_rts(ndev, wl->conf->rts_threshold);
969 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
970 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
971 wl->conf->frag_threshold = wiphy->frag_threshold;
972 err = wl_set_frag(ndev, wl->conf->frag_threshold);
976 if (changed & WIPHY_PARAM_RETRY_LONG
977 && (wl->conf->retry_long != wiphy->retry_long)) {
978 wl->conf->retry_long = wiphy->retry_long;
979 err = wl_set_retry(ndev, wl->conf->retry_long, true);
983 if (changed & WIPHY_PARAM_RETRY_SHORT
984 && (wl->conf->retry_short != wiphy->retry_short)) {
985 wl->conf->retry_short = wiphy->retry_short;
986 err = wl_set_retry(ndev, wl->conf->retry_short, false);
996 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
997 struct cfg80211_ibss_params *params)
999 struct wl_priv *wl = wiphy_to_wl(wiphy);
1000 struct cfg80211_bss *bss;
1001 struct ieee80211_channel *chan;
1002 struct wl_join_params join_params;
1003 struct cfg80211_ssid ssid;
1008 if (params->bssid) {
1009 WL_ERR(("Invalid bssid\n"));
1012 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1014 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1015 ssid.ssid_len = params->ssid_len;
1018 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1024 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1025 rtnl_unlock(); /* to allow scan_inform to paropagate
1026 to cfg80211 plane */
1027 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1028 till scan done.... */
1030 bss = cfg80211_get_ibss(wiphy, NULL,
1031 params->ssid, params->ssid_len);
1034 wl->ibss_starter = false;
1035 WL_DBG(("Found IBSS\n"));
1037 wl->ibss_starter = true;
1039 chan = params->channel;
1041 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1043 ** Join with specific BSSID and cached SSID
1044 ** If SSID is zero join based on BSSID only
1046 memset(&join_params, 0, sizeof(join_params));
1047 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1049 join_params.ssid.SSID_len = htod32(params->ssid_len);
1051 memcpy(&join_params.params.bssid, params->bssid,
1054 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1056 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1057 sizeof(join_params));
1058 if (unlikely(err)) {
1059 WL_ERR(("Error (%d)\n", err));
1065 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1067 struct wl_priv *wl = wiphy_to_wl(wiphy);
1077 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1079 struct wl_priv *wl = ndev_to_wl(dev);
1080 struct wl_security *sec;
1084 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1085 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1086 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1087 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1089 val = WPA_AUTH_DISABLED;
1090 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1091 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1092 if (unlikely(err)) {
1093 WL_ERR(("set wpa_auth failed (%d)\n", err));
1096 sec = wl_read_prof(wl, WL_PROF_SEC);
1097 sec->wpa_versions = sme->crypto.wpa_versions;
1102 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1104 struct wl_priv *wl = ndev_to_wl(dev);
1105 struct wl_security *sec;
1109 switch (sme->auth_type) {
1110 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1112 WL_DBG(("open system\n"));
1114 case NL80211_AUTHTYPE_SHARED_KEY:
1116 WL_DBG(("shared key\n"));
1118 case NL80211_AUTHTYPE_AUTOMATIC:
1120 WL_DBG(("automatic\n"));
1122 case NL80211_AUTHTYPE_NETWORK_EAP:
1123 WL_DBG(("network eap\n"));
1126 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1130 err = wl_dev_intvar_set(dev, "auth", val);
1131 if (unlikely(err)) {
1132 WL_ERR(("set auth failed (%d)\n", err));
1135 sec = wl_read_prof(wl, WL_PROF_SEC);
1136 sec->auth_type = sme->auth_type;
1141 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1143 struct wl_priv *wl = ndev_to_wl(dev);
1144 struct wl_security *sec;
1149 if (sme->crypto.n_ciphers_pairwise) {
1150 switch (sme->crypto.ciphers_pairwise[0]) {
1151 case WLAN_CIPHER_SUITE_WEP40:
1152 case WLAN_CIPHER_SUITE_WEP104:
1155 case WLAN_CIPHER_SUITE_TKIP:
1156 pval = TKIP_ENABLED;
1158 case WLAN_CIPHER_SUITE_CCMP:
1161 case WLAN_CIPHER_SUITE_AES_CMAC:
1165 WL_ERR(("invalid cipher pairwise (%d)\n",
1166 sme->crypto.ciphers_pairwise[0]));
1170 if (sme->crypto.cipher_group) {
1171 switch (sme->crypto.cipher_group) {
1172 case WLAN_CIPHER_SUITE_WEP40:
1173 case WLAN_CIPHER_SUITE_WEP104:
1176 case WLAN_CIPHER_SUITE_TKIP:
1177 gval = TKIP_ENABLED;
1179 case WLAN_CIPHER_SUITE_CCMP:
1182 case WLAN_CIPHER_SUITE_AES_CMAC:
1186 WL_ERR(("invalid cipher group (%d)\n",
1187 sme->crypto.cipher_group));
1192 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1193 err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1194 if (unlikely(err)) {
1195 WL_ERR(("error (%d)\n", err));
1199 sec = wl_read_prof(wl, WL_PROF_SEC);
1200 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1201 sec->cipher_group = sme->crypto.cipher_group;
1207 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1209 struct wl_priv *wl = ndev_to_wl(dev);
1210 struct wl_security *sec;
1214 if (sme->crypto.n_akm_suites) {
1215 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1216 if (unlikely(err)) {
1217 WL_ERR(("could not get wpa_auth (%d)\n", err));
1220 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1221 switch (sme->crypto.akm_suites[0]) {
1222 case WLAN_AKM_SUITE_8021X:
1223 val = WPA_AUTH_UNSPECIFIED;
1225 case WLAN_AKM_SUITE_PSK:
1229 WL_ERR(("invalid cipher group (%d)\n",
1230 sme->crypto.cipher_group));
1233 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1234 switch (sme->crypto.akm_suites[0]) {
1235 case WLAN_AKM_SUITE_8021X:
1236 val = WPA2_AUTH_UNSPECIFIED;
1238 case WLAN_AKM_SUITE_PSK:
1239 val = WPA2_AUTH_PSK;
1242 WL_ERR(("invalid cipher group (%d)\n",
1243 sme->crypto.cipher_group));
1248 WL_DBG(("setting wpa_auth to %d\n", val));
1249 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1250 if (unlikely(err)) {
1251 WL_ERR(("could not set wpa_auth (%d)\n", err));
1255 sec = wl_read_prof(wl, WL_PROF_SEC);
1256 sec->wpa_auth = sme->crypto.akm_suites[0];
1262 wl_set_set_sharedkey(struct net_device *dev,
1263 struct cfg80211_connect_params *sme)
1265 struct wl_priv *wl = ndev_to_wl(dev);
1266 struct wl_security *sec;
1267 struct wl_wsec_key key;
1271 WL_DBG(("key len (%d)\n", sme->key_len));
1273 sec = wl_read_prof(wl, WL_PROF_SEC);
1274 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1275 sec->wpa_versions, sec->cipher_pairwise));
1277 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1278 NL80211_WPA_VERSION_2))
1279 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1280 WLAN_CIPHER_SUITE_WEP104))) {
1281 memset(&key, 0, sizeof(key));
1282 key.len = (u32) sme->key_len;
1283 key.index = (u32) sme->key_idx;
1284 if (unlikely(key.len > sizeof(key.data))) {
1285 WL_ERR(("Too long key length (%u)\n", key.len));
1288 memcpy(key.data, sme->key, key.len);
1289 key.flags = WL_PRIMARY_KEY;
1290 switch (sec->cipher_pairwise) {
1291 case WLAN_CIPHER_SUITE_WEP40:
1292 key.algo = CRYPTO_ALGO_WEP1;
1294 case WLAN_CIPHER_SUITE_WEP104:
1295 key.algo = CRYPTO_ALGO_WEP128;
1298 WL_ERR(("Invalid algorithm (%d)\n",
1299 sme->crypto.ciphers_pairwise[0]));
1302 /* Set the new key/index */
1303 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1304 key.len, key.index, key.algo));
1305 WL_DBG(("key \"%s\"\n", key.data));
1306 swap_key_from_BE(&key);
1307 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1309 if (unlikely(err)) {
1310 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1313 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1314 WL_DBG(("set auth_type to shared key\n"));
1315 val = 1; /* shared key */
1316 err = wl_dev_intvar_set(dev, "auth", val);
1317 if (unlikely(err)) {
1318 WL_ERR(("set auth failed (%d)\n", err));
1328 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1329 struct cfg80211_connect_params *sme)
1331 struct wl_priv *wl = wiphy_to_wl(wiphy);
1332 struct ieee80211_channel *chan = sme->channel;
1333 struct wl_join_params join_params;
1334 size_t join_params_size;
1339 if (unlikely(!sme->ssid)) {
1340 WL_ERR(("Invalid ssid\n"));
1344 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1345 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
1346 chan->center_freq));
1348 WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
1349 err = wl_set_wpa_version(dev, sme);
1353 err = wl_set_auth_type(dev, sme);
1357 err = wl_set_set_cipher(dev, sme);
1361 err = wl_set_key_mgmt(dev, sme);
1365 err = wl_set_set_sharedkey(dev, sme);
1369 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1371 ** Join with specific BSSID and cached SSID
1372 ** If SSID is zero join based on BSSID only
1374 memset(&join_params, 0, sizeof(join_params));
1375 join_params_size = sizeof(join_params.ssid);
1377 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1378 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1379 join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
1380 wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1381 memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1383 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1384 WL_DBG(("join_param_size %d\n", join_params_size));
1386 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1387 WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
1388 join_params.ssid.SSID_len));
1390 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1391 if (unlikely(err)) {
1392 WL_ERR(("error (%d)\n", err));
1395 set_bit(WL_STATUS_CONNECTING, &wl->status);
1401 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1404 struct wl_priv *wl = wiphy_to_wl(wiphy);
1409 WL_DBG(("Reason %d\n", reason_code));
1411 act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
1413 scbval.val = reason_code;
1414 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1415 scbval.val = htod32(scbval.val);
1416 err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1418 if (unlikely(err)) {
1419 WL_ERR(("error (%d)\n", err));
1428 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1429 enum nl80211_tx_power_setting type, s32 dbm)
1432 struct wl_priv *wl = wiphy_to_wl(wiphy);
1433 struct net_device *ndev = wl_to_ndev(wl);
1440 case NL80211_TX_POWER_AUTOMATIC:
1442 case NL80211_TX_POWER_LIMITED:
1444 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1448 case NL80211_TX_POWER_FIXED:
1450 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1455 /* Make sure radio is off or on as far as software is concerned */
1456 disable = WL_RADIO_SW_DISABLE << 16;
1457 disable = htod32(disable);
1458 err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1459 if (unlikely(err)) {
1460 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1467 txpwrmw = (u16) dbm;
1468 err = wl_dev_intvar_set(ndev, "qtxpower",
1469 (s32) (bcm_mw_to_qdbm(txpwrmw)));
1470 if (unlikely(err)) {
1471 WL_ERR(("qtxpower error (%d)\n", err));
1474 wl->conf->tx_power = dbm;
1479 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1481 struct wl_priv *wl = wiphy_to_wl(wiphy);
1482 struct net_device *ndev = wl_to_ndev(wl);
1488 err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1489 if (unlikely(err)) {
1490 WL_ERR(("error (%d)\n", err));
1493 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1494 *dbm = (s32) bcm_qdbm_to_mw(result);
1500 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1507 WL_DBG(("key index (%d)\n", key_idx));
1510 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1511 if (unlikely(err)) {
1512 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1515 wsec = dtoh32(wsec);
1516 if (wsec & WEP_ENABLED) {
1517 /* Just select a new current key */
1518 index = (u32) key_idx;
1519 index = htod32(index);
1520 err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
1522 if (unlikely(err)) {
1523 WL_ERR(("error (%d)\n", err));
1530 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1531 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1533 struct wl_wsec_key key;
1536 memset(&key, 0, sizeof(key));
1537 key.index = (u32) key_idx;
1538 /* Instead of bcast for ea address for default wep keys,
1539 driver needs it to be Null */
1540 if (!ETHER_ISMULTI(mac_addr))
1541 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1542 key.len = (u32) params->key_len;
1543 /* check for key index change */
1546 swap_key_from_BE(&key);
1547 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1548 if (unlikely(err)) {
1549 WL_ERR(("key delete error (%d)\n", err));
1553 if (key.len > sizeof(key.data)) {
1554 WL_ERR(("Invalid key length (%d)\n", key.len));
1558 WL_DBG(("Setting the key index %d\n", key.index));
1559 memcpy(key.data, params->key, key.len);
1561 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1563 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1564 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1565 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1568 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1569 if (params->seq && params->seq_len == 6) {
1572 ivptr = (u8 *) params->seq;
1573 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1574 (ivptr[3] << 8) | ivptr[2];
1575 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1576 key.iv_initialized = true;
1579 switch (params->cipher) {
1580 case WLAN_CIPHER_SUITE_WEP40:
1581 key.algo = CRYPTO_ALGO_WEP1;
1582 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1584 case WLAN_CIPHER_SUITE_WEP104:
1585 key.algo = CRYPTO_ALGO_WEP128;
1586 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1588 case WLAN_CIPHER_SUITE_TKIP:
1589 key.algo = CRYPTO_ALGO_TKIP;
1590 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1592 case WLAN_CIPHER_SUITE_AES_CMAC:
1593 key.algo = CRYPTO_ALGO_AES_CCM;
1594 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1596 case WLAN_CIPHER_SUITE_CCMP:
1597 key.algo = CRYPTO_ALGO_AES_CCM;
1598 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1601 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1604 swap_key_from_BE(&key);
1606 dhd_wait_pend8021x(dev);
1607 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1608 if (unlikely(err)) {
1609 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1617 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1618 u8 key_idx, const u8 *mac_addr,
1619 struct key_params *params)
1621 struct wl_wsec_key key;
1626 WL_DBG(("key index (%d)\n", key_idx));
1630 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1631 memset(&key, 0, sizeof(key));
1633 key.len = (u32) params->key_len;
1634 key.index = (u32) key_idx;
1636 if (unlikely(key.len > sizeof(key.data))) {
1637 WL_ERR(("Too long key length (%u)\n", key.len));
1640 memcpy(key.data, params->key, key.len);
1642 key.flags = WL_PRIMARY_KEY;
1643 switch (params->cipher) {
1644 case WLAN_CIPHER_SUITE_WEP40:
1645 key.algo = CRYPTO_ALGO_WEP1;
1646 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1648 case WLAN_CIPHER_SUITE_WEP104:
1649 key.algo = CRYPTO_ALGO_WEP128;
1650 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1652 case WLAN_CIPHER_SUITE_TKIP:
1653 key.algo = CRYPTO_ALGO_TKIP;
1654 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1656 case WLAN_CIPHER_SUITE_AES_CMAC:
1657 key.algo = CRYPTO_ALGO_AES_CCM;
1658 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1660 case WLAN_CIPHER_SUITE_CCMP:
1661 key.algo = CRYPTO_ALGO_AES_CCM;
1662 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1665 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1669 /* Set the new key/index */
1670 swap_key_from_BE(&key);
1671 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1672 if (unlikely(err)) {
1673 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1678 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1679 if (unlikely(err)) {
1680 WL_ERR(("get wsec error (%d)\n", err));
1683 wsec &= ~(WEP_ENABLED);
1685 err = wl_dev_intvar_set(dev, "wsec", wsec);
1686 if (unlikely(err)) {
1687 WL_ERR(("set wsec error (%d)\n", err));
1691 val = 1; /* assume shared key. otherwise 0 */
1693 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1694 if (unlikely(err)) {
1695 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1702 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1703 u8 key_idx, const u8 *mac_addr)
1705 struct wl_wsec_key key;
1711 memset(&key, 0, sizeof(key));
1713 key.index = (u32) key_idx;
1714 key.flags = WL_PRIMARY_KEY;
1715 key.algo = CRYPTO_ALGO_OFF;
1717 WL_DBG(("key index (%d)\n", key_idx));
1718 /* Set the new key/index */
1719 swap_key_from_BE(&key);
1720 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1721 if (unlikely(err)) {
1722 if (err == -EINVAL) {
1723 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1724 /* we ignore this key index in this case */
1725 WL_DBG(("invalid key index (%d)\n", key_idx));
1728 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1734 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1735 if (unlikely(err)) {
1736 WL_ERR(("get wsec error (%d)\n", err));
1739 wsec &= ~(WEP_ENABLED);
1741 err = wl_dev_intvar_set(dev, "wsec", wsec);
1742 if (unlikely(err)) {
1743 WL_ERR(("set wsec error (%d)\n", err));
1747 val = 0; /* assume open key. otherwise 1 */
1749 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1750 if (unlikely(err)) {
1751 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1758 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1759 u8 key_idx, const u8 *mac_addr, void *cookie,
1760 void (*callback) (void *cookie, struct key_params * params))
1762 struct key_params params;
1763 struct wl_wsec_key key;
1764 struct wl_priv *wl = wiphy_to_wl(wiphy);
1765 struct wl_security *sec;
1769 WL_DBG(("key index (%d)\n", key_idx));
1772 memset(&key, 0, sizeof(key));
1773 key.index = key_idx;
1774 swap_key_to_BE(&key);
1775 memset(¶ms, 0, sizeof(params));
1776 params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
1777 memcpy(params.key, key.data, params.key_len);
1779 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1780 if (unlikely(err)) {
1781 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1784 wsec = dtoh32(wsec);
1787 sec = wl_read_prof(wl, WL_PROF_SEC);
1788 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1789 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1790 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1791 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1792 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1793 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1797 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1798 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1801 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1802 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1805 WL_ERR(("Invalid algo (0x%x)\n", wsec));
1809 callback(cookie, ¶ms);
1814 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1815 struct net_device *dev, u8 key_idx)
1817 WL_INFO(("Not supported\n"));
1823 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1824 u8 *mac, struct station_info *sinfo)
1826 struct wl_priv *wl = wiphy_to_wl(wiphy);
1834 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
1835 WL_ERR(("Wrong Mac address\n"));
1839 /* Report the current tx rate */
1840 err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1842 WL_ERR(("Could not get rate (%d)\n", err));
1844 rate = dtoh32(rate);
1845 sinfo->filled |= STATION_INFO_TX_BITRATE;
1846 sinfo->txrate.legacy = rate * 5;
1847 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1850 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1852 err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1854 if (unlikely(err)) {
1855 WL_ERR(("Could not get rssi (%d)\n", err));
1858 rssi = dtoh32(scb_val.val);
1859 sinfo->filled |= STATION_INFO_SIGNAL;
1860 sinfo->signal = rssi;
1861 WL_DBG(("RSSI %d dBm\n", rssi));
1868 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1869 bool enabled, s32 timeout)
1875 pm = enabled ? PM_FAST : PM_OFF;
1877 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1878 err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1879 if (unlikely(err)) {
1881 WL_DBG(("net_device is not ready yet\n"));
1883 WL_ERR(("error (%d)\n", err));
1889 static __used u32 wl_find_msb(u16 bit16)
1893 if (bit16 & 0xff00) {
1917 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1919 const struct cfg80211_bitrate_mask *mask)
1921 struct wl_rateset rateset;
1930 /* addr param is always NULL. ignore it */
1931 /* Get current rateset */
1932 err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1934 if (unlikely(err)) {
1935 WL_ERR(("could not get current rateset (%d)\n", err));
1939 rateset.count = dtoh32(rateset.count);
1941 legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
1943 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1945 val = wl_g_rates[legacy - 1].bitrate * 100000;
1947 if (val < rateset.count) {
1948 /* Select rate by rateset index */
1949 rate = rateset.rates[val] & 0x7f;
1951 /* Specified rate in bps */
1952 rate = val / 500000;
1955 WL_DBG(("rate %d mbps\n", (rate / 2)));
1959 * Set rate override,
1960 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1962 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1963 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1964 if (unlikely(err_bg && err_a)) {
1965 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
1966 return err_bg | err_a;
1972 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
1977 wl_invoke_iscan(wiphy_to_wl(wiphy));
1982 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
1984 struct wl_priv *wl = wiphy_to_wl(wiphy);
1985 struct net_device *ndev = wl_to_ndev(wl);
1990 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1992 if (wl->scan_request) {
1993 cfg80211_scan_done(wl->scan_request, true); /* true means
1995 wl_set_mpc(ndev, 1);
1996 wl->scan_request = NULL;
1998 clear_bit(WL_STATUS_SCANNING, &wl->status);
1999 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2005 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2010 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2011 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2012 WL_DBG(("PMKID[%d]: %pM =\n", i,
2013 &pmk_list->pmkids.pmkid[i].BSSID));
2014 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2015 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2019 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2027 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2028 struct cfg80211_pmksa *pmksa)
2030 struct wl_priv *wl = wiphy_to_wl(wiphy);
2035 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2036 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2039 if (i < WL_NUM_PMKIDS_MAX) {
2040 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2042 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2044 if (i == wl->pmk_list->pmkids.npmkid)
2045 wl->pmk_list->pmkids.npmkid++;
2049 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2050 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2051 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2053 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2057 err = wl_update_pmklist(dev, wl->pmk_list, err);
2063 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2064 struct cfg80211_pmksa *pmksa)
2066 struct wl_priv *wl = wiphy_to_wl(wiphy);
2067 struct _pmkid_list pmkid;
2072 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2073 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2075 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2076 &pmkid.pmkid[0].BSSID));
2077 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2078 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2081 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2083 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2087 if ((wl->pmk_list->pmkids.npmkid > 0)
2088 && (i < wl->pmk_list->pmkids.npmkid)) {
2089 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2090 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2091 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2092 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2094 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2095 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2098 wl->pmk_list->pmkids.npmkid--;
2103 err = wl_update_pmklist(dev, wl->pmk_list, err);
2110 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2112 struct wl_priv *wl = wiphy_to_wl(wiphy);
2116 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2117 err = wl_update_pmklist(dev, wl->pmk_list, err);
2122 static struct cfg80211_ops wl_cfg80211_ops = {
2123 .change_virtual_intf = wl_cfg80211_change_iface,
2124 .scan = wl_cfg80211_scan,
2125 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2126 .join_ibss = wl_cfg80211_join_ibss,
2127 .leave_ibss = wl_cfg80211_leave_ibss,
2128 .get_station = wl_cfg80211_get_station,
2129 .set_tx_power = wl_cfg80211_set_tx_power,
2130 .get_tx_power = wl_cfg80211_get_tx_power,
2131 .add_key = wl_cfg80211_add_key,
2132 .del_key = wl_cfg80211_del_key,
2133 .get_key = wl_cfg80211_get_key,
2134 .set_default_key = wl_cfg80211_config_default_key,
2135 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2136 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2137 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2138 .connect = wl_cfg80211_connect,
2139 .disconnect = wl_cfg80211_disconnect,
2140 .suspend = wl_cfg80211_suspend,
2141 .resume = wl_cfg80211_resume,
2142 .set_pmksa = wl_cfg80211_set_pmksa,
2143 .del_pmksa = wl_cfg80211_del_pmksa,
2144 .flush_pmksa = wl_cfg80211_flush_pmksa
2147 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2153 return NL80211_IFTYPE_STATION;
2155 return NL80211_IFTYPE_ADHOC;
2157 return NL80211_IFTYPE_UNSPECIFIED;
2163 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2166 struct wireless_dev *wdev;
2169 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2170 if (unlikely(!wdev)) {
2171 WL_ERR(("Could not allocate wireless device\n"));
2172 return ERR_PTR(-ENOMEM);
2175 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2176 if (unlikely(!wdev->wiphy)) {
2177 WL_ERR(("Couldn not allocate wiphy device\n"));
2181 set_wiphy_dev(wdev->wiphy, dev);
2182 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2183 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2184 wdev->wiphy->interface_modes =
2185 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2186 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2187 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2188 * it as 11a by default.
2189 * This will be updated with
2192 * if phy has 11n capability
2194 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2195 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2196 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2197 #ifndef WL_POWERSAVE_DISABLED
2198 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2203 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2204 #endif /* !WL_POWERSAVE_DISABLED */
2205 err = wiphy_register(wdev->wiphy);
2206 if (unlikely(err < 0)) {
2207 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2208 goto wiphy_register_out;
2213 wiphy_free(wdev->wiphy);
2218 return ERR_PTR(err);
2221 static void wl_free_wdev(struct wl_priv *wl)
2223 struct wireless_dev *wdev = wl_to_wdev(wl);
2225 if (unlikely(!wdev)) {
2226 WL_ERR(("wdev is invalid\n"));
2229 wiphy_unregister(wdev->wiphy);
2230 wiphy_free(wdev->wiphy);
2232 wl_to_wdev(wl) = NULL;
2235 static s32 wl_inform_bss(struct wl_priv *wl)
2237 struct wl_scan_results *bss_list;
2238 struct wl_bss_info *bi = NULL; /* must be initialized */
2242 bss_list = wl->bss_list;
2243 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2244 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2245 bss_list->version));
2248 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2249 bi = next_bss(bss_list, bi);
2250 for_each_bss(bss_list, bi, i) {
2251 err = wl_inform_single_bss(wl, bi);
2258 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2260 struct wiphy *wiphy = wl_to_wiphy(wl);
2261 struct ieee80211_mgmt *mgmt;
2262 struct ieee80211_channel *channel;
2263 struct ieee80211_supported_band *band;
2264 struct wl_cfg80211_bss_info *notif_bss_info;
2265 struct wl_scan_req *sr = wl_to_sr(wl);
2266 struct beacon_proberesp *beacon_proberesp;
2272 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
2273 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2277 kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2278 WL_BSS_INFO_MAX, GFP_KERNEL);
2279 if (unlikely(!notif_bss_info)) {
2280 WL_ERR(("notif_bss_info alloc failed\n"));
2283 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2284 notif_bss_info->channel =
2285 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
2287 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2288 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2290 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2291 notif_bss_info->rssi = bi->RSSI;
2292 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
2293 mgmt_type = wl->active_scan ?
2294 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
2295 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2296 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2299 beacon_proberesp = wl->active_scan ?
2300 (struct beacon_proberesp *)&mgmt->u.probe_resp :
2301 (struct beacon_proberesp *)&mgmt->u.beacon;
2302 beacon_proberesp->timestamp = 0;
2303 beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
2304 beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
2307 * wl_add_ie is not necessary because it can only add duplicated
2308 * SSID, rate information to frame_buf
2311 * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2312 * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2313 * bi->rateset.rates);
2315 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2316 wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
2317 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2318 notif_bss_info->frame_len =
2319 offsetof(struct ieee80211_mgmt,
2320 u.beacon.variable) + wl_get_ielen(wl);
2321 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2322 channel = ieee80211_get_channel(wiphy, freq);
2324 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
2326 notif_bss_info->rssi, notif_bss_info->channel,
2327 mgmt->u.beacon.capab_info, &bi->BSSID));
2329 signal = notif_bss_info->rssi * 100;
2330 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2332 (notif_bss_info->frame_len),
2333 signal, GFP_KERNEL))) {
2334 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2335 kfree(notif_bss_info);
2338 kfree(notif_bss_info);
2343 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2345 u32 event = ntoh32(e->event_type);
2346 u16 flags = ntoh16(e->flags);
2348 if (event == WLC_E_LINK) {
2349 if (flags & WLC_EVENT_MSG_LINK) {
2350 if (wl_is_ibssmode(wl)) {
2351 if (wl_is_ibssstarter(wl)) {
2362 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2364 u32 event = ntoh32(e->event_type);
2365 u16 flags = ntoh16(e->flags);
2367 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2369 } else if (event == WLC_E_LINK) {
2370 if (!(flags & WLC_EVENT_MSG_LINK))
2377 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2379 u32 event = ntoh32(e->event_type);
2380 u32 status = ntoh32(e->status);
2382 if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2383 if (status == WLC_E_STATUS_NO_NETWORKS)
2391 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2392 const wl_event_msg_t *e, void *data)
2397 if (wl_is_linkup(wl, e)) {
2399 if (wl_is_ibssmode(wl)) {
2400 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2402 WL_DBG(("joined in IBSS network\n"));
2404 wl_bss_connect_done(wl, ndev, e, data, true);
2405 WL_DBG(("joined in BSS network \"%s\"\n",
2406 ((struct wlc_ssid *)
2407 wl_read_prof(wl, WL_PROF_SSID))->SSID));
2410 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2411 } else if (wl_is_linkdown(wl, e)) {
2412 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2413 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2415 wl_init_prof(wl->profile);
2416 } else if (wl_is_nonetwork(wl, e)) {
2417 wl_bss_connect_done(wl, ndev, e, data, false);
2424 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2425 const wl_event_msg_t *e, void *data)
2430 wl_bss_roaming_done(wl, ndev, e, data);
2432 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2438 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2440 struct wl_priv *wl = ndev_to_wl(dev);
2443 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2444 BUG_ON(unlikely(!buflen));
2446 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2450 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2453 struct wl_priv *wl = ndev_to_wl(dev);
2457 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2458 BUG_ON(unlikely(!len));
2459 err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2461 if (unlikely(err)) {
2462 WL_ERR(("error (%d)\n", err));
2465 memcpy(buf, wl->ioctl_buf, buf_len);
2470 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2472 struct net_device *ndev = wl_to_ndev(wl);
2473 struct wl_assoc_ielen *assoc_info;
2474 struct wl_connect_info *conn_info = wl_to_conn(wl);
2479 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2481 if (unlikely(err)) {
2482 WL_ERR(("could not get assoc info (%d)\n", err));
2485 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2486 req_len = assoc_info->req_len;
2487 resp_len = assoc_info->resp_len;
2489 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2491 if (unlikely(err)) {
2492 WL_ERR(("could not get assoc req (%d)\n", err));
2495 conn_info->req_ie_len = req_len;
2497 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2499 conn_info->req_ie_len = 0;
2500 conn_info->req_ie = NULL;
2503 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2505 if (unlikely(err)) {
2506 WL_ERR(("could not get assoc resp (%d)\n", err));
2509 conn_info->resp_ie_len = resp_len;
2510 conn_info->resp_ie =
2511 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2513 conn_info->resp_ie_len = 0;
2514 conn_info->resp_ie = NULL;
2516 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2517 conn_info->resp_ie_len));
2522 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2523 size_t *join_params_size)
2525 chanspec_t chanspec = 0;
2528 join_params->params.chanspec_num = 1;
2529 join_params->params.chanspec_list[0] = ch;
2531 if (join_params->params.chanspec_list[0])
2532 chanspec |= WL_CHANSPEC_BAND_2G;
2534 chanspec |= WL_CHANSPEC_BAND_5G;
2536 chanspec |= WL_CHANSPEC_BW_20;
2537 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2539 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2540 join_params->params.chanspec_num * sizeof(chanspec_t);
2542 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2543 join_params->params.chanspec_list[0] |= chanspec;
2544 join_params->params.chanspec_list[0] =
2545 htodchanspec(join_params->params.chanspec_list[0]);
2547 join_params->params.chanspec_num =
2548 htod32(join_params->params.chanspec_num);
2550 WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
2551 join_params->params.chanspec_list[0], ch, chanspec));
2555 static s32 wl_update_bss_info(struct wl_priv *wl)
2557 struct cfg80211_bss *bss;
2558 struct wl_bss_info *bi;
2559 struct wlc_ssid *ssid;
2560 struct bcm_tlv *tim;
2561 u16 beacon_interval;
2567 if (wl_is_ibssmode(wl))
2570 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2572 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2573 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2574 WLAN_CAPABILITY_ESS);
2577 if (unlikely(!bss)) {
2578 WL_DBG(("Could not find the AP\n"));
2579 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2580 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2581 wl->extra_buf, WL_EXTRA_BUF_MAX);
2582 if (unlikely(err)) {
2583 WL_ERR(("Could not get bss info %d\n", err));
2584 goto update_bss_info_out;
2586 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2587 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2589 goto update_bss_info_out;
2591 err = wl_inform_single_bss(wl, bi);
2593 goto update_bss_info_out;
2595 ie = ((u8 *)bi) + bi->ie_offset;
2596 ie_len = bi->ie_length;
2597 beacon_interval = cpu_to_le16(bi->beacon_period);
2599 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
2600 ie = bss->information_elements;
2601 ie_len = bss->len_information_elements;
2602 beacon_interval = bss->beacon_interval;
2603 cfg80211_put_bss(bss);
2606 tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2608 dtim_period = tim->data[1];
2611 * active scan was done so we could not get dtim
2612 * information out of probe response.
2613 * so we speficially query dtim information to dongle.
2615 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD,
2616 &dtim_period, sizeof(dtim_period));
2617 if (unlikely(err)) {
2618 WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
2619 goto update_bss_info_out;
2623 wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
2624 wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2626 update_bss_info_out:
2632 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2633 const wl_event_msg_t *e, void *data)
2635 struct wl_connect_info *conn_info = wl_to_conn(wl);
2638 wl_get_assoc_ies(wl);
2639 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2640 wl_update_bss_info(wl);
2641 cfg80211_roamed(ndev,
2643 conn_info->req_ie, conn_info->req_ie_len,
2644 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2645 WL_DBG(("Report roaming result\n"));
2647 set_bit(WL_STATUS_CONNECTED, &wl->status);
2653 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2654 const wl_event_msg_t *e, void *data, bool completed)
2656 struct wl_connect_info *conn_info = wl_to_conn(wl);
2659 wl_get_assoc_ies(wl);
2660 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2661 wl_update_bss_info(wl);
2662 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2663 cfg80211_connect_result(ndev,
2666 conn_info->req_ie_len,
2668 conn_info->resp_ie_len,
2669 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2671 WL_DBG(("Report connect result - connection %s\n",
2672 completed ? "succeeded" : "failed"));
2674 cfg80211_roamed(ndev,
2676 conn_info->req_ie, conn_info->req_ie_len,
2677 conn_info->resp_ie, conn_info->resp_ie_len,
2679 WL_DBG(("Report roaming result\n"));
2681 set_bit(WL_STATUS_CONNECTED, &wl->status);
2687 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2688 const wl_event_msg_t *e, void *data)
2690 u16 flags = ntoh16(e->flags);
2691 enum nl80211_key_type key_type;
2694 if (flags & WLC_EVENT_MSG_GROUP)
2695 key_type = NL80211_KEYTYPE_GROUP;
2697 key_type = NL80211_KEYTYPE_PAIRWISE;
2699 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2707 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2708 const wl_event_msg_t *e, void *data)
2710 struct channel_info channel_inform;
2711 struct wl_scan_results *bss_list;
2712 u32 len = WL_SCAN_BUF_MAX;
2715 if (wl->iscan_on && wl->iscan_kickstart)
2716 return wl_wakeup_iscan(wl_to_iscan(wl));
2718 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2719 WL_ERR(("Scan complete while device not scanning\n"));
2722 if (unlikely(!wl->scan_request)) {
2725 err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2726 sizeof(channel_inform));
2727 if (unlikely(err)) {
2728 WL_ERR(("scan busy (%d)\n", err));
2731 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2732 if (unlikely(channel_inform.scan_channel)) {
2734 WL_DBG(("channel_inform.scan_channel (%d)\n",
2735 channel_inform.scan_channel));
2737 wl->bss_list = wl->scan_results;
2738 bss_list = wl->bss_list;
2739 memset(bss_list, 0, len);
2740 bss_list->buflen = htod32(len);
2741 err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
2742 if (unlikely(err)) {
2743 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2747 bss_list->buflen = dtoh32(bss_list->buflen);
2748 bss_list->version = dtoh32(bss_list->version);
2749 bss_list->count = dtoh32(bss_list->count);
2751 err = wl_inform_bss(wl);
2756 if (wl->scan_request) {
2757 cfg80211_scan_done(wl->scan_request, false);
2758 wl_set_mpc(ndev, 1);
2759 wl->scan_request = NULL;
2765 static void wl_init_conf(struct wl_conf *conf)
2767 conf->mode = (u32)-1;
2768 conf->frag_threshold = (u32)-1;
2769 conf->rts_threshold = (u32)-1;
2770 conf->retry_short = (u32)-1;
2771 conf->retry_long = (u32)-1;
2772 conf->tx_power = -1;
2775 static void wl_init_prof(struct wl_profile *prof)
2777 memset(prof, 0, sizeof(*prof));
2780 static void wl_init_eloop_handler(struct wl_event_loop *el)
2782 memset(el, 0, sizeof(*el));
2783 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2784 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2785 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2786 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2787 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2788 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2789 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2790 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2791 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2792 el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2795 static s32 wl_init_priv_mem(struct wl_priv *wl)
2797 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2798 if (unlikely(!wl->scan_results)) {
2799 WL_ERR(("Scan results alloc failed\n"));
2800 goto init_priv_mem_out;
2802 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2803 if (unlikely(!wl->conf)) {
2804 WL_ERR(("wl_conf alloc failed\n"));
2805 goto init_priv_mem_out;
2807 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2808 if (unlikely(!wl->profile)) {
2809 WL_ERR(("wl_profile alloc failed\n"));
2810 goto init_priv_mem_out;
2812 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2813 if (unlikely(!wl->bss_info)) {
2814 WL_ERR(("Bss information alloc failed\n"));
2815 goto init_priv_mem_out;
2818 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2819 if (unlikely(!wl->scan_req_int)) {
2820 WL_ERR(("Scan req alloc failed\n"));
2821 goto init_priv_mem_out;
2823 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2824 if (unlikely(!wl->ioctl_buf)) {
2825 WL_ERR(("Ioctl buf alloc failed\n"));
2826 goto init_priv_mem_out;
2828 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2829 if (unlikely(!wl->extra_buf)) {
2830 WL_ERR(("Extra buf alloc failed\n"));
2831 goto init_priv_mem_out;
2833 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2834 if (unlikely(!wl->iscan)) {
2835 WL_ERR(("Iscan buf alloc failed\n"));
2836 goto init_priv_mem_out;
2838 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2839 if (unlikely(!wl->fw)) {
2840 WL_ERR(("fw object alloc failed\n"));
2841 goto init_priv_mem_out;
2843 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2844 if (unlikely(!wl->pmk_list)) {
2845 WL_ERR(("pmk list alloc failed\n"));
2846 goto init_priv_mem_out;
2852 wl_deinit_priv_mem(wl);
2857 static void wl_deinit_priv_mem(struct wl_priv *wl)
2859 kfree(wl->scan_results);
2860 wl->scan_results = NULL;
2861 kfree(wl->bss_info);
2862 wl->bss_info = NULL;
2867 kfree(wl->scan_req_int);
2868 wl->scan_req_int = NULL;
2869 kfree(wl->ioctl_buf);
2870 wl->ioctl_buf = NULL;
2871 kfree(wl->extra_buf);
2872 wl->extra_buf = NULL;
2877 kfree(wl->pmk_list);
2878 wl->pmk_list = NULL;
2881 static s32 wl_create_event_handler(struct wl_priv *wl)
2883 sema_init(&wl->event_sync, 0);
2884 wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
2885 if (IS_ERR(wl->event_tsk)) {
2886 wl->event_tsk = NULL;
2887 WL_ERR(("failed to create event thread\n"));
2893 static void wl_destroy_event_handler(struct wl_priv *wl)
2895 if (wl->event_tsk) {
2896 send_sig(SIGTERM, wl->event_tsk, 1);
2897 kthread_stop(wl->event_tsk);
2898 wl->event_tsk = NULL;
2902 static void wl_term_iscan(struct wl_priv *wl)
2904 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2906 if (wl->iscan_on && iscan->tsk) {
2907 iscan->state = WL_ISCAN_STATE_IDLE;
2908 send_sig(SIGTERM, iscan->tsk, 1);
2909 kthread_stop(iscan->tsk);
2914 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2916 struct wl_priv *wl = iscan_to_wl(iscan);
2917 struct net_device *ndev = wl_to_ndev(wl);
2919 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2920 WL_ERR(("Scan complete while device not scanning\n"));
2923 if (likely(wl->scan_request)) {
2924 cfg80211_scan_done(wl->scan_request, aborted);
2925 wl_set_mpc(ndev, 1);
2926 wl->scan_request = NULL;
2928 wl->iscan_kickstart = false;
2931 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2933 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2934 WL_DBG(("wake up iscan\n"));
2943 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
2944 struct wl_scan_results **bss_list)
2946 struct wl_iscan_results list;
2947 struct wl_scan_results *results;
2948 struct wl_iscan_results *list_buf;
2951 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2952 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2953 results = &list_buf->results;
2954 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2955 results->version = 0;
2958 memset(&list, 0, sizeof(list));
2959 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2960 err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2961 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2963 if (unlikely(err)) {
2964 WL_ERR(("error (%d)\n", err));
2967 results->buflen = dtoh32(results->buflen);
2968 results->version = dtoh32(results->version);
2969 results->count = dtoh32(results->count);
2970 WL_DBG(("results->count = %d\n", results->count));
2971 WL_DBG(("results->buflen = %d\n", results->buflen));
2972 *status = dtoh32(list_buf->status);
2973 *bss_list = results;
2978 static s32 wl_iscan_done(struct wl_priv *wl)
2980 struct wl_iscan_ctrl *iscan = wl->iscan;
2983 iscan->state = WL_ISCAN_STATE_IDLE;
2986 wl_notify_iscan_complete(iscan, false);
2992 static s32 wl_iscan_pending(struct wl_priv *wl)
2994 struct wl_iscan_ctrl *iscan = wl->iscan;
2997 /* Reschedule the timer */
2998 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2999 iscan->timer_on = 1;
3004 static s32 wl_iscan_inprogress(struct wl_priv *wl)
3006 struct wl_iscan_ctrl *iscan = wl->iscan;
3011 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
3013 /* Reschedule the timer */
3014 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3015 iscan->timer_on = 1;
3020 static s32 wl_iscan_aborted(struct wl_priv *wl)
3022 struct wl_iscan_ctrl *iscan = wl->iscan;
3025 iscan->state = WL_ISCAN_STATE_IDLE;
3027 wl_notify_iscan_complete(iscan, true);
3033 static s32 wl_iscan_thread(void *data)
3035 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3036 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3037 struct wl_priv *wl = iscan_to_wl(iscan);
3038 struct wl_iscan_eloop *el = &iscan->el;
3042 sched_setscheduler(current, SCHED_FIFO, ¶m);
3043 allow_signal(SIGTERM);
3044 status = WL_SCAN_RESULTS_PARTIAL;
3045 while (likely(!down_interruptible(&iscan->sync))) {
3046 if (kthread_should_stop())
3048 if (iscan->timer_on) {
3049 del_timer_sync(&iscan->timer);
3050 iscan->timer_on = 0;
3053 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
3054 if (unlikely(err)) {
3055 status = WL_SCAN_RESULTS_ABORTED;
3056 WL_ERR(("Abort iscan\n"));
3059 el->handler[status] (wl);
3061 if (iscan->timer_on) {
3062 del_timer_sync(&iscan->timer);
3063 iscan->timer_on = 0;
3065 WL_DBG(("%s was terminated\n", __func__));
3070 static void wl_iscan_timer(unsigned long data)
3072 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3075 iscan->timer_on = 0;
3076 WL_DBG(("timer expired\n"));
3077 wl_wakeup_iscan(iscan);
3081 static s32 wl_invoke_iscan(struct wl_priv *wl)
3083 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3086 if (wl->iscan_on && !iscan->tsk) {
3087 iscan->state = WL_ISCAN_STATE_IDLE;
3088 sema_init(&iscan->sync, 0);
3089 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3090 if (IS_ERR(iscan->tsk)) {
3091 WL_ERR(("Could not create iscan thread\n"));
3100 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
3102 memset(el, 0, sizeof(*el));
3103 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
3104 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
3105 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
3106 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
3107 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
3110 static s32 wl_init_iscan(struct wl_priv *wl)
3112 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3116 iscan->dev = wl_to_ndev(wl);
3117 iscan->state = WL_ISCAN_STATE_IDLE;
3118 wl_init_iscan_eloop(&iscan->el);
3119 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3120 init_timer(&iscan->timer);
3121 iscan->timer.data = (unsigned long) iscan;
3122 iscan->timer.function = wl_iscan_timer;
3123 sema_init(&iscan->sync, 0);
3124 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3125 if (IS_ERR(iscan->tsk)) {
3126 WL_ERR(("Could not create iscan thread\n"));
3136 static void wl_init_fw(struct wl_fw_ctrl *fw)
3138 fw->status = 0; /* init fw loading status.
3139 0 means nothing was loaded yet */
3142 static s32 wl_init_priv(struct wl_priv *wl)
3144 struct wiphy *wiphy = wl_to_wiphy(wl);
3147 wl->scan_request = NULL;
3148 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3149 wl->iscan_on = true; /* iscan on & off switch.
3150 we enable iscan per default */
3151 wl->roam_on = false; /* roam on & off switch.
3152 we enable roam per default */
3154 wl->iscan_kickstart = false;
3155 wl->active_scan = true; /* we do active scan for
3156 specific scan per default */
3157 wl->dongle_up = false; /* dongle is not up yet */
3159 err = wl_init_priv_mem(wl);
3162 if (unlikely(wl_create_event_handler(wl)))
3164 wl_init_eloop_handler(&wl->el);
3165 mutex_init(&wl->usr_sync);
3166 err = wl_init_iscan(wl);
3170 wl_init_conf(wl->conf);
3171 wl_init_prof(wl->profile);
3177 static void wl_deinit_priv(struct wl_priv *wl)
3179 wl_destroy_event_handler(wl);
3180 wl->dongle_up = false; /* dongle down */
3184 wl_deinit_priv_mem(wl);
3187 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3189 struct wireless_dev *wdev;
3191 struct wl_iface *ci;
3194 if (unlikely(!ndev)) {
3195 WL_ERR(("ndev is invaild\n"));
3198 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3199 if (unlikely(!wl_cfg80211_dev)) {
3200 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3203 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
3204 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
3205 if (unlikely(IS_ERR(wdev)))
3208 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3209 wl = wdev_to_wl(wdev);
3212 ci = (struct wl_iface *)wl_to_ci(wl);
3214 ndev->ieee80211_ptr = wdev;
3215 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3216 wdev->netdev = ndev;
3217 err = wl_init_priv(wl);
3218 if (unlikely(err)) {
3219 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
3220 goto cfg80211_attach_out;
3222 wl_set_drvdata(wl_cfg80211_dev, ci);
3223 set_bit(WL_STATUS_READY, &wl->status);
3227 cfg80211_attach_out:
3232 void wl_cfg80211_detach(void)
3240 wl_set_drvdata(wl_cfg80211_dev, NULL);
3241 kfree(wl_cfg80211_dev);
3242 wl_cfg80211_dev = NULL;
3243 wl_clear_sdio_func();
3246 static void wl_wakeup_event(struct wl_priv *wl)
3248 up(&wl->event_sync);
3251 static s32 wl_event_handler(void *data)
3253 struct wl_priv *wl = (struct wl_priv *)data;
3254 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3255 struct wl_event_q *e;
3257 sched_setscheduler(current, SCHED_FIFO, ¶m);
3258 allow_signal(SIGTERM);
3259 while (likely(!down_interruptible(&wl->event_sync))) {
3260 if (kthread_should_stop())
3262 e = wl_deq_event(wl);
3264 WL_ERR(("eqeue empty..\n"));
3267 WL_DBG(("event type (%d)\n", e->etype));
3268 if (wl->el.handler[e->etype]) {
3269 wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3272 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
3276 WL_DBG(("%s was terminated\n", __func__));
3281 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
3283 u32 event_type = ntoh32(e->event_type);
3284 struct wl_priv *wl = ndev_to_wl(ndev);
3285 #if (WL_DBG_LEVEL > 0)
3286 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
3287 wl_dbg_estr[event_type] : (s8 *) "Unknown";
3288 #endif /* (WL_DBG_LEVEL > 0) */
3289 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
3290 if (likely(!wl_enq_event(wl, event_type, e, data)))
3291 wl_wakeup_event(wl);
3294 static void wl_init_eq(struct wl_priv *wl)
3296 wl_init_eq_lock(wl);
3297 INIT_LIST_HEAD(&wl->eq_list);
3300 static void wl_flush_eq(struct wl_priv *wl)
3302 struct wl_event_q *e;
3305 while (!list_empty(&wl->eq_list)) {
3306 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3307 list_del(&e->eq_list);
3314 * retrieve first queued event from head
3317 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3319 struct wl_event_q *e = NULL;
3322 if (likely(!list_empty(&wl->eq_list))) {
3323 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3324 list_del(&e->eq_list);
3332 ** push event to tail of the queue
3336 wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg,
3339 struct wl_event_q *e;
3342 e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
3344 WL_ERR(("event alloc failed\n"));
3349 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
3353 list_add_tail(&e->eq_list, &wl->eq_list);
3359 static void wl_put_event(struct wl_event_q *e)
3364 void wl_cfg80211_sdio_func(void *func)
3366 cfg80211_sdio_func = (struct sdio_func *)func;
3369 static void wl_clear_sdio_func(void)
3371 cfg80211_sdio_func = NULL;
3374 struct sdio_func *wl_cfg80211_get_sdio_func(void)
3376 return cfg80211_sdio_func;
3379 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
3386 case NL80211_IFTYPE_MONITOR:
3387 case NL80211_IFTYPE_WDS:
3388 WL_ERR(("type (%d) : currently we do not support this mode\n",
3392 case NL80211_IFTYPE_ADHOC:
3394 case NL80211_IFTYPE_STATION:
3399 WL_ERR(("invalid type (%d)\n", iftype));
3402 infra = htod32(infra);
3404 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
3405 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
3406 if (unlikely(err)) {
3407 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
3410 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
3411 if (unlikely(err)) {
3412 WL_ERR(("WLC_SET_AP error (%d)\n", err));
3416 return -EINPROGRESS;
3419 #ifndef EMBEDDED_PLATFORM
3420 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3428 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
3432 err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
3433 if (unlikely(err)) {
3434 WL_ERR(("WLC_UP error (%d)\n", err));
3439 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
3443 err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
3444 if (unlikely(err)) {
3445 WL_ERR(("WLC_SET_PM error (%d)\n", err));
3451 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
3453 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3457 /* Match Host and Dongle rx alignment */
3458 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3460 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3461 if (unlikely(err)) {
3462 WL_ERR(("txglomalign error (%d)\n", err));
3463 goto dongle_glom_out;
3465 /* disable glom option per default */
3466 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3467 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3468 if (unlikely(err)) {
3469 WL_ERR(("txglom error (%d)\n", err));
3470 goto dongle_glom_out;
3477 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3479 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3483 /* Setup timeout if Beacons are lost and roam is
3484 off to report link down */
3486 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
3488 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3489 if (unlikely(err)) {
3490 WL_ERR(("bcn_timeout error (%d)\n", err));
3491 goto dongle_rom_out;
3494 /* Enable/Disable built-in roaming to allow supplicant
3495 to take care of roaming */
3496 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
3497 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3498 if (unlikely(err)) {
3499 WL_ERR(("roam_off error (%d)\n", err));
3500 goto dongle_rom_out;
3506 static s32 wl_dongle_eventmsg(struct net_device *ndev)
3509 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3511 s8 eventmask[WL_EVENTING_MASK_LEN];
3514 /* Setup event_msgs */
3515 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3517 err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
3518 if (unlikely(err)) {
3519 WL_ERR(("Get event_msgs error (%d)\n", err));
3520 goto dongle_eventmsg_out;
3522 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3524 setbit(eventmask, WLC_E_SET_SSID);
3525 setbit(eventmask, WLC_E_PRUNE);
3526 setbit(eventmask, WLC_E_AUTH);
3527 setbit(eventmask, WLC_E_REASSOC);
3528 setbit(eventmask, WLC_E_REASSOC_IND);
3529 setbit(eventmask, WLC_E_DEAUTH_IND);
3530 setbit(eventmask, WLC_E_DISASSOC_IND);
3531 setbit(eventmask, WLC_E_DISASSOC);
3532 setbit(eventmask, WLC_E_JOIN);
3533 setbit(eventmask, WLC_E_ASSOC_IND);
3534 setbit(eventmask, WLC_E_PSK_SUP);
3535 setbit(eventmask, WLC_E_LINK);
3536 setbit(eventmask, WLC_E_NDIS_LINK);
3537 setbit(eventmask, WLC_E_MIC_ERROR);
3538 setbit(eventmask, WLC_E_PMKID_CACHE);
3539 setbit(eventmask, WLC_E_TXFAIL);
3540 setbit(eventmask, WLC_E_JOIN_START);
3541 setbit(eventmask, WLC_E_SCAN_COMPLETE);
3543 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3545 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3546 if (unlikely(err)) {
3547 WL_ERR(("Set event_msgs error (%d)\n", err));
3548 goto dongle_eventmsg_out;
3551 dongle_eventmsg_out:
3556 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3557 s32 scan_unassoc_time)
3561 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
3562 sizeof(scan_assoc_time));
3564 if (err == -EOPNOTSUPP) {
3565 WL_INFO(("Scan assoc time is not supported\n"));
3567 WL_ERR(("Scan assoc time error (%d)\n", err));
3569 goto dongle_scantime_out;
3571 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
3572 sizeof(scan_unassoc_time));
3574 if (err == -EOPNOTSUPP) {
3575 WL_INFO(("Scan unassoc time is not supported\n"));
3577 WL_ERR(("Scan unassoc time error (%d)\n", err));
3579 goto dongle_scantime_out;
3582 dongle_scantime_out:
3587 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
3589 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3593 /* Set ARP offload */
3594 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3595 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3597 if (err == -EOPNOTSUPP)
3598 WL_INFO(("arpoe is not supported\n"));
3600 WL_ERR(("arpoe error (%d)\n", err));
3602 goto dongle_offload_out;
3604 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3605 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3607 if (err == -EOPNOTSUPP)
3608 WL_INFO(("arp_ol is not supported\n"));
3610 WL_ERR(("arp_ol error (%d)\n", err));
3612 goto dongle_offload_out;
3619 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
3622 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3623 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3626 src = src + 2; /* Skip past 0x */
3627 if (strlen(src) % 2 != 0) {
3628 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3631 for (i = 0; *src != '\0'; i++) {
3633 strncpy(num, src, 2);
3635 dst[i] = (u8) simple_strtoul(num, NULL, 16);
3641 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
3643 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3646 struct wl_pkt_filter pkt_filter;
3647 struct wl_pkt_filter *pkt_filterp;
3655 /* add a default packet filter pattern */
3656 str = "pkt_filter_add";
3657 str_len = strlen(str);
3658 strncpy(buf, str, str_len);
3659 buf[str_len] = '\0';
3660 buf_len = str_len + 1;
3662 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3664 /* Parse packet filter id. */
3665 pkt_filter.id = htod32(100);
3667 /* Parse filter polarity. */
3668 pkt_filter.negate_match = htod32(0);
3670 /* Parse filter type. */
3671 pkt_filter.type = htod32(0);
3673 /* Parse pattern filter offset. */
3674 pkt_filter.u.pattern.offset = htod32(0);
3676 /* Parse pattern filter mask. */
3677 mask_size = htod32(wl_pattern_atoh("0xff",
3678 (char *)pkt_filterp->u.pattern.
3681 /* Parse pattern filter pattern. */
3682 pattern_size = htod32(wl_pattern_atoh("0x00",
3683 (char *)&pkt_filterp->u.pattern.
3684 mask_and_pattern[mask_size]));
3686 if (mask_size != pattern_size) {
3687 WL_ERR(("Mask and pattern not the same size\n"));
3689 goto dongle_filter_out;
3692 pkt_filter.u.pattern.size_bytes = mask_size;
3693 buf_len += WL_PKT_FILTER_FIXED_LEN;
3694 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3696 /* Keep-alive attributes are set in local
3697 * variable (keep_alive_pkt), and
3698 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3699 * guarantee that the buffer is properly aligned.
3701 memcpy((char *)pkt_filterp, &pkt_filter,
3702 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3704 err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
3706 if (err == -EOPNOTSUPP) {
3707 WL_INFO(("filter not supported\n"));
3709 WL_ERR(("filter (%d)\n", err));
3711 goto dongle_filter_out;
3714 /* set mode to allow pattern */
3715 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3717 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3719 if (err == -EOPNOTSUPP) {
3720 WL_INFO(("filter_mode not supported\n"));
3722 WL_ERR(("filter_mode (%d)\n", err));
3724 goto dongle_filter_out;
3730 #endif /* !EMBEDDED_PLATFORM */
3732 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
3735 #define DHD_SDALIGN 32
3737 struct net_device *ndev;
3738 struct wireless_dev *wdev;
3744 ndev = wl_to_ndev(wl);
3745 wdev = ndev->ieee80211_ptr;
3749 #ifndef EMBEDDED_PLATFORM
3750 err = wl_dongle_up(ndev, 0);
3752 goto default_conf_out;
3753 err = wl_dongle_country(ndev, 0);
3755 goto default_conf_out;
3756 err = wl_dongle_power(ndev, PM_FAST);
3758 goto default_conf_out;
3759 err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
3761 goto default_conf_out;
3762 err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
3764 goto default_conf_out;
3765 err = wl_dongle_eventmsg(ndev);
3767 goto default_conf_out;
3769 wl_dongle_scantime(ndev, 40, 80);
3770 wl_dongle_offload(ndev, 1, 0xf);
3771 wl_dongle_filter(ndev, 1);
3772 #endif /* !EMBEDDED_PLATFORM */
3774 err = wl_dongle_mode(ndev, wdev->iftype);
3775 if (unlikely(err && err != -EINPROGRESS))
3776 goto default_conf_out;
3777 err = wl_dongle_probecap(wl);
3779 goto default_conf_out;
3781 /* -EINPROGRESS: Call commit handler */
3787 wl->dongle_up = true;
3793 static s32 wl_update_wiphybands(struct wl_priv *wl)
3795 struct wiphy *wiphy;
3800 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
3802 if (unlikely(err)) {
3803 WL_ERR(("error (%d)\n", err));
3807 phy = ((char *)&phy_list)[1];
3808 WL_DBG(("%c phy\n", phy));
3809 if (phy == 'n' || phy == 'a') {
3810 wiphy = wl_to_wiphy(wl);
3811 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3817 static s32 __wl_cfg80211_up(struct wl_priv *wl)
3821 wl_debugfs_add_netdev_params(wl);
3823 err = wl_config_dongle(wl, false);
3827 wl_invoke_iscan(wl);
3828 set_bit(WL_STATUS_READY, &wl->status);
3832 static s32 __wl_cfg80211_down(struct wl_priv *wl)
3836 /* Check if cfg80211 interface is already down */
3837 if (!test_bit(WL_STATUS_READY, &wl->status))
3838 return err; /* it is even not ready */
3840 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3842 if (wl->scan_request) {
3843 cfg80211_scan_done(wl->scan_request, true); /* true
3845 /* wl_set_mpc(wl_to_ndev(wl), 1); */ /* BUG
3846 * this operation cannot help
3847 * but here because sdio
3848 * is already down through
3850 * Need to figure out how to
3851 * address this issue
3853 wl->scan_request = NULL;
3855 clear_bit(WL_STATUS_READY, &wl->status);
3856 clear_bit(WL_STATUS_SCANNING, &wl->status);
3857 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3858 clear_bit(WL_STATUS_CONNECTED, &wl->status);
3860 wl_debugfs_remove_netdev(wl);
3865 s32 wl_cfg80211_up(void)
3871 mutex_lock(&wl->usr_sync);
3872 err = __wl_cfg80211_up(wl);
3873 mutex_unlock(&wl->usr_sync);
3878 s32 wl_cfg80211_down(void)
3884 mutex_lock(&wl->usr_sync);
3885 err = __wl_cfg80211_down(wl);
3886 mutex_unlock(&wl->usr_sync);
3891 static s32 wl_dongle_probecap(struct wl_priv *wl)
3895 err = wl_update_wiphybands(wl);
3902 static void *wl_read_prof(struct wl_priv *wl, s32 item)
3906 return &wl->profile->sec;
3908 return &wl->profile->active;
3910 return &wl->profile->bssid;
3912 return &wl->profile->ssid;
3914 WL_ERR(("invalid item (%d)\n", item));
3919 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
3923 struct wlc_ssid *ssid;
3927 ssid = (wlc_ssid_t *) data;
3928 memset(wl->profile->ssid.SSID, 0,
3929 sizeof(wl->profile->ssid.SSID));
3930 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
3931 wl->profile->ssid.SSID_len = ssid->SSID_len;
3935 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
3937 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
3940 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
3943 wl->profile->active = *(bool *)data;
3945 case WL_PROF_BEACONINT:
3946 wl->profile->beacon_interval = *(u16 *)data;
3948 case WL_PROF_DTIMPERIOD:
3949 wl->profile->dtim_period = *(u8 *)data;
3952 WL_ERR(("unsupported item (%d)\n", item));
3960 void wl_cfg80211_dbg_level(u32 level)
3963 * prohibit to change debug level
3964 * by insmod parameter.
3965 * eventually debug level will be configured
3966 * in compile time by using CONFIG_XXX
3968 /* wl_dbg_level = level; */
3971 static bool wl_is_ibssmode(struct wl_priv *wl)
3973 return wl->conf->mode == WL_MODE_IBSS;
3976 static bool wl_is_ibssstarter(struct wl_priv *wl)
3978 return wl->ibss_starter;
3981 static void wl_rst_ie(struct wl_priv *wl)
3983 struct wl_ie *ie = wl_to_ie(wl);
3988 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
3990 struct wl_ie *ie = wl_to_ie(wl);
3993 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3994 WL_ERR(("ei crosses buffer boundary\n"));
3997 ie->buf[ie->offset] = t;
3998 ie->buf[ie->offset + 1] = l;
3999 memcpy(&ie->buf[ie->offset + 2], v, l);
4000 ie->offset += l + 2;
4005 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
4007 struct wl_ie *ie = wl_to_ie(wl);
4010 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
4011 WL_ERR(("ei_stream crosses buffer boundary\n"));
4014 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
4015 ie->offset += ie_size;
4020 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
4022 struct wl_ie *ie = wl_to_ie(wl);
4025 if (unlikely(ie->offset > dst_size)) {
4026 WL_ERR(("dst_size is not enough\n"));
4029 memcpy(dst, &ie->buf[0], ie->offset);
4034 static u32 wl_get_ielen(struct wl_priv *wl)
4036 struct wl_ie *ie = wl_to_ie(wl);
4041 static void wl_link_up(struct wl_priv *wl)
4046 static void wl_link_down(struct wl_priv *wl)
4048 struct wl_connect_info *conn_info = wl_to_conn(wl);
4050 wl->link_up = false;
4051 kfree(conn_info->req_ie);
4052 conn_info->req_ie = NULL;
4053 conn_info->req_ie_len = 0;
4054 kfree(conn_info->resp_ie);
4055 conn_info->resp_ie = NULL;
4056 conn_info->resp_ie_len = 0;
4059 static void wl_lock_eq(struct wl_priv *wl)
4061 spin_lock_irq(&wl->eq_lock);
4064 static void wl_unlock_eq(struct wl_priv *wl)
4066 spin_unlock_irq(&wl->eq_lock);
4069 static void wl_init_eq_lock(struct wl_priv *wl)
4071 spin_lock_init(&wl->eq_lock);
4074 static void wl_delay(u32 ms)
4076 if (ms < 1000 / HZ) {
4084 static void wl_set_drvdata(struct wl_dev *dev, void *data)
4086 dev->driver_data = data;
4089 static void *wl_get_drvdata(struct wl_dev *dev)
4091 return dev->driver_data;
4094 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
4096 const struct firmware *fw_entry;
4101 fw_entry = wl->fw->fw_entry;
4103 if (fw_entry->size < wl->fw->ptr + size)
4104 size = fw_entry->size - wl->fw->ptr;
4106 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
4107 wl->fw->ptr += size;
4111 void wl_cfg80211_release_fw(void)
4116 release_firmware(wl->fw->fw_entry);
4120 void *wl_cfg80211_request_fw(s8 *file_name)
4123 const struct firmware *fw_entry = NULL;
4126 WL_DBG(("file name : \"%s\"\n", file_name));
4129 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
4130 err = request_firmware(&wl->fw->fw_entry, file_name,
4131 &wl_cfg80211_get_sdio_func()->dev);
4132 if (unlikely(err)) {
4133 WL_ERR(("Could not download fw (%d)\n", err));
4136 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
4137 fw_entry = wl->fw->fw_entry;
4139 WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
4142 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
4143 err = request_firmware(&wl->fw->fw_entry, file_name,
4144 &wl_cfg80211_get_sdio_func()->dev);
4145 if (unlikely(err)) {
4146 WL_ERR(("Could not download nvram (%d)\n", err));
4149 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
4150 fw_entry = wl->fw->fw_entry;
4152 WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
4156 WL_DBG(("Downloading already done. Nothing to do more\n"));
4161 if (unlikely(err)) {
4165 return (void *)fw_entry->data;
4168 s8 *wl_cfg80211_get_fwname(void)
4173 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4174 return wl->fw->fw_name;
4177 s8 *wl_cfg80211_get_nvramname(void)
4182 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4183 return wl->fw->nvram_name;
4186 static void wl_set_mpc(struct net_device *ndev, int mpc)
4190 err = wl_dev_intvar_set(ndev, "mpc", mpc);
4191 if (unlikely(err)) {
4192 WL_ERR(("fail to set mpc\n"));
4195 WL_DBG(("MPC : %d\n", mpc));
4198 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
4200 char buf[10+IFNAMSIZ];
4204 sprintf(buf, "netdev:%s", wl_to_ndev(wl)->name);
4205 wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
4207 fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
4208 (u16 *)&wl->profile->beacon_interval);
4214 fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
4215 (u8 *)&wl->profile->dtim_period);
4225 static void wl_debugfs_remove_netdev(struct wl_priv *wl)
4227 debugfs_remove_recursive(wl->debugfsdir);
4228 wl->debugfsdir = NULL;