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>
22 #include <asm/uaccess.h>
24 #include <dngl_stats.h>
29 #include <linux/kthread.h>
30 #include <linux/netdevice.h>
31 #include <linux/sched.h>
32 #include <linux/etherdevice.h>
33 #include <linux/wireless.h>
34 #include <linux/ieee80211.h>
35 #include <net/cfg80211.h>
37 #include <net/rtnetlink.h>
38 #include <linux/mmc/sdio_func.h>
39 #include <linux/firmware.h>
40 #include <wl_cfg80211.h>
42 static struct sdio_func *cfg80211_sdio_func;
43 static struct wl_dev *wl_cfg80211_dev;
44 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
46 u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
48 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
49 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
52 ** cfg80211_ops api/callback list
54 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
55 struct net_device *ndev,
56 enum nl80211_iftype type, u32 *flags,
57 struct vif_params *params);
58 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
59 struct cfg80211_scan_request *request,
60 struct cfg80211_ssid *this_ssid);
61 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
62 struct cfg80211_scan_request *request);
63 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
64 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
65 struct cfg80211_ibss_params *params);
66 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
67 struct net_device *dev);
68 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
69 struct net_device *dev, u8 *mac,
70 struct station_info *sinfo);
71 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
72 struct net_device *dev, bool enabled,
74 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
75 struct net_device *dev,
77 const struct cfg80211_bitrate_mask
79 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
80 struct cfg80211_connect_params *sme);
81 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
83 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
84 enum nl80211_tx_power_setting type,
86 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
87 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
88 struct net_device *dev, u8 key_idx,
89 bool unicast, bool multicast);
90 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
91 u8 key_idx, bool pairwise, const u8 *mac_addr,
92 struct key_params *params);
93 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
94 u8 key_idx, bool pairwise, const u8 *mac_addr);
95 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
96 u8 key_idx, bool pairwise, const u8 *mac_addr,
97 void *cookie, void (*callback) (void *cookie,
101 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
102 struct net_device *dev,
104 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
105 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
106 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
107 struct cfg80211_pmksa *pmksa);
108 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
109 struct cfg80211_pmksa *pmksa);
110 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
111 struct net_device *dev);
113 ** event & event Q handlers for cfg80211 interfaces
115 static s32 wl_create_event_handler(struct wl_priv *wl);
116 static void wl_destroy_event_handler(struct wl_priv *wl);
117 static s32 wl_event_handler(void *data);
118 static void wl_init_eq(struct wl_priv *wl);
119 static void wl_flush_eq(struct wl_priv *wl);
120 static void wl_lock_eq(struct wl_priv *wl);
121 static void wl_unlock_eq(struct wl_priv *wl);
122 static void wl_init_eq_lock(struct wl_priv *wl);
123 static void wl_init_eloop_handler(struct wl_event_loop *el);
124 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
125 static s32 wl_enq_event(struct wl_priv *wl, u32 type,
126 const wl_event_msg_t *msg, void *data);
127 static void wl_put_event(struct wl_event_q *e);
128 static void wl_wakeup_event(struct wl_priv *wl);
129 static s32 wl_notify_connect_status(struct wl_priv *wl,
130 struct net_device *ndev,
131 const wl_event_msg_t *e, void *data);
132 static s32 wl_notify_roaming_status(struct wl_priv *wl,
133 struct net_device *ndev,
134 const wl_event_msg_t *e, void *data);
135 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
136 const wl_event_msg_t *e, void *data);
137 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
138 const wl_event_msg_t *e, void *data,
140 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
141 const wl_event_msg_t *e, void *data);
142 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
143 const wl_event_msg_t *e, void *data);
146 ** register/deregister sdio function
148 struct sdio_func *wl_cfg80211_get_sdio_func(void);
149 static void wl_clear_sdio_func(void);
154 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
156 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
158 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
159 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
161 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
165 ** cfg80211 set_wiphy_params utilities
167 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
168 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
169 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
172 ** wl profile utilities
174 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
175 void *data, s32 item);
176 static void *wl_read_prof(struct wl_priv *wl, s32 item);
177 static void wl_init_prof(struct wl_profile *prof);
180 ** cfg80211 connect utilites
182 static s32 wl_set_wpa_version(struct net_device *dev,
183 struct cfg80211_connect_params *sme);
184 static s32 wl_set_auth_type(struct net_device *dev,
185 struct cfg80211_connect_params *sme);
186 static s32 wl_set_set_cipher(struct net_device *dev,
187 struct cfg80211_connect_params *sme);
188 static s32 wl_set_key_mgmt(struct net_device *dev,
189 struct cfg80211_connect_params *sme);
190 static s32 wl_set_set_sharedkey(struct net_device *dev,
191 struct cfg80211_connect_params *sme);
192 static s32 wl_get_assoc_ies(struct wl_priv *wl);
193 static void wl_ch_to_chanspec(int ch,
194 struct wl_join_params *join_params, size_t *join_params_size);
197 ** information element utilities
199 static void wl_rst_ie(struct wl_priv *wl);
200 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
201 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
202 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
203 static u32 wl_get_ielen(struct wl_priv *wl);
205 static s32 wl_mode_to_nl80211_iftype(s32 mode);
207 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
209 static void wl_free_wdev(struct wl_priv *wl);
211 static s32 wl_inform_bss(struct wl_priv *wl);
212 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
213 static s32 wl_update_bss_info(struct wl_priv *wl);
215 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
216 u8 key_idx, const u8 *mac_addr,
217 struct key_params *params);
220 ** key indianess swap utilities
222 static void swap_key_from_BE(struct wl_wsec_key *key);
223 static void swap_key_to_BE(struct wl_wsec_key *key);
226 ** wl_priv memory init/deinit utilities
228 static s32 wl_init_priv_mem(struct wl_priv *wl);
229 static void wl_deinit_priv_mem(struct wl_priv *wl);
231 static void wl_delay(u32 ms);
234 ** store/restore cfg80211 instance data
236 static void wl_set_drvdata(struct wl_dev *dev, void *data);
237 static void *wl_get_drvdata(struct wl_dev *dev);
240 ** ibss mode utilities
242 static bool wl_is_ibssmode(struct wl_priv *wl);
243 static bool wl_is_ibssstarter(struct wl_priv *wl);
246 ** dongle up/down , default configuration utilities
248 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
249 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
250 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
251 static void wl_link_up(struct wl_priv *wl);
252 static void wl_link_down(struct wl_priv *wl);
253 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
254 static s32 __wl_cfg80211_up(struct wl_priv *wl);
255 static s32 __wl_cfg80211_down(struct wl_priv *wl);
256 static s32 wl_dongle_probecap(struct wl_priv *wl);
257 static void wl_init_conf(struct wl_conf *conf);
260 ** dongle configuration utilities
262 #ifndef EMBEDDED_PLATFORM
263 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
264 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
265 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
266 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
267 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
269 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
271 static s32 wl_dongle_eventmsg(struct net_device *ndev);
272 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
273 s32 scan_unassoc_time);
274 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
276 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
277 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
278 static s32 wl_update_wiphybands(struct wl_priv *wl);
279 #endif /* !EMBEDDED_PLATFORM */
280 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
285 static void wl_iscan_timer(unsigned long data);
286 static void wl_term_iscan(struct wl_priv *wl);
287 static s32 wl_init_iscan(struct wl_priv *wl);
288 static s32 wl_iscan_thread(void *data);
289 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
290 void *param, s32 paramlen, void *bufptr,
292 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
293 void *param, s32 paramlen, void *bufptr,
295 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
297 static s32 wl_do_iscan(struct wl_priv *wl);
298 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
299 static s32 wl_invoke_iscan(struct wl_priv *wl);
300 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
301 struct wl_scan_results **bss_list);
302 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
303 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
304 static s32 wl_iscan_done(struct wl_priv *wl);
305 static s32 wl_iscan_pending(struct wl_priv *wl);
306 static s32 wl_iscan_inprogress(struct wl_priv *wl);
307 static s32 wl_iscan_aborted(struct wl_priv *wl);
310 ** fw/nvram downloading handler
312 static void wl_init_fw(struct wl_fw_ctrl *fw);
315 * find most significant bit set
317 static __used u32 wl_find_msb(u16 bit16);
320 * update pmklist to dongle
322 static __used s32 wl_update_pmklist(struct net_device *dev,
323 struct wl_pmk_list *pmk_list, s32 err);
325 static void wl_set_mpc(struct net_device *ndev, int mpc);
330 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
331 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
333 #define WL_PRIV_GET() \
335 struct wl_iface *ci; \
336 if (unlikely(!(wl_cfg80211_dev && \
337 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
338 WL_ERR("wl_cfg80211_dev is unavailable\n"); \
344 #define CHECK_SYS_UP() \
346 struct wl_priv *wl = wiphy_to_wl(wiphy); \
347 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
348 WL_INFO("device is not ready : status (%d)\n", \
354 extern int dhd_wait_pend8021x(struct net_device *dev);
356 #if (WL_DBG_LEVEL > 0)
357 #define WL_DBG_ESTR_MAX 32
358 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
359 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
360 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
361 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
362 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
363 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
364 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
365 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
367 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
369 "RADIO", "PSM_WATCHDOG",
371 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
372 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
373 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
375 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
377 #endif /* WL_DBG_LEVEL */
379 #define CHAN2G(_channel, _freq, _flags) { \
380 .band = IEEE80211_BAND_2GHZ, \
381 .center_freq = (_freq), \
382 .hw_value = (_channel), \
384 .max_antenna_gain = 0, \
388 #define CHAN5G(_channel, _flags) { \
389 .band = IEEE80211_BAND_5GHZ, \
390 .center_freq = 5000 + (5 * (_channel)), \
391 .hw_value = (_channel), \
393 .max_antenna_gain = 0, \
397 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
398 #define RATETAB_ENT(_rateid, _flags) \
400 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
401 .hw_value = (_rateid), \
405 static struct ieee80211_rate __wl_rates[] = {
406 RATETAB_ENT(WLC_RATE_1M, 0),
407 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
408 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
409 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
410 RATETAB_ENT(WLC_RATE_6M, 0),
411 RATETAB_ENT(WLC_RATE_9M, 0),
412 RATETAB_ENT(WLC_RATE_12M, 0),
413 RATETAB_ENT(WLC_RATE_18M, 0),
414 RATETAB_ENT(WLC_RATE_24M, 0),
415 RATETAB_ENT(WLC_RATE_36M, 0),
416 RATETAB_ENT(WLC_RATE_48M, 0),
417 RATETAB_ENT(WLC_RATE_54M, 0),
420 #define wl_a_rates (__wl_rates + 4)
421 #define wl_a_rates_size 8
422 #define wl_g_rates (__wl_rates + 0)
423 #define wl_g_rates_size 12
425 static struct ieee80211_channel __wl_2ghz_channels[] = {
442 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
443 CHAN5G(34, 0), CHAN5G(36, 0),
444 CHAN5G(38, 0), CHAN5G(40, 0),
445 CHAN5G(42, 0), CHAN5G(44, 0),
446 CHAN5G(46, 0), CHAN5G(48, 0),
447 CHAN5G(52, 0), CHAN5G(56, 0),
448 CHAN5G(60, 0), CHAN5G(64, 0),
449 CHAN5G(100, 0), CHAN5G(104, 0),
450 CHAN5G(108, 0), CHAN5G(112, 0),
451 CHAN5G(116, 0), CHAN5G(120, 0),
452 CHAN5G(124, 0), CHAN5G(128, 0),
453 CHAN5G(132, 0), CHAN5G(136, 0),
454 CHAN5G(140, 0), CHAN5G(149, 0),
455 CHAN5G(153, 0), CHAN5G(157, 0),
456 CHAN5G(161, 0), CHAN5G(165, 0),
457 CHAN5G(184, 0), CHAN5G(188, 0),
458 CHAN5G(192, 0), CHAN5G(196, 0),
459 CHAN5G(200, 0), CHAN5G(204, 0),
460 CHAN5G(208, 0), CHAN5G(212, 0),
464 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
465 CHAN5G(32, 0), CHAN5G(34, 0),
466 CHAN5G(36, 0), CHAN5G(38, 0),
467 CHAN5G(40, 0), CHAN5G(42, 0),
468 CHAN5G(44, 0), CHAN5G(46, 0),
469 CHAN5G(48, 0), CHAN5G(50, 0),
470 CHAN5G(52, 0), CHAN5G(54, 0),
471 CHAN5G(56, 0), CHAN5G(58, 0),
472 CHAN5G(60, 0), CHAN5G(62, 0),
473 CHAN5G(64, 0), CHAN5G(66, 0),
474 CHAN5G(68, 0), CHAN5G(70, 0),
475 CHAN5G(72, 0), CHAN5G(74, 0),
476 CHAN5G(76, 0), CHAN5G(78, 0),
477 CHAN5G(80, 0), CHAN5G(82, 0),
478 CHAN5G(84, 0), CHAN5G(86, 0),
479 CHAN5G(88, 0), CHAN5G(90, 0),
480 CHAN5G(92, 0), CHAN5G(94, 0),
481 CHAN5G(96, 0), CHAN5G(98, 0),
482 CHAN5G(100, 0), CHAN5G(102, 0),
483 CHAN5G(104, 0), CHAN5G(106, 0),
484 CHAN5G(108, 0), CHAN5G(110, 0),
485 CHAN5G(112, 0), CHAN5G(114, 0),
486 CHAN5G(116, 0), CHAN5G(118, 0),
487 CHAN5G(120, 0), CHAN5G(122, 0),
488 CHAN5G(124, 0), CHAN5G(126, 0),
489 CHAN5G(128, 0), CHAN5G(130, 0),
490 CHAN5G(132, 0), CHAN5G(134, 0),
491 CHAN5G(136, 0), CHAN5G(138, 0),
492 CHAN5G(140, 0), CHAN5G(142, 0),
493 CHAN5G(144, 0), CHAN5G(145, 0),
494 CHAN5G(146, 0), CHAN5G(147, 0),
495 CHAN5G(148, 0), CHAN5G(149, 0),
496 CHAN5G(150, 0), CHAN5G(151, 0),
497 CHAN5G(152, 0), CHAN5G(153, 0),
498 CHAN5G(154, 0), CHAN5G(155, 0),
499 CHAN5G(156, 0), CHAN5G(157, 0),
500 CHAN5G(158, 0), CHAN5G(159, 0),
501 CHAN5G(160, 0), CHAN5G(161, 0),
502 CHAN5G(162, 0), CHAN5G(163, 0),
503 CHAN5G(164, 0), CHAN5G(165, 0),
504 CHAN5G(166, 0), CHAN5G(168, 0),
505 CHAN5G(170, 0), CHAN5G(172, 0),
506 CHAN5G(174, 0), CHAN5G(176, 0),
507 CHAN5G(178, 0), CHAN5G(180, 0),
508 CHAN5G(182, 0), CHAN5G(184, 0),
509 CHAN5G(186, 0), CHAN5G(188, 0),
510 CHAN5G(190, 0), CHAN5G(192, 0),
511 CHAN5G(194, 0), CHAN5G(196, 0),
512 CHAN5G(198, 0), CHAN5G(200, 0),
513 CHAN5G(202, 0), CHAN5G(204, 0),
514 CHAN5G(206, 0), CHAN5G(208, 0),
515 CHAN5G(210, 0), CHAN5G(212, 0),
516 CHAN5G(214, 0), CHAN5G(216, 0),
517 CHAN5G(218, 0), CHAN5G(220, 0),
518 CHAN5G(222, 0), CHAN5G(224, 0),
519 CHAN5G(226, 0), CHAN5G(228, 0),
522 static struct ieee80211_supported_band __wl_band_2ghz = {
523 .band = IEEE80211_BAND_2GHZ,
524 .channels = __wl_2ghz_channels,
525 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
526 .bitrates = wl_g_rates,
527 .n_bitrates = wl_g_rates_size,
530 static struct ieee80211_supported_band __wl_band_5ghz_a = {
531 .band = IEEE80211_BAND_5GHZ,
532 .channels = __wl_5ghz_a_channels,
533 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
534 .bitrates = wl_a_rates,
535 .n_bitrates = wl_a_rates_size,
538 static struct ieee80211_supported_band __wl_band_5ghz_n = {
539 .band = IEEE80211_BAND_5GHZ,
540 .channels = __wl_5ghz_n_channels,
541 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
542 .bitrates = wl_a_rates,
543 .n_bitrates = wl_a_rates_size,
546 static const u32 __wl_cipher_suites[] = {
547 WLAN_CIPHER_SUITE_WEP40,
548 WLAN_CIPHER_SUITE_WEP104,
549 WLAN_CIPHER_SUITE_TKIP,
550 WLAN_CIPHER_SUITE_CCMP,
551 WLAN_CIPHER_SUITE_AES_CMAC,
554 static void swap_key_from_BE(struct wl_wsec_key *key)
556 key->index = cpu_to_le32(key->index);
557 key->len = cpu_to_le32(key->len);
558 key->algo = cpu_to_le32(key->algo);
559 key->flags = cpu_to_le32(key->flags);
560 key->rxiv.hi = cpu_to_le32(key->rxiv.hi);
561 key->rxiv.lo = cpu_to_le16(key->rxiv.lo);
562 key->iv_initialized = cpu_to_le32(key->iv_initialized);
565 static void swap_key_to_BE(struct wl_wsec_key *key)
567 key->index = le32_to_cpu(key->index);
568 key->len = le32_to_cpu(key->len);
569 key->algo = le32_to_cpu(key->algo);
570 key->flags = le32_to_cpu(key->flags);
571 key->rxiv.hi = le32_to_cpu(key->rxiv.hi);
572 key->rxiv.lo = le16_to_cpu(key->rxiv.lo);
573 key->iv_initialized = le32_to_cpu(key->iv_initialized);
577 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
584 memset(&ioc, 0, sizeof(ioc));
588 strcpy(ifr.ifr_name, dev->name);
589 ifr.ifr_data = (caddr_t)&ioc;
593 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
600 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
601 enum nl80211_iftype type, u32 *flags,
602 struct vif_params *params)
604 struct wl_priv *wl = wiphy_to_wl(wiphy);
605 struct wireless_dev *wdev;
612 case NL80211_IFTYPE_MONITOR:
613 case NL80211_IFTYPE_WDS:
614 WL_ERR("type (%d) : currently we do not support this type\n",
617 case NL80211_IFTYPE_ADHOC:
618 wl->conf->mode = WL_MODE_IBSS;
620 case NL80211_IFTYPE_STATION:
621 wl->conf->mode = WL_MODE_BSS;
627 infra = cpu_to_le32(infra);
628 ap = cpu_to_le32(ap);
629 wdev = ndev->ieee80211_ptr;
631 WL_DBG("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra);
632 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
634 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
637 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
639 WL_ERR("WLC_SET_AP error (%d)\n", err);
643 /* -EINPROGRESS: Call commit handler */
647 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
649 memcpy(params->bssid, ether_bcast, ETH_ALEN);
650 params->bss_type = DOT11_BSSTYPE_ANY;
651 params->scan_type = 0;
652 params->nprobes = -1;
653 params->active_time = -1;
654 params->passive_time = -1;
655 params->home_time = -1;
656 params->channel_num = 0;
658 params->nprobes = cpu_to_le32(params->nprobes);
659 params->active_time = cpu_to_le32(params->active_time);
660 params->passive_time = cpu_to_le32(params->passive_time);
661 params->home_time = cpu_to_le32(params->home_time);
662 if (ssid && ssid->SSID_len)
663 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
668 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
669 s32 paramlen, void *bufptr, s32 buflen)
673 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
676 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
680 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
681 s32 paramlen, void *bufptr, s32 buflen)
685 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
688 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
692 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
695 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
696 struct wl_iscan_params *params;
699 if (ssid && ssid->SSID_len)
700 params_size += sizeof(struct wlc_ssid);
701 params = kzalloc(params_size, GFP_KERNEL);
702 if (unlikely(!params))
704 BUG_ON(params_size >= WLC_IOCTL_SMLEN);
706 wl_iscan_prep(¶ms->params, ssid);
708 params->version = cpu_to_le32(ISCAN_REQ_VERSION);
709 params->action = cpu_to_le16(action);
710 params->scan_duration = cpu_to_le16(0);
712 /* params_size += offsetof(wl_iscan_params_t, params); */
713 err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
714 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
717 WL_INFO("system busy : iscan canceled\n");
719 WL_ERR("error (%d)\n", err);
726 static s32 wl_do_iscan(struct wl_priv *wl)
728 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
729 struct net_device *ndev = wl_to_ndev(wl);
730 struct wlc_ssid ssid;
734 /* Broadcast scan by default */
735 memset(&ssid, 0, sizeof(ssid));
737 iscan->state = WL_ISCAN_STATE_SCANING;
739 passive_scan = wl->active_scan ? 0 : 1;
740 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
741 &passive_scan, sizeof(passive_scan));
743 WL_DBG("error (%d)\n", err);
747 wl->iscan_kickstart = true;
748 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
749 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
756 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
757 struct cfg80211_scan_request *request,
758 struct cfg80211_ssid *this_ssid)
760 struct wl_priv *wl = ndev_to_wl(ndev);
761 struct cfg80211_ssid *ssids;
762 struct wl_scan_req *sr = wl_to_sr(wl);
768 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
769 WL_ERR("Scanning already : status (%d)\n", (int)wl->status);
772 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
773 WL_ERR("Scanning being aborted : status (%d)\n",
780 if (request) { /* scan bss */
781 ssids = request->ssids;
782 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) { /* for
784 * ssids->ssid_len has
785 * non-zero(ssid string)
787 * Otherwise this is 0.
788 * we do not iscan for
789 * specific scan request
793 } else { /* scan in ibss */
794 /* we don't do iscan in ibss */
797 wl->scan_request = request;
798 set_bit(WL_STATUS_SCANNING, &wl->status);
800 err = wl_do_iscan(wl);
806 WL_DBG("ssid \"%s\", ssid_len (%d)\n",
807 ssids->ssid, ssids->ssid_len);
808 memset(&sr->ssid, 0, sizeof(sr->ssid));
810 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
811 if (sr->ssid.SSID_len) {
812 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
813 sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
814 WL_DBG("Specific scan ssid=\"%s\" len=%d\n",
815 sr->ssid.SSID, sr->ssid.SSID_len);
818 WL_DBG("Broadcast scan\n");
820 WL_DBG("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len);
821 passive_scan = wl->active_scan ? 0 : 1;
822 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
823 &passive_scan, sizeof(passive_scan));
825 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
829 err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
833 WL_INFO("system busy : scan for \"%s\" canceled\n",
836 WL_ERR("WLC_SCAN error (%d)\n", err);
846 clear_bit(WL_STATUS_SCANNING, &wl->status);
847 wl->scan_request = NULL;
852 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
853 struct cfg80211_scan_request *request)
858 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
860 WL_DBG("scan error (%d)\n", err);
867 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
869 s8 buf[WLC_IOCTL_SMLEN];
873 val = cpu_to_le32(val);
874 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
877 err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
879 WL_ERR("error (%d)\n", err);
886 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
889 s8 buf[WLC_IOCTL_SMLEN];
897 bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
900 err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
902 WL_ERR("error (%d)\n", err);
904 *retval = le32_to_cpu(var.val);
909 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
913 err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
915 WL_ERR("Error (%d)\n", err);
921 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
925 err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
927 WL_ERR("Error (%d)\n", err);
933 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
936 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
938 retry = cpu_to_le32(retry);
939 err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
941 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
947 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
949 struct wl_priv *wl = wiphy_to_wl(wiphy);
950 struct net_device *ndev = wl_to_ndev(wl);
954 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
955 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
956 wl->conf->rts_threshold = wiphy->rts_threshold;
957 err = wl_set_rts(ndev, wl->conf->rts_threshold);
961 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
962 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
963 wl->conf->frag_threshold = wiphy->frag_threshold;
964 err = wl_set_frag(ndev, wl->conf->frag_threshold);
968 if (changed & WIPHY_PARAM_RETRY_LONG
969 && (wl->conf->retry_long != wiphy->retry_long)) {
970 wl->conf->retry_long = wiphy->retry_long;
971 err = wl_set_retry(ndev, wl->conf->retry_long, true);
975 if (changed & WIPHY_PARAM_RETRY_SHORT
976 && (wl->conf->retry_short != wiphy->retry_short)) {
977 wl->conf->retry_short = wiphy->retry_short;
978 err = wl_set_retry(ndev, wl->conf->retry_short, false);
988 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
989 struct cfg80211_ibss_params *params)
991 struct wl_priv *wl = wiphy_to_wl(wiphy);
992 struct cfg80211_bss *bss;
993 struct ieee80211_channel *chan;
994 struct wl_join_params join_params;
995 struct cfg80211_ssid ssid;
1000 if (params->bssid) {
1001 WL_ERR("Invalid bssid\n");
1004 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1006 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1007 ssid.ssid_len = params->ssid_len;
1010 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1016 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1017 rtnl_unlock(); /* to allow scan_inform to paropagate
1018 to cfg80211 plane */
1019 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1020 till scan done.... */
1022 bss = cfg80211_get_ibss(wiphy, NULL,
1023 params->ssid, params->ssid_len);
1026 wl->ibss_starter = false;
1027 WL_DBG("Found IBSS\n");
1029 wl->ibss_starter = true;
1031 chan = params->channel;
1033 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1035 ** Join with specific BSSID and cached SSID
1036 ** If SSID is zero join based on BSSID only
1038 memset(&join_params, 0, sizeof(join_params));
1039 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1041 join_params.ssid.SSID_len = cpu_to_le32(params->ssid_len);
1043 memcpy(&join_params.params.bssid, params->bssid,
1046 memset(&join_params.params.bssid, 0, ETH_ALEN);
1048 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1049 sizeof(join_params));
1050 if (unlikely(err)) {
1051 WL_ERR("Error (%d)\n", err);
1057 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1059 struct wl_priv *wl = wiphy_to_wl(wiphy);
1069 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1071 struct wl_priv *wl = ndev_to_wl(dev);
1072 struct wl_security *sec;
1076 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1077 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1078 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1079 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1081 val = WPA_AUTH_DISABLED;
1082 WL_DBG("setting wpa_auth to 0x%0x\n", val);
1083 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1084 if (unlikely(err)) {
1085 WL_ERR("set wpa_auth failed (%d)\n", err);
1088 sec = wl_read_prof(wl, WL_PROF_SEC);
1089 sec->wpa_versions = sme->crypto.wpa_versions;
1094 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1096 struct wl_priv *wl = ndev_to_wl(dev);
1097 struct wl_security *sec;
1101 switch (sme->auth_type) {
1102 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1104 WL_DBG("open system\n");
1106 case NL80211_AUTHTYPE_SHARED_KEY:
1108 WL_DBG("shared key\n");
1110 case NL80211_AUTHTYPE_AUTOMATIC:
1112 WL_DBG("automatic\n");
1114 case NL80211_AUTHTYPE_NETWORK_EAP:
1115 WL_DBG("network eap\n");
1118 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1122 err = wl_dev_intvar_set(dev, "auth", val);
1123 if (unlikely(err)) {
1124 WL_ERR("set auth failed (%d)\n", err);
1127 sec = wl_read_prof(wl, WL_PROF_SEC);
1128 sec->auth_type = sme->auth_type;
1133 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1135 struct wl_priv *wl = ndev_to_wl(dev);
1136 struct wl_security *sec;
1141 if (sme->crypto.n_ciphers_pairwise) {
1142 switch (sme->crypto.ciphers_pairwise[0]) {
1143 case WLAN_CIPHER_SUITE_WEP40:
1144 case WLAN_CIPHER_SUITE_WEP104:
1147 case WLAN_CIPHER_SUITE_TKIP:
1148 pval = TKIP_ENABLED;
1150 case WLAN_CIPHER_SUITE_CCMP:
1153 case WLAN_CIPHER_SUITE_AES_CMAC:
1157 WL_ERR("invalid cipher pairwise (%d)\n",
1158 sme->crypto.ciphers_pairwise[0]);
1162 if (sme->crypto.cipher_group) {
1163 switch (sme->crypto.cipher_group) {
1164 case WLAN_CIPHER_SUITE_WEP40:
1165 case WLAN_CIPHER_SUITE_WEP104:
1168 case WLAN_CIPHER_SUITE_TKIP:
1169 gval = TKIP_ENABLED;
1171 case WLAN_CIPHER_SUITE_CCMP:
1174 case WLAN_CIPHER_SUITE_AES_CMAC:
1178 WL_ERR("invalid cipher group (%d)\n",
1179 sme->crypto.cipher_group);
1184 WL_DBG("pval (%d) gval (%d)\n", pval, gval);
1185 err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1186 if (unlikely(err)) {
1187 WL_ERR("error (%d)\n", err);
1191 sec = wl_read_prof(wl, WL_PROF_SEC);
1192 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1193 sec->cipher_group = sme->crypto.cipher_group;
1199 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1201 struct wl_priv *wl = ndev_to_wl(dev);
1202 struct wl_security *sec;
1206 if (sme->crypto.n_akm_suites) {
1207 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1208 if (unlikely(err)) {
1209 WL_ERR("could not get wpa_auth (%d)\n", err);
1212 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1213 switch (sme->crypto.akm_suites[0]) {
1214 case WLAN_AKM_SUITE_8021X:
1215 val = WPA_AUTH_UNSPECIFIED;
1217 case WLAN_AKM_SUITE_PSK:
1221 WL_ERR("invalid cipher group (%d)\n",
1222 sme->crypto.cipher_group);
1225 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1226 switch (sme->crypto.akm_suites[0]) {
1227 case WLAN_AKM_SUITE_8021X:
1228 val = WPA2_AUTH_UNSPECIFIED;
1230 case WLAN_AKM_SUITE_PSK:
1231 val = WPA2_AUTH_PSK;
1234 WL_ERR("invalid cipher group (%d)\n",
1235 sme->crypto.cipher_group);
1240 WL_DBG("setting wpa_auth to %d\n", val);
1241 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1242 if (unlikely(err)) {
1243 WL_ERR("could not set wpa_auth (%d)\n", err);
1247 sec = wl_read_prof(wl, WL_PROF_SEC);
1248 sec->wpa_auth = sme->crypto.akm_suites[0];
1254 wl_set_set_sharedkey(struct net_device *dev,
1255 struct cfg80211_connect_params *sme)
1257 struct wl_priv *wl = ndev_to_wl(dev);
1258 struct wl_security *sec;
1259 struct wl_wsec_key key;
1263 WL_DBG("key len (%d)\n", sme->key_len);
1265 sec = wl_read_prof(wl, WL_PROF_SEC);
1266 WL_DBG("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1267 sec->wpa_versions, sec->cipher_pairwise);
1269 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1270 NL80211_WPA_VERSION_2))
1271 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1272 WLAN_CIPHER_SUITE_WEP104))) {
1273 memset(&key, 0, sizeof(key));
1274 key.len = (u32) sme->key_len;
1275 key.index = (u32) sme->key_idx;
1276 if (unlikely(key.len > sizeof(key.data))) {
1277 WL_ERR("Too long key length (%u)\n", key.len);
1280 memcpy(key.data, sme->key, key.len);
1281 key.flags = WL_PRIMARY_KEY;
1282 switch (sec->cipher_pairwise) {
1283 case WLAN_CIPHER_SUITE_WEP40:
1284 key.algo = CRYPTO_ALGO_WEP1;
1286 case WLAN_CIPHER_SUITE_WEP104:
1287 key.algo = CRYPTO_ALGO_WEP128;
1290 WL_ERR("Invalid algorithm (%d)\n",
1291 sme->crypto.ciphers_pairwise[0]);
1294 /* Set the new key/index */
1295 WL_DBG("key length (%d) key index (%d) algo (%d)\n",
1296 key.len, key.index, key.algo);
1297 WL_DBG("key \"%s\"\n", key.data);
1298 swap_key_from_BE(&key);
1299 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1301 if (unlikely(err)) {
1302 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1305 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1306 WL_DBG("set auth_type to shared key\n");
1307 val = 1; /* shared key */
1308 err = wl_dev_intvar_set(dev, "auth", val);
1309 if (unlikely(err)) {
1310 WL_ERR("set auth failed (%d)\n", err);
1320 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1321 struct cfg80211_connect_params *sme)
1323 struct wl_priv *wl = wiphy_to_wl(wiphy);
1324 struct ieee80211_channel *chan = sme->channel;
1325 struct wl_join_params join_params;
1326 size_t join_params_size;
1331 if (unlikely(!sme->ssid)) {
1332 WL_ERR("Invalid ssid\n");
1336 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1337 WL_DBG("channel (%d), center_req (%d)\n",
1338 wl->channel, chan->center_freq);
1340 WL_DBG("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1341 err = wl_set_wpa_version(dev, sme);
1345 err = wl_set_auth_type(dev, sme);
1349 err = wl_set_set_cipher(dev, sme);
1353 err = wl_set_key_mgmt(dev, sme);
1357 err = wl_set_set_sharedkey(dev, sme);
1361 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1363 ** Join with specific BSSID and cached SSID
1364 ** If SSID is zero join based on BSSID only
1366 memset(&join_params, 0, sizeof(join_params));
1367 join_params_size = sizeof(join_params.ssid);
1369 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1370 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1371 join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
1372 wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1373 memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
1375 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1376 WL_DBG("join_param_size %zu\n", join_params_size);
1378 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1379 WL_DBG("ssid \"%s\", len (%d)\n",
1380 join_params.ssid.SSID, join_params.ssid.SSID_len);
1382 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1383 if (unlikely(err)) {
1384 WL_ERR("error (%d)\n", err);
1387 set_bit(WL_STATUS_CONNECTING, &wl->status);
1393 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1396 struct wl_priv *wl = wiphy_to_wl(wiphy);
1401 WL_DBG("Reason %d\n", reason_code);
1403 act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
1405 scbval.val = reason_code;
1406 memcpy(&scbval.ea, &wl->bssid, ETH_ALEN);
1407 scbval.val = cpu_to_le32(scbval.val);
1408 err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1410 if (unlikely(err)) {
1411 WL_ERR("error (%d)\n", err);
1420 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1421 enum nl80211_tx_power_setting type, s32 dbm)
1424 struct wl_priv *wl = wiphy_to_wl(wiphy);
1425 struct net_device *ndev = wl_to_ndev(wl);
1432 case NL80211_TX_POWER_AUTOMATIC:
1434 case NL80211_TX_POWER_LIMITED:
1436 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1440 case NL80211_TX_POWER_FIXED:
1442 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1447 /* Make sure radio is off or on as far as software is concerned */
1448 disable = WL_RADIO_SW_DISABLE << 16;
1449 disable = cpu_to_le32(disable);
1450 err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1451 if (unlikely(err)) {
1452 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1459 txpwrmw = (u16) dbm;
1460 err = wl_dev_intvar_set(ndev, "qtxpower",
1461 (s32) (bcm_mw_to_qdbm(txpwrmw)));
1462 if (unlikely(err)) {
1463 WL_ERR("qtxpower error (%d)\n", err);
1466 wl->conf->tx_power = dbm;
1471 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1473 struct wl_priv *wl = wiphy_to_wl(wiphy);
1474 struct net_device *ndev = wl_to_ndev(wl);
1480 err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1481 if (unlikely(err)) {
1482 WL_ERR("error (%d)\n", err);
1485 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1486 *dbm = (s32) bcm_qdbm_to_mw(result);
1492 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1493 u8 key_idx, bool unicast, bool multicast)
1499 WL_DBG("key index (%d)\n", key_idx);
1502 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1503 if (unlikely(err)) {
1504 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1507 wsec = le32_to_cpu(wsec);
1508 if (wsec & WEP_ENABLED) {
1509 /* Just select a new current key */
1510 index = (u32) key_idx;
1511 index = cpu_to_le32(index);
1512 err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
1514 if (unlikely(err)) {
1515 WL_ERR("error (%d)\n", err);
1522 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1523 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1525 struct wl_wsec_key key;
1528 memset(&key, 0, sizeof(key));
1529 key.index = (u32) key_idx;
1530 /* Instead of bcast for ea address for default wep keys,
1531 driver needs it to be Null */
1532 if (!is_multicast_ether_addr(mac_addr))
1533 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1534 key.len = (u32) params->key_len;
1535 /* check for key index change */
1538 swap_key_from_BE(&key);
1539 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1540 if (unlikely(err)) {
1541 WL_ERR("key delete error (%d)\n", err);
1545 if (key.len > sizeof(key.data)) {
1546 WL_ERR("Invalid key length (%d)\n", key.len);
1550 WL_DBG("Setting the key index %d\n", key.index);
1551 memcpy(key.data, params->key, key.len);
1553 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1555 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1556 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1557 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1560 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1561 if (params->seq && params->seq_len == 6) {
1564 ivptr = (u8 *) params->seq;
1565 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1566 (ivptr[3] << 8) | ivptr[2];
1567 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1568 key.iv_initialized = true;
1571 switch (params->cipher) {
1572 case WLAN_CIPHER_SUITE_WEP40:
1573 key.algo = CRYPTO_ALGO_WEP1;
1574 WL_DBG("WLAN_CIPHER_SUITE_WEP40\n");
1576 case WLAN_CIPHER_SUITE_WEP104:
1577 key.algo = CRYPTO_ALGO_WEP128;
1578 WL_DBG("WLAN_CIPHER_SUITE_WEP104\n");
1580 case WLAN_CIPHER_SUITE_TKIP:
1581 key.algo = CRYPTO_ALGO_TKIP;
1582 WL_DBG("WLAN_CIPHER_SUITE_TKIP\n");
1584 case WLAN_CIPHER_SUITE_AES_CMAC:
1585 key.algo = CRYPTO_ALGO_AES_CCM;
1586 WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n");
1588 case WLAN_CIPHER_SUITE_CCMP:
1589 key.algo = CRYPTO_ALGO_AES_CCM;
1590 WL_DBG("WLAN_CIPHER_SUITE_CCMP\n");
1593 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1596 swap_key_from_BE(&key);
1598 dhd_wait_pend8021x(dev);
1599 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1600 if (unlikely(err)) {
1601 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1609 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1610 u8 key_idx, bool pairwise, const u8 *mac_addr,
1611 struct key_params *params)
1613 struct wl_wsec_key key;
1618 WL_DBG("key index (%d)\n", key_idx);
1622 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1623 memset(&key, 0, sizeof(key));
1625 key.len = (u32) params->key_len;
1626 key.index = (u32) key_idx;
1628 if (unlikely(key.len > sizeof(key.data))) {
1629 WL_ERR("Too long key length (%u)\n", key.len);
1632 memcpy(key.data, params->key, key.len);
1634 key.flags = WL_PRIMARY_KEY;
1635 switch (params->cipher) {
1636 case WLAN_CIPHER_SUITE_WEP40:
1637 key.algo = CRYPTO_ALGO_WEP1;
1638 WL_DBG("WLAN_CIPHER_SUITE_WEP40\n");
1640 case WLAN_CIPHER_SUITE_WEP104:
1641 key.algo = CRYPTO_ALGO_WEP128;
1642 WL_DBG("WLAN_CIPHER_SUITE_WEP104\n");
1644 case WLAN_CIPHER_SUITE_TKIP:
1645 key.algo = CRYPTO_ALGO_TKIP;
1646 WL_DBG("WLAN_CIPHER_SUITE_TKIP\n");
1648 case WLAN_CIPHER_SUITE_AES_CMAC:
1649 key.algo = CRYPTO_ALGO_AES_CCM;
1650 WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n");
1652 case WLAN_CIPHER_SUITE_CCMP:
1653 key.algo = CRYPTO_ALGO_AES_CCM;
1654 WL_DBG("WLAN_CIPHER_SUITE_CCMP\n");
1657 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1661 /* Set the new key/index */
1662 swap_key_from_BE(&key);
1663 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1664 if (unlikely(err)) {
1665 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1670 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1671 if (unlikely(err)) {
1672 WL_ERR("get wsec error (%d)\n", err);
1675 wsec &= ~(WEP_ENABLED);
1677 err = wl_dev_intvar_set(dev, "wsec", wsec);
1678 if (unlikely(err)) {
1679 WL_ERR("set wsec error (%d)\n", err);
1683 val = 1; /* assume shared key. otherwise 0 */
1684 val = cpu_to_le32(val);
1685 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1686 if (unlikely(err)) {
1687 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1694 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1695 u8 key_idx, bool pairwise, const u8 *mac_addr)
1697 struct wl_wsec_key key;
1703 memset(&key, 0, sizeof(key));
1705 key.index = (u32) key_idx;
1706 key.flags = WL_PRIMARY_KEY;
1707 key.algo = CRYPTO_ALGO_OFF;
1709 WL_DBG("key index (%d)\n", key_idx);
1710 /* Set the new key/index */
1711 swap_key_from_BE(&key);
1712 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1713 if (unlikely(err)) {
1714 if (err == -EINVAL) {
1715 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1716 /* we ignore this key index in this case */
1717 WL_DBG("invalid key index (%d)\n", key_idx);
1720 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1726 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1727 if (unlikely(err)) {
1728 WL_ERR("get wsec error (%d)\n", err);
1731 wsec &= ~(WEP_ENABLED);
1733 err = wl_dev_intvar_set(dev, "wsec", wsec);
1734 if (unlikely(err)) {
1735 WL_ERR("set wsec error (%d)\n", err);
1739 val = 0; /* assume open key. otherwise 1 */
1740 val = cpu_to_le32(val);
1741 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1742 if (unlikely(err)) {
1743 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1750 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1751 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1752 void (*callback) (void *cookie, struct key_params * params))
1754 struct key_params params;
1755 struct wl_wsec_key key;
1756 struct wl_priv *wl = wiphy_to_wl(wiphy);
1757 struct wl_security *sec;
1761 WL_DBG("key index (%d)\n", key_idx);
1764 memset(&key, 0, sizeof(key));
1765 key.index = key_idx;
1766 swap_key_to_BE(&key);
1767 memset(¶ms, 0, sizeof(params));
1768 params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len);
1769 memcpy(params.key, key.data, params.key_len);
1771 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1772 if (unlikely(err)) {
1773 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1776 wsec = le32_to_cpu(wsec);
1779 sec = wl_read_prof(wl, WL_PROF_SEC);
1780 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1781 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1782 WL_DBG("WLAN_CIPHER_SUITE_WEP40\n");
1783 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1784 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1785 WL_DBG("WLAN_CIPHER_SUITE_WEP104\n");
1789 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1790 WL_DBG("WLAN_CIPHER_SUITE_TKIP\n");
1793 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1794 WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n");
1797 WL_ERR("Invalid algo (0x%x)\n", wsec);
1801 callback(cookie, ¶ms);
1806 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1807 struct net_device *dev, u8 key_idx)
1809 WL_INFO("Not supported\n");
1815 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1816 u8 *mac, struct station_info *sinfo)
1818 struct wl_priv *wl = wiphy_to_wl(wiphy);
1826 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN))) {
1827 WL_ERR("Wrong Mac address\n");
1831 /* Report the current tx rate */
1832 err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1834 WL_ERR("Could not get rate (%d)\n", err);
1836 rate = le32_to_cpu(rate);
1837 sinfo->filled |= STATION_INFO_TX_BITRATE;
1838 sinfo->txrate.legacy = rate * 5;
1839 WL_DBG("Rate %d Mbps\n", rate / 2);
1842 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1844 err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1846 if (unlikely(err)) {
1847 WL_ERR("Could not get rssi (%d)\n", err);
1850 rssi = le32_to_cpu(scb_val.val);
1851 sinfo->filled |= STATION_INFO_SIGNAL;
1852 sinfo->signal = rssi;
1853 WL_DBG("RSSI %d dBm\n", rssi);
1860 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1861 bool enabled, s32 timeout)
1867 pm = enabled ? PM_FAST : PM_OFF;
1868 pm = cpu_to_le32(pm);
1869 WL_DBG("power save %s\n", (pm ? "enabled" : "disabled"));
1870 err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1871 if (unlikely(err)) {
1873 WL_DBG("net_device is not ready yet\n");
1875 WL_ERR("error (%d)\n", err);
1881 static __used u32 wl_find_msb(u16 bit16)
1885 if (bit16 & 0xff00) {
1909 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1911 const struct cfg80211_bitrate_mask *mask)
1913 struct wl_rateset rateset;
1922 /* addr param is always NULL. ignore it */
1923 /* Get current rateset */
1924 err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1926 if (unlikely(err)) {
1927 WL_ERR("could not get current rateset (%d)\n", err);
1931 rateset.count = le32_to_cpu(rateset.count);
1933 legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
1935 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1937 val = wl_g_rates[legacy - 1].bitrate * 100000;
1939 if (val < rateset.count) {
1940 /* Select rate by rateset index */
1941 rate = rateset.rates[val] & 0x7f;
1943 /* Specified rate in bps */
1944 rate = val / 500000;
1947 WL_DBG("rate %d mbps\n", rate / 2);
1951 * Set rate override,
1952 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1954 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1955 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1956 if (unlikely(err_bg && err_a)) {
1957 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1958 return err_bg | err_a;
1964 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
1969 wl_invoke_iscan(wiphy_to_wl(wiphy));
1974 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
1976 struct wl_priv *wl = wiphy_to_wl(wiphy);
1977 struct net_device *ndev = wl_to_ndev(wl);
1980 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1982 if (wl->scan_request) {
1983 cfg80211_scan_done(wl->scan_request, true); /* true means
1985 wl_set_mpc(ndev, 1);
1986 wl->scan_request = NULL;
1988 clear_bit(WL_STATUS_SCANNING, &wl->status);
1989 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1995 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2000 WL_DBG("No of elements %d\n", pmk_list->pmkids.npmkid);
2001 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2002 WL_DBG("PMKID[%d]: %pM =\n", i,
2003 &pmk_list->pmkids.pmkid[i].BSSID);
2004 for (j = 0; j < WLAN_PMKID_LEN; j++) {
2005 WL_DBG("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2009 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2017 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2018 struct cfg80211_pmksa *pmksa)
2020 struct wl_priv *wl = wiphy_to_wl(wiphy);
2025 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2026 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2029 if (i < WL_NUM_PMKIDS_MAX) {
2030 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2032 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2034 if (i == wl->pmk_list->pmkids.npmkid)
2035 wl->pmk_list->pmkids.npmkid++;
2039 WL_DBG("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2040 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID);
2041 for (i = 0; i < WLAN_PMKID_LEN; i++) {
2043 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2047 err = wl_update_pmklist(dev, wl->pmk_list, err);
2053 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2054 struct cfg80211_pmksa *pmksa)
2056 struct wl_priv *wl = wiphy_to_wl(wiphy);
2057 struct _pmkid_list pmkid;
2062 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2063 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2065 WL_DBG("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2066 &pmkid.pmkid[0].BSSID);
2067 for (i = 0; i < WLAN_PMKID_LEN; i++) {
2068 WL_DBG("%02x\n", pmkid.pmkid[0].PMKID[i]);
2071 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2073 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2077 if ((wl->pmk_list->pmkids.npmkid > 0)
2078 && (i < wl->pmk_list->pmkids.npmkid)) {
2079 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2080 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2081 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2082 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2084 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2085 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2088 wl->pmk_list->pmkids.npmkid--;
2093 err = wl_update_pmklist(dev, wl->pmk_list, err);
2100 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2102 struct wl_priv *wl = wiphy_to_wl(wiphy);
2106 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2107 err = wl_update_pmklist(dev, wl->pmk_list, err);
2112 static struct cfg80211_ops wl_cfg80211_ops = {
2113 .change_virtual_intf = wl_cfg80211_change_iface,
2114 .scan = wl_cfg80211_scan,
2115 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2116 .join_ibss = wl_cfg80211_join_ibss,
2117 .leave_ibss = wl_cfg80211_leave_ibss,
2118 .get_station = wl_cfg80211_get_station,
2119 .set_tx_power = wl_cfg80211_set_tx_power,
2120 .get_tx_power = wl_cfg80211_get_tx_power,
2121 .add_key = wl_cfg80211_add_key,
2122 .del_key = wl_cfg80211_del_key,
2123 .get_key = wl_cfg80211_get_key,
2124 .set_default_key = wl_cfg80211_config_default_key,
2125 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2126 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2127 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2128 .connect = wl_cfg80211_connect,
2129 .disconnect = wl_cfg80211_disconnect,
2130 .suspend = wl_cfg80211_suspend,
2131 .resume = wl_cfg80211_resume,
2132 .set_pmksa = wl_cfg80211_set_pmksa,
2133 .del_pmksa = wl_cfg80211_del_pmksa,
2134 .flush_pmksa = wl_cfg80211_flush_pmksa
2137 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2143 return NL80211_IFTYPE_STATION;
2145 return NL80211_IFTYPE_ADHOC;
2147 return NL80211_IFTYPE_UNSPECIFIED;
2153 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2156 struct wireless_dev *wdev;
2159 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2160 if (unlikely(!wdev)) {
2161 WL_ERR("Could not allocate wireless device\n");
2162 return ERR_PTR(-ENOMEM);
2165 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2166 if (unlikely(!wdev->wiphy)) {
2167 WL_ERR("Couldn not allocate wiphy device\n");
2171 set_wiphy_dev(wdev->wiphy, dev);
2172 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2173 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2174 wdev->wiphy->interface_modes =
2175 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2176 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2177 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2178 * it as 11a by default.
2179 * This will be updated with
2182 * if phy has 11n capability
2184 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2185 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2186 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2187 #ifndef WL_POWERSAVE_DISABLED
2188 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2193 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2194 #endif /* !WL_POWERSAVE_DISABLED */
2195 err = wiphy_register(wdev->wiphy);
2196 if (unlikely(err < 0)) {
2197 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2198 goto wiphy_register_out;
2203 wiphy_free(wdev->wiphy);
2208 return ERR_PTR(err);
2211 static void wl_free_wdev(struct wl_priv *wl)
2213 struct wireless_dev *wdev = wl_to_wdev(wl);
2215 if (unlikely(!wdev)) {
2216 WL_ERR("wdev is invalid\n");
2219 wiphy_unregister(wdev->wiphy);
2220 wiphy_free(wdev->wiphy);
2222 wl_to_wdev(wl) = NULL;
2225 static s32 wl_inform_bss(struct wl_priv *wl)
2227 struct wl_scan_results *bss_list;
2228 struct wl_bss_info *bi = NULL; /* must be initialized */
2232 bss_list = wl->bss_list;
2233 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2234 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2238 WL_DBG("scanned AP count (%d)\n", bss_list->count);
2239 bi = next_bss(bss_list, bi);
2240 for_each_bss(bss_list, bi, i) {
2241 err = wl_inform_single_bss(wl, bi);
2248 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2250 struct wiphy *wiphy = wl_to_wiphy(wl);
2251 struct ieee80211_mgmt *mgmt;
2252 struct ieee80211_channel *channel;
2253 struct ieee80211_supported_band *band;
2254 struct wl_cfg80211_bss_info *notif_bss_info;
2255 struct wl_scan_req *sr = wl_to_sr(wl);
2256 struct beacon_proberesp *beacon_proberesp;
2262 if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
2263 WL_DBG("Beacon is larger than buffer. Discarding\n");
2267 kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2268 WL_BSS_INFO_MAX, GFP_KERNEL);
2269 if (unlikely(!notif_bss_info)) {
2270 WL_ERR("notif_bss_info alloc failed\n");
2273 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2274 notif_bss_info->channel =
2275 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
2277 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2278 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2280 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2281 notif_bss_info->rssi = bi->RSSI;
2282 memcpy(mgmt->bssid, &bi->BSSID, ETH_ALEN);
2283 mgmt_type = wl->active_scan ?
2284 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
2285 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2286 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2289 beacon_proberesp = wl->active_scan ?
2290 (struct beacon_proberesp *)&mgmt->u.probe_resp :
2291 (struct beacon_proberesp *)&mgmt->u.beacon;
2292 beacon_proberesp->timestamp = 0;
2293 beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
2294 beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
2297 * wl_add_ie is not necessary because it can only add duplicated
2298 * SSID, rate information to frame_buf
2301 * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2302 * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2303 * bi->rateset.rates);
2305 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2306 wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
2307 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2308 notif_bss_info->frame_len =
2309 offsetof(struct ieee80211_mgmt,
2310 u.beacon.variable) + wl_get_ielen(wl);
2311 freq = ieee80211_channel_to_frequency(notif_bss_info->channel,
2314 channel = ieee80211_get_channel(wiphy, freq);
2316 WL_DBG("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
2318 notif_bss_info->rssi, notif_bss_info->channel,
2319 mgmt->u.beacon.capab_info, &bi->BSSID);
2321 signal = notif_bss_info->rssi * 100;
2322 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2324 (notif_bss_info->frame_len),
2325 signal, GFP_KERNEL))) {
2326 WL_ERR("cfg80211_inform_bss_frame error\n");
2327 kfree(notif_bss_info);
2330 kfree(notif_bss_info);
2335 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2337 u32 event = be32_to_cpu(e->event_type);
2338 u16 flags = be16_to_cpu(e->flags);
2340 if (event == WLC_E_LINK) {
2341 if (flags & WLC_EVENT_MSG_LINK) {
2342 if (wl_is_ibssmode(wl)) {
2343 if (wl_is_ibssstarter(wl)) {
2354 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2356 u32 event = be32_to_cpu(e->event_type);
2357 u16 flags = be16_to_cpu(e->flags);
2359 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2361 } else if (event == WLC_E_LINK) {
2362 if (!(flags & WLC_EVENT_MSG_LINK))
2369 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2371 u32 event = be32_to_cpu(e->event_type);
2372 u32 status = be32_to_cpu(e->status);
2374 if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2375 if (status == WLC_E_STATUS_NO_NETWORKS)
2383 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2384 const wl_event_msg_t *e, void *data)
2389 if (wl_is_linkup(wl, e)) {
2391 if (wl_is_ibssmode(wl)) {
2392 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2394 WL_DBG("joined in IBSS network\n");
2396 wl_bss_connect_done(wl, ndev, e, data, true);
2397 WL_DBG("joined in BSS network \"%s\"\n",
2398 ((struct wlc_ssid *)
2399 wl_read_prof(wl, WL_PROF_SSID))->SSID);
2402 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2403 } else if (wl_is_linkdown(wl, e)) {
2404 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2405 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2407 wl_init_prof(wl->profile);
2408 } else if (wl_is_nonetwork(wl, e)) {
2409 wl_bss_connect_done(wl, ndev, e, data, false);
2416 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2417 const wl_event_msg_t *e, void *data)
2422 wl_bss_roaming_done(wl, ndev, e, data);
2424 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2430 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2432 struct wl_priv *wl = ndev_to_wl(dev);
2435 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2438 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2442 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2445 struct wl_priv *wl = ndev_to_wl(dev);
2449 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2451 err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2453 if (unlikely(err)) {
2454 WL_ERR("error (%d)\n", err);
2457 memcpy(buf, wl->ioctl_buf, buf_len);
2462 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2464 struct net_device *ndev = wl_to_ndev(wl);
2465 struct wl_assoc_ielen *assoc_info;
2466 struct wl_connect_info *conn_info = wl_to_conn(wl);
2471 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2473 if (unlikely(err)) {
2474 WL_ERR("could not get assoc info (%d)\n", err);
2477 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2478 req_len = assoc_info->req_len;
2479 resp_len = assoc_info->resp_len;
2481 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2483 if (unlikely(err)) {
2484 WL_ERR("could not get assoc req (%d)\n", err);
2487 conn_info->req_ie_len = req_len;
2489 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2491 conn_info->req_ie_len = 0;
2492 conn_info->req_ie = NULL;
2495 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2497 if (unlikely(err)) {
2498 WL_ERR("could not get assoc resp (%d)\n", err);
2501 conn_info->resp_ie_len = resp_len;
2502 conn_info->resp_ie =
2503 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2505 conn_info->resp_ie_len = 0;
2506 conn_info->resp_ie = NULL;
2508 WL_DBG("req len (%d) resp len (%d)\n",
2509 conn_info->req_ie_len, conn_info->resp_ie_len);
2514 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2515 size_t *join_params_size)
2517 chanspec_t chanspec = 0;
2520 join_params->params.chanspec_num = 1;
2521 join_params->params.chanspec_list[0] = ch;
2523 if (join_params->params.chanspec_list[0])
2524 chanspec |= WL_CHANSPEC_BAND_2G;
2526 chanspec |= WL_CHANSPEC_BAND_5G;
2528 chanspec |= WL_CHANSPEC_BW_20;
2529 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2531 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2532 join_params->params.chanspec_num * sizeof(chanspec_t);
2534 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2535 join_params->params.chanspec_list[0] |= chanspec;
2536 join_params->params.chanspec_list[0] =
2537 cpu_to_le16(join_params->params.chanspec_list[0]);
2539 join_params->params.chanspec_num =
2540 cpu_to_le32(join_params->params.chanspec_num);
2542 WL_DBG("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
2543 join_params->params.chanspec_list[0], ch, chanspec);
2547 static s32 wl_update_bss_info(struct wl_priv *wl)
2549 struct cfg80211_bss *bss;
2550 struct wl_bss_info *bi;
2551 struct wlc_ssid *ssid;
2552 struct bcm_tlv *tim;
2553 u16 beacon_interval;
2559 if (wl_is_ibssmode(wl))
2562 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2564 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2565 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2566 WLAN_CAPABILITY_ESS);
2569 if (unlikely(!bss)) {
2570 WL_DBG("Could not find the AP\n");
2571 *(u32 *) wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2572 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2573 wl->extra_buf, WL_EXTRA_BUF_MAX);
2574 if (unlikely(err)) {
2575 WL_ERR("Could not get bss info %d\n", err);
2576 goto update_bss_info_out;
2578 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2579 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETH_ALEN))) {
2581 goto update_bss_info_out;
2583 err = wl_inform_single_bss(wl, bi);
2585 goto update_bss_info_out;
2587 ie = ((u8 *)bi) + bi->ie_offset;
2588 ie_len = bi->ie_length;
2589 beacon_interval = cpu_to_le16(bi->beacon_period);
2591 WL_DBG("Found the AP in the list - BSSID %pM\n", bss->bssid);
2592 ie = bss->information_elements;
2593 ie_len = bss->len_information_elements;
2594 beacon_interval = bss->beacon_interval;
2595 cfg80211_put_bss(bss);
2598 tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2600 dtim_period = tim->data[1];
2603 * active scan was done so we could not get dtim
2604 * information out of probe response.
2605 * so we speficially query dtim information to dongle.
2607 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD,
2608 &dtim_period, sizeof(dtim_period));
2609 if (unlikely(err)) {
2610 WL_ERR("WLC_GET_DTIMPRD error (%d)\n", err);
2611 goto update_bss_info_out;
2615 wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
2616 wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2618 update_bss_info_out:
2624 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2625 const wl_event_msg_t *e, void *data)
2627 struct wl_connect_info *conn_info = wl_to_conn(wl);
2630 wl_get_assoc_ies(wl);
2631 memcpy(&wl->bssid, &e->addr, ETH_ALEN);
2632 wl_update_bss_info(wl);
2633 cfg80211_roamed(ndev, NULL,
2635 conn_info->req_ie, conn_info->req_ie_len,
2636 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2637 WL_DBG("Report roaming result\n");
2639 set_bit(WL_STATUS_CONNECTED, &wl->status);
2645 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2646 const wl_event_msg_t *e, void *data, bool completed)
2648 struct wl_connect_info *conn_info = wl_to_conn(wl);
2651 wl_get_assoc_ies(wl);
2652 memcpy(&wl->bssid, &e->addr, ETH_ALEN);
2653 wl_update_bss_info(wl);
2654 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2655 cfg80211_connect_result(ndev,
2658 conn_info->req_ie_len,
2660 conn_info->resp_ie_len,
2661 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2663 WL_DBG("Report connect result - connection %s\n",
2664 completed ? "succeeded" : "failed");
2666 cfg80211_roamed(ndev, NULL,
2668 conn_info->req_ie, conn_info->req_ie_len,
2669 conn_info->resp_ie, conn_info->resp_ie_len,
2671 WL_DBG("Report roaming result\n");
2673 set_bit(WL_STATUS_CONNECTED, &wl->status);
2679 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2680 const wl_event_msg_t *e, void *data)
2682 u16 flags = be16_to_cpu(e->flags);
2683 enum nl80211_key_type key_type;
2686 if (flags & WLC_EVENT_MSG_GROUP)
2687 key_type = NL80211_KEYTYPE_GROUP;
2689 key_type = NL80211_KEYTYPE_PAIRWISE;
2691 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2699 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2700 const wl_event_msg_t *e, void *data)
2702 struct channel_info channel_inform;
2703 struct wl_scan_results *bss_list;
2704 u32 len = WL_SCAN_BUF_MAX;
2707 if (wl->iscan_on && wl->iscan_kickstart)
2708 return wl_wakeup_iscan(wl_to_iscan(wl));
2710 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2711 WL_ERR("Scan complete while device not scanning\n");
2714 if (unlikely(!wl->scan_request)) {
2717 err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2718 sizeof(channel_inform));
2719 if (unlikely(err)) {
2720 WL_ERR("scan busy (%d)\n", err);
2723 channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
2724 if (unlikely(channel_inform.scan_channel)) {
2726 WL_DBG("channel_inform.scan_channel (%d)\n",
2727 channel_inform.scan_channel);
2729 wl->bss_list = wl->scan_results;
2730 bss_list = wl->bss_list;
2731 memset(bss_list, 0, len);
2732 bss_list->buflen = cpu_to_le32(len);
2733 err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
2734 if (unlikely(err)) {
2735 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
2739 bss_list->buflen = le32_to_cpu(bss_list->buflen);
2740 bss_list->version = le32_to_cpu(bss_list->version);
2741 bss_list->count = le32_to_cpu(bss_list->count);
2743 err = wl_inform_bss(wl);
2748 if (wl->scan_request) {
2749 cfg80211_scan_done(wl->scan_request, false);
2750 wl_set_mpc(ndev, 1);
2751 wl->scan_request = NULL;
2757 static void wl_init_conf(struct wl_conf *conf)
2759 conf->mode = (u32)-1;
2760 conf->frag_threshold = (u32)-1;
2761 conf->rts_threshold = (u32)-1;
2762 conf->retry_short = (u32)-1;
2763 conf->retry_long = (u32)-1;
2764 conf->tx_power = -1;
2767 static void wl_init_prof(struct wl_profile *prof)
2769 memset(prof, 0, sizeof(*prof));
2772 static void wl_init_eloop_handler(struct wl_event_loop *el)
2774 memset(el, 0, sizeof(*el));
2775 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2776 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2777 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2778 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2779 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2780 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2781 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2782 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2783 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2784 el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2787 static s32 wl_init_priv_mem(struct wl_priv *wl)
2789 wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2790 if (unlikely(!wl->scan_results)) {
2791 WL_ERR("Scan results alloc failed\n");
2792 goto init_priv_mem_out;
2794 wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2795 if (unlikely(!wl->conf)) {
2796 WL_ERR("wl_conf alloc failed\n");
2797 goto init_priv_mem_out;
2799 wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2800 if (unlikely(!wl->profile)) {
2801 WL_ERR("wl_profile alloc failed\n");
2802 goto init_priv_mem_out;
2804 wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2805 if (unlikely(!wl->bss_info)) {
2806 WL_ERR("Bss information alloc failed\n");
2807 goto init_priv_mem_out;
2809 wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2810 if (unlikely(!wl->scan_req_int)) {
2811 WL_ERR("Scan req alloc failed\n");
2812 goto init_priv_mem_out;
2814 wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2815 if (unlikely(!wl->ioctl_buf)) {
2816 WL_ERR("Ioctl buf alloc failed\n");
2817 goto init_priv_mem_out;
2819 wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2820 if (unlikely(!wl->extra_buf)) {
2821 WL_ERR("Extra buf alloc failed\n");
2822 goto init_priv_mem_out;
2824 wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2825 if (unlikely(!wl->iscan)) {
2826 WL_ERR("Iscan buf alloc failed\n");
2827 goto init_priv_mem_out;
2829 wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2830 if (unlikely(!wl->fw)) {
2831 WL_ERR("fw object alloc failed\n");
2832 goto init_priv_mem_out;
2834 wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2835 if (unlikely(!wl->pmk_list)) {
2836 WL_ERR("pmk list alloc failed\n");
2837 goto init_priv_mem_out;
2843 wl_deinit_priv_mem(wl);
2848 static void wl_deinit_priv_mem(struct wl_priv *wl)
2850 kfree(wl->scan_results);
2851 wl->scan_results = NULL;
2852 kfree(wl->bss_info);
2853 wl->bss_info = NULL;
2858 kfree(wl->scan_req_int);
2859 wl->scan_req_int = NULL;
2860 kfree(wl->ioctl_buf);
2861 wl->ioctl_buf = NULL;
2862 kfree(wl->extra_buf);
2863 wl->extra_buf = NULL;
2868 kfree(wl->pmk_list);
2869 wl->pmk_list = NULL;
2872 static s32 wl_create_event_handler(struct wl_priv *wl)
2874 sema_init(&wl->event_sync, 0);
2875 wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
2876 if (IS_ERR(wl->event_tsk)) {
2877 wl->event_tsk = NULL;
2878 WL_ERR("failed to create event thread\n");
2884 static void wl_destroy_event_handler(struct wl_priv *wl)
2886 if (wl->event_tsk) {
2887 send_sig(SIGTERM, wl->event_tsk, 1);
2888 kthread_stop(wl->event_tsk);
2889 wl->event_tsk = NULL;
2893 static void wl_term_iscan(struct wl_priv *wl)
2895 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2897 if (wl->iscan_on && iscan->tsk) {