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.
20 #include <linux/kernel.h>
23 #include <bcmendian.h>
24 #include <proto/ethernet.h>
26 #include <linux/if_arp.h>
27 #include <asm/uaccess.h>
29 #include <dngl_stats.h>
34 #include <proto/ethernet.h>
35 #include <dngl_stats.h>
38 #include <linux/kernel.h>
39 #include <linux/kthread.h>
40 #include <linux/netdevice.h>
41 #include <linux/sched.h>
42 #include <linux/etherdevice.h>
43 #include <linux/wireless.h>
44 #include <linux/ieee80211.h>
45 #include <net/cfg80211.h>
47 #include <net/rtnetlink.h>
48 #include <linux/mmc/sdio_func.h>
49 #include <linux/firmware.h>
50 #include <wl_cfg80211.h>
52 static struct sdio_func *cfg80211_sdio_func;
53 static struct wl_dev *wl_cfg80211_dev;
55 u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
57 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
58 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
61 ** cfg80211_ops api/callback list
63 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
64 struct net_device *ndev,
65 enum nl80211_iftype type, u32 *flags,
66 struct vif_params *params);
67 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
68 struct cfg80211_scan_request *request,
69 struct cfg80211_ssid *this_ssid);
70 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
71 struct cfg80211_scan_request *request);
72 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
73 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
74 struct cfg80211_ibss_params *params);
75 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
76 struct net_device *dev);
77 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
78 struct net_device *dev, u8 *mac,
79 struct station_info *sinfo);
80 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
81 struct net_device *dev, bool enabled,
83 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
84 struct net_device *dev,
86 const struct cfg80211_bitrate_mask
88 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
89 struct cfg80211_connect_params *sme);
90 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
92 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
93 enum nl80211_tx_power_setting type,
95 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
96 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
97 struct net_device *dev,
99 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
100 u8 key_idx, const u8 *mac_addr,
101 struct key_params *params);
102 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
103 u8 key_idx, const u8 *mac_addr);
104 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
105 u8 key_idx, const u8 *mac_addr,
106 void *cookie, void (*callback) (void *cookie,
110 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
111 struct net_device *dev,
113 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
114 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
115 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
116 struct cfg80211_pmksa *pmksa);
117 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
118 struct cfg80211_pmksa *pmksa);
119 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
120 struct net_device *dev);
122 ** event & event Q handlers for cfg80211 interfaces
124 static s32 wl_create_event_handler(struct wl_priv *wl);
125 static void wl_destroy_event_handler(struct wl_priv *wl);
126 static s32 wl_event_handler(void *data);
127 static void wl_init_eq(struct wl_priv *wl);
128 static void wl_flush_eq(struct wl_priv *wl);
129 static void wl_lock_eq(struct wl_priv *wl);
130 static void wl_unlock_eq(struct wl_priv *wl);
131 static void wl_init_eq_lock(struct wl_priv *wl);
132 static void wl_init_eloop_handler(struct wl_event_loop *el);
133 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
134 static s32 wl_enq_event(struct wl_priv *wl, u32 type,
135 const wl_event_msg_t *msg, void *data);
136 static void wl_put_event(struct wl_event_q *e);
137 static void wl_wakeup_event(struct wl_priv *wl);
138 static s32 wl_notify_connect_status(struct wl_priv *wl,
139 struct net_device *ndev,
140 const wl_event_msg_t *e, void *data);
141 static s32 wl_notify_roaming_status(struct wl_priv *wl,
142 struct net_device *ndev,
143 const wl_event_msg_t *e, void *data);
144 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
145 const wl_event_msg_t *e, void *data);
146 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
147 const wl_event_msg_t *e, void *data,
149 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
150 const wl_event_msg_t *e, void *data);
151 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
152 const wl_event_msg_t *e, void *data);
155 ** register/deregister sdio function
157 struct sdio_func *wl_cfg80211_get_sdio_func(void);
158 static void wl_clear_sdio_func(void);
163 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
165 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
167 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
168 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
170 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
174 ** cfg80211 set_wiphy_params utilities
176 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
177 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
178 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
181 ** wl profile utilities
183 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
184 void *data, s32 item);
185 static void *wl_read_prof(struct wl_priv *wl, s32 item);
186 static void wl_init_prof(struct wl_profile *prof);
189 ** cfg80211 connect utilites
191 static s32 wl_set_wpa_version(struct net_device *dev,
192 struct cfg80211_connect_params *sme);
193 static s32 wl_set_auth_type(struct net_device *dev,
194 struct cfg80211_connect_params *sme);
195 static s32 wl_set_set_cipher(struct net_device *dev,
196 struct cfg80211_connect_params *sme);
197 static s32 wl_set_key_mgmt(struct net_device *dev,
198 struct cfg80211_connect_params *sme);
199 static s32 wl_set_set_sharedkey(struct net_device *dev,
200 struct cfg80211_connect_params *sme);
201 static s32 wl_get_assoc_ies(struct wl_priv *wl);
202 static void wl_ch_to_chanspec(int ch,
203 struct wl_join_params *join_params, size_t *join_params_size);
206 ** information element utilities
208 static void wl_rst_ie(struct wl_priv *wl);
209 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
210 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
211 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
212 static u32 wl_get_ielen(struct wl_priv *wl);
214 static s32 wl_mode_to_nl80211_iftype(s32 mode);
216 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
218 static void wl_free_wdev(struct wl_priv *wl);
220 static s32 wl_inform_bss(struct wl_priv *wl);
221 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
222 static s32 wl_update_bss_info(struct wl_priv *wl);
224 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
225 u8 key_idx, const u8 *mac_addr,
226 struct key_params *params);
229 ** key indianess swap utilities
231 static void swap_key_from_BE(struct wl_wsec_key *key);
232 static void swap_key_to_BE(struct wl_wsec_key *key);
235 ** wl_priv memory init/deinit utilities
237 static s32 wl_init_priv_mem(struct wl_priv *wl);
238 static void wl_deinit_priv_mem(struct wl_priv *wl);
240 static void wl_delay(u32 ms);
243 ** store/restore cfg80211 instance data
245 static void wl_set_drvdata(struct wl_dev *dev, void *data);
246 static void *wl_get_drvdata(struct wl_dev *dev);
249 ** ibss mode utilities
251 static bool wl_is_ibssmode(struct wl_priv *wl);
252 static bool wl_is_ibssstarter(struct wl_priv *wl);
255 ** dongle up/down , default configuration utilities
257 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
258 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
259 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
260 static void wl_link_up(struct wl_priv *wl);
261 static void wl_link_down(struct wl_priv *wl);
262 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
263 static s32 __wl_cfg80211_up(struct wl_priv *wl);
264 static s32 __wl_cfg80211_down(struct wl_priv *wl);
265 static s32 wl_dongle_probecap(struct wl_priv *wl);
266 static void wl_init_conf(struct wl_conf *conf);
269 ** dongle configuration utilities
271 #ifndef EMBEDDED_PLATFORM
272 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
273 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
274 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
275 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
276 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
278 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
280 static s32 wl_dongle_eventmsg(struct net_device *ndev);
281 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
282 s32 scan_unassoc_time);
283 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
285 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
286 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
287 static s32 wl_update_wiphybands(struct wl_priv *wl);
288 #endif /* !EMBEDDED_PLATFORM */
289 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
294 static void wl_iscan_timer(unsigned long data);
295 static void wl_term_iscan(struct wl_priv *wl);
296 static s32 wl_init_iscan(struct wl_priv *wl);
297 static s32 wl_iscan_thread(void *data);
298 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
299 void *param, s32 paramlen, void *bufptr,
301 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
302 void *param, s32 paramlen, void *bufptr,
304 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
306 static s32 wl_do_iscan(struct wl_priv *wl);
307 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
308 static s32 wl_invoke_iscan(struct wl_priv *wl);
309 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
310 struct wl_scan_results **bss_list);
311 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
312 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
313 static s32 wl_iscan_done(struct wl_priv *wl);
314 static s32 wl_iscan_pending(struct wl_priv *wl);
315 static s32 wl_iscan_inprogress(struct wl_priv *wl);
316 static s32 wl_iscan_aborted(struct wl_priv *wl);
319 ** fw/nvram downloading handler
321 static void wl_init_fw(struct wl_fw_ctrl *fw);
324 * find most significant bit set
326 static __used u32 wl_find_msb(u16 bit16);
329 * update pmklist to dongle
331 static __used s32 wl_update_pmklist(struct net_device *dev,
332 struct wl_pmk_list *pmk_list, s32 err);
334 static void wl_set_mpc(struct net_device *ndev, int mpc);
336 #define WL_PRIV_GET() \
338 struct wl_iface *ci; \
339 if (unlikely(!(wl_cfg80211_dev && \
340 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
341 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
347 #define CHECK_SYS_UP() \
349 struct wl_priv *wl = wiphy_to_wl(wiphy); \
350 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
351 WL_INFO(("device is not ready : status (%d)\n", \
357 extern int dhd_wait_pend8021x(struct net_device *dev);
359 #if (WL_DBG_LEVEL > 0)
360 #define WL_DBG_ESTR_MAX 32
361 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
362 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
363 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
364 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
365 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
366 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
367 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
368 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
370 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
372 "RADIO", "PSM_WATCHDOG",
374 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
375 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
376 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
378 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
380 #endif /* WL_DBG_LEVEL */
382 #define CHAN2G(_channel, _freq, _flags) { \
383 .band = IEEE80211_BAND_2GHZ, \
384 .center_freq = (_freq), \
385 .hw_value = (_channel), \
387 .max_antenna_gain = 0, \
391 #define CHAN5G(_channel, _flags) { \
392 .band = IEEE80211_BAND_5GHZ, \
393 .center_freq = 5000 + (5 * (_channel)), \
394 .hw_value = (_channel), \
396 .max_antenna_gain = 0, \
400 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
401 #define RATETAB_ENT(_rateid, _flags) \
403 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
404 .hw_value = (_rateid), \
408 static struct ieee80211_rate __wl_rates[] = {
409 RATETAB_ENT(WLC_RATE_1M, 0),
410 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
411 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
412 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
413 RATETAB_ENT(WLC_RATE_6M, 0),
414 RATETAB_ENT(WLC_RATE_9M, 0),
415 RATETAB_ENT(WLC_RATE_12M, 0),
416 RATETAB_ENT(WLC_RATE_18M, 0),
417 RATETAB_ENT(WLC_RATE_24M, 0),
418 RATETAB_ENT(WLC_RATE_36M, 0),
419 RATETAB_ENT(WLC_RATE_48M, 0),
420 RATETAB_ENT(WLC_RATE_54M, 0),
423 #define wl_a_rates (__wl_rates + 4)
424 #define wl_a_rates_size 8
425 #define wl_g_rates (__wl_rates + 0)
426 #define wl_g_rates_size 12
428 static struct ieee80211_channel __wl_2ghz_channels[] = {
445 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
446 CHAN5G(34, 0), CHAN5G(36, 0),
447 CHAN5G(38, 0), CHAN5G(40, 0),
448 CHAN5G(42, 0), CHAN5G(44, 0),
449 CHAN5G(46, 0), CHAN5G(48, 0),
450 CHAN5G(52, 0), CHAN5G(56, 0),
451 CHAN5G(60, 0), CHAN5G(64, 0),
452 CHAN5G(100, 0), CHAN5G(104, 0),
453 CHAN5G(108, 0), CHAN5G(112, 0),
454 CHAN5G(116, 0), CHAN5G(120, 0),
455 CHAN5G(124, 0), CHAN5G(128, 0),
456 CHAN5G(132, 0), CHAN5G(136, 0),
457 CHAN5G(140, 0), CHAN5G(149, 0),
458 CHAN5G(153, 0), CHAN5G(157, 0),
459 CHAN5G(161, 0), CHAN5G(165, 0),
460 CHAN5G(184, 0), CHAN5G(188, 0),
461 CHAN5G(192, 0), CHAN5G(196, 0),
462 CHAN5G(200, 0), CHAN5G(204, 0),
463 CHAN5G(208, 0), CHAN5G(212, 0),
467 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
468 CHAN5G(32, 0), CHAN5G(34, 0),
469 CHAN5G(36, 0), CHAN5G(38, 0),
470 CHAN5G(40, 0), CHAN5G(42, 0),
471 CHAN5G(44, 0), CHAN5G(46, 0),
472 CHAN5G(48, 0), CHAN5G(50, 0),
473 CHAN5G(52, 0), CHAN5G(54, 0),
474 CHAN5G(56, 0), CHAN5G(58, 0),
475 CHAN5G(60, 0), CHAN5G(62, 0),
476 CHAN5G(64, 0), CHAN5G(66, 0),
477 CHAN5G(68, 0), CHAN5G(70, 0),
478 CHAN5G(72, 0), CHAN5G(74, 0),
479 CHAN5G(76, 0), CHAN5G(78, 0),
480 CHAN5G(80, 0), CHAN5G(82, 0),
481 CHAN5G(84, 0), CHAN5G(86, 0),
482 CHAN5G(88, 0), CHAN5G(90, 0),
483 CHAN5G(92, 0), CHAN5G(94, 0),
484 CHAN5G(96, 0), CHAN5G(98, 0),
485 CHAN5G(100, 0), CHAN5G(102, 0),
486 CHAN5G(104, 0), CHAN5G(106, 0),
487 CHAN5G(108, 0), CHAN5G(110, 0),
488 CHAN5G(112, 0), CHAN5G(114, 0),
489 CHAN5G(116, 0), CHAN5G(118, 0),
490 CHAN5G(120, 0), CHAN5G(122, 0),
491 CHAN5G(124, 0), CHAN5G(126, 0),
492 CHAN5G(128, 0), CHAN5G(130, 0),
493 CHAN5G(132, 0), CHAN5G(134, 0),
494 CHAN5G(136, 0), CHAN5G(138, 0),
495 CHAN5G(140, 0), CHAN5G(142, 0),
496 CHAN5G(144, 0), CHAN5G(145, 0),
497 CHAN5G(146, 0), CHAN5G(147, 0),
498 CHAN5G(148, 0), CHAN5G(149, 0),
499 CHAN5G(150, 0), CHAN5G(151, 0),
500 CHAN5G(152, 0), CHAN5G(153, 0),
501 CHAN5G(154, 0), CHAN5G(155, 0),
502 CHAN5G(156, 0), CHAN5G(157, 0),
503 CHAN5G(158, 0), CHAN5G(159, 0),
504 CHAN5G(160, 0), CHAN5G(161, 0),
505 CHAN5G(162, 0), CHAN5G(163, 0),
506 CHAN5G(164, 0), CHAN5G(165, 0),
507 CHAN5G(166, 0), CHAN5G(168, 0),
508 CHAN5G(170, 0), CHAN5G(172, 0),
509 CHAN5G(174, 0), CHAN5G(176, 0),
510 CHAN5G(178, 0), CHAN5G(180, 0),
511 CHAN5G(182, 0), CHAN5G(184, 0),
512 CHAN5G(186, 0), CHAN5G(188, 0),
513 CHAN5G(190, 0), CHAN5G(192, 0),
514 CHAN5G(194, 0), CHAN5G(196, 0),
515 CHAN5G(198, 0), CHAN5G(200, 0),
516 CHAN5G(202, 0), CHAN5G(204, 0),
517 CHAN5G(206, 0), CHAN5G(208, 0),
518 CHAN5G(210, 0), CHAN5G(212, 0),
519 CHAN5G(214, 0), CHAN5G(216, 0),
520 CHAN5G(218, 0), CHAN5G(220, 0),
521 CHAN5G(222, 0), CHAN5G(224, 0),
522 CHAN5G(226, 0), CHAN5G(228, 0),
525 static struct ieee80211_supported_band __wl_band_2ghz = {
526 .band = IEEE80211_BAND_2GHZ,
527 .channels = __wl_2ghz_channels,
528 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
529 .bitrates = wl_g_rates,
530 .n_bitrates = wl_g_rates_size,
533 static struct ieee80211_supported_band __wl_band_5ghz_a = {
534 .band = IEEE80211_BAND_5GHZ,
535 .channels = __wl_5ghz_a_channels,
536 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
537 .bitrates = wl_a_rates,
538 .n_bitrates = wl_a_rates_size,
541 static struct ieee80211_supported_band __wl_band_5ghz_n = {
542 .band = IEEE80211_BAND_5GHZ,
543 .channels = __wl_5ghz_n_channels,
544 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
545 .bitrates = wl_a_rates,
546 .n_bitrates = wl_a_rates_size,
549 static const u32 __wl_cipher_suites[] = {
550 WLAN_CIPHER_SUITE_WEP40,
551 WLAN_CIPHER_SUITE_WEP104,
552 WLAN_CIPHER_SUITE_TKIP,
553 WLAN_CIPHER_SUITE_CCMP,
554 WLAN_CIPHER_SUITE_AES_CMAC,
557 static void swap_key_from_BE(struct wl_wsec_key *key)
559 key->index = htod32(key->index);
560 key->len = htod32(key->len);
561 key->algo = htod32(key->algo);
562 key->flags = htod32(key->flags);
563 key->rxiv.hi = htod32(key->rxiv.hi);
564 key->rxiv.lo = htod16(key->rxiv.lo);
565 key->iv_initialized = htod32(key->iv_initialized);
568 static void swap_key_to_BE(struct wl_wsec_key *key)
570 key->index = dtoh32(key->index);
571 key->len = dtoh32(key->len);
572 key->algo = dtoh32(key->algo);
573 key->flags = dtoh32(key->flags);
574 key->rxiv.hi = dtoh32(key->rxiv.hi);
575 key->rxiv.lo = dtoh16(key->rxiv.lo);
576 key->iv_initialized = dtoh32(key->iv_initialized);
580 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
587 memset(&ioc, 0, sizeof(ioc));
591 strcpy(ifr.ifr_name, dev->name);
592 ifr.ifr_data = (caddr_t)&ioc;
596 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
603 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
604 enum nl80211_iftype type, u32 *flags,
605 struct vif_params *params)
607 struct wl_priv *wl = wiphy_to_wl(wiphy);
608 struct wireless_dev *wdev;
615 case NL80211_IFTYPE_MONITOR:
616 case NL80211_IFTYPE_WDS:
617 WL_ERR(("type (%d) : currently we do not support this type\n",
620 case NL80211_IFTYPE_ADHOC:
621 wl->conf->mode = WL_MODE_IBSS;
623 case NL80211_IFTYPE_STATION:
624 wl->conf->mode = WL_MODE_BSS;
630 infra = htod32(infra);
632 wdev = ndev->ieee80211_ptr;
634 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
635 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
637 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
640 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
642 WL_ERR(("WLC_SET_AP error (%d)\n", err));
646 /* -EINPROGRESS: Call commit handler */
650 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
652 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
653 params->bss_type = DOT11_BSSTYPE_ANY;
654 params->scan_type = 0;
655 params->nprobes = -1;
656 params->active_time = -1;
657 params->passive_time = -1;
658 params->home_time = -1;
659 params->channel_num = 0;
661 params->nprobes = htod32(params->nprobes);
662 params->active_time = htod32(params->active_time);
663 params->passive_time = htod32(params->passive_time);
664 params->home_time = htod32(params->home_time);
665 if (ssid && ssid->SSID_len)
666 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
671 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
672 s32 paramlen, void *bufptr, s32 buflen)
676 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
677 BUG_ON(unlikely(!iolen));
679 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
683 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
684 s32 paramlen, void *bufptr, s32 buflen)
688 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
689 BUG_ON(unlikely(!iolen));
691 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
695 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
698 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
699 struct wl_iscan_params *params;
702 if (ssid && ssid->SSID_len)
703 params_size += sizeof(struct wlc_ssid);
704 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
705 if (unlikely(!params))
707 memset(params, 0, params_size);
708 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
710 wl_iscan_prep(¶ms->params, ssid);
712 params->version = htod32(ISCAN_REQ_VERSION);
713 params->action = htod16(action);
714 params->scan_duration = htod16(0);
716 /* params_size += offsetof(wl_iscan_params_t, params); */
717 err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
718 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
721 WL_INFO(("system busy : iscan canceled\n"));
723 WL_ERR(("error (%d)\n", err));
730 static s32 wl_do_iscan(struct wl_priv *wl)
732 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
733 struct net_device *ndev = wl_to_ndev(wl);
734 struct wlc_ssid ssid;
737 /* Broadcast scan by default */
738 memset(&ssid, 0, sizeof(ssid));
740 iscan->state = WL_ISCAN_STATE_SCANING;
742 if (wl->active_scan) {
743 s32 passive_scan = 0;
744 /* make it active scan */
745 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
746 &passive_scan, sizeof(passive_scan));
748 WL_DBG(("error (%d)\n", err));
753 wl->iscan_kickstart = true;
754 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
755 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
762 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
763 struct cfg80211_scan_request *request,
764 struct cfg80211_ssid *this_ssid)
766 struct wl_priv *wl = ndev_to_wl(ndev);
767 struct cfg80211_ssid *ssids;
768 struct wl_scan_req *sr = wl_to_sr(wl);
773 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
774 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
777 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
778 WL_ERR(("Scanning being aborted : status (%d)\n",
785 if (request) { /* scan bss */
786 ssids = request->ssids;
787 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) { /* for
789 * ssids->ssid_len has
790 * non-zero(ssid string)
792 * Otherwise this is 0.
793 * we do not iscan for
794 * specific scan request
798 } else { /* scan in ibss */
799 /* we don't do iscan in ibss */
802 wl->scan_request = request;
803 set_bit(WL_STATUS_SCANNING, &wl->status);
805 err = wl_do_iscan(wl);
811 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
812 ssids->ssid, ssids->ssid_len));
813 memset(&sr->ssid, 0, sizeof(sr->ssid));
815 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
816 if (sr->ssid.SSID_len) {
817 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
818 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
819 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
820 sr->ssid.SSID, sr->ssid.SSID_len));
823 WL_DBG(("Broadcast scan\n"));
825 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
826 if (wl->active_scan) {
828 /* make it active scan */
829 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
830 &pssive_scan, sizeof(pssive_scan));
832 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n",
838 err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
842 WL_INFO(("system busy : scan for \"%s\" "
843 "canceled\n", sr->ssid.SSID));
845 WL_ERR(("WLC_SCAN error (%d)\n", err));
855 clear_bit(WL_STATUS_SCANNING, &wl->status);
856 wl->scan_request = NULL;
861 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
862 struct cfg80211_scan_request *request)
867 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
869 WL_DBG(("scan error (%d)\n", err));
876 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
878 s8 buf[WLC_IOCTL_SMLEN];
883 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
884 BUG_ON(unlikely(!len));
886 err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
888 WL_ERR(("error (%d)\n", err));
895 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
898 s8 buf[WLC_IOCTL_SMLEN];
906 bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
908 BUG_ON(unlikely(!len));
909 err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
911 WL_ERR(("error (%d)\n", err));
913 *retval = dtoh32(var.val);
918 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
922 err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
924 WL_ERR(("Error (%d)\n", err));
930 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
934 err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
936 WL_ERR(("Error (%d)\n", err));
942 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
945 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
947 retry = htod32(retry);
948 err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
950 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
956 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
958 struct wl_priv *wl = wiphy_to_wl(wiphy);
959 struct net_device *ndev = wl_to_ndev(wl);
963 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
964 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
965 wl->conf->rts_threshold = wiphy->rts_threshold;
966 err = wl_set_rts(ndev, wl->conf->rts_threshold);
970 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
971 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
972 wl->conf->frag_threshold = wiphy->frag_threshold;
973 err = wl_set_frag(ndev, wl->conf->frag_threshold);
977 if (changed & WIPHY_PARAM_RETRY_LONG
978 && (wl->conf->retry_long != wiphy->retry_long)) {
979 wl->conf->retry_long = wiphy->retry_long;
980 err = wl_set_retry(ndev, wl->conf->retry_long, true);
984 if (changed & WIPHY_PARAM_RETRY_SHORT
985 && (wl->conf->retry_short != wiphy->retry_short)) {
986 wl->conf->retry_short = wiphy->retry_short;
987 err = wl_set_retry(ndev, wl->conf->retry_short, false);
997 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
998 struct cfg80211_ibss_params *params)
1000 struct wl_priv *wl = wiphy_to_wl(wiphy);
1001 struct cfg80211_bss *bss;
1002 struct ieee80211_channel *chan;
1003 struct wl_join_params join_params;
1004 struct cfg80211_ssid ssid;
1009 if (params->bssid) {
1010 WL_ERR(("Invalid bssid\n"));
1013 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1015 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1016 ssid.ssid_len = params->ssid_len;
1019 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1025 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1026 rtnl_unlock(); /* to allow scan_inform to paropagate
1027 to cfg80211 plane */
1028 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1029 till scan done.... */
1031 bss = cfg80211_get_ibss(wiphy, NULL,
1032 params->ssid, params->ssid_len);
1035 wl->ibss_starter = false;
1036 WL_DBG(("Found IBSS\n"));
1038 wl->ibss_starter = true;
1040 chan = params->channel;
1042 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1044 ** Join with specific BSSID and cached SSID
1045 ** If SSID is zero join based on BSSID only
1047 memset(&join_params, 0, sizeof(join_params));
1048 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1050 join_params.ssid.SSID_len = htod32(params->ssid_len);
1052 memcpy(&join_params.params.bssid, params->bssid,
1055 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1057 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1058 sizeof(join_params));
1059 if (unlikely(err)) {
1060 WL_ERR(("Error (%d)\n", err));
1066 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1068 struct wl_priv *wl = wiphy_to_wl(wiphy);
1078 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1080 struct wl_priv *wl = ndev_to_wl(dev);
1081 struct wl_security *sec;
1085 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1086 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1087 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1088 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1090 val = WPA_AUTH_DISABLED;
1091 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1092 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1093 if (unlikely(err)) {
1094 WL_ERR(("set wpa_auth failed (%d)\n", err));
1097 sec = wl_read_prof(wl, WL_PROF_SEC);
1098 sec->wpa_versions = sme->crypto.wpa_versions;
1103 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1105 struct wl_priv *wl = ndev_to_wl(dev);
1106 struct wl_security *sec;
1110 switch (sme->auth_type) {
1111 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1113 WL_DBG(("open system\n"));
1115 case NL80211_AUTHTYPE_SHARED_KEY:
1117 WL_DBG(("shared key\n"));
1119 case NL80211_AUTHTYPE_AUTOMATIC:
1121 WL_DBG(("automatic\n"));
1123 case NL80211_AUTHTYPE_NETWORK_EAP:
1124 WL_DBG(("network eap\n"));
1127 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1131 err = wl_dev_intvar_set(dev, "auth", val);
1132 if (unlikely(err)) {
1133 WL_ERR(("set auth failed (%d)\n", err));
1136 sec = wl_read_prof(wl, WL_PROF_SEC);
1137 sec->auth_type = sme->auth_type;
1142 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1144 struct wl_priv *wl = ndev_to_wl(dev);
1145 struct wl_security *sec;
1150 if (sme->crypto.n_ciphers_pairwise) {
1151 switch (sme->crypto.ciphers_pairwise[0]) {
1152 case WLAN_CIPHER_SUITE_WEP40:
1153 case WLAN_CIPHER_SUITE_WEP104:
1156 case WLAN_CIPHER_SUITE_TKIP:
1157 pval = TKIP_ENABLED;
1159 case WLAN_CIPHER_SUITE_CCMP:
1162 case WLAN_CIPHER_SUITE_AES_CMAC:
1166 WL_ERR(("invalid cipher pairwise (%d)\n",
1167 sme->crypto.ciphers_pairwise[0]));
1171 if (sme->crypto.cipher_group) {
1172 switch (sme->crypto.cipher_group) {
1173 case WLAN_CIPHER_SUITE_WEP40:
1174 case WLAN_CIPHER_SUITE_WEP104:
1177 case WLAN_CIPHER_SUITE_TKIP:
1178 gval = TKIP_ENABLED;
1180 case WLAN_CIPHER_SUITE_CCMP:
1183 case WLAN_CIPHER_SUITE_AES_CMAC:
1187 WL_ERR(("invalid cipher group (%d)\n",
1188 sme->crypto.cipher_group));
1193 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1194 err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1195 if (unlikely(err)) {
1196 WL_ERR(("error (%d)\n", err));
1200 sec = wl_read_prof(wl, WL_PROF_SEC);
1201 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1202 sec->cipher_group = sme->crypto.cipher_group;
1208 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1210 struct wl_priv *wl = ndev_to_wl(dev);
1211 struct wl_security *sec;
1215 if (sme->crypto.n_akm_suites) {
1216 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1217 if (unlikely(err)) {
1218 WL_ERR(("could not get wpa_auth (%d)\n", err));
1221 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1222 switch (sme->crypto.akm_suites[0]) {
1223 case WLAN_AKM_SUITE_8021X:
1224 val = WPA_AUTH_UNSPECIFIED;
1226 case WLAN_AKM_SUITE_PSK:
1230 WL_ERR(("invalid cipher group (%d)\n",
1231 sme->crypto.cipher_group));
1234 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1235 switch (sme->crypto.akm_suites[0]) {
1236 case WLAN_AKM_SUITE_8021X:
1237 val = WPA2_AUTH_UNSPECIFIED;
1239 case WLAN_AKM_SUITE_PSK:
1240 val = WPA2_AUTH_PSK;
1243 WL_ERR(("invalid cipher group (%d)\n",
1244 sme->crypto.cipher_group));
1249 WL_DBG(("setting wpa_auth to %d\n", val));
1250 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1251 if (unlikely(err)) {
1252 WL_ERR(("could not set wpa_auth (%d)\n", err));
1256 sec = wl_read_prof(wl, WL_PROF_SEC);
1257 sec->wpa_auth = sme->crypto.akm_suites[0];
1263 wl_set_set_sharedkey(struct net_device *dev,
1264 struct cfg80211_connect_params *sme)
1266 struct wl_priv *wl = ndev_to_wl(dev);
1267 struct wl_security *sec;
1268 struct wl_wsec_key key;
1272 WL_DBG(("key len (%d)\n", sme->key_len));
1274 sec = wl_read_prof(wl, WL_PROF_SEC);
1275 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1276 sec->wpa_versions, sec->cipher_pairwise));
1278 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1279 NL80211_WPA_VERSION_2))
1280 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1281 WLAN_CIPHER_SUITE_WEP104))) {
1282 memset(&key, 0, sizeof(key));
1283 key.len = (u32) sme->key_len;
1284 key.index = (u32) sme->key_idx;
1285 if (unlikely(key.len > sizeof(key.data))) {
1286 WL_ERR(("Too long key length (%u)\n", key.len));
1289 memcpy(key.data, sme->key, key.len);
1290 key.flags = WL_PRIMARY_KEY;
1291 switch (sec->cipher_pairwise) {
1292 case WLAN_CIPHER_SUITE_WEP40:
1293 key.algo = CRYPTO_ALGO_WEP1;
1295 case WLAN_CIPHER_SUITE_WEP104:
1296 key.algo = CRYPTO_ALGO_WEP128;
1299 WL_ERR(("Invalid algorithm (%d)\n",
1300 sme->crypto.ciphers_pairwise[0]));
1303 /* Set the new key/index */
1304 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1305 key.len, key.index, key.algo));
1306 WL_DBG(("key \"%s\"\n", key.data));
1307 swap_key_from_BE(&key);
1308 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1310 if (unlikely(err)) {
1311 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1314 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1315 WL_DBG(("set auth_type to shared key\n"));
1316 val = 1; /* shared key */
1317 err = wl_dev_intvar_set(dev, "auth", val);
1318 if (unlikely(err)) {
1319 WL_ERR(("set auth failed (%d)\n", err));
1329 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1330 struct cfg80211_connect_params *sme)
1332 struct wl_priv *wl = wiphy_to_wl(wiphy);
1333 struct ieee80211_channel *chan = sme->channel;
1334 struct wl_join_params join_params;
1335 size_t join_params_size;
1340 if (unlikely(!sme->ssid)) {
1341 WL_ERR(("Invalid ssid\n"));
1345 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1346 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
1347 chan->center_freq));
1349 WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
1350 err = wl_set_wpa_version(dev, sme);
1354 err = wl_set_auth_type(dev, sme);
1358 err = wl_set_set_cipher(dev, sme);
1362 err = wl_set_key_mgmt(dev, sme);
1366 err = wl_set_set_sharedkey(dev, sme);
1370 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1372 ** Join with specific BSSID and cached SSID
1373 ** If SSID is zero join based on BSSID only
1375 memset(&join_params, 0, sizeof(join_params));
1376 join_params_size = sizeof(join_params.ssid);
1378 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1379 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1380 join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
1381 wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1382 memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1384 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1385 WL_DBG(("join_param_size %d\n", join_params_size));
1387 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1388 WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
1389 join_params.ssid.SSID_len));
1391 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1392 if (unlikely(err)) {
1393 WL_ERR(("error (%d)\n", err));
1396 set_bit(WL_STATUS_CONNECTING, &wl->status);
1402 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1405 struct wl_priv *wl = wiphy_to_wl(wiphy);
1410 WL_DBG(("Reason %d\n", reason_code));
1412 act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
1414 scbval.val = reason_code;
1415 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1416 scbval.val = htod32(scbval.val);
1417 err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1419 if (unlikely(err)) {
1420 WL_ERR(("error (%d)\n", err));
1429 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1430 enum nl80211_tx_power_setting type, s32 dbm)
1433 struct wl_priv *wl = wiphy_to_wl(wiphy);
1434 struct net_device *ndev = wl_to_ndev(wl);
1441 case NL80211_TX_POWER_AUTOMATIC:
1443 case NL80211_TX_POWER_LIMITED:
1445 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1449 case NL80211_TX_POWER_FIXED:
1451 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1456 /* Make sure radio is off or on as far as software is concerned */
1457 disable = WL_RADIO_SW_DISABLE << 16;
1458 disable = htod32(disable);
1459 err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1460 if (unlikely(err)) {
1461 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1468 txpwrmw = (u16) dbm;
1469 err = wl_dev_intvar_set(ndev, "qtxpower",
1470 (s32) (bcm_mw_to_qdbm(txpwrmw)));
1471 if (unlikely(err)) {
1472 WL_ERR(("qtxpower error (%d)\n", err));
1475 wl->conf->tx_power = dbm;
1480 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1482 struct wl_priv *wl = wiphy_to_wl(wiphy);
1483 struct net_device *ndev = wl_to_ndev(wl);
1489 err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1490 if (unlikely(err)) {
1491 WL_ERR(("error (%d)\n", err));
1494 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1495 *dbm = (s32) bcm_qdbm_to_mw(result);
1501 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1508 WL_DBG(("key index (%d)\n", key_idx));
1511 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1512 if (unlikely(err)) {
1513 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1516 wsec = dtoh32(wsec);
1517 if (wsec & WEP_ENABLED) {
1518 /* Just select a new current key */
1519 index = (u32) key_idx;
1520 index = htod32(index);
1521 err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
1523 if (unlikely(err)) {
1524 WL_ERR(("error (%d)\n", err));
1531 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1532 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1534 struct wl_wsec_key key;
1537 memset(&key, 0, sizeof(key));
1538 key.index = (u32) key_idx;
1539 /* Instead of bcast for ea address for default wep keys,
1540 driver needs it to be Null */
1541 if (!ETHER_ISMULTI(mac_addr))
1542 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1543 key.len = (u32) params->key_len;
1544 /* check for key index change */
1547 swap_key_from_BE(&key);
1548 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1549 if (unlikely(err)) {
1550 WL_ERR(("key delete error (%d)\n", err));
1554 if (key.len > sizeof(key.data)) {
1555 WL_ERR(("Invalid key length (%d)\n", key.len));
1559 WL_DBG(("Setting the key index %d\n", key.index));
1560 memcpy(key.data, params->key, key.len);
1562 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1564 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1565 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1566 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1569 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1570 if (params->seq && params->seq_len == 6) {
1573 ivptr = (u8 *) params->seq;
1574 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1575 (ivptr[3] << 8) | ivptr[2];
1576 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1577 key.iv_initialized = true;
1580 switch (params->cipher) {
1581 case WLAN_CIPHER_SUITE_WEP40:
1582 key.algo = CRYPTO_ALGO_WEP1;
1583 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1585 case WLAN_CIPHER_SUITE_WEP104:
1586 key.algo = CRYPTO_ALGO_WEP128;
1587 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1589 case WLAN_CIPHER_SUITE_TKIP:
1590 key.algo = CRYPTO_ALGO_TKIP;
1591 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1593 case WLAN_CIPHER_SUITE_AES_CMAC:
1594 key.algo = CRYPTO_ALGO_AES_CCM;
1595 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1597 case WLAN_CIPHER_SUITE_CCMP:
1598 key.algo = CRYPTO_ALGO_AES_CCM;
1599 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1602 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1605 swap_key_from_BE(&key);
1607 dhd_wait_pend8021x(dev);
1608 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1609 if (unlikely(err)) {
1610 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1618 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1619 u8 key_idx, const u8 *mac_addr,
1620 struct key_params *params)
1622 struct wl_wsec_key key;
1627 WL_DBG(("key index (%d)\n", key_idx));
1631 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1632 memset(&key, 0, sizeof(key));
1634 key.len = (u32) params->key_len;
1635 key.index = (u32) key_idx;
1637 if (unlikely(key.len > sizeof(key.data))) {
1638 WL_ERR(("Too long key length (%u)\n", key.len));
1641 memcpy(key.data, params->key, key.len);
1643 key.flags = WL_PRIMARY_KEY;
1644 switch (params->cipher) {
1645 case WLAN_CIPHER_SUITE_WEP40:
1646 key.algo = CRYPTO_ALGO_WEP1;
1647 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1649 case WLAN_CIPHER_SUITE_WEP104:
1650 key.algo = CRYPTO_ALGO_WEP128;
1651 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1653 case WLAN_CIPHER_SUITE_TKIP:
1654 key.algo = CRYPTO_ALGO_TKIP;
1655 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1657 case WLAN_CIPHER_SUITE_AES_CMAC:
1658 key.algo = CRYPTO_ALGO_AES_CCM;
1659 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1661 case WLAN_CIPHER_SUITE_CCMP:
1662 key.algo = CRYPTO_ALGO_AES_CCM;
1663 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1666 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1670 /* Set the new key/index */
1671 swap_key_from_BE(&key);
1672 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1673 if (unlikely(err)) {
1674 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1679 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1680 if (unlikely(err)) {
1681 WL_ERR(("get wsec error (%d)\n", err));
1684 wsec &= ~(WEP_ENABLED);
1686 err = wl_dev_intvar_set(dev, "wsec", wsec);
1687 if (unlikely(err)) {
1688 WL_ERR(("set wsec error (%d)\n", err));
1692 val = 1; /* assume shared key. otherwise 0 */
1694 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1695 if (unlikely(err)) {
1696 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1703 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1704 u8 key_idx, const u8 *mac_addr)
1706 struct wl_wsec_key key;
1712 memset(&key, 0, sizeof(key));
1714 key.index = (u32) key_idx;
1715 key.flags = WL_PRIMARY_KEY;
1716 key.algo = CRYPTO_ALGO_OFF;
1718 WL_DBG(("key index (%d)\n", key_idx));
1719 /* Set the new key/index */
1720 swap_key_from_BE(&key);
1721 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1722 if (unlikely(err)) {
1723 if (err == -EINVAL) {
1724 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1725 /* we ignore this key index in this case */
1726 WL_DBG(("invalid key index (%d)\n", key_idx));
1729 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1735 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1736 if (unlikely(err)) {
1737 WL_ERR(("get wsec error (%d)\n", err));
1740 wsec &= ~(WEP_ENABLED);
1742 err = wl_dev_intvar_set(dev, "wsec", wsec);
1743 if (unlikely(err)) {
1744 WL_ERR(("set wsec error (%d)\n", err));
1748 val = 0; /* assume open key. otherwise 1 */
1750 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1751 if (unlikely(err)) {
1752 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1759 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1760 u8 key_idx, const u8 *mac_addr, void *cookie,
1761 void (*callback) (void *cookie, struct key_params * params))
1763 struct key_params params;
1764 struct wl_wsec_key key;
1765 struct wl_priv *wl = wiphy_to_wl(wiphy);
1766 struct wl_security *sec;
1770 WL_DBG(("key index (%d)\n", key_idx));
1773 memset(&key, 0, sizeof(key));
1774 key.index = key_idx;
1775 swap_key_to_BE(&key);
1776 memset(¶ms, 0, sizeof(params));
1777 params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
1778 memcpy(params.key, key.data, params.key_len);
1780 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1781 if (unlikely(err)) {
1782 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1785 wsec = dtoh32(wsec);
1788 sec = wl_read_prof(wl, WL_PROF_SEC);
1789 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1790 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1791 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1792 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1793 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1794 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1798 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1799 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1802 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1803 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1806 WL_ERR(("Invalid algo (0x%x)\n", wsec));
1810 callback(cookie, ¶ms);
1815 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1816 struct net_device *dev, u8 key_idx)
1818 WL_INFO(("Not supported\n"));
1824 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1825 u8 *mac, struct station_info *sinfo)
1827 struct wl_priv *wl = wiphy_to_wl(wiphy);
1835 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
1836 WL_ERR(("Wrong Mac address\n"));
1840 /* Report the current tx rate */
1841 err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1843 WL_ERR(("Could not get rate (%d)\n", err));
1845 rate = dtoh32(rate);
1846 sinfo->filled |= STATION_INFO_TX_BITRATE;
1847 sinfo->txrate.legacy = rate * 5;
1848 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1851 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1853 err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1855 if (unlikely(err)) {
1856 WL_ERR(("Could not get rssi (%d)\n", err));
1859 rssi = dtoh32(scb_val.val);
1860 sinfo->filled |= STATION_INFO_SIGNAL;
1861 sinfo->signal = rssi;
1862 WL_DBG(("RSSI %d dBm\n", rssi));
1869 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1870 bool enabled, s32 timeout)
1876 pm = enabled ? PM_FAST : PM_OFF;
1878 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1879 err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1880 if (unlikely(err)) {
1882 WL_DBG(("net_device is not ready yet\n"));
1884 WL_ERR(("error (%d)\n", err));
1890 static __used u32 wl_find_msb(u16 bit16)
1894 if (bit16 & 0xff00) {
1918 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1920 const struct cfg80211_bitrate_mask *mask)
1922 struct wl_rateset rateset;
1931 /* addr param is always NULL. ignore it */
1932 /* Get current rateset */
1933 err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1935 if (unlikely(err)) {
1936 WL_ERR(("could not get current rateset (%d)\n", err));
1940 rateset.count = dtoh32(rateset.count);
1942 legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
1944 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1946 val = wl_g_rates[legacy - 1].bitrate * 100000;
1948 if (val < rateset.count) {
1949 /* Select rate by rateset index */
1950 rate = rateset.rates[val] & 0x7f;
1952 /* Specified rate in bps */
1953 rate = val / 500000;
1956 WL_DBG(("rate %d mbps\n", (rate / 2)));
1960 * Set rate override,
1961 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1963 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1964 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1965 if (unlikely(err_bg && err_a)) {
1966 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
1967 return err_bg | err_a;
1973 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
1978 wl_invoke_iscan(wiphy_to_wl(wiphy));
1983 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
1985 struct wl_priv *wl = wiphy_to_wl(wiphy);
1986 struct net_device *ndev = wl_to_ndev(wl);
1991 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1993 if (wl->scan_request) {
1994 cfg80211_scan_done(wl->scan_request, true); /* true means
1996 wl_set_mpc(ndev, 1);
1997 wl->scan_request = NULL;
1999 clear_bit(WL_STATUS_SCANNING, &wl->status);
2000 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2006 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2011 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2012 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2013 WL_DBG(("PMKID[%d]: %pM =\n", i,
2014 &pmk_list->pmkids.pmkid[i].BSSID));
2015 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2016 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2020 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2028 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2029 struct cfg80211_pmksa *pmksa)
2031 struct wl_priv *wl = wiphy_to_wl(wiphy);
2036 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2037 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2040 if (i < WL_NUM_PMKIDS_MAX) {
2041 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2043 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2045 if (i == wl->pmk_list->pmkids.npmkid)
2046 wl->pmk_list->pmkids.npmkid++;
2050 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2051 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2052 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2054 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2058 err = wl_update_pmklist(dev, wl->pmk_list, err);
2064 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2065 struct cfg80211_pmksa *pmksa)
2067 struct wl_priv *wl = wiphy_to_wl(wiphy);
2068 struct _pmkid_list pmkid;
2073 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2074 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2076 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2077 &pmkid.pmkid[0].BSSID));
2078 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2079 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2082 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2084 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2088 if ((wl->pmk_list->pmkids.npmkid > 0)
2089 && (i < wl->pmk_list->pmkids.npmkid)) {
2090 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2091 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2092 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2093 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2095 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2096 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2099 wl->pmk_list->pmkids.npmkid--;
2104 err = wl_update_pmklist(dev, wl->pmk_list, err);
2111 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2113 struct wl_priv *wl = wiphy_to_wl(wiphy);
2117 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2118 err = wl_update_pmklist(dev, wl->pmk_list, err);
2123 static struct cfg80211_ops wl_cfg80211_ops = {
2124 .change_virtual_intf = wl_cfg80211_change_iface,
2125 .scan = wl_cfg80211_scan,
2126 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2127 .join_ibss = wl_cfg80211_join_ibss,
2128 .leave_ibss = wl_cfg80211_leave_ibss,
2129 .get_station = wl_cfg80211_get_station,
2130 .set_tx_power = wl_cfg80211_set_tx_power,
2131 .get_tx_power = wl_cfg80211_get_tx_power,
2132 .add_key = wl_cfg80211_add_key,
2133 .del_key = wl_cfg80211_del_key,
2134 .get_key = wl_cfg80211_get_key,
2135 .set_default_key = wl_cfg80211_config_default_key,
2136 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2137 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2138 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2139 .connect = wl_cfg80211_connect,
2140 .disconnect = wl_cfg80211_disconnect,
2141 .suspend = wl_cfg80211_suspend,
2142 .resume = wl_cfg80211_resume,
2143 .set_pmksa = wl_cfg80211_set_pmksa,
2144 .del_pmksa = wl_cfg80211_del_pmksa,
2145 .flush_pmksa = wl_cfg80211_flush_pmksa
2148 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2154 return NL80211_IFTYPE_STATION;
2156 return NL80211_IFTYPE_ADHOC;
2158 return NL80211_IFTYPE_UNSPECIFIED;
2164 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2167 struct wireless_dev *wdev;
2170 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2171 if (unlikely(!wdev)) {
2172 WL_ERR(("Could not allocate wireless device\n"));
2173 return ERR_PTR(-ENOMEM);
2176 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2177 if (unlikely(!wdev->wiphy)) {
2178 WL_ERR(("Couldn not allocate wiphy device\n"));
2182 set_wiphy_dev(wdev->wiphy, dev);
2183 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2184 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2185 wdev->wiphy->interface_modes =
2186 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2187 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2188 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2189 * it as 11a by default.
2190 * This will be updated with
2193 * if phy has 11n capability
2195 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2196 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2197 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2198 #ifndef WL_POWERSAVE_DISABLED
2199 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2204 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2205 #endif /* !WL_POWERSAVE_DISABLED */
2206 err = wiphy_register(wdev->wiphy);
2207 if (unlikely(err < 0)) {
2208 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2209 goto wiphy_register_out;
2214 wiphy_free(wdev->wiphy);
2219 return ERR_PTR(err);
2222 static void wl_free_wdev(struct wl_priv *wl)
2224 struct wireless_dev *wdev = wl_to_wdev(wl);
2226 if (unlikely(!wdev)) {
2227 WL_ERR(("wdev is invalid\n"));
2230 wiphy_unregister(wdev->wiphy);
2231 wiphy_free(wdev->wiphy);
2233 wl_to_wdev(wl) = NULL;
2236 static s32 wl_inform_bss(struct wl_priv *wl)
2238 struct wl_scan_results *bss_list;
2239 struct wl_bss_info *bi = NULL; /* must be initialized */
2243 bss_list = wl->bss_list;
2244 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2245 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2246 bss_list->version));
2249 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2250 bi = next_bss(bss_list, bi);
2251 for_each_bss(bss_list, bi, i) {
2252 err = wl_inform_single_bss(wl, bi);
2259 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2261 struct wiphy *wiphy = wl_to_wiphy(wl);
2262 struct ieee80211_mgmt *mgmt;
2263 struct ieee80211_channel *channel;
2264 struct ieee80211_supported_band *band;
2265 struct wl_cfg80211_bss_info *notif_bss_info;
2266 struct wl_scan_req *sr = wl_to_sr(wl);
2271 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
2272 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2276 kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2277 WL_BSS_INFO_MAX, GFP_KERNEL);
2278 if (unlikely(!notif_bss_info)) {
2279 WL_ERR(("notif_bss_info alloc failed\n"));
2282 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2283 notif_bss_info->channel =
2284 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
2286 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2287 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2289 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2290 notif_bss_info->rssi = bi->RSSI;
2291 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
2292 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2293 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2294 IEEE80211_STYPE_PROBE_RESP);
2296 mgmt->u.probe_resp.timestamp = 0;
2297 mgmt->u.probe_resp.beacon_int = cpu_to_le16(bi->beacon_period);
2298 mgmt->u.probe_resp.capab_info = cpu_to_le16(bi->capability);
2301 * wl_add_ie is not necessary because it can only add duplicated
2302 * SSID, rate information to frame_buf
2305 * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2306 * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2307 * bi->rateset.rates);
2309 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2310 wl_cp_ie(wl, mgmt->u.probe_resp.variable, WL_BSS_INFO_MAX -
2311 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2312 notif_bss_info->frame_len =
2313 offsetof(struct ieee80211_mgmt,
2314 u.probe_resp.variable) + wl_get_ielen(wl);
2315 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2316 channel = ieee80211_get_channel(wiphy, freq);
2318 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
2320 notif_bss_info->rssi, notif_bss_info->channel,
2321 mgmt->u.probe_resp.capab_info, &bi->BSSID));
2323 signal = notif_bss_info->rssi * 100;
2324 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2326 (notif_bss_info->frame_len),
2327 signal, GFP_KERNEL))) {
2328 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2329 kfree(notif_bss_info);
2332 kfree(notif_bss_info);
2337 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2339 u32 event = ntoh32(e->event_type);
2340 u16 flags = ntoh16(e->flags);
2342 if (event == WLC_E_LINK) {
2343 if (flags & WLC_EVENT_MSG_LINK) {
2344 if (wl_is_ibssmode(wl)) {
2345 if (wl_is_ibssstarter(wl)) {
2356 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2358 u32 event = ntoh32(e->event_type);
2359 u16 flags = ntoh16(e->flags);
2361 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2363 } else if (event == WLC_E_LINK) {
2364 if (!(flags & WLC_EVENT_MSG_LINK))
2371 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2373 u32 event = ntoh32(e->event_type);
2374 u32 status = ntoh32(e->status);
2376 if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2377 if (status == WLC_E_STATUS_NO_NETWORKS)
2385 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2386 const wl_event_msg_t *e, void *data)
2391 if (wl_is_linkup(wl, e)) {
2393 if (wl_is_ibssmode(wl)) {
2394 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2396 WL_DBG(("joined in IBSS network\n"));
2398 wl_bss_connect_done(wl, ndev, e, data, true);
2399 WL_DBG(("joined in BSS network \"%s\"\n",
2400 ((struct wlc_ssid *)
2401 wl_read_prof(wl, WL_PROF_SSID))->SSID));
2404 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2405 } else if (wl_is_linkdown(wl, e)) {
2406 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2407 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2409 wl_init_prof(wl->profile);
2410 } else if (wl_is_nonetwork(wl, e)) {
2411 wl_bss_connect_done(wl, ndev, e, data, false);
2418 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2419 const wl_event_msg_t *e, void *data)
2424 wl_bss_roaming_done(wl, ndev, e, data);
2426 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2432 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2434 struct wl_priv *wl = ndev_to_wl(dev);
2437 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2438 BUG_ON(unlikely(!buflen));
2440 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2444 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2447 struct wl_priv *wl = ndev_to_wl(dev);
2451 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2452 BUG_ON(unlikely(!len));
2453 err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2455 if (unlikely(err)) {
2456 WL_ERR(("error (%d)\n", err));
2459 memcpy(buf, wl->ioctl_buf, buf_len);
2464 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2466 struct net_device *ndev = wl_to_ndev(wl);
2467 struct wl_assoc_ielen *assoc_info;
2468 struct wl_connect_info *conn_info = wl_to_conn(wl);
2473 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2475 if (unlikely(err)) {
2476 WL_ERR(("could not get assoc info (%d)\n", err));
2479 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2480 req_len = assoc_info->req_len;
2481 resp_len = assoc_info->resp_len;
2483 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2485 if (unlikely(err)) {
2486 WL_ERR(("could not get assoc req (%d)\n", err));
2489 conn_info->req_ie_len = req_len;
2491 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2493 conn_info->req_ie_len = 0;
2494 conn_info->req_ie = NULL;
2497 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2499 if (unlikely(err)) {
2500 WL_ERR(("could not get assoc resp (%d)\n", err));
2503 conn_info->resp_ie_len = resp_len;
2504 conn_info->resp_ie =
2505 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2507 conn_info->resp_ie_len = 0;
2508 conn_info->resp_ie = NULL;
2510 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2511 conn_info->resp_ie_len));
2516 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2517 size_t *join_params_size)
2519 chanspec_t chanspec = 0;
2522 join_params->params.chanspec_num = 1;
2523 join_params->params.chanspec_list[0] = ch;
2525 if (join_params->params.chanspec_list[0])
2526 chanspec |= WL_CHANSPEC_BAND_2G;
2528 chanspec |= WL_CHANSPEC_BAND_5G;
2530 chanspec |= WL_CHANSPEC_BW_20;
2531 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2533 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2534 join_params->params.chanspec_num * sizeof(chanspec_t);
2536 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2537 join_params->params.chanspec_list[0] |= chanspec;
2538 join_params->params.chanspec_list[0] =
2539 htodchanspec(join_params->params.chanspec_list[0]);
2541 join_params->params.chanspec_num =
2542 htod32(join_params->params.chanspec_num);
2544 WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
2545 join_params->params.chanspec_list[0], ch, chanspec));
2549 static s32 wl_update_bss_info(struct wl_priv *wl)
2551 struct cfg80211_bss *bss;
2552 struct wl_bss_info *bi;
2553 struct wlc_ssid *ssid;
2556 if (wl_is_ibssmode(wl))
2559 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2561 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2562 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2563 WLAN_CAPABILITY_ESS);
2566 if (unlikely(!bss)) {
2567 WL_DBG(("Could not find the AP\n"));
2568 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2569 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2570 wl->extra_buf, WL_EXTRA_BUF_MAX);
2571 if (unlikely(err)) {
2572 WL_ERR(("Could not get bss info %d\n", err));
2573 goto update_bss_info_out;
2575 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2576 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2578 goto update_bss_info_out;
2580 err = wl_inform_single_bss(wl, bi);
2582 goto update_bss_info_out;
2584 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
2585 cfg80211_put_bss(bss);
2588 update_bss_info_out:
2594 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2595 const wl_event_msg_t *e, void *data)
2597 struct wl_connect_info *conn_info = wl_to_conn(wl);
2600 wl_get_assoc_ies(wl);
2601 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2602 wl_update_bss_info(wl);
2603 cfg80211_roamed(ndev,
2605 conn_info->req_ie, conn_info->req_ie_len,
2606 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2607 WL_DBG(("Report roaming result\n"));
2609 set_bit(WL_STATUS_CONNECTED, &wl->status);
2615 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2616 const wl_event_msg_t *e, void *data, bool completed)
2618 struct wl_connect_info *conn_info = wl_to_conn(wl);
2621 wl_get_assoc_ies(wl);
2622 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2623 wl_update_bss_info(wl);
2624 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2625 cfg80211_connect_result(ndev,
2628 conn_info->req_ie_len,
2630 conn_info->resp_ie_len,
2631 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2633 WL_DBG(("Report connect result - connection %s\n",
2634 completed ? "succeeded" : "failed"));
2636 cfg80211_roamed(ndev,
2638 conn_info->req_ie, conn_info->req_ie_len,
2639 conn_info->resp_ie, conn_info->resp_ie_len,
2641 WL_DBG(("Report roaming result\n"));
2643 set_bit(WL_STATUS_CONNECTED, &wl->status);
2649 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2650 const wl_event_msg_t *e, void *data)
2652 u16 flags = ntoh16(e->flags);
2653 enum nl80211_key_type key_type;
2656 if (flags & WLC_EVENT_MSG_GROUP)
2657 key_type = NL80211_KEYTYPE_GROUP;
2659 key_type = NL80211_KEYTYPE_PAIRWISE;
2661 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2669 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2670 const wl_event_msg_t *e, void *data)
2672 struct channel_info channel_inform;
2673 struct wl_scan_results *bss_list;
2674 u32 len = WL_SCAN_BUF_MAX;
2677 if (wl->iscan_on && wl->iscan_kickstart)
2678 return wl_wakeup_iscan(wl_to_iscan(wl));
2680 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2681 WL_ERR(("Scan complete while device not scanning\n"));
2684 if (unlikely(!wl->scan_request)) {
2687 err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2688 sizeof(channel_inform));
2689 if (unlikely(err)) {
2690 WL_ERR(("scan busy (%d)\n", err));
2693 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2694 if (unlikely(channel_inform.scan_channel)) {
2696 WL_DBG(("channel_inform.scan_channel (%d)\n",
2697 channel_inform.scan_channel));
2699 wl->bss_list = wl->scan_results;
2700 bss_list = wl->bss_list;
2701 memset(bss_list, 0, len);
2702 bss_list->buflen = htod32(len);
2703 err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
2704 if (unlikely(err)) {
2705 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2709 bss_list->buflen = dtoh32(bss_list->buflen);
2710 bss_list->version = dtoh32(bss_list->version);
2711 bss_list->count = dtoh32(bss_list->count);
2713 err = wl_inform_bss(wl);
2718 if (wl->scan_request) {
2719 cfg80211_scan_done(wl->scan_request, false);
2720 wl_set_mpc(ndev, 1);
2721 wl->scan_request = NULL;
2727 static void wl_init_conf(struct wl_conf *conf)
2729 conf->mode = (u32)-1;
2730 conf->frag_threshold = (u32)-1;
2731 conf->rts_threshold = (u32)-1;
2732 conf->retry_short = (u32)-1;
2733 conf->retry_long = (u32)-1;
2734 conf->tx_power = -1;
2737 static void wl_init_prof(struct wl_profile *prof)
2739 memset(prof, 0, sizeof(*prof));
2742 static void wl_init_eloop_handler(struct wl_event_loop *el)
2744 memset(el, 0, sizeof(*el));
2745 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2746 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2747 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2748 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2749 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2750 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2751 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2752 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2753 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2754 el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2757 static s32 wl_init_priv_mem(struct wl_priv *wl)
2759 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2760 if (unlikely(!wl->scan_results)) {
2761 WL_ERR(("Scan results alloc failed\n"));
2762 goto init_priv_mem_out;
2764 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2765 if (unlikely(!wl->conf)) {
2766 WL_ERR(("wl_conf alloc failed\n"));
2767 goto init_priv_mem_out;
2769 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2770 if (unlikely(!wl->profile)) {
2771 WL_ERR(("wl_profile alloc failed\n"));
2772 goto init_priv_mem_out;
2774 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2775 if (unlikely(!wl->bss_info)) {
2776 WL_ERR(("Bss information alloc failed\n"));
2777 goto init_priv_mem_out;
2780 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2781 if (unlikely(!wl->scan_req_int)) {
2782 WL_ERR(("Scan req alloc failed\n"));
2783 goto init_priv_mem_out;
2785 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2786 if (unlikely(!wl->ioctl_buf)) {
2787 WL_ERR(("Ioctl buf alloc failed\n"));
2788 goto init_priv_mem_out;
2790 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2791 if (unlikely(!wl->extra_buf)) {
2792 WL_ERR(("Extra buf alloc failed\n"));
2793 goto init_priv_mem_out;
2795 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2796 if (unlikely(!wl->iscan)) {
2797 WL_ERR(("Iscan buf alloc failed\n"));
2798 goto init_priv_mem_out;
2800 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2801 if (unlikely(!wl->fw)) {
2802 WL_ERR(("fw object alloc failed\n"));
2803 goto init_priv_mem_out;
2805 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2806 if (unlikely(!wl->pmk_list)) {
2807 WL_ERR(("pmk list alloc failed\n"));
2808 goto init_priv_mem_out;
2814 wl_deinit_priv_mem(wl);
2819 static void wl_deinit_priv_mem(struct wl_priv *wl)
2821 kfree(wl->scan_results);
2822 wl->scan_results = NULL;
2823 kfree(wl->bss_info);
2824 wl->bss_info = NULL;
2829 kfree(wl->scan_req_int);
2830 wl->scan_req_int = NULL;
2831 kfree(wl->ioctl_buf);
2832 wl->ioctl_buf = NULL;
2833 kfree(wl->extra_buf);
2834 wl->extra_buf = NULL;
2839 kfree(wl->pmk_list);
2840 wl->pmk_list = NULL;
2843 static s32 wl_create_event_handler(struct wl_priv *wl)
2845 sema_init(&wl->event_sync, 0);
2846 wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
2847 if (IS_ERR(wl->event_tsk)) {
2848 wl->event_tsk = NULL;
2849 WL_ERR(("failed to create event thread\n"));
2855 static void wl_destroy_event_handler(struct wl_priv *wl)
2857 if (wl->event_tsk) {
2858 send_sig(SIGTERM, wl->event_tsk, 1);
2859 kthread_stop(wl->event_tsk);
2860 wl->event_tsk = NULL;
2864 static void wl_term_iscan(struct wl_priv *wl)
2866 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2868 if (wl->iscan_on && iscan->tsk) {
2869 iscan->state = WL_ISCAN_STATE_IDLE;
2870 send_sig(SIGTERM, iscan->tsk, 1);
2871 kthread_stop(iscan->tsk);
2876 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2878 struct wl_priv *wl = iscan_to_wl(iscan);
2879 struct net_device *ndev = wl_to_ndev(wl);
2881 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2882 WL_ERR(("Scan complete while device not scanning\n"));
2885 if (likely(wl->scan_request)) {
2886 cfg80211_scan_done(wl->scan_request, aborted);
2887 wl_set_mpc(ndev, 1);
2888 wl->scan_request = NULL;
2890 wl->iscan_kickstart = false;
2893 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2895 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2896 WL_DBG(("wake up iscan\n"));
2905 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
2906 struct wl_scan_results **bss_list)
2908 struct wl_iscan_results list;
2909 struct wl_scan_results *results;
2910 struct wl_iscan_results *list_buf;
2913 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2914 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2915 results = &list_buf->results;
2916 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2917 results->version = 0;
2920 memset(&list, 0, sizeof(list));
2921 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2922 err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2923 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2925 if (unlikely(err)) {
2926 WL_ERR(("error (%d)\n", err));
2929 results->buflen = dtoh32(results->buflen);
2930 results->version = dtoh32(results->version);
2931 results->count = dtoh32(results->count);
2932 WL_DBG(("results->count = %d\n", results->count));
2933 WL_DBG(("results->buflen = %d\n", results->buflen));
2934 *status = dtoh32(list_buf->status);
2935 *bss_list = results;
2940 static s32 wl_iscan_done(struct wl_priv *wl)
2942 struct wl_iscan_ctrl *iscan = wl->iscan;
2945 iscan->state = WL_ISCAN_STATE_IDLE;
2948 wl_notify_iscan_complete(iscan, false);
2954 static s32 wl_iscan_pending(struct wl_priv *wl)
2956 struct wl_iscan_ctrl *iscan = wl->iscan;
2959 /* Reschedule the timer */
2960 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2961 iscan->timer_on = 1;
2966 static s32 wl_iscan_inprogress(struct wl_priv *wl)
2968 struct wl_iscan_ctrl *iscan = wl->iscan;
2973 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
2975 /* Reschedule the timer */
2976 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2977 iscan->timer_on = 1;
2982 static s32 wl_iscan_aborted(struct wl_priv *wl)
2984 struct wl_iscan_ctrl *iscan = wl->iscan;
2987 iscan->state = WL_ISCAN_STATE_IDLE;
2989 wl_notify_iscan_complete(iscan, true);
2995 static s32 wl_iscan_thread(void *data)
2997 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
2998 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
2999 struct wl_priv *wl = iscan_to_wl(iscan);
3000 struct wl_iscan_eloop *el = &iscan->el;
3004 sched_setscheduler(current, SCHED_FIFO, ¶m);
3005 allow_signal(SIGTERM);
3006 status = WL_SCAN_RESULTS_PARTIAL;
3007 while (likely(!down_interruptible(&iscan->sync))) {
3008 if (kthread_should_stop())
3010 if (iscan->timer_on) {
3011 del_timer_sync(&iscan->timer);
3012 iscan->timer_on = 0;
3015 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
3016 if (unlikely(err)) {
3017 status = WL_SCAN_RESULTS_ABORTED;
3018 WL_ERR(("Abort iscan\n"));
3021 el->handler[status] (wl);
3023 if (iscan->timer_on) {
3024 del_timer_sync(&iscan->timer);
3025 iscan->timer_on = 0;
3027 WL_DBG(("%s was terminated\n", __func__));
3032 static void wl_iscan_timer(unsigned long data)
3034 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3037 iscan->timer_on = 0;
3038 WL_DBG(("timer expired\n"));
3039 wl_wakeup_iscan(iscan);
3043 static s32 wl_invoke_iscan(struct wl_priv *wl)
3045 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3048 if (wl->iscan_on && !iscan->tsk) {
3049 iscan->state = WL_ISCAN_STATE_IDLE;
3050 sema_init(&iscan->sync, 0);
3051 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3052 if (IS_ERR(iscan->tsk)) {
3053 WL_ERR(("Could not create iscan thread\n"));
3062 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
3064 memset(el, 0, sizeof(*el));
3065 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
3066 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
3067 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
3068 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
3069 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
3072 static s32 wl_init_iscan(struct wl_priv *wl)
3074 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3078 iscan->dev = wl_to_ndev(wl);
3079 iscan->state = WL_ISCAN_STATE_IDLE;
3080 wl_init_iscan_eloop(&iscan->el);
3081 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3082 init_timer(&iscan->timer);
3083 iscan->timer.data = (unsigned long) iscan;
3084 iscan->timer.function = wl_iscan_timer;
3085 sema_init(&iscan->sync, 0);
3086 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3087 if (IS_ERR(iscan->tsk)) {
3088 WL_ERR(("Could not create iscan thread\n"));
3098 static void wl_init_fw(struct wl_fw_ctrl *fw)
3100 fw->status = 0; /* init fw loading status.
3101 0 means nothing was loaded yet */
3104 static s32 wl_init_priv(struct wl_priv *wl)
3106 struct wiphy *wiphy = wl_to_wiphy(wl);
3109 wl->scan_request = NULL;
3110 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3111 #ifndef WL_ISCAN_DISABLED
3112 wl->iscan_on = true; /* iscan on & off switch.
3113 we enable iscan per default */
3115 wl->iscan_on = false;
3116 #endif /* WL_ISCAN_DISABLED */
3117 #ifndef WL_ROAM_DISABLED
3118 wl->roam_on = true; /* roam on & off switch.
3119 we enable roam per default */
3121 wl->roam_on = false;
3122 #endif /* WL_ROAM_DISABLED */
3124 wl->iscan_kickstart = false;
3125 wl->active_scan = true; /* we do active scan for
3126 specific scan per default */
3127 wl->dongle_up = false; /* dongle is not up yet */
3129 err = wl_init_priv_mem(wl);
3132 if (unlikely(wl_create_event_handler(wl)))
3134 wl_init_eloop_handler(&wl->el);
3135 mutex_init(&wl->usr_sync);
3136 err = wl_init_iscan(wl);
3140 wl_init_conf(wl->conf);
3141 wl_init_prof(wl->profile);
3147 static void wl_deinit_priv(struct wl_priv *wl)
3149 wl_destroy_event_handler(wl);
3150 wl->dongle_up = false; /* dongle down */
3154 wl_deinit_priv_mem(wl);
3157 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3159 struct wireless_dev *wdev;
3161 struct wl_iface *ci;
3164 if (unlikely(!ndev)) {
3165 WL_ERR(("ndev is invaild\n"));
3168 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3169 if (unlikely(!wl_cfg80211_dev)) {
3170 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3173 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
3174 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
3175 if (unlikely(IS_ERR(wdev)))
3178 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3179 wl = wdev_to_wl(wdev);
3182 ci = (struct wl_iface *)wl_to_ci(wl);
3184 ndev->ieee80211_ptr = wdev;
3185 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3186 wdev->netdev = ndev;
3187 err = wl_init_priv(wl);
3188 if (unlikely(err)) {
3189 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
3190 goto cfg80211_attach_out;
3192 wl_set_drvdata(wl_cfg80211_dev, ci);
3193 set_bit(WL_STATUS_READY, &wl->status);
3197 cfg80211_attach_out:
3202 void wl_cfg80211_detach(void)
3210 wl_set_drvdata(wl_cfg80211_dev, NULL);
3211 kfree(wl_cfg80211_dev);
3212 wl_cfg80211_dev = NULL;
3213 wl_clear_sdio_func();
3216 static void wl_wakeup_event(struct wl_priv *wl)
3218 up(&wl->event_sync);
3221 static s32 wl_event_handler(void *data)
3223 struct wl_priv *wl = (struct wl_priv *)data;
3224 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3225 struct wl_event_q *e;
3227 sched_setscheduler(current, SCHED_FIFO, ¶m);
3228 allow_signal(SIGTERM);
3229 while (likely(!down_interruptible(&wl->event_sync))) {
3230 if (kthread_should_stop())
3232 e = wl_deq_event(wl);
3234 WL_ERR(("eqeue empty..\n"));
3237 WL_DBG(("event type (%d)\n", e->etype));
3238 if (wl->el.handler[e->etype]) {
3239 wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3242 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
3246 WL_DBG(("%s was terminated\n", __func__));
3251 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
3253 u32 event_type = ntoh32(e->event_type);
3254 struct wl_priv *wl = ndev_to_wl(ndev);
3255 #if (WL_DBG_LEVEL > 0)
3256 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
3257 wl_dbg_estr[event_type] : (s8 *) "Unknown";
3258 #endif /* (WL_DBG_LEVEL > 0) */
3259 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
3260 if (likely(!wl_enq_event(wl, event_type, e, data)))
3261 wl_wakeup_event(wl);
3264 static void wl_init_eq(struct wl_priv *wl)
3266 wl_init_eq_lock(wl);
3267 INIT_LIST_HEAD(&wl->eq_list);
3270 static void wl_flush_eq(struct wl_priv *wl)
3272 struct wl_event_q *e;
3275 while (!list_empty(&wl->eq_list)) {
3276 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3277 list_del(&e->eq_list);
3284 * retrieve first queued event from head
3287 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3289 struct wl_event_q *e = NULL;
3292 if (likely(!list_empty(&wl->eq_list))) {
3293 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3294 list_del(&e->eq_list);
3302 ** push event to tail of the queue
3306 wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg,
3309 struct wl_event_q *e;
3312 e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
3314 WL_ERR(("event alloc failed\n"));
3319 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
3323 list_add_tail(&e->eq_list, &wl->eq_list);
3329 static void wl_put_event(struct wl_event_q *e)
3334 void wl_cfg80211_sdio_func(void *func)
3336 cfg80211_sdio_func = (struct sdio_func *)func;
3339 static void wl_clear_sdio_func(void)
3341 cfg80211_sdio_func = NULL;
3344 struct sdio_func *wl_cfg80211_get_sdio_func(void)
3346 return cfg80211_sdio_func;
3349 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
3356 case NL80211_IFTYPE_MONITOR:
3357 case NL80211_IFTYPE_WDS:
3358 WL_ERR(("type (%d) : currently we do not support this mode\n",
3362 case NL80211_IFTYPE_ADHOC:
3364 case NL80211_IFTYPE_STATION:
3369 WL_ERR(("invalid type (%d)\n", iftype));
3372 infra = htod32(infra);
3374 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
3375 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
3376 if (unlikely(err)) {
3377 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
3380 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
3381 if (unlikely(err)) {
3382 WL_ERR(("WLC_SET_AP error (%d)\n", err));
3386 return -EINPROGRESS;
3389 #ifndef EMBEDDED_PLATFORM
3390 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3398 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
3402 err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
3403 if (unlikely(err)) {
3404 WL_ERR(("WLC_UP error (%d)\n", err));
3409 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
3413 err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
3414 if (unlikely(err)) {
3415 WL_ERR(("WLC_SET_PM error (%d)\n", err));
3421 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
3423 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3427 /* Match Host and Dongle rx alignment */
3428 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3430 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3431 if (unlikely(err)) {
3432 WL_ERR(("txglomalign error (%d)\n", err));
3433 goto dongle_glom_out;
3435 /* disable glom option per default */
3436 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3437 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3438 if (unlikely(err)) {
3439 WL_ERR(("txglom error (%d)\n", err));
3440 goto dongle_glom_out;
3447 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3449 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3453 /* Setup timeout if Beacons are lost and roam is
3454 off to report link down */
3456 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
3458 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3459 if (unlikely(err)) {
3460 WL_ERR(("bcn_timeout error (%d)\n", err));
3461 goto dongle_rom_out;
3464 /* Enable/Disable built-in roaming to allow supplicant
3465 to take care of roaming */
3466 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
3467 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3468 if (unlikely(err)) {
3469 WL_ERR(("roam_off error (%d)\n", err));
3470 goto dongle_rom_out;
3476 static s32 wl_dongle_eventmsg(struct net_device *ndev)
3479 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3481 s8 eventmask[WL_EVENTING_MASK_LEN];
3484 /* Setup event_msgs */
3485 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3487 err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
3488 if (unlikely(err)) {
3489 WL_ERR(("Get event_msgs error (%d)\n", err));
3490 goto dongle_eventmsg_out;
3492 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3494 setbit(eventmask, WLC_E_SET_SSID);
3495 setbit(eventmask, WLC_E_PRUNE);
3496 setbit(eventmask, WLC_E_AUTH);
3497 setbit(eventmask, WLC_E_REASSOC);
3498 setbit(eventmask, WLC_E_REASSOC_IND);
3499 setbit(eventmask, WLC_E_DEAUTH_IND);
3500 setbit(eventmask, WLC_E_DISASSOC_IND);
3501 setbit(eventmask, WLC_E_DISASSOC);
3502 setbit(eventmask, WLC_E_JOIN);
3503 setbit(eventmask, WLC_E_ASSOC_IND);
3504 setbit(eventmask, WLC_E_PSK_SUP);
3505 setbit(eventmask, WLC_E_LINK);
3506 setbit(eventmask, WLC_E_NDIS_LINK);
3507 setbit(eventmask, WLC_E_MIC_ERROR);
3508 setbit(eventmask, WLC_E_PMKID_CACHE);
3509 setbit(eventmask, WLC_E_TXFAIL);
3510 setbit(eventmask, WLC_E_JOIN_START);
3511 setbit(eventmask, WLC_E_SCAN_COMPLETE);
3513 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3515 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3516 if (unlikely(err)) {
3517 WL_ERR(("Set event_msgs error (%d)\n", err));
3518 goto dongle_eventmsg_out;
3521 dongle_eventmsg_out:
3526 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3527 s32 scan_unassoc_time)
3531 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
3532 sizeof(scan_assoc_time));
3534 if (err == -EOPNOTSUPP) {
3535 WL_INFO(("Scan assoc time is not supported\n"));
3537 WL_ERR(("Scan assoc time error (%d)\n", err));
3539 goto dongle_scantime_out;
3541 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
3542 sizeof(scan_unassoc_time));
3544 if (err == -EOPNOTSUPP) {
3545 WL_INFO(("Scan unassoc time is not supported\n"));
3547 WL_ERR(("Scan unassoc time error (%d)\n", err));
3549 goto dongle_scantime_out;
3552 dongle_scantime_out:
3557 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
3559 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3563 /* Set ARP offload */
3564 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3565 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3567 if (err == -EOPNOTSUPP)
3568 WL_INFO(("arpoe is not supported\n"));
3570 WL_ERR(("arpoe error (%d)\n", err));
3572 goto dongle_offload_out;
3574 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3575 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3577 if (err == -EOPNOTSUPP)
3578 WL_INFO(("arp_ol is not supported\n"));
3580 WL_ERR(("arp_ol error (%d)\n", err));
3582 goto dongle_offload_out;
3589 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
3592 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3593 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3596 src = src + 2; /* Skip past 0x */
3597 if (strlen(src) % 2 != 0) {
3598 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3601 for (i = 0; *src != '\0'; i++) {
3603 strncpy(num, src, 2);
3605 dst[i] = (u8) simple_strtoul(num, NULL, 16);
3611 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
3613 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3616 struct wl_pkt_filter pkt_filter;
3617 struct wl_pkt_filter *pkt_filterp;
3625 /* add a default packet filter pattern */
3626 str = "pkt_filter_add";
3627 str_len = strlen(str);
3628 strncpy(buf, str, str_len);
3629 buf[str_len] = '\0';
3630 buf_len = str_len + 1;
3632 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3634 /* Parse packet filter id. */
3635 pkt_filter.id = htod32(100);
3637 /* Parse filter polarity. */
3638 pkt_filter.negate_match = htod32(0);
3640 /* Parse filter type. */
3641 pkt_filter.type = htod32(0);
3643 /* Parse pattern filter offset. */
3644 pkt_filter.u.pattern.offset = htod32(0);
3646 /* Parse pattern filter mask. */
3647 mask_size = htod32(wl_pattern_atoh("0xff",
3648 (char *)pkt_filterp->u.pattern.
3651 /* Parse pattern filter pattern. */
3652 pattern_size = htod32(wl_pattern_atoh("0x00",
3653 (char *)&pkt_filterp->u.pattern.
3654 mask_and_pattern[mask_size]));
3656 if (mask_size != pattern_size) {
3657 WL_ERR(("Mask and pattern not the same size\n"));
3659 goto dongle_filter_out;
3662 pkt_filter.u.pattern.size_bytes = mask_size;
3663 buf_len += WL_PKT_FILTER_FIXED_LEN;
3664 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3666 /* Keep-alive attributes are set in local
3667 * variable (keep_alive_pkt), and
3668 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3669 * guarantee that the buffer is properly aligned.
3671 memcpy((char *)pkt_filterp, &pkt_filter,
3672 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3674 err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
3676 if (err == -EOPNOTSUPP) {
3677 WL_INFO(("filter not supported\n"));
3679 WL_ERR(("filter (%d)\n", err));
3681 goto dongle_filter_out;
3684 /* set mode to allow pattern */
3685 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3687 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3689 if (err == -EOPNOTSUPP) {
3690 WL_INFO(("filter_mode not supported\n"));
3692 WL_ERR(("filter_mode (%d)\n", err));
3694 goto dongle_filter_out;
3700 #endif /* !EMBEDDED_PLATFORM */
3702 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
3705 #define DHD_SDALIGN 32
3707 struct net_device *ndev;
3708 struct wireless_dev *wdev;
3714 ndev = wl_to_ndev(wl);
3715 wdev = ndev->ieee80211_ptr;
3719 #ifndef EMBEDDED_PLATFORM
3720 err = wl_dongle_up(ndev, 0);
3722 goto default_conf_out;
3723 err = wl_dongle_country(ndev, 0);
3725 goto default_conf_out;
3726 err = wl_dongle_power(ndev, PM_FAST);
3728 goto default_conf_out;
3729 err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
3731 goto default_conf_out;
3732 err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
3734 goto default_conf_out;
3735 err = wl_dongle_eventmsg(ndev);
3737 goto default_conf_out;
3739 wl_dongle_scantime(ndev, 40, 80);
3740 wl_dongle_offload(ndev, 1, 0xf);
3741 wl_dongle_filter(ndev, 1);
3742 #endif /* !EMBEDDED_PLATFORM */
3744 err = wl_dongle_mode(ndev, wdev->iftype);
3745 if (unlikely(err && err != -EINPROGRESS))
3746 goto default_conf_out;
3747 err = wl_dongle_probecap(wl);
3749 goto default_conf_out;
3751 /* -EINPROGRESS: Call commit handler */
3757 wl->dongle_up = true;
3763 static s32 wl_update_wiphybands(struct wl_priv *wl)
3765 struct wiphy *wiphy;
3770 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
3772 if (unlikely(err)) {
3773 WL_ERR(("error (%d)\n", err));
3777 phy = ((char *)&phy_list)[1];
3778 WL_DBG(("%c phy\n", phy));
3779 if (phy == 'n' || phy == 'a') {
3780 wiphy = wl_to_wiphy(wl);
3781 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3787 static s32 __wl_cfg80211_up(struct wl_priv *wl)
3791 err = wl_config_dongle(wl, false);
3795 wl_invoke_iscan(wl);
3796 set_bit(WL_STATUS_READY, &wl->status);
3800 static s32 __wl_cfg80211_down(struct wl_priv *wl)
3804 /* Check if cfg80211 interface is already down */
3805 if (!test_bit(WL_STATUS_READY, &wl->status))
3806 return err; /* it is even not ready */
3808 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3810 if (wl->scan_request) {
3811 cfg80211_scan_done(wl->scan_request, true); /* true
3813 /* wl_set_mpc(wl_to_ndev(wl), 1); */ /* BUG
3814 * this operation cannot help
3815 * but here because sdio
3816 * is already down through
3818 * Need to figure out how to
3819 * address this issue
3821 wl->scan_request = NULL;
3823 clear_bit(WL_STATUS_READY, &wl->status);
3824 clear_bit(WL_STATUS_SCANNING, &wl->status);
3825 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3826 clear_bit(WL_STATUS_CONNECTED, &wl->status);
3831 s32 wl_cfg80211_up(void)
3837 mutex_lock(&wl->usr_sync);
3838 err = __wl_cfg80211_up(wl);
3839 mutex_unlock(&wl->usr_sync);
3844 s32 wl_cfg80211_down(void)
3850 mutex_lock(&wl->usr_sync);
3851 err = __wl_cfg80211_down(wl);
3852 mutex_unlock(&wl->usr_sync);
3857 static s32 wl_dongle_probecap(struct wl_priv *wl)
3861 err = wl_update_wiphybands(wl);
3868 static void *wl_read_prof(struct wl_priv *wl, s32 item)
3872 return &wl->profile->sec;
3874 return &wl->profile->active;
3876 return &wl->profile->bssid;
3878 return &wl->profile->ssid;
3880 WL_ERR(("invalid item (%d)\n", item));
3885 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
3889 struct wlc_ssid *ssid;
3893 ssid = (wlc_ssid_t *) data;
3894 memset(wl->profile->ssid.SSID, 0,
3895 sizeof(wl->profile->ssid.SSID));
3896 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
3897 wl->profile->ssid.SSID_len = ssid->SSID_len;
3901 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
3903 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
3906 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
3909 wl->profile->active = *(bool *) data;
3912 WL_ERR(("unsupported item (%d)\n", item));
3920 void wl_cfg80211_dbg_level(u32 level)
3923 * prohibit to change debug level
3924 * by insmod parameter.
3925 * eventually debug level will be configured
3926 * in compile time by using CONFIG_XXX
3928 /* wl_dbg_level = level; */
3931 static bool wl_is_ibssmode(struct wl_priv *wl)
3933 return wl->conf->mode == WL_MODE_IBSS;
3936 static bool wl_is_ibssstarter(struct wl_priv *wl)
3938 return wl->ibss_starter;
3941 static void wl_rst_ie(struct wl_priv *wl)
3943 struct wl_ie *ie = wl_to_ie(wl);
3948 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
3950 struct wl_ie *ie = wl_to_ie(wl);
3953 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3954 WL_ERR(("ei crosses buffer boundary\n"));
3957 ie->buf[ie->offset] = t;
3958 ie->buf[ie->offset + 1] = l;
3959 memcpy(&ie->buf[ie->offset + 2], v, l);
3960 ie->offset += l + 2;
3965 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
3967 struct wl_ie *ie = wl_to_ie(wl);
3970 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
3971 WL_ERR(("ei_stream crosses buffer boundary\n"));
3974 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
3975 ie->offset += ie_size;
3980 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
3982 struct wl_ie *ie = wl_to_ie(wl);
3985 if (unlikely(ie->offset > dst_size)) {
3986 WL_ERR(("dst_size is not enough\n"));
3989 memcpy(dst, &ie->buf[0], ie->offset);
3994 static u32 wl_get_ielen(struct wl_priv *wl)
3996 struct wl_ie *ie = wl_to_ie(wl);
4001 static void wl_link_up(struct wl_priv *wl)
4006 static void wl_link_down(struct wl_priv *wl)
4008 struct wl_connect_info *conn_info = wl_to_conn(wl);
4010 wl->link_up = false;
4011 kfree(conn_info->req_ie);
4012 conn_info->req_ie = NULL;
4013 conn_info->req_ie_len = 0;
4014 kfree(conn_info->resp_ie);
4015 conn_info->resp_ie = NULL;
4016 conn_info->resp_ie_len = 0;
4019 static void wl_lock_eq(struct wl_priv *wl)
4021 spin_lock_irq(&wl->eq_lock);
4024 static void wl_unlock_eq(struct wl_priv *wl)
4026 spin_unlock_irq(&wl->eq_lock);
4029 static void wl_init_eq_lock(struct wl_priv *wl)
4031 spin_lock_init(&wl->eq_lock);
4034 static void wl_delay(u32 ms)
4036 if (ms < 1000 / HZ) {
4044 static void wl_set_drvdata(struct wl_dev *dev, void *data)
4046 dev->driver_data = data;
4049 static void *wl_get_drvdata(struct wl_dev *dev)
4051 return dev->driver_data;
4054 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
4056 const struct firmware *fw_entry;
4061 fw_entry = wl->fw->fw_entry;
4063 if (fw_entry->size < wl->fw->ptr + size)
4064 size = fw_entry->size - wl->fw->ptr;
4066 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
4067 wl->fw->ptr += size;
4071 void wl_cfg80211_release_fw(void)
4076 release_firmware(wl->fw->fw_entry);
4080 void *wl_cfg80211_request_fw(s8 *file_name)
4083 const struct firmware *fw_entry = NULL;
4086 WL_DBG(("file name : \"%s\"\n", file_name));
4089 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
4090 err = request_firmware(&wl->fw->fw_entry, file_name,
4091 &wl_cfg80211_get_sdio_func()->dev);
4092 if (unlikely(err)) {
4093 WL_ERR(("Could not download fw (%d)\n", err));
4096 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
4097 fw_entry = wl->fw->fw_entry;
4099 WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
4102 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
4103 err = request_firmware(&wl->fw->fw_entry, file_name,
4104 &wl_cfg80211_get_sdio_func()->dev);
4105 if (unlikely(err)) {
4106 WL_ERR(("Could not download nvram (%d)\n", err));
4109 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
4110 fw_entry = wl->fw->fw_entry;
4112 WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
4116 WL_DBG(("Downloading already done. Nothing to do more\n"));
4121 if (unlikely(err)) {
4125 return (void *)fw_entry->data;
4128 s8 *wl_cfg80211_get_fwname(void)
4133 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4134 return wl->fw->fw_name;
4137 s8 *wl_cfg80211_get_nvramname(void)
4142 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4143 return wl->fw->nvram_name;
4146 static void wl_set_mpc(struct net_device *ndev, int mpc)
4150 err = wl_dev_intvar_set(ndev, "mpc", mpc);
4151 if (unlikely(err)) {
4152 WL_ERR(("fail to set mpc\n"));
4155 WL_DBG(("MPC : %d\n", mpc));