2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/kernel.h>
18 #include <linux/if_arp.h>
22 #include <bcmendian.h>
23 #include <proto/ethernet.h>
25 #include <asm/uaccess.h>
27 #include <dngl_stats.h>
32 #include <proto/ethernet.h>
33 #include <dngl_stats.h>
36 #include <linux/kthread.h>
37 #include <linux/netdevice.h>
38 #include <linux/sched.h>
39 #include <linux/etherdevice.h>
40 #include <linux/wireless.h>
41 #include <linux/ieee80211.h>
42 #include <net/cfg80211.h>
44 #include <net/rtnetlink.h>
45 #include <linux/mmc/sdio_func.h>
46 #include <linux/firmware.h>
47 #include <wl_cfg80211.h>
49 static struct sdio_func *cfg80211_sdio_func;
50 static struct wl_dev *wl_cfg80211_dev;
52 u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
54 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
55 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
58 ** cfg80211_ops api/callback list
60 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
61 struct net_device *ndev,
62 enum nl80211_iftype type, u32 *flags,
63 struct vif_params *params);
64 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
65 struct cfg80211_scan_request *request,
66 struct cfg80211_ssid *this_ssid);
67 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
68 struct cfg80211_scan_request *request);
69 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
70 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
71 struct cfg80211_ibss_params *params);
72 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
73 struct net_device *dev);
74 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
75 struct net_device *dev, u8 *mac,
76 struct station_info *sinfo);
77 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
78 struct net_device *dev, bool enabled,
80 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
81 struct net_device *dev,
83 const struct cfg80211_bitrate_mask
85 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
86 struct cfg80211_connect_params *sme);
87 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
89 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
90 enum nl80211_tx_power_setting type,
92 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
93 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
94 struct net_device *dev,
96 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
97 u8 key_idx, const u8 *mac_addr,
98 struct key_params *params);
99 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
100 u8 key_idx, const u8 *mac_addr);
101 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
102 u8 key_idx, const u8 *mac_addr,
103 void *cookie, void (*callback) (void *cookie,
107 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
108 struct net_device *dev,
110 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
111 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
112 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
113 struct cfg80211_pmksa *pmksa);
114 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
115 struct cfg80211_pmksa *pmksa);
116 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
117 struct net_device *dev);
119 ** event & event Q handlers for cfg80211 interfaces
121 static s32 wl_create_event_handler(struct wl_priv *wl);
122 static void wl_destroy_event_handler(struct wl_priv *wl);
123 static s32 wl_event_handler(void *data);
124 static void wl_init_eq(struct wl_priv *wl);
125 static void wl_flush_eq(struct wl_priv *wl);
126 static void wl_lock_eq(struct wl_priv *wl);
127 static void wl_unlock_eq(struct wl_priv *wl);
128 static void wl_init_eq_lock(struct wl_priv *wl);
129 static void wl_init_eloop_handler(struct wl_event_loop *el);
130 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
131 static s32 wl_enq_event(struct wl_priv *wl, u32 type,
132 const wl_event_msg_t *msg, void *data);
133 static void wl_put_event(struct wl_event_q *e);
134 static void wl_wakeup_event(struct wl_priv *wl);
135 static s32 wl_notify_connect_status(struct wl_priv *wl,
136 struct net_device *ndev,
137 const wl_event_msg_t *e, void *data);
138 static s32 wl_notify_roaming_status(struct wl_priv *wl,
139 struct net_device *ndev,
140 const wl_event_msg_t *e, void *data);
141 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
142 const wl_event_msg_t *e, void *data);
143 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
144 const wl_event_msg_t *e, void *data,
146 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
147 const wl_event_msg_t *e, void *data);
148 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
149 const wl_event_msg_t *e, void *data);
152 ** register/deregister sdio function
154 struct sdio_func *wl_cfg80211_get_sdio_func(void);
155 static void wl_clear_sdio_func(void);
160 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
162 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
164 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
165 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
167 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
171 ** cfg80211 set_wiphy_params utilities
173 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
174 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
175 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
178 ** wl profile utilities
180 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
181 void *data, s32 item);
182 static void *wl_read_prof(struct wl_priv *wl, s32 item);
183 static void wl_init_prof(struct wl_profile *prof);
186 ** cfg80211 connect utilites
188 static s32 wl_set_wpa_version(struct net_device *dev,
189 struct cfg80211_connect_params *sme);
190 static s32 wl_set_auth_type(struct net_device *dev,
191 struct cfg80211_connect_params *sme);
192 static s32 wl_set_set_cipher(struct net_device *dev,
193 struct cfg80211_connect_params *sme);
194 static s32 wl_set_key_mgmt(struct net_device *dev,
195 struct cfg80211_connect_params *sme);
196 static s32 wl_set_set_sharedkey(struct net_device *dev,
197 struct cfg80211_connect_params *sme);
198 static s32 wl_get_assoc_ies(struct wl_priv *wl);
199 static void wl_ch_to_chanspec(int ch,
200 struct wl_join_params *join_params, size_t *join_params_size);
203 ** information element utilities
205 static void wl_rst_ie(struct wl_priv *wl);
206 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
207 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
208 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
209 static u32 wl_get_ielen(struct wl_priv *wl);
211 static s32 wl_mode_to_nl80211_iftype(s32 mode);
213 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
215 static void wl_free_wdev(struct wl_priv *wl);
217 static s32 wl_inform_bss(struct wl_priv *wl);
218 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
219 static s32 wl_update_bss_info(struct wl_priv *wl);
221 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
222 u8 key_idx, const u8 *mac_addr,
223 struct key_params *params);
226 ** key indianess swap utilities
228 static void swap_key_from_BE(struct wl_wsec_key *key);
229 static void swap_key_to_BE(struct wl_wsec_key *key);
232 ** wl_priv memory init/deinit utilities
234 static s32 wl_init_priv_mem(struct wl_priv *wl);
235 static void wl_deinit_priv_mem(struct wl_priv *wl);
237 static void wl_delay(u32 ms);
240 ** store/restore cfg80211 instance data
242 static void wl_set_drvdata(struct wl_dev *dev, void *data);
243 static void *wl_get_drvdata(struct wl_dev *dev);
246 ** ibss mode utilities
248 static bool wl_is_ibssmode(struct wl_priv *wl);
249 static bool wl_is_ibssstarter(struct wl_priv *wl);
252 ** dongle up/down , default configuration utilities
254 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
255 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
256 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
257 static void wl_link_up(struct wl_priv *wl);
258 static void wl_link_down(struct wl_priv *wl);
259 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
260 static s32 __wl_cfg80211_up(struct wl_priv *wl);
261 static s32 __wl_cfg80211_down(struct wl_priv *wl);
262 static s32 wl_dongle_probecap(struct wl_priv *wl);
263 static void wl_init_conf(struct wl_conf *conf);
266 ** dongle configuration utilities
268 #ifndef EMBEDDED_PLATFORM
269 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
270 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
271 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
272 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
273 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
275 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
277 static s32 wl_dongle_eventmsg(struct net_device *ndev);
278 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
279 s32 scan_unassoc_time);
280 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
282 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
283 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
284 static s32 wl_update_wiphybands(struct wl_priv *wl);
285 #endif /* !EMBEDDED_PLATFORM */
286 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
291 static void wl_iscan_timer(unsigned long data);
292 static void wl_term_iscan(struct wl_priv *wl);
293 static s32 wl_init_iscan(struct wl_priv *wl);
294 static s32 wl_iscan_thread(void *data);
295 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
296 void *param, s32 paramlen, void *bufptr,
298 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
299 void *param, s32 paramlen, void *bufptr,
301 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
303 static s32 wl_do_iscan(struct wl_priv *wl);
304 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
305 static s32 wl_invoke_iscan(struct wl_priv *wl);
306 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
307 struct wl_scan_results **bss_list);
308 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
309 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
310 static s32 wl_iscan_done(struct wl_priv *wl);
311 static s32 wl_iscan_pending(struct wl_priv *wl);
312 static s32 wl_iscan_inprogress(struct wl_priv *wl);
313 static s32 wl_iscan_aborted(struct wl_priv *wl);
316 ** fw/nvram downloading handler
318 static void wl_init_fw(struct wl_fw_ctrl *fw);
321 * find most significant bit set
323 static __used u32 wl_find_msb(u16 bit16);
326 * update pmklist to dongle
328 static __used s32 wl_update_pmklist(struct net_device *dev,
329 struct wl_pmk_list *pmk_list, s32 err);
331 static void wl_set_mpc(struct net_device *ndev, int mpc);
336 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
337 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
339 #define WL_PRIV_GET() \
341 struct wl_iface *ci; \
342 if (unlikely(!(wl_cfg80211_dev && \
343 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
344 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
350 #define CHECK_SYS_UP() \
352 struct wl_priv *wl = wiphy_to_wl(wiphy); \
353 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
354 WL_INFO(("device is not ready : status (%d)\n", \
360 extern int dhd_wait_pend8021x(struct net_device *dev);
362 #if (WL_DBG_LEVEL > 0)
363 #define WL_DBG_ESTR_MAX 32
364 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
365 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
366 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
367 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
368 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
369 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
370 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
371 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
373 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
375 "RADIO", "PSM_WATCHDOG",
377 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
378 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
379 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
381 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
383 #endif /* WL_DBG_LEVEL */
385 #define CHAN2G(_channel, _freq, _flags) { \
386 .band = IEEE80211_BAND_2GHZ, \
387 .center_freq = (_freq), \
388 .hw_value = (_channel), \
390 .max_antenna_gain = 0, \
394 #define CHAN5G(_channel, _flags) { \
395 .band = IEEE80211_BAND_5GHZ, \
396 .center_freq = 5000 + (5 * (_channel)), \
397 .hw_value = (_channel), \
399 .max_antenna_gain = 0, \
403 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
404 #define RATETAB_ENT(_rateid, _flags) \
406 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
407 .hw_value = (_rateid), \
411 static struct ieee80211_rate __wl_rates[] = {
412 RATETAB_ENT(WLC_RATE_1M, 0),
413 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
414 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
415 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
416 RATETAB_ENT(WLC_RATE_6M, 0),
417 RATETAB_ENT(WLC_RATE_9M, 0),
418 RATETAB_ENT(WLC_RATE_12M, 0),
419 RATETAB_ENT(WLC_RATE_18M, 0),
420 RATETAB_ENT(WLC_RATE_24M, 0),
421 RATETAB_ENT(WLC_RATE_36M, 0),
422 RATETAB_ENT(WLC_RATE_48M, 0),
423 RATETAB_ENT(WLC_RATE_54M, 0),
426 #define wl_a_rates (__wl_rates + 4)
427 #define wl_a_rates_size 8
428 #define wl_g_rates (__wl_rates + 0)
429 #define wl_g_rates_size 12
431 static struct ieee80211_channel __wl_2ghz_channels[] = {
448 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
449 CHAN5G(34, 0), CHAN5G(36, 0),
450 CHAN5G(38, 0), CHAN5G(40, 0),
451 CHAN5G(42, 0), CHAN5G(44, 0),
452 CHAN5G(46, 0), CHAN5G(48, 0),
453 CHAN5G(52, 0), CHAN5G(56, 0),
454 CHAN5G(60, 0), CHAN5G(64, 0),
455 CHAN5G(100, 0), CHAN5G(104, 0),
456 CHAN5G(108, 0), CHAN5G(112, 0),
457 CHAN5G(116, 0), CHAN5G(120, 0),
458 CHAN5G(124, 0), CHAN5G(128, 0),
459 CHAN5G(132, 0), CHAN5G(136, 0),
460 CHAN5G(140, 0), CHAN5G(149, 0),
461 CHAN5G(153, 0), CHAN5G(157, 0),
462 CHAN5G(161, 0), CHAN5G(165, 0),
463 CHAN5G(184, 0), CHAN5G(188, 0),
464 CHAN5G(192, 0), CHAN5G(196, 0),
465 CHAN5G(200, 0), CHAN5G(204, 0),
466 CHAN5G(208, 0), CHAN5G(212, 0),
470 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
471 CHAN5G(32, 0), CHAN5G(34, 0),
472 CHAN5G(36, 0), CHAN5G(38, 0),
473 CHAN5G(40, 0), CHAN5G(42, 0),
474 CHAN5G(44, 0), CHAN5G(46, 0),
475 CHAN5G(48, 0), CHAN5G(50, 0),
476 CHAN5G(52, 0), CHAN5G(54, 0),
477 CHAN5G(56, 0), CHAN5G(58, 0),
478 CHAN5G(60, 0), CHAN5G(62, 0),
479 CHAN5G(64, 0), CHAN5G(66, 0),
480 CHAN5G(68, 0), CHAN5G(70, 0),
481 CHAN5G(72, 0), CHAN5G(74, 0),
482 CHAN5G(76, 0), CHAN5G(78, 0),
483 CHAN5G(80, 0), CHAN5G(82, 0),
484 CHAN5G(84, 0), CHAN5G(86, 0),
485 CHAN5G(88, 0), CHAN5G(90, 0),
486 CHAN5G(92, 0), CHAN5G(94, 0),
487 CHAN5G(96, 0), CHAN5G(98, 0),
488 CHAN5G(100, 0), CHAN5G(102, 0),
489 CHAN5G(104, 0), CHAN5G(106, 0),
490 CHAN5G(108, 0), CHAN5G(110, 0),
491 CHAN5G(112, 0), CHAN5G(114, 0),
492 CHAN5G(116, 0), CHAN5G(118, 0),
493 CHAN5G(120, 0), CHAN5G(122, 0),
494 CHAN5G(124, 0), CHAN5G(126, 0),
495 CHAN5G(128, 0), CHAN5G(130, 0),
496 CHAN5G(132, 0), CHAN5G(134, 0),
497 CHAN5G(136, 0), CHAN5G(138, 0),
498 CHAN5G(140, 0), CHAN5G(142, 0),
499 CHAN5G(144, 0), CHAN5G(145, 0),
500 CHAN5G(146, 0), CHAN5G(147, 0),
501 CHAN5G(148, 0), CHAN5G(149, 0),
502 CHAN5G(150, 0), CHAN5G(151, 0),
503 CHAN5G(152, 0), CHAN5G(153, 0),
504 CHAN5G(154, 0), CHAN5G(155, 0),
505 CHAN5G(156, 0), CHAN5G(157, 0),
506 CHAN5G(158, 0), CHAN5G(159, 0),
507 CHAN5G(160, 0), CHAN5G(161, 0),
508 CHAN5G(162, 0), CHAN5G(163, 0),
509 CHAN5G(164, 0), CHAN5G(165, 0),
510 CHAN5G(166, 0), CHAN5G(168, 0),
511 CHAN5G(170, 0), CHAN5G(172, 0),
512 CHAN5G(174, 0), CHAN5G(176, 0),
513 CHAN5G(178, 0), CHAN5G(180, 0),
514 CHAN5G(182, 0), CHAN5G(184, 0),
515 CHAN5G(186, 0), CHAN5G(188, 0),
516 CHAN5G(190, 0), CHAN5G(192, 0),
517 CHAN5G(194, 0), CHAN5G(196, 0),
518 CHAN5G(198, 0), CHAN5G(200, 0),
519 CHAN5G(202, 0), CHAN5G(204, 0),
520 CHAN5G(206, 0), CHAN5G(208, 0),
521 CHAN5G(210, 0), CHAN5G(212, 0),
522 CHAN5G(214, 0), CHAN5G(216, 0),
523 CHAN5G(218, 0), CHAN5G(220, 0),
524 CHAN5G(222, 0), CHAN5G(224, 0),
525 CHAN5G(226, 0), CHAN5G(228, 0),
528 static struct ieee80211_supported_band __wl_band_2ghz = {
529 .band = IEEE80211_BAND_2GHZ,
530 .channels = __wl_2ghz_channels,
531 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
532 .bitrates = wl_g_rates,
533 .n_bitrates = wl_g_rates_size,
536 static struct ieee80211_supported_band __wl_band_5ghz_a = {
537 .band = IEEE80211_BAND_5GHZ,
538 .channels = __wl_5ghz_a_channels,
539 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
540 .bitrates = wl_a_rates,
541 .n_bitrates = wl_a_rates_size,
544 static struct ieee80211_supported_band __wl_band_5ghz_n = {
545 .band = IEEE80211_BAND_5GHZ,
546 .channels = __wl_5ghz_n_channels,
547 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
548 .bitrates = wl_a_rates,
549 .n_bitrates = wl_a_rates_size,
552 static const u32 __wl_cipher_suites[] = {
553 WLAN_CIPHER_SUITE_WEP40,
554 WLAN_CIPHER_SUITE_WEP104,
555 WLAN_CIPHER_SUITE_TKIP,
556 WLAN_CIPHER_SUITE_CCMP,
557 WLAN_CIPHER_SUITE_AES_CMAC,
560 static void swap_key_from_BE(struct wl_wsec_key *key)
562 key->index = htod32(key->index);
563 key->len = htod32(key->len);
564 key->algo = htod32(key->algo);
565 key->flags = htod32(key->flags);
566 key->rxiv.hi = htod32(key->rxiv.hi);
567 key->rxiv.lo = htod16(key->rxiv.lo);
568 key->iv_initialized = htod32(key->iv_initialized);
571 static void swap_key_to_BE(struct wl_wsec_key *key)
573 key->index = dtoh32(key->index);
574 key->len = dtoh32(key->len);
575 key->algo = dtoh32(key->algo);
576 key->flags = dtoh32(key->flags);
577 key->rxiv.hi = dtoh32(key->rxiv.hi);
578 key->rxiv.lo = dtoh16(key->rxiv.lo);
579 key->iv_initialized = dtoh32(key->iv_initialized);
583 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
590 memset(&ioc, 0, sizeof(ioc));
594 strcpy(ifr.ifr_name, dev->name);
595 ifr.ifr_data = (caddr_t)&ioc;
599 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
606 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
607 enum nl80211_iftype type, u32 *flags,
608 struct vif_params *params)
610 struct wl_priv *wl = wiphy_to_wl(wiphy);
611 struct wireless_dev *wdev;
618 case NL80211_IFTYPE_MONITOR:
619 case NL80211_IFTYPE_WDS:
620 WL_ERR(("type (%d) : currently we do not support this type\n",
623 case NL80211_IFTYPE_ADHOC:
624 wl->conf->mode = WL_MODE_IBSS;
626 case NL80211_IFTYPE_STATION:
627 wl->conf->mode = WL_MODE_BSS;
633 infra = htod32(infra);
635 wdev = ndev->ieee80211_ptr;
637 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
638 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
640 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
643 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
645 WL_ERR(("WLC_SET_AP error (%d)\n", err));
649 /* -EINPROGRESS: Call commit handler */
653 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
655 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
656 params->bss_type = DOT11_BSSTYPE_ANY;
657 params->scan_type = 0;
658 params->nprobes = -1;
659 params->active_time = -1;
660 params->passive_time = -1;
661 params->home_time = -1;
662 params->channel_num = 0;
664 params->nprobes = htod32(params->nprobes);
665 params->active_time = htod32(params->active_time);
666 params->passive_time = htod32(params->passive_time);
667 params->home_time = htod32(params->home_time);
668 if (ssid && ssid->SSID_len)
669 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
674 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
675 s32 paramlen, void *bufptr, s32 buflen)
679 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
680 BUG_ON(unlikely(!iolen));
682 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
686 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
687 s32 paramlen, void *bufptr, s32 buflen)
691 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
692 BUG_ON(unlikely(!iolen));
694 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
698 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
701 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
702 struct wl_iscan_params *params;
705 if (ssid && ssid->SSID_len)
706 params_size += sizeof(struct wlc_ssid);
707 params = kzalloc(params_size, GFP_KERNEL);
708 if (unlikely(!params))
710 memset(params, 0, params_size);
711 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
713 wl_iscan_prep(¶ms->params, ssid);
715 params->version = htod32(ISCAN_REQ_VERSION);
716 params->action = htod16(action);
717 params->scan_duration = htod16(0);
719 /* params_size += offsetof(wl_iscan_params_t, params); */
720 err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
721 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
724 WL_INFO(("system busy : iscan canceled\n"));
726 WL_ERR(("error (%d)\n", err));
733 static s32 wl_do_iscan(struct wl_priv *wl)
735 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
736 struct net_device *ndev = wl_to_ndev(wl);
737 struct wlc_ssid ssid;
741 /* Broadcast scan by default */
742 memset(&ssid, 0, sizeof(ssid));
744 iscan->state = WL_ISCAN_STATE_SCANING;
746 passive_scan = wl->active_scan ? 0 : 1;
747 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
748 &passive_scan, sizeof(passive_scan));
750 WL_DBG(("error (%d)\n", err));
754 wl->iscan_kickstart = true;
755 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
756 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
763 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
764 struct cfg80211_scan_request *request,
765 struct cfg80211_ssid *this_ssid)
767 struct wl_priv *wl = ndev_to_wl(ndev);
768 struct cfg80211_ssid *ssids;
769 struct wl_scan_req *sr = wl_to_sr(wl);
775 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
776 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
779 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
780 WL_ERR(("Scanning being aborted : status (%d)\n",
787 if (request) { /* scan bss */
788 ssids = request->ssids;
789 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) { /* for
791 * ssids->ssid_len has
792 * non-zero(ssid string)
794 * Otherwise this is 0.
795 * we do not iscan for
796 * specific scan request
800 } else { /* scan in ibss */
801 /* we don't do iscan in ibss */
804 wl->scan_request = request;
805 set_bit(WL_STATUS_SCANNING, &wl->status);
807 err = wl_do_iscan(wl);
813 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
814 ssids->ssid, ssids->ssid_len));
815 memset(&sr->ssid, 0, sizeof(sr->ssid));
817 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
818 if (sr->ssid.SSID_len) {
819 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
820 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
821 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
822 sr->ssid.SSID, sr->ssid.SSID_len));
825 WL_DBG(("Broadcast scan\n"));
827 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
828 passive_scan = wl->active_scan ? 0 : 1;
829 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
830 &passive_scan, sizeof(passive_scan));
832 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
836 err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
840 WL_INFO(("system busy : scan for \"%s\" "
841 "canceled\n", sr->ssid.SSID));
843 WL_ERR(("WLC_SCAN error (%d)\n", err));
853 clear_bit(WL_STATUS_SCANNING, &wl->status);
854 wl->scan_request = NULL;
859 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
860 struct cfg80211_scan_request *request)
865 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
867 WL_DBG(("scan error (%d)\n", err));
874 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
876 s8 buf[WLC_IOCTL_SMLEN];
881 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
882 BUG_ON(unlikely(!len));
884 err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
886 WL_ERR(("error (%d)\n", err));
893 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
896 s8 buf[WLC_IOCTL_SMLEN];
904 bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
906 BUG_ON(unlikely(!len));
907 err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
909 WL_ERR(("error (%d)\n", err));
911 *retval = dtoh32(var.val);
916 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
920 err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
922 WL_ERR(("Error (%d)\n", err));
928 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
932 err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
934 WL_ERR(("Error (%d)\n", err));
940 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
943 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
945 retry = htod32(retry);
946 err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
948 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
954 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
956 struct wl_priv *wl = wiphy_to_wl(wiphy);
957 struct net_device *ndev = wl_to_ndev(wl);
961 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
962 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
963 wl->conf->rts_threshold = wiphy->rts_threshold;
964 err = wl_set_rts(ndev, wl->conf->rts_threshold);
968 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
969 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
970 wl->conf->frag_threshold = wiphy->frag_threshold;
971 err = wl_set_frag(ndev, wl->conf->frag_threshold);
975 if (changed & WIPHY_PARAM_RETRY_LONG
976 && (wl->conf->retry_long != wiphy->retry_long)) {
977 wl->conf->retry_long = wiphy->retry_long;
978 err = wl_set_retry(ndev, wl->conf->retry_long, true);
982 if (changed & WIPHY_PARAM_RETRY_SHORT
983 && (wl->conf->retry_short != wiphy->retry_short)) {
984 wl->conf->retry_short = wiphy->retry_short;
985 err = wl_set_retry(ndev, wl->conf->retry_short, false);
995 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
996 struct cfg80211_ibss_params *params)
998 struct wl_priv *wl = wiphy_to_wl(wiphy);
999 struct cfg80211_bss *bss;
1000 struct ieee80211_channel *chan;
1001 struct wl_join_params join_params;
1002 struct cfg80211_ssid ssid;
1007 if (params->bssid) {
1008 WL_ERR(("Invalid bssid\n"));
1011 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1013 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1014 ssid.ssid_len = params->ssid_len;
1017 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1023 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1024 rtnl_unlock(); /* to allow scan_inform to paropagate
1025 to cfg80211 plane */
1026 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1027 till scan done.... */
1029 bss = cfg80211_get_ibss(wiphy, NULL,
1030 params->ssid, params->ssid_len);
1033 wl->ibss_starter = false;
1034 WL_DBG(("Found IBSS\n"));
1036 wl->ibss_starter = true;
1038 chan = params->channel;
1040 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1042 ** Join with specific BSSID and cached SSID
1043 ** If SSID is zero join based on BSSID only
1045 memset(&join_params, 0, sizeof(join_params));
1046 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1048 join_params.ssid.SSID_len = htod32(params->ssid_len);
1050 memcpy(&join_params.params.bssid, params->bssid,
1053 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1055 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1056 sizeof(join_params));
1057 if (unlikely(err)) {
1058 WL_ERR(("Error (%d)\n", err));
1064 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1066 struct wl_priv *wl = wiphy_to_wl(wiphy);
1076 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1078 struct wl_priv *wl = ndev_to_wl(dev);
1079 struct wl_security *sec;
1083 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1084 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1085 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1086 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1088 val = WPA_AUTH_DISABLED;
1089 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1090 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1091 if (unlikely(err)) {
1092 WL_ERR(("set wpa_auth failed (%d)\n", err));
1095 sec = wl_read_prof(wl, WL_PROF_SEC);
1096 sec->wpa_versions = sme->crypto.wpa_versions;
1101 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1103 struct wl_priv *wl = ndev_to_wl(dev);
1104 struct wl_security *sec;
1108 switch (sme->auth_type) {
1109 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1111 WL_DBG(("open system\n"));
1113 case NL80211_AUTHTYPE_SHARED_KEY:
1115 WL_DBG(("shared key\n"));
1117 case NL80211_AUTHTYPE_AUTOMATIC:
1119 WL_DBG(("automatic\n"));
1121 case NL80211_AUTHTYPE_NETWORK_EAP:
1122 WL_DBG(("network eap\n"));
1125 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1129 err = wl_dev_intvar_set(dev, "auth", val);
1130 if (unlikely(err)) {
1131 WL_ERR(("set auth failed (%d)\n", err));
1134 sec = wl_read_prof(wl, WL_PROF_SEC);
1135 sec->auth_type = sme->auth_type;
1140 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1142 struct wl_priv *wl = ndev_to_wl(dev);
1143 struct wl_security *sec;
1148 if (sme->crypto.n_ciphers_pairwise) {
1149 switch (sme->crypto.ciphers_pairwise[0]) {
1150 case WLAN_CIPHER_SUITE_WEP40:
1151 case WLAN_CIPHER_SUITE_WEP104:
1154 case WLAN_CIPHER_SUITE_TKIP:
1155 pval = TKIP_ENABLED;
1157 case WLAN_CIPHER_SUITE_CCMP:
1160 case WLAN_CIPHER_SUITE_AES_CMAC:
1164 WL_ERR(("invalid cipher pairwise (%d)\n",
1165 sme->crypto.ciphers_pairwise[0]));
1169 if (sme->crypto.cipher_group) {
1170 switch (sme->crypto.cipher_group) {
1171 case WLAN_CIPHER_SUITE_WEP40:
1172 case WLAN_CIPHER_SUITE_WEP104:
1175 case WLAN_CIPHER_SUITE_TKIP:
1176 gval = TKIP_ENABLED;
1178 case WLAN_CIPHER_SUITE_CCMP:
1181 case WLAN_CIPHER_SUITE_AES_CMAC:
1185 WL_ERR(("invalid cipher group (%d)\n",
1186 sme->crypto.cipher_group));
1191 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1192 err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1193 if (unlikely(err)) {
1194 WL_ERR(("error (%d)\n", err));
1198 sec = wl_read_prof(wl, WL_PROF_SEC);
1199 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1200 sec->cipher_group = sme->crypto.cipher_group;
1206 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1208 struct wl_priv *wl = ndev_to_wl(dev);
1209 struct wl_security *sec;
1213 if (sme->crypto.n_akm_suites) {
1214 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1215 if (unlikely(err)) {
1216 WL_ERR(("could not get wpa_auth (%d)\n", err));
1219 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1220 switch (sme->crypto.akm_suites[0]) {
1221 case WLAN_AKM_SUITE_8021X:
1222 val = WPA_AUTH_UNSPECIFIED;
1224 case WLAN_AKM_SUITE_PSK:
1228 WL_ERR(("invalid cipher group (%d)\n",
1229 sme->crypto.cipher_group));
1232 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1233 switch (sme->crypto.akm_suites[0]) {
1234 case WLAN_AKM_SUITE_8021X:
1235 val = WPA2_AUTH_UNSPECIFIED;
1237 case WLAN_AKM_SUITE_PSK:
1238 val = WPA2_AUTH_PSK;
1241 WL_ERR(("invalid cipher group (%d)\n",
1242 sme->crypto.cipher_group));
1247 WL_DBG(("setting wpa_auth to %d\n", val));
1248 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1249 if (unlikely(err)) {
1250 WL_ERR(("could not set wpa_auth (%d)\n", err));
1254 sec = wl_read_prof(wl, WL_PROF_SEC);
1255 sec->wpa_auth = sme->crypto.akm_suites[0];
1261 wl_set_set_sharedkey(struct net_device *dev,
1262 struct cfg80211_connect_params *sme)
1264 struct wl_priv *wl = ndev_to_wl(dev);
1265 struct wl_security *sec;
1266 struct wl_wsec_key key;
1270 WL_DBG(("key len (%d)\n", sme->key_len));
1272 sec = wl_read_prof(wl, WL_PROF_SEC);
1273 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1274 sec->wpa_versions, sec->cipher_pairwise));
1276 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1277 NL80211_WPA_VERSION_2))
1278 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1279 WLAN_CIPHER_SUITE_WEP104))) {
1280 memset(&key, 0, sizeof(key));
1281 key.len = (u32) sme->key_len;
1282 key.index = (u32) sme->key_idx;
1283 if (unlikely(key.len > sizeof(key.data))) {
1284 WL_ERR(("Too long key length (%u)\n", key.len));
1287 memcpy(key.data, sme->key, key.len);
1288 key.flags = WL_PRIMARY_KEY;
1289 switch (sec->cipher_pairwise) {
1290 case WLAN_CIPHER_SUITE_WEP40:
1291 key.algo = CRYPTO_ALGO_WEP1;
1293 case WLAN_CIPHER_SUITE_WEP104:
1294 key.algo = CRYPTO_ALGO_WEP128;
1297 WL_ERR(("Invalid algorithm (%d)\n",
1298 sme->crypto.ciphers_pairwise[0]));
1301 /* Set the new key/index */
1302 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1303 key.len, key.index, key.algo));
1304 WL_DBG(("key \"%s\"\n", key.data));
1305 swap_key_from_BE(&key);
1306 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1308 if (unlikely(err)) {
1309 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1312 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1313 WL_DBG(("set auth_type to shared key\n"));
1314 val = 1; /* shared key */
1315 err = wl_dev_intvar_set(dev, "auth", val);
1316 if (unlikely(err)) {
1317 WL_ERR(("set auth failed (%d)\n", err));
1327 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1328 struct cfg80211_connect_params *sme)
1330 struct wl_priv *wl = wiphy_to_wl(wiphy);
1331 struct ieee80211_channel *chan = sme->channel;
1332 struct wl_join_params join_params;
1333 size_t join_params_size;
1338 if (unlikely(!sme->ssid)) {
1339 WL_ERR(("Invalid ssid\n"));
1343 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1344 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
1345 chan->center_freq));
1347 WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
1348 err = wl_set_wpa_version(dev, sme);
1352 err = wl_set_auth_type(dev, sme);
1356 err = wl_set_set_cipher(dev, sme);
1360 err = wl_set_key_mgmt(dev, sme);
1364 err = wl_set_set_sharedkey(dev, sme);
1368 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1370 ** Join with specific BSSID and cached SSID
1371 ** If SSID is zero join based on BSSID only
1373 memset(&join_params, 0, sizeof(join_params));
1374 join_params_size = sizeof(join_params.ssid);
1376 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1377 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1378 join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
1379 wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1380 memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1382 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1383 WL_DBG(("join_param_size %d\n", join_params_size));
1385 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1386 WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
1387 join_params.ssid.SSID_len));
1389 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1390 if (unlikely(err)) {
1391 WL_ERR(("error (%d)\n", err));
1394 set_bit(WL_STATUS_CONNECTING, &wl->status);
1400 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1403 struct wl_priv *wl = wiphy_to_wl(wiphy);
1408 WL_DBG(("Reason %d\n", reason_code));
1410 act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
1412 scbval.val = reason_code;
1413 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1414 scbval.val = htod32(scbval.val);
1415 err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1417 if (unlikely(err)) {
1418 WL_ERR(("error (%d)\n", err));
1427 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1428 enum nl80211_tx_power_setting type, s32 dbm)
1431 struct wl_priv *wl = wiphy_to_wl(wiphy);
1432 struct net_device *ndev = wl_to_ndev(wl);
1439 case NL80211_TX_POWER_AUTOMATIC:
1441 case NL80211_TX_POWER_LIMITED:
1443 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1447 case NL80211_TX_POWER_FIXED:
1449 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1454 /* Make sure radio is off or on as far as software is concerned */
1455 disable = WL_RADIO_SW_DISABLE << 16;
1456 disable = htod32(disable);
1457 err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1458 if (unlikely(err)) {
1459 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1466 txpwrmw = (u16) dbm;
1467 err = wl_dev_intvar_set(ndev, "qtxpower",
1468 (s32) (bcm_mw_to_qdbm(txpwrmw)));
1469 if (unlikely(err)) {
1470 WL_ERR(("qtxpower error (%d)\n", err));
1473 wl->conf->tx_power = dbm;
1478 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1480 struct wl_priv *wl = wiphy_to_wl(wiphy);
1481 struct net_device *ndev = wl_to_ndev(wl);
1487 err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1488 if (unlikely(err)) {
1489 WL_ERR(("error (%d)\n", err));
1492 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1493 *dbm = (s32) bcm_qdbm_to_mw(result);
1499 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1506 WL_DBG(("key index (%d)\n", key_idx));
1509 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1510 if (unlikely(err)) {
1511 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1514 wsec = dtoh32(wsec);
1515 if (wsec & WEP_ENABLED) {
1516 /* Just select a new current key */
1517 index = (u32) key_idx;
1518 index = htod32(index);
1519 err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
1521 if (unlikely(err)) {
1522 WL_ERR(("error (%d)\n", err));
1529 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1530 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1532 struct wl_wsec_key key;
1535 memset(&key, 0, sizeof(key));
1536 key.index = (u32) key_idx;
1537 /* Instead of bcast for ea address for default wep keys,
1538 driver needs it to be Null */
1539 if (!ETHER_ISMULTI(mac_addr))
1540 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1541 key.len = (u32) params->key_len;
1542 /* check for key index change */
1545 swap_key_from_BE(&key);
1546 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1547 if (unlikely(err)) {
1548 WL_ERR(("key delete error (%d)\n", err));
1552 if (key.len > sizeof(key.data)) {
1553 WL_ERR(("Invalid key length (%d)\n", key.len));
1557 WL_DBG(("Setting the key index %d\n", key.index));
1558 memcpy(key.data, params->key, key.len);
1560 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1562 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1563 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1564 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1567 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1568 if (params->seq && params->seq_len == 6) {
1571 ivptr = (u8 *) params->seq;
1572 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1573 (ivptr[3] << 8) | ivptr[2];
1574 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1575 key.iv_initialized = true;
1578 switch (params->cipher) {
1579 case WLAN_CIPHER_SUITE_WEP40:
1580 key.algo = CRYPTO_ALGO_WEP1;
1581 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1583 case WLAN_CIPHER_SUITE_WEP104:
1584 key.algo = CRYPTO_ALGO_WEP128;
1585 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1587 case WLAN_CIPHER_SUITE_TKIP:
1588 key.algo = CRYPTO_ALGO_TKIP;
1589 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1591 case WLAN_CIPHER_SUITE_AES_CMAC:
1592 key.algo = CRYPTO_ALGO_AES_CCM;
1593 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1595 case WLAN_CIPHER_SUITE_CCMP:
1596 key.algo = CRYPTO_ALGO_AES_CCM;
1597 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1600 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1603 swap_key_from_BE(&key);
1605 dhd_wait_pend8021x(dev);
1606 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1607 if (unlikely(err)) {
1608 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1616 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1617 u8 key_idx, const u8 *mac_addr,
1618 struct key_params *params)
1620 struct wl_wsec_key key;
1625 WL_DBG(("key index (%d)\n", key_idx));
1629 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1630 memset(&key, 0, sizeof(key));
1632 key.len = (u32) params->key_len;
1633 key.index = (u32) key_idx;
1635 if (unlikely(key.len > sizeof(key.data))) {
1636 WL_ERR(("Too long key length (%u)\n", key.len));
1639 memcpy(key.data, params->key, key.len);
1641 key.flags = WL_PRIMARY_KEY;
1642 switch (params->cipher) {
1643 case WLAN_CIPHER_SUITE_WEP40:
1644 key.algo = CRYPTO_ALGO_WEP1;
1645 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1647 case WLAN_CIPHER_SUITE_WEP104:
1648 key.algo = CRYPTO_ALGO_WEP128;
1649 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1651 case WLAN_CIPHER_SUITE_TKIP:
1652 key.algo = CRYPTO_ALGO_TKIP;
1653 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1655 case WLAN_CIPHER_SUITE_AES_CMAC:
1656 key.algo = CRYPTO_ALGO_AES_CCM;
1657 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1659 case WLAN_CIPHER_SUITE_CCMP:
1660 key.algo = CRYPTO_ALGO_AES_CCM;
1661 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1664 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1668 /* Set the new key/index */
1669 swap_key_from_BE(&key);
1670 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1671 if (unlikely(err)) {
1672 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1677 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1678 if (unlikely(err)) {
1679 WL_ERR(("get wsec error (%d)\n", err));
1682 wsec &= ~(WEP_ENABLED);
1684 err = wl_dev_intvar_set(dev, "wsec", wsec);
1685 if (unlikely(err)) {
1686 WL_ERR(("set wsec error (%d)\n", err));
1690 val = 1; /* assume shared key. otherwise 0 */
1692 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1693 if (unlikely(err)) {
1694 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1701 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1702 u8 key_idx, const u8 *mac_addr)
1704 struct wl_wsec_key key;
1710 memset(&key, 0, sizeof(key));
1712 key.index = (u32) key_idx;
1713 key.flags = WL_PRIMARY_KEY;
1714 key.algo = CRYPTO_ALGO_OFF;
1716 WL_DBG(("key index (%d)\n", key_idx));
1717 /* Set the new key/index */
1718 swap_key_from_BE(&key);
1719 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1720 if (unlikely(err)) {
1721 if (err == -EINVAL) {
1722 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1723 /* we ignore this key index in this case */
1724 WL_DBG(("invalid key index (%d)\n", key_idx));
1727 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1733 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1734 if (unlikely(err)) {
1735 WL_ERR(("get wsec error (%d)\n", err));
1738 wsec &= ~(WEP_ENABLED);
1740 err = wl_dev_intvar_set(dev, "wsec", wsec);
1741 if (unlikely(err)) {
1742 WL_ERR(("set wsec error (%d)\n", err));
1746 val = 0; /* assume open key. otherwise 1 */
1748 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1749 if (unlikely(err)) {
1750 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1757 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1758 u8 key_idx, const u8 *mac_addr, void *cookie,
1759 void (*callback) (void *cookie, struct key_params * params))
1761 struct key_params params;
1762 struct wl_wsec_key key;
1763 struct wl_priv *wl = wiphy_to_wl(wiphy);
1764 struct wl_security *sec;
1768 WL_DBG(("key index (%d)\n", key_idx));
1771 memset(&key, 0, sizeof(key));
1772 key.index = key_idx;
1773 swap_key_to_BE(&key);
1774 memset(¶ms, 0, sizeof(params));
1775 params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
1776 memcpy(params.key, key.data, params.key_len);
1778 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1779 if (unlikely(err)) {
1780 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1783 wsec = dtoh32(wsec);
1786 sec = wl_read_prof(wl, WL_PROF_SEC);
1787 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1788 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1789 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1790 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1791 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1792 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1796 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1797 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1800 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1801 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1804 WL_ERR(("Invalid algo (0x%x)\n", wsec));
1808 callback(cookie, ¶ms);
1813 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1814 struct net_device *dev, u8 key_idx)
1816 WL_INFO(("Not supported\n"));
1822 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1823 u8 *mac, struct station_info *sinfo)
1825 struct wl_priv *wl = wiphy_to_wl(wiphy);
1833 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
1834 WL_ERR(("Wrong Mac address\n"));
1838 /* Report the current tx rate */
1839 err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1841 WL_ERR(("Could not get rate (%d)\n", err));
1843 rate = dtoh32(rate);
1844 sinfo->filled |= STATION_INFO_TX_BITRATE;
1845 sinfo->txrate.legacy = rate * 5;
1846 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1849 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1851 err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1853 if (unlikely(err)) {
1854 WL_ERR(("Could not get rssi (%d)\n", err));
1857 rssi = dtoh32(scb_val.val);
1858 sinfo->filled |= STATION_INFO_SIGNAL;
1859 sinfo->signal = rssi;
1860 WL_DBG(("RSSI %d dBm\n", rssi));
1867 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1868 bool enabled, s32 timeout)
1874 pm = enabled ? PM_FAST : PM_OFF;
1876 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1877 err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1878 if (unlikely(err)) {
1880 WL_DBG(("net_device is not ready yet\n"));
1882 WL_ERR(("error (%d)\n", err));
1888 static __used u32 wl_find_msb(u16 bit16)
1892 if (bit16 & 0xff00) {
1916 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1918 const struct cfg80211_bitrate_mask *mask)
1920 struct wl_rateset rateset;
1929 /* addr param is always NULL. ignore it */
1930 /* Get current rateset */
1931 err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1933 if (unlikely(err)) {
1934 WL_ERR(("could not get current rateset (%d)\n", err));
1938 rateset.count = dtoh32(rateset.count);
1940 legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
1942 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1944 val = wl_g_rates[legacy - 1].bitrate * 100000;
1946 if (val < rateset.count) {
1947 /* Select rate by rateset index */
1948 rate = rateset.rates[val] & 0x7f;
1950 /* Specified rate in bps */
1951 rate = val / 500000;
1954 WL_DBG(("rate %d mbps\n", (rate / 2)));
1958 * Set rate override,
1959 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1961 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1962 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1963 if (unlikely(err_bg && err_a)) {
1964 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
1965 return err_bg | err_a;
1971 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
1976 wl_invoke_iscan(wiphy_to_wl(wiphy));
1981 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
1983 struct wl_priv *wl = wiphy_to_wl(wiphy);
1984 struct net_device *ndev = wl_to_ndev(wl);
1989 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1991 if (wl->scan_request) {
1992 cfg80211_scan_done(wl->scan_request, true); /* true means
1994 wl_set_mpc(ndev, 1);
1995 wl->scan_request = NULL;
1997 clear_bit(WL_STATUS_SCANNING, &wl->status);
1998 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2004 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2009 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2010 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2011 WL_DBG(("PMKID[%d]: %pM =\n", i,
2012 &pmk_list->pmkids.pmkid[i].BSSID));
2013 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2014 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2018 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2026 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2027 struct cfg80211_pmksa *pmksa)
2029 struct wl_priv *wl = wiphy_to_wl(wiphy);
2034 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2035 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2038 if (i < WL_NUM_PMKIDS_MAX) {
2039 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2041 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2043 if (i == wl->pmk_list->pmkids.npmkid)
2044 wl->pmk_list->pmkids.npmkid++;
2048 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2049 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2050 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2052 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2056 err = wl_update_pmklist(dev, wl->pmk_list, err);
2062 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2063 struct cfg80211_pmksa *pmksa)
2065 struct wl_priv *wl = wiphy_to_wl(wiphy);
2066 struct _pmkid_list pmkid;
2071 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2072 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2074 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2075 &pmkid.pmkid[0].BSSID));
2076 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2077 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2080 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2082 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2086 if ((wl->pmk_list->pmkids.npmkid > 0)
2087 && (i < wl->pmk_list->pmkids.npmkid)) {
2088 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2089 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2090 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2091 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2093 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2094 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2097 wl->pmk_list->pmkids.npmkid--;
2102 err = wl_update_pmklist(dev, wl->pmk_list, err);
2109 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2111 struct wl_priv *wl = wiphy_to_wl(wiphy);
2115 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2116 err = wl_update_pmklist(dev, wl->pmk_list, err);
2121 static struct cfg80211_ops wl_cfg80211_ops = {
2122 .change_virtual_intf = wl_cfg80211_change_iface,
2123 .scan = wl_cfg80211_scan,
2124 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2125 .join_ibss = wl_cfg80211_join_ibss,
2126 .leave_ibss = wl_cfg80211_leave_ibss,
2127 .get_station = wl_cfg80211_get_station,
2128 .set_tx_power = wl_cfg80211_set_tx_power,
2129 .get_tx_power = wl_cfg80211_get_tx_power,
2130 .add_key = wl_cfg80211_add_key,
2131 .del_key = wl_cfg80211_del_key,
2132 .get_key = wl_cfg80211_get_key,
2133 .set_default_key = wl_cfg80211_config_default_key,
2134 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2135 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2136 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2137 .connect = wl_cfg80211_connect,
2138 .disconnect = wl_cfg80211_disconnect,
2139 .suspend = wl_cfg80211_suspend,
2140 .resume = wl_cfg80211_resume,
2141 .set_pmksa = wl_cfg80211_set_pmksa,
2142 .del_pmksa = wl_cfg80211_del_pmksa,
2143 .flush_pmksa = wl_cfg80211_flush_pmksa
2146 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2152 return NL80211_IFTYPE_STATION;
2154 return NL80211_IFTYPE_ADHOC;
2156 return NL80211_IFTYPE_UNSPECIFIED;
2162 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2165 struct wireless_dev *wdev;
2168 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2169 if (unlikely(!wdev)) {
2170 WL_ERR(("Could not allocate wireless device\n"));
2171 return ERR_PTR(-ENOMEM);
2174 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2175 if (unlikely(!wdev->wiphy)) {
2176 WL_ERR(("Couldn not allocate wiphy device\n"));
2180 set_wiphy_dev(wdev->wiphy, dev);
2181 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2182 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2183 wdev->wiphy->interface_modes =
2184 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2185 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2186 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2187 * it as 11a by default.
2188 * This will be updated with
2191 * if phy has 11n capability
2193 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2194 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2195 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2196 #ifndef WL_POWERSAVE_DISABLED
2197 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2202 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2203 #endif /* !WL_POWERSAVE_DISABLED */
2204 err = wiphy_register(wdev->wiphy);
2205 if (unlikely(err < 0)) {
2206 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2207 goto wiphy_register_out;
2212 wiphy_free(wdev->wiphy);
2217 return ERR_PTR(err);
2220 static void wl_free_wdev(struct wl_priv *wl)
2222 struct wireless_dev *wdev = wl_to_wdev(wl);
2224 if (unlikely(!wdev)) {
2225 WL_ERR(("wdev is invalid\n"));
2228 wiphy_unregister(wdev->wiphy);
2229 wiphy_free(wdev->wiphy);
2231 wl_to_wdev(wl) = NULL;
2234 static s32 wl_inform_bss(struct wl_priv *wl)
2236 struct wl_scan_results *bss_list;
2237 struct wl_bss_info *bi = NULL; /* must be initialized */
2241 bss_list = wl->bss_list;
2242 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2243 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2244 bss_list->version));
2247 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2248 bi = next_bss(bss_list, bi);
2249 for_each_bss(bss_list, bi, i) {
2250 err = wl_inform_single_bss(wl, bi);
2257 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2259 struct wiphy *wiphy = wl_to_wiphy(wl);
2260 struct ieee80211_mgmt *mgmt;
2261 struct ieee80211_channel *channel;
2262 struct ieee80211_supported_band *band;
2263 struct wl_cfg80211_bss_info *notif_bss_info;
2264 struct wl_scan_req *sr = wl_to_sr(wl);
2265 struct beacon_proberesp *beacon_proberesp;
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 mgmt_type = wl->active_scan ?
2293 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
2294 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2295 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2298 beacon_proberesp = wl->active_scan ?
2299 (struct beacon_proberesp *)&mgmt->u.probe_resp :
2300 (struct beacon_proberesp *)&mgmt->u.beacon;
2301 beacon_proberesp->timestamp = 0;
2302 beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
2303 beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
2306 * wl_add_ie is not necessary because it can only add duplicated
2307 * SSID, rate information to frame_buf
2310 * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2311 * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2312 * bi->rateset.rates);
2314 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2315 wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
2316 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2317 notif_bss_info->frame_len =
2318 offsetof(struct ieee80211_mgmt,
2319 u.beacon.variable) + wl_get_ielen(wl);
2320 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2321 channel = ieee80211_get_channel(wiphy, freq);
2323 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
2325 notif_bss_info->rssi, notif_bss_info->channel,
2326 mgmt->u.beacon.capab_info, &bi->BSSID));
2328 signal = notif_bss_info->rssi * 100;
2329 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2331 (notif_bss_info->frame_len),
2332 signal, GFP_KERNEL))) {
2333 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2334 kfree(notif_bss_info);
2337 kfree(notif_bss_info);
2342 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2344 u32 event = ntoh32(e->event_type);
2345 u16 flags = ntoh16(e->flags);
2347 if (event == WLC_E_LINK) {
2348 if (flags & WLC_EVENT_MSG_LINK) {
2349 if (wl_is_ibssmode(wl)) {
2350 if (wl_is_ibssstarter(wl)) {
2361 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2363 u32 event = ntoh32(e->event_type);
2364 u16 flags = ntoh16(e->flags);
2366 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2368 } else if (event == WLC_E_LINK) {
2369 if (!(flags & WLC_EVENT_MSG_LINK))
2376 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2378 u32 event = ntoh32(e->event_type);
2379 u32 status = ntoh32(e->status);
2381 if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2382 if (status == WLC_E_STATUS_NO_NETWORKS)
2390 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2391 const wl_event_msg_t *e, void *data)
2396 if (wl_is_linkup(wl, e)) {
2398 if (wl_is_ibssmode(wl)) {
2399 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2401 WL_DBG(("joined in IBSS network\n"));
2403 wl_bss_connect_done(wl, ndev, e, data, true);
2404 WL_DBG(("joined in BSS network \"%s\"\n",
2405 ((struct wlc_ssid *)
2406 wl_read_prof(wl, WL_PROF_SSID))->SSID));
2409 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2410 } else if (wl_is_linkdown(wl, e)) {
2411 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2412 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2414 wl_init_prof(wl->profile);
2415 } else if (wl_is_nonetwork(wl, e)) {
2416 wl_bss_connect_done(wl, ndev, e, data, false);
2423 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2424 const wl_event_msg_t *e, void *data)
2429 wl_bss_roaming_done(wl, ndev, e, data);
2431 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2437 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2439 struct wl_priv *wl = ndev_to_wl(dev);
2442 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2443 BUG_ON(unlikely(!buflen));
2445 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2449 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2452 struct wl_priv *wl = ndev_to_wl(dev);
2456 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2457 BUG_ON(unlikely(!len));
2458 err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2460 if (unlikely(err)) {
2461 WL_ERR(("error (%d)\n", err));
2464 memcpy(buf, wl->ioctl_buf, buf_len);
2469 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2471 struct net_device *ndev = wl_to_ndev(wl);
2472 struct wl_assoc_ielen *assoc_info;
2473 struct wl_connect_info *conn_info = wl_to_conn(wl);
2478 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2480 if (unlikely(err)) {
2481 WL_ERR(("could not get assoc info (%d)\n", err));
2484 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2485 req_len = assoc_info->req_len;
2486 resp_len = assoc_info->resp_len;
2488 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2490 if (unlikely(err)) {
2491 WL_ERR(("could not get assoc req (%d)\n", err));
2494 conn_info->req_ie_len = req_len;
2496 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2498 conn_info->req_ie_len = 0;
2499 conn_info->req_ie = NULL;
2502 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2504 if (unlikely(err)) {
2505 WL_ERR(("could not get assoc resp (%d)\n", err));
2508 conn_info->resp_ie_len = resp_len;
2509 conn_info->resp_ie =
2510 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2512 conn_info->resp_ie_len = 0;
2513 conn_info->resp_ie = NULL;
2515 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2516 conn_info->resp_ie_len));
2521 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2522 size_t *join_params_size)
2524 chanspec_t chanspec = 0;
2527 join_params->params.chanspec_num = 1;
2528 join_params->params.chanspec_list[0] = ch;
2530 if (join_params->params.chanspec_list[0])
2531 chanspec |= WL_CHANSPEC_BAND_2G;
2533 chanspec |= WL_CHANSPEC_BAND_5G;
2535 chanspec |= WL_CHANSPEC_BW_20;
2536 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2538 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2539 join_params->params.chanspec_num * sizeof(chanspec_t);
2541 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2542 join_params->params.chanspec_list[0] |= chanspec;
2543 join_params->params.chanspec_list[0] =
2544 htodchanspec(join_params->params.chanspec_list[0]);
2546 join_params->params.chanspec_num =
2547 htod32(join_params->params.chanspec_num);
2549 WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
2550 join_params->params.chanspec_list[0], ch, chanspec));
2554 static s32 wl_update_bss_info(struct wl_priv *wl)
2556 struct cfg80211_bss *bss;
2557 struct wl_bss_info *bi;
2558 struct wlc_ssid *ssid;
2559 struct bcm_tlv *tim;
2560 u16 beacon_interval;
2566 if (wl_is_ibssmode(wl))
2569 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2571 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2572 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2573 WLAN_CAPABILITY_ESS);
2576 if (unlikely(!bss)) {
2577 WL_DBG(("Could not find the AP\n"));
2578 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2579 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2580 wl->extra_buf, WL_EXTRA_BUF_MAX);
2581 if (unlikely(err)) {
2582 WL_ERR(("Could not get bss info %d\n", err));
2583 goto update_bss_info_out;
2585 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2586 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2588 goto update_bss_info_out;
2590 err = wl_inform_single_bss(wl, bi);
2592 goto update_bss_info_out;
2594 ie = ((u8 *)bi) + bi->ie_offset;
2595 ie_len = bi->ie_length;
2596 beacon_interval = cpu_to_le16(bi->beacon_period);
2598 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
2599 ie = bss->information_elements;
2600 ie_len = bss->len_information_elements;
2601 beacon_interval = bss->beacon_interval;
2602 cfg80211_put_bss(bss);
2605 tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2607 dtim_period = tim->data[1];
2610 * active scan was done so we could not get dtim
2611 * information out of probe response.
2612 * so we speficially query dtim information to dongle.
2614 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD,
2615 &dtim_period, sizeof(dtim_period));
2616 if (unlikely(err)) {
2617 WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
2618 goto update_bss_info_out;
2622 wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
2623 wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2625 update_bss_info_out:
2631 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2632 const wl_event_msg_t *e, void *data)
2634 struct wl_connect_info *conn_info = wl_to_conn(wl);
2637 wl_get_assoc_ies(wl);
2638 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2639 wl_update_bss_info(wl);
2640 cfg80211_roamed(ndev,
2642 conn_info->req_ie, conn_info->req_ie_len,
2643 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2644 WL_DBG(("Report roaming result\n"));
2646 set_bit(WL_STATUS_CONNECTED, &wl->status);
2652 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2653 const wl_event_msg_t *e, void *data, bool completed)
2655 struct wl_connect_info *conn_info = wl_to_conn(wl);
2658 wl_get_assoc_ies(wl);
2659 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2660 wl_update_bss_info(wl);
2661 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2662 cfg80211_connect_result(ndev,
2665 conn_info->req_ie_len,
2667 conn_info->resp_ie_len,
2668 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2670 WL_DBG(("Report connect result - connection %s\n",
2671 completed ? "succeeded" : "failed"));
2673 cfg80211_roamed(ndev,
2675 conn_info->req_ie, conn_info->req_ie_len,
2676 conn_info->resp_ie, conn_info->resp_ie_len,
2678 WL_DBG(("Report roaming result\n"));
2680 set_bit(WL_STATUS_CONNECTED, &wl->status);
2686 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2687 const wl_event_msg_t *e, void *data)
2689 u16 flags = ntoh16(e->flags);
2690 enum nl80211_key_type key_type;
2693 if (flags & WLC_EVENT_MSG_GROUP)
2694 key_type = NL80211_KEYTYPE_GROUP;
2696 key_type = NL80211_KEYTYPE_PAIRWISE;
2698 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2706 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2707 const wl_event_msg_t *e, void *data)
2709 struct channel_info channel_inform;
2710 struct wl_scan_results *bss_list;
2711 u32 len = WL_SCAN_BUF_MAX;
2714 if (wl->iscan_on && wl->iscan_kickstart)
2715 return wl_wakeup_iscan(wl_to_iscan(wl));
2717 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2718 WL_ERR(("Scan complete while device not scanning\n"));
2721 if (unlikely(!wl->scan_request)) {
2724 err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2725 sizeof(channel_inform));
2726 if (unlikely(err)) {
2727 WL_ERR(("scan busy (%d)\n", err));
2730 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2731 if (unlikely(channel_inform.scan_channel)) {
2733 WL_DBG(("channel_inform.scan_channel (%d)\n",
2734 channel_inform.scan_channel));
2736 wl->bss_list = wl->scan_results;
2737 bss_list = wl->bss_list;
2738 memset(bss_list, 0, len);
2739 bss_list->buflen = htod32(len);
2740 err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
2741 if (unlikely(err)) {
2742 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2746 bss_list->buflen = dtoh32(bss_list->buflen);
2747 bss_list->version = dtoh32(bss_list->version);
2748 bss_list->count = dtoh32(bss_list->count);
2750 err = wl_inform_bss(wl);
2755 if (wl->scan_request) {
2756 cfg80211_scan_done(wl->scan_request, false);
2757 wl_set_mpc(ndev, 1);
2758 wl->scan_request = NULL;
2764 static void wl_init_conf(struct wl_conf *conf)
2766 conf->mode = (u32)-1;
2767 conf->frag_threshold = (u32)-1;
2768 conf->rts_threshold = (u32)-1;
2769 conf->retry_short = (u32)-1;
2770 conf->retry_long = (u32)-1;
2771 conf->tx_power = -1;
2774 static void wl_init_prof(struct wl_profile *prof)
2776 memset(prof, 0, sizeof(*prof));
2779 static void wl_init_eloop_handler(struct wl_event_loop *el)
2781 memset(el, 0, sizeof(*el));
2782 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2783 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2784 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2785 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2786 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2787 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2788 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2789 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2790 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2791 el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2794 static s32 wl_init_priv_mem(struct wl_priv *wl)
2796 wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2797 if (unlikely(!wl->scan_results)) {
2798 WL_ERR(("Scan results alloc failed\n"));
2799 goto init_priv_mem_out;
2801 wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2802 if (unlikely(!wl->conf)) {
2803 WL_ERR(("wl_conf alloc failed\n"));
2804 goto init_priv_mem_out;
2806 wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2807 if (unlikely(!wl->profile)) {
2808 WL_ERR(("wl_profile alloc failed\n"));
2809 goto init_priv_mem_out;
2811 wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2812 if (unlikely(!wl->bss_info)) {
2813 WL_ERR(("Bss information alloc failed\n"));
2814 goto init_priv_mem_out;
2816 wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2817 if (unlikely(!wl->scan_req_int)) {
2818 WL_ERR(("Scan req alloc failed\n"));
2819 goto init_priv_mem_out;
2821 wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2822 if (unlikely(!wl->ioctl_buf)) {
2823 WL_ERR(("Ioctl buf alloc failed\n"));
2824 goto init_priv_mem_out;
2826 wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2827 if (unlikely(!wl->extra_buf)) {
2828 WL_ERR(("Extra buf alloc failed\n"));
2829 goto init_priv_mem_out;
2831 wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2832 if (unlikely(!wl->iscan)) {
2833 WL_ERR(("Iscan buf alloc failed\n"));
2834 goto init_priv_mem_out;
2836 wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2837 if (unlikely(!wl->fw)) {
2838 WL_ERR(("fw object alloc failed\n"));
2839 goto init_priv_mem_out;
2841 wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2842 if (unlikely(!wl->pmk_list)) {
2843 WL_ERR(("pmk list alloc failed\n"));
2844 goto init_priv_mem_out;
2850 wl_deinit_priv_mem(wl);
2855 static void wl_deinit_priv_mem(struct wl_priv *wl)
2857 kfree(wl->scan_results);
2858 wl->scan_results = NULL;
2859 kfree(wl->bss_info);
2860 wl->bss_info = NULL;
2865 kfree(wl->scan_req_int);
2866 wl->scan_req_int = NULL;
2867 kfree(wl->ioctl_buf);
2868 wl->ioctl_buf = NULL;
2869 kfree(wl->extra_buf);
2870 wl->extra_buf = NULL;
2875 kfree(wl->pmk_list);
2876 wl->pmk_list = NULL;
2879 static s32 wl_create_event_handler(struct wl_priv *wl)
2881 sema_init(&wl->event_sync, 0);
2882 wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
2883 if (IS_ERR(wl->event_tsk)) {
2884 wl->event_tsk = NULL;
2885 WL_ERR(("failed to create event thread\n"));
2891 static void wl_destroy_event_handler(struct wl_priv *wl)
2893 if (wl->event_tsk) {
2894 send_sig(SIGTERM, wl->event_tsk, 1);
2895 kthread_stop(wl->event_tsk);
2896 wl->event_tsk = NULL;
2900 static void wl_term_iscan(struct wl_priv *wl)
2902 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2904 if (wl->iscan_on && iscan->tsk) {
2905 iscan->state = WL_ISCAN_STATE_IDLE;
2906 send_sig(SIGTERM, iscan->tsk, 1);
2907 kthread_stop(iscan->tsk);
2912 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2914 struct wl_priv *wl = iscan_to_wl(iscan);
2915 struct net_device *ndev = wl_to_ndev(wl);
2917 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2918 WL_ERR(("Scan complete while device not scanning\n"));
2921 if (likely(wl->scan_request)) {
2922 cfg80211_scan_done(wl->scan_request, aborted);
2923 wl_set_mpc(ndev, 1);
2924 wl->scan_request = NULL;
2926 wl->iscan_kickstart = false;
2929 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2931 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2932 WL_DBG(("wake up iscan\n"));
2941 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
2942 struct wl_scan_results **bss_list)
2944 struct wl_iscan_results list;
2945 struct wl_scan_results *results;
2946 struct wl_iscan_results *list_buf;
2949 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2950 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2951 results = &list_buf->results;
2952 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2953 results->version = 0;
2956 memset(&list, 0, sizeof(list));
2957 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2958 err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2959 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2961 if (unlikely(err)) {
2962 WL_ERR(("error (%d)\n", err));
2965 results->buflen = dtoh32(results->buflen);
2966 results->version = dtoh32(results->version);
2967 results->count = dtoh32(results->count);
2968 WL_DBG(("results->count = %d\n", results->count));
2969 WL_DBG(("results->buflen = %d\n", results->buflen));
2970 *status = dtoh32(list_buf->status);
2971 *bss_list = results;
2976 static s32 wl_iscan_done(struct wl_priv *wl)
2978 struct wl_iscan_ctrl *iscan = wl->iscan;
2981 iscan->state = WL_ISCAN_STATE_IDLE;
2984 wl_notify_iscan_complete(iscan, false);
2990 static s32 wl_iscan_pending(struct wl_priv *wl)
2992 struct wl_iscan_ctrl *iscan = wl->iscan;
2995 /* Reschedule the timer */
2996 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2997 iscan->timer_on = 1;
3002 static s32 wl_iscan_inprogress(struct wl_priv *wl)
3004 struct wl_iscan_ctrl *iscan = wl->iscan;
3009 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
3011 /* Reschedule the timer */
3012 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3013 iscan->timer_on = 1;
3018 static s32 wl_iscan_aborted(struct wl_priv *wl)
3020 struct wl_iscan_ctrl *iscan = wl->iscan;
3023 iscan->state = WL_ISCAN_STATE_IDLE;
3025 wl_notify_iscan_complete(iscan, true);
3031 static s32 wl_iscan_thread(void *data)
3033 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3034 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3035 struct wl_priv *wl = iscan_to_wl(iscan);
3036 struct wl_iscan_eloop *el = &iscan->el;
3040 sched_setscheduler(current, SCHED_FIFO, ¶m);
3041 allow_signal(SIGTERM);
3042 status = WL_SCAN_RESULTS_PARTIAL;
3043 while (likely(!down_interruptible(&iscan->sync))) {
3044 if (kthread_should_stop())
3046 if (iscan->timer_on) {
3047 del_timer_sync(&iscan->timer);
3048 iscan->timer_on = 0;
3051 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
3052 if (unlikely(err)) {
3053 status = WL_SCAN_RESULTS_ABORTED;
3054 WL_ERR(("Abort iscan\n"));
3057 el->handler[status] (wl);
3059 if (iscan->timer_on) {
3060 del_timer_sync(&iscan->timer);
3061 iscan->timer_on = 0;
3063 WL_DBG(("%s was terminated\n", __func__));
3068 static void wl_iscan_timer(unsigned long data)
3070 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3073 iscan->timer_on = 0;
3074 WL_DBG(("timer expired\n"));
3075 wl_wakeup_iscan(iscan);
3079 static s32 wl_invoke_iscan(struct wl_priv *wl)
3081 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3084 if (wl->iscan_on && !iscan->tsk) {
3085 iscan->state = WL_ISCAN_STATE_IDLE;
3086 sema_init(&iscan->sync, 0);
3087 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3088 if (IS_ERR(iscan->tsk)) {
3089 WL_ERR(("Could not create iscan thread\n"));
3098 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
3100 memset(el, 0, sizeof(*el));
3101 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
3102 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
3103 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
3104 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
3105 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
3108 static s32 wl_init_iscan(struct wl_priv *wl)
3110 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3114 iscan->dev = wl_to_ndev(wl);
3115 iscan->state = WL_ISCAN_STATE_IDLE;
3116 wl_init_iscan_eloop(&iscan->el);
3117 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3118 init_timer(&iscan->timer);
3119 iscan->timer.data = (unsigned long) iscan;
3120 iscan->timer.function = wl_iscan_timer;
3121 sema_init(&iscan->sync, 0);
3122 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3123 if (IS_ERR(iscan->tsk)) {
3124 WL_ERR(("Could not create iscan thread\n"));
3134 static void wl_init_fw(struct wl_fw_ctrl *fw)
3136 fw->status = 0; /* init fw loading status.
3137 0 means nothing was loaded yet */
3140 static s32 wl_init_priv(struct wl_priv *wl)
3142 struct wiphy *wiphy = wl_to_wiphy(wl);
3145 wl->scan_request = NULL;
3146 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3147 wl->iscan_on = true; /* iscan on & off switch.
3148 we enable iscan per default */
3149 wl->roam_on = false; /* roam on & off switch.
3150 we enable roam per default */
3152 wl->iscan_kickstart = false;
3153 wl->active_scan = true; /* we do active scan for
3154 specific scan per default */
3155 wl->dongle_up = false; /* dongle is not up yet */
3157 err = wl_init_priv_mem(wl);
3160 if (unlikely(wl_create_event_handler(wl)))
3162 wl_init_eloop_handler(&wl->el);
3163 mutex_init(&wl->usr_sync);
3164 err = wl_init_iscan(wl);
3168 wl_init_conf(wl->conf);
3169 wl_init_prof(wl->profile);
3175 static void wl_deinit_priv(struct wl_priv *wl)
3177 wl_destroy_event_handler(wl);
3178 wl->dongle_up = false; /* dongle down */
3182 wl_deinit_priv_mem(wl);
3185 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3187 struct wireless_dev *wdev;
3189 struct wl_iface *ci;
3192 if (unlikely(!ndev)) {
3193 WL_ERR(("ndev is invaild\n"));
3196 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3197 if (unlikely(!wl_cfg80211_dev)) {
3198 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3201 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
3202 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
3203 if (unlikely(IS_ERR(wdev)))
3206 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3207 wl = wdev_to_wl(wdev);
3210 ci = (struct wl_iface *)wl_to_ci(wl);
3212 ndev->ieee80211_ptr = wdev;
3213 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3214 wdev->netdev = ndev;
3215 err = wl_init_priv(wl);
3216 if (unlikely(err)) {
3217 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
3218 goto cfg80211_attach_out;
3220 wl_set_drvdata(wl_cfg80211_dev, ci);
3221 set_bit(WL_STATUS_READY, &wl->status);
3225 cfg80211_attach_out:
3230 void wl_cfg80211_detach(void)
3238 wl_set_drvdata(wl_cfg80211_dev, NULL);
3239 kfree(wl_cfg80211_dev);
3240 wl_cfg80211_dev = NULL;
3241 wl_clear_sdio_func();
3244 static void wl_wakeup_event(struct wl_priv *wl)
3246 up(&wl->event_sync);
3249 static s32 wl_event_handler(void *data)
3251 struct wl_priv *wl = (struct wl_priv *)data;
3252 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3253 struct wl_event_q *e;
3255 sched_setscheduler(current, SCHED_FIFO, ¶m);
3256 allow_signal(SIGTERM);
3257 while (likely(!down_interruptible(&wl->event_sync))) {
3258 if (kthread_should_stop())
3260 e = wl_deq_event(wl);
3262 WL_ERR(("eqeue empty..\n"));
3265 WL_DBG(("event type (%d)\n", e->etype));
3266 if (wl->el.handler[e->etype]) {
3267 wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3270 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
3274 WL_DBG(("%s was terminated\n", __func__));
3279 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
3281 u32 event_type = ntoh32(e->event_type);
3282 struct wl_priv *wl = ndev_to_wl(ndev);
3283 #if (WL_DBG_LEVEL > 0)
3284 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
3285 wl_dbg_estr[event_type] : (s8 *) "Unknown";
3286 #endif /* (WL_DBG_LEVEL > 0) */
3287 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
3288 if (likely(!wl_enq_event(wl, event_type, e, data)))
3289 wl_wakeup_event(wl);
3292 static void wl_init_eq(struct wl_priv *wl)
3294 wl_init_eq_lock(wl);
3295 INIT_LIST_HEAD(&wl->eq_list);
3298 static void wl_flush_eq(struct wl_priv *wl)
3300 struct wl_event_q *e;
3303 while (!list_empty(&wl->eq_list)) {
3304 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3305 list_del(&e->eq_list);
3312 * retrieve first queued event from head
3315 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3317 struct wl_event_q *e = NULL;
3320 if (likely(!list_empty(&wl->eq_list))) {
3321 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3322 list_del(&e->eq_list);
3330 ** push event to tail of the queue
3334 wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg,
3337 struct wl_event_q *e;
3340 e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
3342 WL_ERR(("event alloc failed\n"));
3347 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
3351 list_add_tail(&e->eq_list, &wl->eq_list);
3357 static void wl_put_event(struct wl_event_q *e)
3362 void wl_cfg80211_sdio_func(void *func)
3364 cfg80211_sdio_func = (struct sdio_func *)func;
3367 static void wl_clear_sdio_func(void)
3369 cfg80211_sdio_func = NULL;
3372 struct sdio_func *wl_cfg80211_get_sdio_func(void)
3374 return cfg80211_sdio_func;
3377 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
3384 case NL80211_IFTYPE_MONITOR:
3385 case NL80211_IFTYPE_WDS:
3386 WL_ERR(("type (%d) : currently we do not support this mode\n",
3390 case NL80211_IFTYPE_ADHOC:
3392 case NL80211_IFTYPE_STATION:
3397 WL_ERR(("invalid type (%d)\n", iftype));
3400 infra = htod32(infra);
3402 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
3403 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
3404 if (unlikely(err)) {
3405 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
3408 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
3409 if (unlikely(err)) {
3410 WL_ERR(("WLC_SET_AP error (%d)\n", err));
3414 return -EINPROGRESS;
3417 #ifndef EMBEDDED_PLATFORM
3418 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3426 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
3430 err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
3431 if (unlikely(err)) {
3432 WL_ERR(("WLC_UP error (%d)\n", err));
3437 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
3441 err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
3442 if (unlikely(err)) {
3443 WL_ERR(("WLC_SET_PM error (%d)\n", err));
3449 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
3451 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3455 /* Match Host and Dongle rx alignment */
3456 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3458 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3459 if (unlikely(err)) {
3460 WL_ERR(("txglomalign error (%d)\n", err));
3461 goto dongle_glom_out;
3463 /* disable glom option per default */
3464 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3465 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3466 if (unlikely(err)) {
3467 WL_ERR(("txglom error (%d)\n", err));
3468 goto dongle_glom_out;
3475 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3477 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3481 /* Setup timeout if Beacons are lost and roam is
3482 off to report link down */
3484 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
3486 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3487 if (unlikely(err)) {
3488 WL_ERR(("bcn_timeout error (%d)\n", err));
3489 goto dongle_rom_out;
3492 /* Enable/Disable built-in roaming to allow supplicant
3493 to take care of roaming */
3494 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
3495 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3496 if (unlikely(err)) {
3497 WL_ERR(("roam_off error (%d)\n", err));
3498 goto dongle_rom_out;
3504 static s32 wl_dongle_eventmsg(struct net_device *ndev)
3507 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3509 s8 eventmask[WL_EVENTING_MASK_LEN];
3512 /* Setup event_msgs */
3513 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3515 err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
3516 if (unlikely(err)) {
3517 WL_ERR(("Get event_msgs error (%d)\n", err));
3518 goto dongle_eventmsg_out;
3520 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3522 setbit(eventmask, WLC_E_SET_SSID);
3523 setbit(eventmask, WLC_E_PRUNE);
3524 setbit(eventmask, WLC_E_AUTH);
3525 setbit(eventmask, WLC_E_REASSOC);
3526 setbit(eventmask, WLC_E_REASSOC_IND);
3527 setbit(eventmask, WLC_E_DEAUTH_IND);
3528 setbit(eventmask, WLC_E_DISASSOC_IND);
3529 setbit(eventmask, WLC_E_DISASSOC);
3530 setbit(eventmask, WLC_E_JOIN);
3531 setbit(eventmask, WLC_E_ASSOC_IND);
3532 setbit(eventmask, WLC_E_PSK_SUP);
3533 setbit(eventmask, WLC_E_LINK);
3534 setbit(eventmask, WLC_E_NDIS_LINK);
3535 setbit(eventmask, WLC_E_MIC_ERROR);
3536 setbit(eventmask, WLC_E_PMKID_CACHE);
3537 setbit(eventmask, WLC_E_TXFAIL);
3538 setbit(eventmask, WLC_E_JOIN_START);
3539 setbit(eventmask, WLC_E_SCAN_COMPLETE);
3541 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3543 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3544 if (unlikely(err)) {
3545 WL_ERR(("Set event_msgs error (%d)\n", err));
3546 goto dongle_eventmsg_out;
3549 dongle_eventmsg_out:
3554 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3555 s32 scan_unassoc_time)
3559 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
3560 sizeof(scan_assoc_time));
3562 if (err == -EOPNOTSUPP) {
3563 WL_INFO(("Scan assoc time is not supported\n"));
3565 WL_ERR(("Scan assoc time error (%d)\n", err));
3567 goto dongle_scantime_out;
3569 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
3570 sizeof(scan_unassoc_time));
3572 if (err == -EOPNOTSUPP) {
3573 WL_INFO(("Scan unassoc time is not supported\n"));
3575 WL_ERR(("Scan unassoc time error (%d)\n", err));
3577 goto dongle_scantime_out;
3580 dongle_scantime_out:
3585 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
3587 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3591 /* Set ARP offload */
3592 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3593 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3595 if (err == -EOPNOTSUPP)
3596 WL_INFO(("arpoe is not supported\n"));
3598 WL_ERR(("arpoe error (%d)\n", err));
3600 goto dongle_offload_out;
3602 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3603 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3605 if (err == -EOPNOTSUPP)
3606 WL_INFO(("arp_ol is not supported\n"));
3608 WL_ERR(("arp_ol error (%d)\n", err));
3610 goto dongle_offload_out;
3617 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
3620 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3621 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3624 src = src + 2; /* Skip past 0x */
3625 if (strlen(src) % 2 != 0) {
3626 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3629 for (i = 0; *src != '\0'; i++) {
3631 strncpy(num, src, 2);
3633 dst[i] = (u8) simple_strtoul(num, NULL, 16);
3639 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
3641 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3644 struct wl_pkt_filter pkt_filter;
3645 struct wl_pkt_filter *pkt_filterp;
3653 /* add a default packet filter pattern */
3654 str = "pkt_filter_add";
3655 str_len = strlen(str);
3656 strncpy(buf, str, str_len);
3657 buf[str_len] = '\0';
3658 buf_len = str_len + 1;
3660 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3662 /* Parse packet filter id. */
3663 pkt_filter.id = htod32(100);
3665 /* Parse filter polarity. */
3666 pkt_filter.negate_match = htod32(0);
3668 /* Parse filter type. */
3669 pkt_filter.type = htod32(0);
3671 /* Parse pattern filter offset. */
3672 pkt_filter.u.pattern.offset = htod32(0);
3674 /* Parse pattern filter mask. */
3675 mask_size = htod32(wl_pattern_atoh("0xff",
3676 (char *)pkt_filterp->u.pattern.
3679 /* Parse pattern filter pattern. */
3680 pattern_size = htod32(wl_pattern_atoh("0x00",
3681 (char *)&pkt_filterp->u.pattern.
3682 mask_and_pattern[mask_size]));
3684 if (mask_size != pattern_size) {
3685 WL_ERR(("Mask and pattern not the same size\n"));
3687 goto dongle_filter_out;
3690 pkt_filter.u.pattern.size_bytes = mask_size;
3691 buf_len += WL_PKT_FILTER_FIXED_LEN;
3692 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3694 /* Keep-alive attributes are set in local
3695 * variable (keep_alive_pkt), and
3696 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3697 * guarantee that the buffer is properly aligned.
3699 memcpy((char *)pkt_filterp, &pkt_filter,
3700 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3702 err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
3704 if (err == -EOPNOTSUPP) {
3705 WL_INFO(("filter not supported\n"));
3707 WL_ERR(("filter (%d)\n", err));
3709 goto dongle_filter_out;
3712 /* set mode to allow pattern */
3713 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3715 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3717 if (err == -EOPNOTSUPP) {
3718 WL_INFO(("filter_mode not supported\n"));
3720 WL_ERR(("filter_mode (%d)\n", err));
3722 goto dongle_filter_out;
3728 #endif /* !EMBEDDED_PLATFORM */
3730 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
3733 #define DHD_SDALIGN 32
3735 struct net_device *ndev;
3736 struct wireless_dev *wdev;
3742 ndev = wl_to_ndev(wl);
3743 wdev = ndev->ieee80211_ptr;
3747 #ifndef EMBEDDED_PLATFORM
3748 err = wl_dongle_up(ndev, 0);
3750 goto default_conf_out;
3751 err = wl_dongle_country(ndev, 0);
3753 goto default_conf_out;
3754 err = wl_dongle_power(ndev, PM_FAST);
3756 goto default_conf_out;
3757 err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
3759 goto default_conf_out;
3760 err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
3762 goto default_conf_out;
3763 err = wl_dongle_eventmsg(ndev);
3765 goto default_conf_out;
3767 wl_dongle_scantime(ndev, 40, 80);
3768 wl_dongle_offload(ndev, 1, 0xf);
3769 wl_dongle_filter(ndev, 1);
3770 #endif /* !EMBEDDED_PLATFORM */
3772 err = wl_dongle_mode(ndev, wdev->iftype);
3773 if (unlikely(err && err != -EINPROGRESS))
3774 goto default_conf_out;
3775 err = wl_dongle_probecap(wl);
3777 goto default_conf_out;
3779 /* -EINPROGRESS: Call commit handler */
3785 wl->dongle_up = true;
3791 static s32 wl_update_wiphybands(struct wl_priv *wl)
3793 struct wiphy *wiphy;
3798 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
3800 if (unlikely(err)) {
3801 WL_ERR(("error (%d)\n", err));
3805 phy = ((char *)&phy_list)[1];
3806 WL_DBG(("%c phy\n", phy));
3807 if (phy == 'n' || phy == 'a') {
3808 wiphy = wl_to_wiphy(wl);
3809 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3815 static s32 __wl_cfg80211_up(struct wl_priv *wl)
3819 wl_debugfs_add_netdev_params(wl);
3821 err = wl_config_dongle(wl, false);
3825 wl_invoke_iscan(wl);
3826 set_bit(WL_STATUS_READY, &wl->status);
3830 static s32 __wl_cfg80211_down(struct wl_priv *wl)
3834 /* Check if cfg80211 interface is already down */
3835 if (!test_bit(WL_STATUS_READY, &wl->status))
3836 return err; /* it is even not ready */
3838 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3840 if (wl->scan_request) {
3841 cfg80211_scan_done(wl->scan_request, true); /* true
3843 /* wl_set_mpc(wl_to_ndev(wl), 1); */ /* BUG
3844 * this operation cannot help
3845 * but here because sdio
3846 * is already down through
3848 * Need to figure out how to
3849 * address this issue
3851 wl->scan_request = NULL;
3853 clear_bit(WL_STATUS_READY, &wl->status);
3854 clear_bit(WL_STATUS_SCANNING, &wl->status);
3855 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3856 clear_bit(WL_STATUS_CONNECTED, &wl->status);
3858 wl_debugfs_remove_netdev(wl);
3863 s32 wl_cfg80211_up(void)
3869 mutex_lock(&wl->usr_sync);
3870 err = __wl_cfg80211_up(wl);
3871 mutex_unlock(&wl->usr_sync);
3876 s32 wl_cfg80211_down(void)
3882 mutex_lock(&wl->usr_sync);
3883 err = __wl_cfg80211_down(wl);
3884 mutex_unlock(&wl->usr_sync);
3889 static s32 wl_dongle_probecap(struct wl_priv *wl)
3893 err = wl_update_wiphybands(wl);
3900 static void *wl_read_prof(struct wl_priv *wl, s32 item)
3904 return &wl->profile->sec;
3906 return &wl->profile->active;
3908 return &wl->profile->bssid;
3910 return &wl->profile->ssid;
3912 WL_ERR(("invalid item (%d)\n", item));
3917 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
3921 struct wlc_ssid *ssid;
3925 ssid = (wlc_ssid_t *) data;
3926 memset(wl->profile->ssid.SSID, 0,
3927 sizeof(wl->profile->ssid.SSID));
3928 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
3929 wl->profile->ssid.SSID_len = ssid->SSID_len;
3933 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
3935 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
3938 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
3941 wl->profile->active = *(bool *)data;
3943 case WL_PROF_BEACONINT:
3944 wl->profile->beacon_interval = *(u16 *)data;
3946 case WL_PROF_DTIMPERIOD:
3947 wl->profile->dtim_period = *(u8 *)data;
3950 WL_ERR(("unsupported item (%d)\n", item));
3958 void wl_cfg80211_dbg_level(u32 level)
3961 * prohibit to change debug level
3962 * by insmod parameter.
3963 * eventually debug level will be configured
3964 * in compile time by using CONFIG_XXX
3966 /* wl_dbg_level = level; */
3969 static bool wl_is_ibssmode(struct wl_priv *wl)
3971 return wl->conf->mode == WL_MODE_IBSS;
3974 static bool wl_is_ibssstarter(struct wl_priv *wl)
3976 return wl->ibss_starter;
3979 static void wl_rst_ie(struct wl_priv *wl)
3981 struct wl_ie *ie = wl_to_ie(wl);
3986 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
3988 struct wl_ie *ie = wl_to_ie(wl);
3991 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3992 WL_ERR(("ei crosses buffer boundary\n"));
3995 ie->buf[ie->offset] = t;
3996 ie->buf[ie->offset + 1] = l;
3997 memcpy(&ie->buf[ie->offset + 2], v, l);
3998 ie->offset += l + 2;
4003 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
4005 struct wl_ie *ie = wl_to_ie(wl);
4008 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
4009 WL_ERR(("ei_stream crosses buffer boundary\n"));
4012 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
4013 ie->offset += ie_size;
4018 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
4020 struct wl_ie *ie = wl_to_ie(wl);
4023 if (unlikely(ie->offset > dst_size)) {
4024 WL_ERR(("dst_size is not enough\n"));
4027 memcpy(dst, &ie->buf[0], ie->offset);
4032 static u32 wl_get_ielen(struct wl_priv *wl)
4034 struct wl_ie *ie = wl_to_ie(wl);
4039 static void wl_link_up(struct wl_priv *wl)
4044 static void wl_link_down(struct wl_priv *wl)
4046 struct wl_connect_info *conn_info = wl_to_conn(wl);
4048 wl->link_up = false;
4049 kfree(conn_info->req_ie);
4050 conn_info->req_ie = NULL;
4051 conn_info->req_ie_len = 0;
4052 kfree(conn_info->resp_ie);
4053 conn_info->resp_ie = NULL;
4054 conn_info->resp_ie_len = 0;
4057 static void wl_lock_eq(struct wl_priv *wl)
4059 spin_lock_irq(&wl->eq_lock);
4062 static void wl_unlock_eq(struct wl_priv *wl)
4064 spin_unlock_irq(&wl->eq_lock);
4067 static void wl_init_eq_lock(struct wl_priv *wl)
4069 spin_lock_init(&wl->eq_lock);
4072 static void wl_delay(u32 ms)
4074 if (ms < 1000 / HZ) {
4082 static void wl_set_drvdata(struct wl_dev *dev, void *data)
4084 dev->driver_data = data;
4087 static void *wl_get_drvdata(struct wl_dev *dev)
4089 return dev->driver_data;
4092 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
4094 const struct firmware *fw_entry;
4099 fw_entry = wl->fw->fw_entry;
4101 if (fw_entry->size < wl->fw->ptr + size)
4102 size = fw_entry->size - wl->fw->ptr;
4104 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
4105 wl->fw->ptr += size;
4109 void wl_cfg80211_release_fw(void)
4114 release_firmware(wl->fw->fw_entry);
4118 void *wl_cfg80211_request_fw(s8 *file_name)
4121 const struct firmware *fw_entry = NULL;
4124 WL_DBG(("file name : \"%s\"\n", file_name));
4127 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
4128 err = request_firmware(&wl->fw->fw_entry, file_name,
4129 &wl_cfg80211_get_sdio_func()->dev);
4130 if (unlikely(err)) {
4131 WL_ERR(("Could not download fw (%d)\n", err));
4134 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
4135 fw_entry = wl->fw->fw_entry;
4137 WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
4140 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
4141 err = request_firmware(&wl->fw->fw_entry, file_name,
4142 &wl_cfg80211_get_sdio_func()->dev);
4143 if (unlikely(err)) {
4144 WL_ERR(("Could not download nvram (%d)\n", err));
4147 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
4148 fw_entry = wl->fw->fw_entry;
4150 WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
4154 WL_DBG(("Downloading already done. Nothing to do more\n"));
4159 if (unlikely(err)) {
4163 return (void *)fw_entry->data;
4166 s8 *wl_cfg80211_get_fwname(void)
4171 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4172 return wl->fw->fw_name;
4175 s8 *wl_cfg80211_get_nvramname(void)
4180 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4181 return wl->fw->nvram_name;
4184 static void wl_set_mpc(struct net_device *ndev, int mpc)
4188 err = wl_dev_intvar_set(ndev, "mpc", mpc);
4189 if (unlikely(err)) {
4190 WL_ERR(("fail to set mpc\n"));
4193 WL_DBG(("MPC : %d\n", mpc));
4196 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
4198 char buf[10+IFNAMSIZ];
4202 sprintf(buf, "netdev:%s", wl_to_ndev(wl)->name);
4203 wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
4205 fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
4206 (u16 *)&wl->profile->beacon_interval);
4212 fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
4213 (u8 *)&wl->profile->dtim_period);
4223 static void wl_debugfs_remove_netdev(struct wl_priv *wl)
4225 debugfs_remove_recursive(wl->debugfsdir);
4226 wl->debugfsdir = NULL;