2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include <bcmendian.h>
23 #include <proto/ethernet.h>
25 #include <linux/if_arp.h>
26 #include <asm/uaccess.h>
28 #include <dngl_stats.h>
33 #include <proto/ethernet.h>
34 #include <dngl_stats.h>
37 #include <linux/kernel.h>
38 #include <linux/netdevice.h>
39 #include <linux/sched.h>
40 #include <linux/etherdevice.h>
41 #include <linux/wireless.h>
42 #include <linux/ieee80211.h>
43 #include <net/cfg80211.h>
45 #include <net/rtnetlink.h>
46 #include <linux/mmc/sdio_func.h>
47 #include <linux/firmware.h>
48 #include <wl_cfg80211.h>
50 static struct sdio_func *cfg80211_sdio_func;
51 static struct wl_dev *wl_cfg80211_dev;
53 u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
55 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
56 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
59 ** cfg80211_ops api/callback list
61 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
62 struct net_device *ndev,
63 enum nl80211_iftype type, u32 *flags,
64 struct vif_params *params);
65 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
66 struct cfg80211_scan_request *request,
67 struct cfg80211_ssid *this_ssid);
68 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
69 struct cfg80211_scan_request *request);
70 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
71 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
72 struct cfg80211_ibss_params *params);
73 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
74 struct net_device *dev);
75 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
76 struct net_device *dev, u8 *mac,
77 struct station_info *sinfo);
78 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
79 struct net_device *dev, bool enabled,
81 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
82 struct net_device *dev,
84 const struct cfg80211_bitrate_mask
86 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
87 struct cfg80211_connect_params *sme);
88 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
90 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
91 enum nl80211_tx_power_setting type,
93 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
94 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
95 struct net_device *dev,
97 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
98 u8 key_idx, const u8 *mac_addr,
99 struct key_params *params);
100 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
101 u8 key_idx, const u8 *mac_addr);
102 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
103 u8 key_idx, const u8 *mac_addr,
104 void *cookie, void (*callback) (void *cookie,
108 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
109 struct net_device *dev,
111 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
112 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
113 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
114 struct cfg80211_pmksa *pmksa);
115 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
116 struct cfg80211_pmksa *pmksa);
117 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
118 struct net_device *dev);
120 ** event & event Q handlers for cfg80211 interfaces
122 static s32 wl_create_event_handler(struct wl_priv *wl);
123 static void wl_destroy_event_handler(struct wl_priv *wl);
124 static s32 wl_event_handler(void *data);
125 static void wl_init_eq(struct wl_priv *wl);
126 static void wl_flush_eq(struct wl_priv *wl);
127 static void wl_lock_eq(struct wl_priv *wl);
128 static void wl_unlock_eq(struct wl_priv *wl);
129 static void wl_init_eq_lock(struct wl_priv *wl);
130 static void wl_init_eloop_handler(struct wl_event_loop *el);
131 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
132 static s32 wl_enq_event(struct wl_priv *wl, u32 type,
133 const wl_event_msg_t *msg, void *data);
134 static void wl_put_event(struct wl_event_q *e);
135 static void wl_wakeup_event(struct wl_priv *wl);
136 static s32 wl_notify_connect_status(struct wl_priv *wl,
137 struct net_device *ndev,
138 const wl_event_msg_t *e, void *data);
139 static s32 wl_notify_roaming_status(struct wl_priv *wl,
140 struct net_device *ndev,
141 const wl_event_msg_t *e, void *data);
142 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
143 const wl_event_msg_t *e, void *data);
144 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
145 const wl_event_msg_t *e, void *data,
147 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
148 const wl_event_msg_t *e, void *data);
149 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
150 const wl_event_msg_t *e, void *data);
153 ** register/deregister sdio function
155 struct sdio_func *wl_cfg80211_get_sdio_func(void);
156 static void wl_clear_sdio_func(void);
161 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
163 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
165 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
166 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
168 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
172 ** cfg80211 set_wiphy_params utilities
174 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
175 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
176 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
179 ** wl profile utilities
181 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
182 void *data, s32 item);
183 static void *wl_read_prof(struct wl_priv *wl, s32 item);
184 static void wl_init_prof(struct wl_profile *prof);
187 ** cfg80211 connect utilites
189 static s32 wl_set_wpa_version(struct net_device *dev,
190 struct cfg80211_connect_params *sme);
191 static s32 wl_set_auth_type(struct net_device *dev,
192 struct cfg80211_connect_params *sme);
193 static s32 wl_set_set_cipher(struct net_device *dev,
194 struct cfg80211_connect_params *sme);
195 static s32 wl_set_key_mgmt(struct net_device *dev,
196 struct cfg80211_connect_params *sme);
197 static s32 wl_set_set_sharedkey(struct net_device *dev,
198 struct cfg80211_connect_params *sme);
199 static s32 wl_get_assoc_ies(struct wl_priv *wl);
200 static void wl_ch_to_chanspec(int ch,
201 struct wl_join_params *join_params, size_t *join_params_size);
204 ** information element utilities
206 static void wl_rst_ie(struct wl_priv *wl);
207 static s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
208 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
209 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
210 static u32 wl_get_ielen(struct wl_priv *wl);
212 static s32 wl_mode_to_nl80211_iftype(s32 mode);
214 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
216 static void wl_free_wdev(struct wl_priv *wl);
218 static s32 wl_inform_bss(struct wl_priv *wl);
219 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
220 static s32 wl_update_bss_info(struct wl_priv *wl);
222 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
223 u8 key_idx, const u8 *mac_addr,
224 struct key_params *params);
227 ** key indianess swap utilities
229 static void swap_key_from_BE(struct wl_wsec_key *key);
230 static void swap_key_to_BE(struct wl_wsec_key *key);
233 ** wl_priv memory init/deinit utilities
235 static s32 wl_init_priv_mem(struct wl_priv *wl);
236 static void wl_deinit_priv_mem(struct wl_priv *wl);
238 static void wl_delay(u32 ms);
241 ** store/restore cfg80211 instance data
243 static void wl_set_drvdata(struct wl_dev *dev, void *data);
244 static void *wl_get_drvdata(struct wl_dev *dev);
247 ** ibss mode utilities
249 static bool wl_is_ibssmode(struct wl_priv *wl);
250 static bool wl_is_ibssstarter(struct wl_priv *wl);
253 ** dongle up/down , default configuration utilities
255 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
256 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
257 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
258 static void wl_link_up(struct wl_priv *wl);
259 static void wl_link_down(struct wl_priv *wl);
260 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
261 static s32 __wl_cfg80211_up(struct wl_priv *wl);
262 static s32 __wl_cfg80211_down(struct wl_priv *wl);
263 static s32 wl_dongle_probecap(struct wl_priv *wl);
264 static void wl_init_conf(struct wl_conf *conf);
267 ** dongle configuration utilities
269 #ifndef EMBEDDED_PLATFORM
270 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
271 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
272 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
273 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
274 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
276 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
278 static s32 wl_dongle_eventmsg(struct net_device *ndev);
279 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
280 s32 scan_unassoc_time);
281 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
283 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
284 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
285 static s32 wl_update_wiphybands(struct wl_priv *wl);
286 #endif /* !EMBEDDED_PLATFORM */
287 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
292 static void wl_iscan_timer(unsigned long data);
293 static void wl_term_iscan(struct wl_priv *wl);
294 static s32 wl_init_iscan(struct wl_priv *wl);
295 static s32 wl_iscan_thread(void *data);
296 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
297 void *param, s32 paramlen, void *bufptr,
299 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
300 void *param, s32 paramlen, void *bufptr,
302 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
304 static s32 wl_do_iscan(struct wl_priv *wl);
305 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
306 static s32 wl_invoke_iscan(struct wl_priv *wl);
307 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
308 struct wl_scan_results **bss_list);
309 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
310 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
311 static s32 wl_iscan_done(struct wl_priv *wl);
312 static s32 wl_iscan_pending(struct wl_priv *wl);
313 static s32 wl_iscan_inprogress(struct wl_priv *wl);
314 static s32 wl_iscan_aborted(struct wl_priv *wl);
317 ** fw/nvram downloading handler
319 static void wl_init_fw(struct wl_fw_ctrl *fw);
322 * find most significant bit set
324 static __used u32 wl_find_msb(u16 bit16);
327 * update pmklist to dongle
329 static __used s32 wl_update_pmklist(struct net_device *dev,
330 struct wl_pmk_list *pmk_list, s32 err);
332 static void wl_set_mpc(struct net_device *ndev, int mpc);
334 #define WL_PRIV_GET() \
336 struct wl_iface *ci; \
337 if (unlikely(!(wl_cfg80211_dev && \
338 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
339 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
345 #define CHECK_SYS_UP() \
347 struct wl_priv *wl = wiphy_to_wl(wiphy); \
348 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
349 WL_INFO(("device is not ready : status (%d)\n", \
355 extern int dhd_wait_pend8021x(struct net_device *dev);
357 #if (WL_DBG_LEVEL > 0)
358 #define WL_DBG_ESTR_MAX 32
359 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
360 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
361 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
362 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
363 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
364 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
365 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
366 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
368 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
370 "RADIO", "PSM_WATCHDOG",
372 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
373 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
374 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
376 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
378 #endif /* WL_DBG_LEVEL */
380 #define CHAN2G(_channel, _freq, _flags) { \
381 .band = IEEE80211_BAND_2GHZ, \
382 .center_freq = (_freq), \
383 .hw_value = (_channel), \
385 .max_antenna_gain = 0, \
389 #define CHAN5G(_channel, _flags) { \
390 .band = IEEE80211_BAND_5GHZ, \
391 .center_freq = 5000 + (5 * (_channel)), \
392 .hw_value = (_channel), \
394 .max_antenna_gain = 0, \
398 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
399 #define RATETAB_ENT(_rateid, _flags) \
401 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
402 .hw_value = (_rateid), \
406 static struct ieee80211_rate __wl_rates[] = {
407 RATETAB_ENT(WLC_RATE_1M, 0),
408 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
409 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
410 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
411 RATETAB_ENT(WLC_RATE_6M, 0),
412 RATETAB_ENT(WLC_RATE_9M, 0),
413 RATETAB_ENT(WLC_RATE_12M, 0),
414 RATETAB_ENT(WLC_RATE_18M, 0),
415 RATETAB_ENT(WLC_RATE_24M, 0),
416 RATETAB_ENT(WLC_RATE_36M, 0),
417 RATETAB_ENT(WLC_RATE_48M, 0),
418 RATETAB_ENT(WLC_RATE_54M, 0),
421 #define wl_a_rates (__wl_rates + 4)
422 #define wl_a_rates_size 8
423 #define wl_g_rates (__wl_rates + 0)
424 #define wl_g_rates_size 12
426 static struct ieee80211_channel __wl_2ghz_channels[] = {
443 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
444 CHAN5G(34, 0), CHAN5G(36, 0),
445 CHAN5G(38, 0), CHAN5G(40, 0),
446 CHAN5G(42, 0), CHAN5G(44, 0),
447 CHAN5G(46, 0), CHAN5G(48, 0),
448 CHAN5G(52, 0), CHAN5G(56, 0),
449 CHAN5G(60, 0), CHAN5G(64, 0),
450 CHAN5G(100, 0), CHAN5G(104, 0),
451 CHAN5G(108, 0), CHAN5G(112, 0),
452 CHAN5G(116, 0), CHAN5G(120, 0),
453 CHAN5G(124, 0), CHAN5G(128, 0),
454 CHAN5G(132, 0), CHAN5G(136, 0),
455 CHAN5G(140, 0), CHAN5G(149, 0),
456 CHAN5G(153, 0), CHAN5G(157, 0),
457 CHAN5G(161, 0), CHAN5G(165, 0),
458 CHAN5G(184, 0), CHAN5G(188, 0),
459 CHAN5G(192, 0), CHAN5G(196, 0),
460 CHAN5G(200, 0), CHAN5G(204, 0),
461 CHAN5G(208, 0), CHAN5G(212, 0),
465 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
466 CHAN5G(32, 0), CHAN5G(34, 0),
467 CHAN5G(36, 0), CHAN5G(38, 0),
468 CHAN5G(40, 0), CHAN5G(42, 0),
469 CHAN5G(44, 0), CHAN5G(46, 0),
470 CHAN5G(48, 0), CHAN5G(50, 0),
471 CHAN5G(52, 0), CHAN5G(54, 0),
472 CHAN5G(56, 0), CHAN5G(58, 0),
473 CHAN5G(60, 0), CHAN5G(62, 0),
474 CHAN5G(64, 0), CHAN5G(66, 0),
475 CHAN5G(68, 0), CHAN5G(70, 0),
476 CHAN5G(72, 0), CHAN5G(74, 0),
477 CHAN5G(76, 0), CHAN5G(78, 0),
478 CHAN5G(80, 0), CHAN5G(82, 0),
479 CHAN5G(84, 0), CHAN5G(86, 0),
480 CHAN5G(88, 0), CHAN5G(90, 0),
481 CHAN5G(92, 0), CHAN5G(94, 0),
482 CHAN5G(96, 0), CHAN5G(98, 0),
483 CHAN5G(100, 0), CHAN5G(102, 0),
484 CHAN5G(104, 0), CHAN5G(106, 0),
485 CHAN5G(108, 0), CHAN5G(110, 0),
486 CHAN5G(112, 0), CHAN5G(114, 0),
487 CHAN5G(116, 0), CHAN5G(118, 0),
488 CHAN5G(120, 0), CHAN5G(122, 0),
489 CHAN5G(124, 0), CHAN5G(126, 0),
490 CHAN5G(128, 0), CHAN5G(130, 0),
491 CHAN5G(132, 0), CHAN5G(134, 0),
492 CHAN5G(136, 0), CHAN5G(138, 0),
493 CHAN5G(140, 0), CHAN5G(142, 0),
494 CHAN5G(144, 0), CHAN5G(145, 0),
495 CHAN5G(146, 0), CHAN5G(147, 0),
496 CHAN5G(148, 0), CHAN5G(149, 0),
497 CHAN5G(150, 0), CHAN5G(151, 0),
498 CHAN5G(152, 0), CHAN5G(153, 0),
499 CHAN5G(154, 0), CHAN5G(155, 0),
500 CHAN5G(156, 0), CHAN5G(157, 0),
501 CHAN5G(158, 0), CHAN5G(159, 0),
502 CHAN5G(160, 0), CHAN5G(161, 0),
503 CHAN5G(162, 0), CHAN5G(163, 0),
504 CHAN5G(164, 0), CHAN5G(165, 0),
505 CHAN5G(166, 0), CHAN5G(168, 0),
506 CHAN5G(170, 0), CHAN5G(172, 0),
507 CHAN5G(174, 0), CHAN5G(176, 0),
508 CHAN5G(178, 0), CHAN5G(180, 0),
509 CHAN5G(182, 0), CHAN5G(184, 0),
510 CHAN5G(186, 0), CHAN5G(188, 0),
511 CHAN5G(190, 0), CHAN5G(192, 0),
512 CHAN5G(194, 0), CHAN5G(196, 0),
513 CHAN5G(198, 0), CHAN5G(200, 0),
514 CHAN5G(202, 0), CHAN5G(204, 0),
515 CHAN5G(206, 0), CHAN5G(208, 0),
516 CHAN5G(210, 0), CHAN5G(212, 0),
517 CHAN5G(214, 0), CHAN5G(216, 0),
518 CHAN5G(218, 0), CHAN5G(220, 0),
519 CHAN5G(222, 0), CHAN5G(224, 0),
520 CHAN5G(226, 0), CHAN5G(228, 0),
523 static struct ieee80211_supported_band __wl_band_2ghz = {
524 .band = IEEE80211_BAND_2GHZ,
525 .channels = __wl_2ghz_channels,
526 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
527 .bitrates = wl_g_rates,
528 .n_bitrates = wl_g_rates_size,
531 static struct ieee80211_supported_band __wl_band_5ghz_a = {
532 .band = IEEE80211_BAND_5GHZ,
533 .channels = __wl_5ghz_a_channels,
534 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
535 .bitrates = wl_a_rates,
536 .n_bitrates = wl_a_rates_size,
539 static struct ieee80211_supported_band __wl_band_5ghz_n = {
540 .band = IEEE80211_BAND_5GHZ,
541 .channels = __wl_5ghz_n_channels,
542 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
543 .bitrates = wl_a_rates,
544 .n_bitrates = wl_a_rates_size,
547 static const u32 __wl_cipher_suites[] = {
548 WLAN_CIPHER_SUITE_WEP40,
549 WLAN_CIPHER_SUITE_WEP104,
550 WLAN_CIPHER_SUITE_TKIP,
551 WLAN_CIPHER_SUITE_CCMP,
552 WLAN_CIPHER_SUITE_AES_CMAC,
555 static void swap_key_from_BE(struct wl_wsec_key *key)
557 key->index = htod32(key->index);
558 key->len = htod32(key->len);
559 key->algo = htod32(key->algo);
560 key->flags = htod32(key->flags);
561 key->rxiv.hi = htod32(key->rxiv.hi);
562 key->rxiv.lo = htod16(key->rxiv.lo);
563 key->iv_initialized = htod32(key->iv_initialized);
566 static void swap_key_to_BE(struct wl_wsec_key *key)
568 key->index = dtoh32(key->index);
569 key->len = dtoh32(key->len);
570 key->algo = dtoh32(key->algo);
571 key->flags = dtoh32(key->flags);
572 key->rxiv.hi = dtoh32(key->rxiv.hi);
573 key->rxiv.lo = dtoh16(key->rxiv.lo);
574 key->iv_initialized = dtoh32(key->iv_initialized);
578 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
585 memset(&ioc, 0, sizeof(ioc));
589 strcpy(ifr.ifr_name, dev->name);
590 ifr.ifr_data = (caddr_t)&ioc;
594 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
601 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
602 enum nl80211_iftype type, u32 *flags,
603 struct vif_params *params)
605 struct wl_priv *wl = wiphy_to_wl(wiphy);
606 struct wireless_dev *wdev;
613 case NL80211_IFTYPE_MONITOR:
614 case NL80211_IFTYPE_WDS:
615 WL_ERR(("type (%d) : currently we do not support this type\n",
618 case NL80211_IFTYPE_ADHOC:
619 wl->conf->mode = WL_MODE_IBSS;
621 case NL80211_IFTYPE_STATION:
622 wl->conf->mode = WL_MODE_BSS;
628 infra = htod32(infra);
630 wdev = ndev->ieee80211_ptr;
632 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
633 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
635 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
638 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
640 WL_ERR(("WLC_SET_AP error (%d)\n", err));
644 /* -EINPROGRESS: Call commit handler */
648 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
650 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
651 params->bss_type = DOT11_BSSTYPE_ANY;
652 params->scan_type = 0;
653 params->nprobes = -1;
654 params->active_time = -1;
655 params->passive_time = -1;
656 params->home_time = -1;
657 params->channel_num = 0;
659 params->nprobes = htod32(params->nprobes);
660 params->active_time = htod32(params->active_time);
661 params->passive_time = htod32(params->passive_time);
662 params->home_time = htod32(params->home_time);
663 if (ssid && ssid->SSID_len)
664 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
669 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
670 s32 paramlen, void *bufptr, s32 buflen)
674 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
675 BUG_ON(unlikely(!iolen));
677 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
681 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
682 s32 paramlen, void *bufptr, s32 buflen)
686 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
687 BUG_ON(unlikely(!iolen));
689 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
693 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
696 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
697 struct wl_iscan_params *params;
700 if (ssid && ssid->SSID_len)
701 params_size += sizeof(struct wlc_ssid);
702 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
703 if (unlikely(!params))
705 memset(params, 0, params_size);
706 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
708 wl_iscan_prep(¶ms->params, ssid);
710 params->version = htod32(ISCAN_REQ_VERSION);
711 params->action = htod16(action);
712 params->scan_duration = htod16(0);
714 /* params_size += offsetof(wl_iscan_params_t, params); */
715 err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
716 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
719 WL_INFO(("system busy : iscan canceled\n"));
721 WL_ERR(("error (%d)\n", err));
728 static s32 wl_do_iscan(struct wl_priv *wl)
730 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
731 struct net_device *ndev = wl_to_ndev(wl);
732 struct wlc_ssid ssid;
735 /* Broadcast scan by default */
736 memset(&ssid, 0, sizeof(ssid));
738 iscan->state = WL_ISCAN_STATE_SCANING;
740 if (wl->active_scan) {
741 s32 passive_scan = 0;
742 /* make it active scan */
743 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
744 &passive_scan, sizeof(passive_scan));
746 WL_DBG(("error (%d)\n", err));
751 wl->iscan_kickstart = TRUE;
752 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
753 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
760 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
761 struct cfg80211_scan_request *request,
762 struct cfg80211_ssid *this_ssid)
764 struct wl_priv *wl = ndev_to_wl(ndev);
765 struct cfg80211_ssid *ssids;
766 struct wl_scan_req *sr = wl_to_sr(wl);
771 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
772 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
775 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
776 WL_ERR(("Scanning being aborted : status (%d)\n",
783 if (request) { /* scan bss */
784 ssids = request->ssids;
785 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) { /* for
787 * ssids->ssid_len has
788 * non-zero(ssid string)
790 * Otherwise this is 0.
791 * we do not iscan for
792 * specific scan request
796 } else { /* scan in ibss */
797 /* we don't do iscan in ibss */
800 wl->scan_request = request;
801 set_bit(WL_STATUS_SCANNING, &wl->status);
803 err = wl_do_iscan(wl);
809 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
810 ssids->ssid, ssids->ssid_len));
811 memset(&sr->ssid, 0, sizeof(sr->ssid));
813 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
814 if (sr->ssid.SSID_len) {
815 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
816 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
817 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
818 sr->ssid.SSID, sr->ssid.SSID_len));
821 WL_DBG(("Broadcast scan\n"));
823 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
824 if (wl->active_scan) {
826 /* make it active scan */
827 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
828 &pssive_scan, sizeof(pssive_scan));
830 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n",
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,
2007 s8 eabuf[ETHER_ADDR_STR_LEN];
2010 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
2012 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2013 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2014 WL_DBG(("PMKID[%d]: %s =\n", i,
2015 bcm_ether_ntoa(&pmk_list->pmkids.pmkid[i].BSSID,
2017 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2018 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2022 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2030 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2031 struct cfg80211_pmksa *pmksa)
2033 struct wl_priv *wl = wiphy_to_wl(wiphy);
2034 s8 eabuf[ETHER_ADDR_STR_LEN];
2039 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
2040 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2041 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2044 if (i < WL_NUM_PMKIDS_MAX) {
2045 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2047 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2049 if (i == wl->pmk_list->pmkids.npmkid)
2050 wl->pmk_list->pmkids.npmkid++;
2054 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %s =\n",
2055 bcm_ether_ntoa(&wl->pmk_list->pmkids.
2056 pmkid[wl->pmk_list->pmkids.npmkid].BSSID,
2058 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2060 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2064 err = wl_update_pmklist(dev, wl->pmk_list, err);
2070 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2071 struct cfg80211_pmksa *pmksa)
2073 struct wl_priv *wl = wiphy_to_wl(wiphy);
2074 s8 eabuf[ETHER_ADDR_STR_LEN];
2075 struct _pmkid_list pmkid;
2080 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
2081 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2082 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2084 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %s =\n",
2085 bcm_ether_ntoa(&pmkid.pmkid[0].BSSID, eabuf)));
2086 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2087 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2090 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2092 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2096 if ((wl->pmk_list->pmkids.npmkid > 0)
2097 && (i < wl->pmk_list->pmkids.npmkid)) {
2098 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2099 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2100 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2101 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2103 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2104 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2107 wl->pmk_list->pmkids.npmkid--;
2112 err = wl_update_pmklist(dev, wl->pmk_list, err);
2119 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2121 struct wl_priv *wl = wiphy_to_wl(wiphy);
2125 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2126 err = wl_update_pmklist(dev, wl->pmk_list, err);
2131 static struct cfg80211_ops wl_cfg80211_ops = {
2132 .change_virtual_intf = wl_cfg80211_change_iface,
2133 .scan = wl_cfg80211_scan,
2134 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2135 .join_ibss = wl_cfg80211_join_ibss,
2136 .leave_ibss = wl_cfg80211_leave_ibss,
2137 .get_station = wl_cfg80211_get_station,
2138 .set_tx_power = wl_cfg80211_set_tx_power,
2139 .get_tx_power = wl_cfg80211_get_tx_power,
2140 .add_key = wl_cfg80211_add_key,
2141 .del_key = wl_cfg80211_del_key,
2142 .get_key = wl_cfg80211_get_key,
2143 .set_default_key = wl_cfg80211_config_default_key,
2144 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2145 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2146 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2147 .connect = wl_cfg80211_connect,
2148 .disconnect = wl_cfg80211_disconnect,
2149 .suspend = wl_cfg80211_suspend,
2150 .resume = wl_cfg80211_resume,
2151 .set_pmksa = wl_cfg80211_set_pmksa,
2152 .del_pmksa = wl_cfg80211_del_pmksa,
2153 .flush_pmksa = wl_cfg80211_flush_pmksa
2156 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2162 return NL80211_IFTYPE_STATION;
2164 return NL80211_IFTYPE_ADHOC;
2166 return NL80211_IFTYPE_UNSPECIFIED;
2172 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2175 struct wireless_dev *wdev;
2178 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2179 if (unlikely(!wdev)) {
2180 WL_ERR(("Could not allocate wireless device\n"));
2181 return ERR_PTR(-ENOMEM);
2184 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2185 if (unlikely(!wdev->wiphy)) {
2186 WL_ERR(("Couldn not allocate wiphy device\n"));
2190 set_wiphy_dev(wdev->wiphy, dev);
2191 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2192 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2193 wdev->wiphy->interface_modes =
2194 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2195 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2196 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2197 * it as 11a by default.
2198 * This will be updated with
2201 * if phy has 11n capability
2203 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2204 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2205 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2206 #ifndef WL_POWERSAVE_DISABLED
2207 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2212 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2213 #endif /* !WL_POWERSAVE_DISABLED */
2214 err = wiphy_register(wdev->wiphy);
2215 if (unlikely(err < 0)) {
2216 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2217 goto wiphy_register_out;
2222 wiphy_free(wdev->wiphy);
2227 return ERR_PTR(err);
2230 static void wl_free_wdev(struct wl_priv *wl)
2232 struct wireless_dev *wdev = wl_to_wdev(wl);
2234 if (unlikely(!wdev)) {
2235 WL_ERR(("wdev is invalid\n"));
2238 wiphy_unregister(wdev->wiphy);
2239 wiphy_free(wdev->wiphy);
2241 wl_to_wdev(wl) = NULL;
2244 static s32 wl_inform_bss(struct wl_priv *wl)
2246 struct wl_scan_results *bss_list;
2247 struct wl_bss_info *bi = NULL; /* must be initialized */
2251 bss_list = wl->bss_list;
2252 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2253 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2254 bss_list->version));
2257 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2258 bi = next_bss(bss_list, bi);
2259 for_each_bss(bss_list, bi, i) {
2260 err = wl_inform_single_bss(wl, bi);
2267 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2269 struct wiphy *wiphy = wl_to_wiphy(wl);
2270 struct ieee80211_mgmt *mgmt;
2271 struct ieee80211_channel *channel;
2272 struct ieee80211_supported_band *band;
2273 struct wl_cfg80211_bss_info *notif_bss_info;
2274 struct wl_scan_req *sr = wl_to_sr(wl);
2279 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
2280 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2284 kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2285 WL_BSS_INFO_MAX, GFP_KERNEL);
2286 if (unlikely(!notif_bss_info)) {
2287 WL_ERR(("notif_bss_info alloc failed\n"));
2290 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2291 notif_bss_info->channel =
2292 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
2294 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2295 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2297 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2298 notif_bss_info->rssi = bi->RSSI;
2299 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
2300 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2301 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2302 IEEE80211_STYPE_PROBE_RESP);
2304 mgmt->u.probe_resp.timestamp = 0;
2305 mgmt->u.probe_resp.beacon_int = cpu_to_le16(bi->beacon_period);
2306 mgmt->u.probe_resp.capab_info = cpu_to_le16(bi->capability);
2308 wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2309 wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2311 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2312 wl_cp_ie(wl, mgmt->u.probe_resp.variable, WL_BSS_INFO_MAX -
2313 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2314 notif_bss_info->frame_len =
2315 offsetof(struct ieee80211_mgmt,
2316 u.probe_resp.variable) + wl_get_ielen(wl);
2317 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2318 channel = ieee80211_get_channel(wiphy, freq);
2320 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
2322 notif_bss_info->rssi, notif_bss_info->channel,
2323 mgmt->u.probe_resp.capab_info, &bi->BSSID));
2325 signal = notif_bss_info->rssi * 100;
2326 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2328 (notif_bss_info->frame_len),
2329 signal, GFP_KERNEL))) {
2330 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2331 kfree(notif_bss_info);
2334 kfree(notif_bss_info);
2339 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2341 u32 event = ntoh32(e->event_type);
2342 u16 flags = ntoh16(e->flags);
2344 if (event == WLC_E_LINK) {
2345 if (flags & WLC_EVENT_MSG_LINK) {
2346 if (wl_is_ibssmode(wl)) {
2347 if (wl_is_ibssstarter(wl)) {
2358 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2360 u32 event = ntoh32(e->event_type);
2361 u16 flags = ntoh16(e->flags);
2363 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2365 } else if (event == WLC_E_LINK) {
2366 if (!(flags & WLC_EVENT_MSG_LINK))
2373 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2375 u32 event = ntoh32(e->event_type);
2376 u32 status = ntoh32(e->status);
2378 if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2379 if (status == WLC_E_STATUS_NO_NETWORKS)
2387 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2388 const wl_event_msg_t *e, void *data)
2393 if (wl_is_linkup(wl, e)) {
2395 if (wl_is_ibssmode(wl)) {
2396 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2398 WL_DBG(("joined in IBSS network\n"));
2400 wl_bss_connect_done(wl, ndev, e, data, TRUE);
2401 WL_DBG(("joined in BSS network \"%s\"\n",
2402 ((struct wlc_ssid *)
2403 wl_read_prof(wl, WL_PROF_SSID))->SSID));
2406 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2407 } else if (wl_is_linkdown(wl, e)) {
2408 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2409 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2411 wl_init_prof(wl->profile);
2412 } else if (wl_is_nonetwork(wl, e)) {
2413 wl_bss_connect_done(wl, ndev, e, data, FALSE);
2420 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2421 const wl_event_msg_t *e, void *data)
2426 wl_bss_roaming_done(wl, ndev, e, data);
2428 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2434 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2436 struct wl_priv *wl = ndev_to_wl(dev);
2439 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2440 BUG_ON(unlikely(!buflen));
2442 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2446 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2449 struct wl_priv *wl = ndev_to_wl(dev);
2453 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2454 BUG_ON(unlikely(!len));
2455 err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2457 if (unlikely(err)) {
2458 WL_ERR(("error (%d)\n", err));
2461 memcpy(buf, wl->ioctl_buf, buf_len);
2466 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2468 struct net_device *ndev = wl_to_ndev(wl);
2469 struct wl_assoc_ielen *assoc_info;
2470 struct wl_connect_info *conn_info = wl_to_conn(wl);
2475 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2477 if (unlikely(err)) {
2478 WL_ERR(("could not get assoc info (%d)\n", err));
2481 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2482 req_len = assoc_info->req_len;
2483 resp_len = assoc_info->resp_len;
2485 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2487 if (unlikely(err)) {
2488 WL_ERR(("could not get assoc req (%d)\n", err));
2491 conn_info->req_ie_len = req_len;
2493 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2495 conn_info->req_ie_len = 0;
2496 conn_info->req_ie = NULL;
2499 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2501 if (unlikely(err)) {
2502 WL_ERR(("could not get assoc resp (%d)\n", err));
2505 conn_info->resp_ie_len = resp_len;
2506 conn_info->resp_ie =
2507 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2509 conn_info->resp_ie_len = 0;
2510 conn_info->resp_ie = NULL;
2512 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2513 conn_info->resp_ie_len));
2518 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2519 size_t *join_params_size)
2521 chanspec_t chanspec = 0;
2524 join_params->params.chanspec_num = 1;
2525 join_params->params.chanspec_list[0] = ch;
2527 if (join_params->params.chanspec_list[0])
2528 chanspec |= WL_CHANSPEC_BAND_2G;
2530 chanspec |= WL_CHANSPEC_BAND_5G;
2532 chanspec |= WL_CHANSPEC_BW_20;
2533 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2535 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2536 join_params->params.chanspec_num * sizeof(chanspec_t);
2538 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2539 join_params->params.chanspec_list[0] |= chanspec;
2540 join_params->params.chanspec_list[0] =
2541 htodchanspec(join_params->params.chanspec_list[0]);
2543 join_params->params.chanspec_num =
2544 htod32(join_params->params.chanspec_num);
2546 WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
2547 join_params->params.chanspec_list[0], ch, chanspec));
2551 static s32 wl_update_bss_info(struct wl_priv *wl)
2553 struct cfg80211_bss *bss;
2554 struct wl_bss_info *bi;
2555 struct wlc_ssid *ssid;
2558 if (wl_is_ibssmode(wl))
2561 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2563 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2564 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2565 WLAN_CAPABILITY_ESS);
2568 if (unlikely(!bss)) {
2569 WL_DBG(("Could not find the AP\n"));
2570 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2571 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2572 wl->extra_buf, WL_EXTRA_BUF_MAX);
2573 if (unlikely(err)) {
2574 WL_ERR(("Could not get bss info %d\n", err));
2575 goto update_bss_info_out;
2577 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2578 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2580 goto update_bss_info_out;
2582 err = wl_inform_single_bss(wl, bi);
2584 goto update_bss_info_out;
2586 WL_DBG(("Found the AP in the list - "
2587 "BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
2588 bss->bssid[0], bss->bssid[1], bss->bssid[2],
2589 bss->bssid[3], bss->bssid[4], bss->bssid[5]));
2590 cfg80211_put_bss(bss);
2593 update_bss_info_out:
2599 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2600 const wl_event_msg_t *e, void *data)
2602 struct wl_connect_info *conn_info = wl_to_conn(wl);
2605 wl_get_assoc_ies(wl);
2606 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2607 wl_update_bss_info(wl);
2608 cfg80211_roamed(ndev,
2610 conn_info->req_ie, conn_info->req_ie_len,
2611 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2612 WL_DBG(("Report roaming result\n"));
2614 set_bit(WL_STATUS_CONNECTED, &wl->status);
2620 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2621 const wl_event_msg_t *e, void *data, bool completed)
2623 struct wl_connect_info *conn_info = wl_to_conn(wl);
2626 wl_get_assoc_ies(wl);
2627 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2628 wl_update_bss_info(wl);
2629 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2630 cfg80211_connect_result(ndev,
2633 conn_info->req_ie_len,
2635 conn_info->resp_ie_len,
2636 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2638 WL_DBG(("Report connect result - connection %s\n",
2639 completed ? "succeeded" : "failed"));
2641 cfg80211_roamed(ndev,
2643 conn_info->req_ie, conn_info->req_ie_len,
2644 conn_info->resp_ie, conn_info->resp_ie_len,
2646 WL_DBG(("Report roaming result\n"));
2648 set_bit(WL_STATUS_CONNECTED, &wl->status);
2654 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2655 const wl_event_msg_t *e, void *data)
2657 u16 flags = ntoh16(e->flags);
2658 enum nl80211_key_type key_type;
2661 if (flags & WLC_EVENT_MSG_GROUP)
2662 key_type = NL80211_KEYTYPE_GROUP;
2664 key_type = NL80211_KEYTYPE_PAIRWISE;
2666 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2674 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2675 const wl_event_msg_t *e, void *data)
2677 struct channel_info channel_inform;
2678 struct wl_scan_results *bss_list;
2679 u32 len = WL_SCAN_BUF_MAX;
2682 if (wl->iscan_on && wl->iscan_kickstart)
2683 return wl_wakeup_iscan(wl_to_iscan(wl));
2685 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2686 WL_ERR(("Scan complete while device not scanning\n"));
2689 if (unlikely(!wl->scan_request)) {
2692 err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2693 sizeof(channel_inform));
2694 if (unlikely(err)) {
2695 WL_ERR(("scan busy (%d)\n", err));
2698 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2699 if (unlikely(channel_inform.scan_channel)) {
2701 WL_DBG(("channel_inform.scan_channel (%d)\n",
2702 channel_inform.scan_channel));
2704 wl->bss_list = wl->scan_results;
2705 bss_list = wl->bss_list;
2706 memset(bss_list, 0, len);
2707 bss_list->buflen = htod32(len);
2708 err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
2709 if (unlikely(err)) {
2710 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2714 bss_list->buflen = dtoh32(bss_list->buflen);
2715 bss_list->version = dtoh32(bss_list->version);
2716 bss_list->count = dtoh32(bss_list->count);
2718 err = wl_inform_bss(wl);
2723 if (wl->scan_request) {
2724 cfg80211_scan_done(wl->scan_request, FALSE);
2725 wl_set_mpc(ndev, 1);
2726 wl->scan_request = NULL;
2732 static void wl_init_conf(struct wl_conf *conf)
2734 conf->mode = (u32)-1;
2735 conf->frag_threshold = (u32)-1;
2736 conf->rts_threshold = (u32)-1;
2737 conf->retry_short = (u32)-1;
2738 conf->retry_long = (u32)-1;
2739 conf->tx_power = -1;
2742 static void wl_init_prof(struct wl_profile *prof)
2744 memset(prof, 0, sizeof(*prof));
2747 static void wl_init_eloop_handler(struct wl_event_loop *el)
2749 memset(el, 0, sizeof(*el));
2750 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2751 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2752 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2753 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2754 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2755 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2756 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2757 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2758 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2759 el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2762 static s32 wl_init_priv_mem(struct wl_priv *wl)
2764 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2765 if (unlikely(!wl->scan_results)) {
2766 WL_ERR(("Scan results alloc failed\n"));
2767 goto init_priv_mem_out;
2769 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2770 if (unlikely(!wl->conf)) {
2771 WL_ERR(("wl_conf alloc failed\n"));
2772 goto init_priv_mem_out;
2774 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2775 if (unlikely(!wl->profile)) {
2776 WL_ERR(("wl_profile alloc failed\n"));
2777 goto init_priv_mem_out;
2779 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2780 if (unlikely(!wl->bss_info)) {
2781 WL_ERR(("Bss information alloc failed\n"));
2782 goto init_priv_mem_out;
2785 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2786 if (unlikely(!wl->scan_req_int)) {
2787 WL_ERR(("Scan req alloc failed\n"));
2788 goto init_priv_mem_out;
2790 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2791 if (unlikely(!wl->ioctl_buf)) {
2792 WL_ERR(("Ioctl buf alloc failed\n"));
2793 goto init_priv_mem_out;
2795 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2796 if (unlikely(!wl->extra_buf)) {
2797 WL_ERR(("Extra buf alloc failed\n"));
2798 goto init_priv_mem_out;
2800 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2801 if (unlikely(!wl->iscan)) {
2802 WL_ERR(("Iscan buf alloc failed\n"));
2803 goto init_priv_mem_out;
2805 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2806 if (unlikely(!wl->fw)) {
2807 WL_ERR(("fw object alloc failed\n"));
2808 goto init_priv_mem_out;
2810 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2811 if (unlikely(!wl->pmk_list)) {
2812 WL_ERR(("pmk list alloc failed\n"));
2813 goto init_priv_mem_out;
2819 wl_deinit_priv_mem(wl);
2824 static void wl_deinit_priv_mem(struct wl_priv *wl)
2826 kfree(wl->scan_results);
2827 wl->scan_results = NULL;
2828 kfree(wl->bss_info);
2829 wl->bss_info = NULL;
2834 kfree(wl->scan_req_int);
2835 wl->scan_req_int = NULL;
2836 kfree(wl->ioctl_buf);
2837 wl->ioctl_buf = NULL;
2838 kfree(wl->extra_buf);
2839 wl->extra_buf = NULL;
2844 kfree(wl->pmk_list);
2845 wl->pmk_list = NULL;
2848 static s32 wl_create_event_handler(struct wl_priv *wl)
2850 sema_init(&wl->event_sync, 0);
2851 init_completion(&wl->event_exit);
2852 wl->event_pid = kernel_thread(wl_event_handler, wl, 0);
2853 if (unlikely(wl->event_pid < 0)) {
2854 WL_ERR(("failed to create event thread\n"));
2857 WL_DBG(("pid %d\n", wl->event_pid));
2861 static void wl_destroy_event_handler(struct wl_priv *wl)
2863 if (wl->event_pid >= 0) {
2864 KILL_PROC(wl->event_pid, SIGTERM);
2865 wait_for_completion(&wl->event_exit);
2869 static void wl_term_iscan(struct wl_priv *wl)
2871 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2873 if (wl->iscan_on && iscan->pid >= 0) {
2874 iscan->state = WL_ISCAN_STATE_IDLE;
2875 KILL_PROC(iscan->pid, SIGTERM);
2876 wait_for_completion(&iscan->exited);
2881 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2883 struct wl_priv *wl = iscan_to_wl(iscan);
2884 struct net_device *ndev = wl_to_ndev(wl);
2886 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2887 WL_ERR(("Scan complete while device not scanning\n"));
2890 if (likely(wl->scan_request)) {
2891 cfg80211_scan_done(wl->scan_request, aborted);
2892 wl_set_mpc(ndev, 1);
2893 wl->scan_request = NULL;
2895 wl->iscan_kickstart = FALSE;
2898 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2900 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2901 WL_DBG(("wake up iscan\n"));
2910 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
2911 struct wl_scan_results **bss_list)
2913 struct wl_iscan_results list;
2914 struct wl_scan_results *results;
2915 struct wl_iscan_results *list_buf;
2918 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2919 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2920 results = &list_buf->results;
2921 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2922 results->version = 0;
2925 memset(&list, 0, sizeof(list));
2926 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2927 err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2928 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2930 if (unlikely(err)) {
2931 WL_ERR(("error (%d)\n", err));
2934 results->buflen = dtoh32(results->buflen);
2935 results->version = dtoh32(results->version);
2936 results->count = dtoh32(results->count);
2937 WL_DBG(("results->count = %d\n", results->count));
2938 WL_DBG(("results->buflen = %d\n", results->buflen));
2939 *status = dtoh32(list_buf->status);
2940 *bss_list = results;
2945 static s32 wl_iscan_done(struct wl_priv *wl)
2947 struct wl_iscan_ctrl *iscan = wl->iscan;
2950 iscan->state = WL_ISCAN_STATE_IDLE;
2953 wl_notify_iscan_complete(iscan, FALSE);
2959 static s32 wl_iscan_pending(struct wl_priv *wl)
2961 struct wl_iscan_ctrl *iscan = wl->iscan;
2964 /* Reschedule the timer */
2965 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2966 iscan->timer_on = 1;
2971 static s32 wl_iscan_inprogress(struct wl_priv *wl)
2973 struct wl_iscan_ctrl *iscan = wl->iscan;
2978 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
2980 /* Reschedule the timer */
2981 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2982 iscan->timer_on = 1;
2987 static s32 wl_iscan_aborted(struct wl_priv *wl)
2989 struct wl_iscan_ctrl *iscan = wl->iscan;
2992 iscan->state = WL_ISCAN_STATE_IDLE;
2994 wl_notify_iscan_complete(iscan, TRUE);
3000 static s32 wl_iscan_thread(void *data)
3002 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3003 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3004 struct wl_priv *wl = iscan_to_wl(iscan);
3005 struct wl_iscan_eloop *el = &iscan->el;
3009 sched_setscheduler(current, SCHED_FIFO, ¶m);
3010 status = WL_SCAN_RESULTS_PARTIAL;
3011 while (likely(!down_interruptible(&iscan->sync))) {
3012 if (iscan->timer_on) {
3013 del_timer_sync(&iscan->timer);
3014 iscan->timer_on = 0;
3017 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
3018 if (unlikely(err)) {
3019 status = WL_SCAN_RESULTS_ABORTED;
3020 WL_ERR(("Abort iscan\n"));
3023 el->handler[status] (wl);
3025 if (iscan->timer_on) {
3026 del_timer_sync(&iscan->timer);
3027 iscan->timer_on = 0;
3029 complete_and_exit(&iscan->exited, 0);
3034 static void wl_iscan_timer(unsigned long data)
3036 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3039 iscan->timer_on = 0;
3040 WL_DBG(("timer expired\n"));
3041 wl_wakeup_iscan(iscan);
3045 static s32 wl_invoke_iscan(struct wl_priv *wl)
3047 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3050 if (wl->iscan_on && iscan->pid < 0) {
3051 iscan->state = WL_ISCAN_STATE_IDLE;
3052 sema_init(&iscan->sync, 0);
3053 init_completion(&iscan->exited);
3054 iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0);
3055 if (unlikely(iscan->pid < 0)) {
3056 WL_ERR(("Could not create iscan thread\n"));
3064 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
3066 memset(el, 0, sizeof(*el));
3067 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
3068 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
3069 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
3070 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
3071 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
3074 static s32 wl_init_iscan(struct wl_priv *wl)
3076 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3080 iscan->dev = wl_to_ndev(wl);
3081 iscan->state = WL_ISCAN_STATE_IDLE;
3082 wl_init_iscan_eloop(&iscan->el);
3083 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3084 init_timer(&iscan->timer);
3085 iscan->timer.data = (unsigned long) iscan;
3086 iscan->timer.function = wl_iscan_timer;
3087 sema_init(&iscan->sync, 0);
3088 init_completion(&iscan->exited);
3089 iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0);
3090 if (unlikely(iscan->pid < 0)) {
3091 WL_ERR(("Could not create iscan thread\n"));
3100 static void wl_init_fw(struct wl_fw_ctrl *fw)
3102 fw->status = 0; /* init fw loading status.
3103 0 means nothing was loaded yet */
3106 static s32 wl_init_priv(struct wl_priv *wl)
3108 struct wiphy *wiphy = wl_to_wiphy(wl);
3111 wl->scan_request = NULL;
3112 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3113 #ifndef WL_ISCAN_DISABLED
3114 wl->iscan_on = TRUE; /* iscan on & off switch.
3115 we enable iscan per default */
3117 wl->iscan_on = FALSE;
3118 #endif /* WL_ISCAN_DISABLED */
3119 #ifndef WL_ROAM_DISABLED
3120 wl->roam_on = TRUE; /* roam on & off switch.
3121 we enable roam per default */
3123 wl->roam_on = FALSE;
3124 #endif /* WL_ROAM_DISABLED */
3126 wl->iscan_kickstart = FALSE;
3127 wl->active_scan = TRUE; /* we do active scan for
3128 specific scan per default */
3129 wl->dongle_up = FALSE; /* dongle is not up yet */
3131 err = wl_init_priv_mem(wl);
3134 if (unlikely(wl_create_event_handler(wl)))
3136 wl_init_eloop_handler(&wl->el);
3137 mutex_init(&wl->usr_sync);
3138 err = wl_init_iscan(wl);
3142 wl_init_conf(wl->conf);
3143 wl_init_prof(wl->profile);
3149 static void wl_deinit_priv(struct wl_priv *wl)
3151 wl_destroy_event_handler(wl);
3152 wl->dongle_up = FALSE; /* dongle down */
3156 wl_deinit_priv_mem(wl);
3159 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3161 struct wireless_dev *wdev;
3163 struct wl_iface *ci;
3166 if (unlikely(!ndev)) {
3167 WL_ERR(("ndev is invaild\n"));
3170 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3171 if (unlikely(!wl_cfg80211_dev)) {
3172 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3175 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
3176 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
3177 if (unlikely(IS_ERR(wdev)))
3180 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3181 wl = wdev_to_wl(wdev);
3184 ci = (struct wl_iface *)wl_to_ci(wl);
3186 ndev->ieee80211_ptr = wdev;
3187 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3188 wdev->netdev = ndev;
3189 err = wl_init_priv(wl);
3190 if (unlikely(err)) {
3191 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
3192 goto cfg80211_attach_out;
3194 wl_set_drvdata(wl_cfg80211_dev, ci);
3195 set_bit(WL_STATUS_READY, &wl->status);
3199 cfg80211_attach_out:
3204 void wl_cfg80211_detach(void)
3212 wl_set_drvdata(wl_cfg80211_dev, NULL);
3213 kfree(wl_cfg80211_dev);
3214 wl_cfg80211_dev = NULL;
3215 wl_clear_sdio_func();
3218 static void wl_wakeup_event(struct wl_priv *wl)
3220 up(&wl->event_sync);
3223 static s32 wl_event_handler(void *data)
3225 struct wl_priv *wl = (struct wl_priv *)data;
3226 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3227 struct wl_event_q *e;
3229 sched_setscheduler(current, SCHED_FIFO, ¶m);
3230 while (likely(!down_interruptible(&wl->event_sync))) {
3231 e = wl_deq_event(wl);
3233 WL_ERR(("eqeue empty..\n"));
3236 WL_DBG(("event type (%d)\n", e->etype));
3237 if (wl->el.handler[e->etype]) {
3238 wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3241 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
3245 complete_and_exit(&wl->event_exit, 0);
3249 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
3251 u32 event_type = ntoh32(e->event_type);
3252 struct wl_priv *wl = ndev_to_wl(ndev);
3253 #if (WL_DBG_LEVEL > 0)
3254 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
3255 wl_dbg_estr[event_type] : (s8 *) "Unknown";
3256 #endif /* (WL_DBG_LEVEL > 0) */
3257 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
3258 if (likely(!wl_enq_event(wl, event_type, e, data)))
3259 wl_wakeup_event(wl);
3262 static void wl_init_eq(struct wl_priv *wl)
3264 wl_init_eq_lock(wl);
3265 INIT_LIST_HEAD(&wl->eq_list);
3268 static void wl_flush_eq(struct wl_priv *wl)
3270 struct wl_event_q *e;
3273 while (!list_empty(&wl->eq_list)) {
3274 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3275 list_del(&e->eq_list);
3282 * retrieve first queued event from head
3285 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3287 struct wl_event_q *e = NULL;
3290 if (likely(!list_empty(&wl->eq_list))) {
3291 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3292 list_del(&e->eq_list);
3300 ** push event to tail of the queue
3304 wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg,
3307 struct wl_event_q *e;
3310 e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
3312 WL_ERR(("event alloc failed\n"));
3317 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
3321 list_add_tail(&e->eq_list, &wl->eq_list);
3327 static void wl_put_event(struct wl_event_q *e)
3332 void wl_cfg80211_sdio_func(void *func)
3334 cfg80211_sdio_func = (struct sdio_func *)func;
3337 static void wl_clear_sdio_func(void)
3339 cfg80211_sdio_func = NULL;
3342 struct sdio_func *wl_cfg80211_get_sdio_func(void)
3344 return cfg80211_sdio_func;
3347 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
3354 case NL80211_IFTYPE_MONITOR:
3355 case NL80211_IFTYPE_WDS:
3356 WL_ERR(("type (%d) : currently we do not support this mode\n",
3360 case NL80211_IFTYPE_ADHOC:
3362 case NL80211_IFTYPE_STATION:
3367 WL_ERR(("invalid type (%d)\n", iftype));
3370 infra = htod32(infra);
3372 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
3373 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
3374 if (unlikely(err)) {
3375 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
3378 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
3379 if (unlikely(err)) {
3380 WL_ERR(("WLC_SET_AP error (%d)\n", err));
3384 return -EINPROGRESS;
3387 #ifndef EMBEDDED_PLATFORM
3388 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3396 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
3400 err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
3401 if (unlikely(err)) {
3402 WL_ERR(("WLC_UP error (%d)\n", err));
3407 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
3411 err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
3412 if (unlikely(err)) {
3413 WL_ERR(("WLC_SET_PM error (%d)\n", err));
3419 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
3421 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3425 /* Match Host and Dongle rx alignment */
3426 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3428 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3429 if (unlikely(err)) {
3430 WL_ERR(("txglomalign error (%d)\n", err));
3431 goto dongle_glom_out;
3433 /* disable glom option per default */
3434 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3435 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3436 if (unlikely(err)) {
3437 WL_ERR(("txglom error (%d)\n", err));
3438 goto dongle_glom_out;
3445 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3447 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3451 /* Setup timeout if Beacons are lost and roam is
3452 off to report link down */
3454 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
3456 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3457 if (unlikely(err)) {
3458 WL_ERR(("bcn_timeout error (%d)\n", err));
3459 goto dongle_rom_out;
3462 /* Enable/Disable built-in roaming to allow supplicant
3463 to take care of roaming */
3464 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
3465 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3466 if (unlikely(err)) {
3467 WL_ERR(("roam_off error (%d)\n", err));
3468 goto dongle_rom_out;
3474 static s32 wl_dongle_eventmsg(struct net_device *ndev)
3477 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3479 s8 eventmask[WL_EVENTING_MASK_LEN];
3482 /* Setup event_msgs */
3483 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3485 err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
3486 if (unlikely(err)) {
3487 WL_ERR(("Get event_msgs error (%d)\n", err));
3488 goto dongle_eventmsg_out;
3490 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3492 setbit(eventmask, WLC_E_SET_SSID);
3493 setbit(eventmask, WLC_E_PRUNE);
3494 setbit(eventmask, WLC_E_AUTH);
3495 setbit(eventmask, WLC_E_REASSOC);
3496 setbit(eventmask, WLC_E_REASSOC_IND);
3497 setbit(eventmask, WLC_E_DEAUTH_IND);
3498 setbit(eventmask, WLC_E_DISASSOC_IND);
3499 setbit(eventmask, WLC_E_DISASSOC);
3500 setbit(eventmask, WLC_E_JOIN);
3501 setbit(eventmask, WLC_E_ASSOC_IND);
3502 setbit(eventmask, WLC_E_PSK_SUP);
3503 setbit(eventmask, WLC_E_LINK);
3504 setbit(eventmask, WLC_E_NDIS_LINK);
3505 setbit(eventmask, WLC_E_MIC_ERROR);
3506 setbit(eventmask, WLC_E_PMKID_CACHE);
3507 setbit(eventmask, WLC_E_TXFAIL);
3508 setbit(eventmask, WLC_E_JOIN_START);
3509 setbit(eventmask, WLC_E_SCAN_COMPLETE);
3511 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3513 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3514 if (unlikely(err)) {
3515 WL_ERR(("Set event_msgs error (%d)\n", err));
3516 goto dongle_eventmsg_out;
3519 dongle_eventmsg_out:
3524 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3525 s32 scan_unassoc_time)
3529 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
3530 sizeof(scan_assoc_time));
3532 if (err == -EOPNOTSUPP) {
3533 WL_INFO(("Scan assoc time is not supported\n"));
3535 WL_ERR(("Scan assoc time error (%d)\n", err));
3537 goto dongle_scantime_out;
3539 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
3540 sizeof(scan_unassoc_time));
3542 if (err == -EOPNOTSUPP) {
3543 WL_INFO(("Scan unassoc time is not supported\n"));
3545 WL_ERR(("Scan unassoc time error (%d)\n", err));
3547 goto dongle_scantime_out;
3550 dongle_scantime_out:
3555 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
3557 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3561 /* Set ARP offload */
3562 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3563 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3565 if (err == -EOPNOTSUPP)
3566 WL_INFO(("arpoe is not supported\n"));
3568 WL_ERR(("arpoe error (%d)\n", err));
3570 goto dongle_offload_out;
3572 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3573 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3575 if (err == -EOPNOTSUPP)
3576 WL_INFO(("arp_ol is not supported\n"));
3578 WL_ERR(("arp_ol error (%d)\n", err));
3580 goto dongle_offload_out;
3587 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
3589 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
3591 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3592 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3595 src = src + 2; /* Skip past 0x */
3596 if (strlen(src) % 2 != 0) {
3597 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3600 for (i = 0; *src != '\0'; i++) {
3602 strncpy(num, src, 2);
3604 dst[i] = (u8) strtoul(num, NULL, 16);
3610 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
3612 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3615 struct wl_pkt_filter pkt_filter;
3616 struct wl_pkt_filter *pkt_filterp;
3624 /* add a default packet filter pattern */
3625 str = "pkt_filter_add";
3626 str_len = strlen(str);
3627 strncpy(buf, str, str_len);
3628 buf[str_len] = '\0';
3629 buf_len = str_len + 1;
3631 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3633 /* Parse packet filter id. */
3634 pkt_filter.id = htod32(100);
3636 /* Parse filter polarity. */
3637 pkt_filter.negate_match = htod32(0);
3639 /* Parse filter type. */
3640 pkt_filter.type = htod32(0);
3642 /* Parse pattern filter offset. */
3643 pkt_filter.u.pattern.offset = htod32(0);
3645 /* Parse pattern filter mask. */
3646 mask_size = htod32(wl_pattern_atoh("0xff",
3647 (char *)pkt_filterp->u.pattern.
3650 /* Parse pattern filter pattern. */
3651 pattern_size = htod32(wl_pattern_atoh("0x00",
3652 (char *)&pkt_filterp->u.pattern.
3653 mask_and_pattern[mask_size]));
3655 if (mask_size != pattern_size) {
3656 WL_ERR(("Mask and pattern not the same size\n"));
3658 goto dongle_filter_out;
3661 pkt_filter.u.pattern.size_bytes = mask_size;
3662 buf_len += WL_PKT_FILTER_FIXED_LEN;
3663 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3665 /* Keep-alive attributes are set in local
3666 * variable (keep_alive_pkt), and
3667 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3668 * guarantee that the buffer is properly aligned.
3670 memcpy((char *)pkt_filterp, &pkt_filter,
3671 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3673 err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
3675 if (err == -EOPNOTSUPP) {
3676 WL_INFO(("filter not supported\n"));
3678 WL_ERR(("filter (%d)\n", err));
3680 goto dongle_filter_out;
3683 /* set mode to allow pattern */
3684 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3686 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3688 if (err == -EOPNOTSUPP) {
3689 WL_INFO(("filter_mode not supported\n"));
3691 WL_ERR(("filter_mode (%d)\n", err));
3693 goto dongle_filter_out;
3699 #endif /* !EMBEDDED_PLATFORM */
3701 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
3704 #define DHD_SDALIGN 32
3706 struct net_device *ndev;
3707 struct wireless_dev *wdev;
3713 ndev = wl_to_ndev(wl);
3714 wdev = ndev->ieee80211_ptr;
3718 #ifndef EMBEDDED_PLATFORM
3719 err = wl_dongle_up(ndev, 0);
3721 goto default_conf_out;
3722 err = wl_dongle_country(ndev, 0);
3724 goto default_conf_out;
3725 err = wl_dongle_power(ndev, PM_FAST);
3727 goto default_conf_out;
3728 err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
3730 goto default_conf_out;
3731 err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
3733 goto default_conf_out;
3734 err = wl_dongle_eventmsg(ndev);
3736 goto default_conf_out;
3738 wl_dongle_scantime(ndev, 40, 80);
3739 wl_dongle_offload(ndev, 1, 0xf);
3740 wl_dongle_filter(ndev, 1);
3741 #endif /* !EMBEDDED_PLATFORM */
3743 err = wl_dongle_mode(ndev, wdev->iftype);
3744 if (unlikely(err && err != -EINPROGRESS))
3745 goto default_conf_out;
3746 err = wl_dongle_probecap(wl);
3748 goto default_conf_out;
3750 /* -EINPROGRESS: Call commit handler */
3756 wl->dongle_up = TRUE;
3762 static s32 wl_update_wiphybands(struct wl_priv *wl)
3764 struct wiphy *wiphy;
3769 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
3771 if (unlikely(err)) {
3772 WL_ERR(("error (%d)\n", err));
3776 phy = ((char *)&phy_list)[1];
3777 WL_DBG(("%c phy\n", phy));
3778 if (phy == 'n' || phy == 'a') {
3779 wiphy = wl_to_wiphy(wl);
3780 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3786 static s32 __wl_cfg80211_up(struct wl_priv *wl)
3790 err = wl_config_dongle(wl, FALSE);
3794 wl_invoke_iscan(wl);
3795 set_bit(WL_STATUS_READY, &wl->status);
3799 static s32 __wl_cfg80211_down(struct wl_priv *wl)
3801 struct net_device *ndev = wl_to_ndev(wl);
3804 /* Check if cfg80211 interface is already down */
3805 if (!test_bit(WL_STATUS_READY, &wl->status))
3806 return err; /* it is even not ready */
3808 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3810 if (wl->scan_request) {
3811 cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE
3813 wl_set_mpc(ndev, 1);
3814 wl->scan_request = NULL;
3816 clear_bit(WL_STATUS_READY, &wl->status);
3817 clear_bit(WL_STATUS_SCANNING, &wl->status);
3818 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3819 clear_bit(WL_STATUS_CONNECTED, &wl->status);
3824 s32 wl_cfg80211_up(void)
3830 mutex_lock(&wl->usr_sync);
3831 err = __wl_cfg80211_up(wl);
3832 mutex_unlock(&wl->usr_sync);
3837 s32 wl_cfg80211_down(void)
3843 mutex_lock(&wl->usr_sync);
3844 err = __wl_cfg80211_down(wl);
3845 mutex_unlock(&wl->usr_sync);
3850 static s32 wl_dongle_probecap(struct wl_priv *wl)
3854 err = wl_update_wiphybands(wl);
3861 static void *wl_read_prof(struct wl_priv *wl, s32 item)
3865 return &wl->profile->sec;
3867 return &wl->profile->active;
3869 return &wl->profile->bssid;
3871 return &wl->profile->ssid;
3873 WL_ERR(("invalid item (%d)\n", item));
3878 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
3882 struct wlc_ssid *ssid;
3886 ssid = (wlc_ssid_t *) data;
3887 memset(wl->profile->ssid.SSID, 0,
3888 sizeof(wl->profile->ssid.SSID));
3889 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
3890 wl->profile->ssid.SSID_len = ssid->SSID_len;
3894 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
3896 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
3899 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
3902 wl->profile->active = *(bool *) data;
3905 WL_ERR(("unsupported item (%d)\n", item));
3913 void wl_cfg80211_dbg_level(u32 level)
3916 * prohibit to change debug level
3917 * by insmod parameter.
3918 * eventually debug level will be configured
3919 * in compile time by using CONFIG_XXX
3921 /* wl_dbg_level = level; */
3924 static bool wl_is_ibssmode(struct wl_priv *wl)
3926 return wl->conf->mode == WL_MODE_IBSS;
3929 static bool wl_is_ibssstarter(struct wl_priv *wl)
3931 return wl->ibss_starter;
3934 static void wl_rst_ie(struct wl_priv *wl)
3936 struct wl_ie *ie = wl_to_ie(wl);
3941 static s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
3943 struct wl_ie *ie = wl_to_ie(wl);
3946 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3947 WL_ERR(("ei crosses buffer boundary\n"));
3950 ie->buf[ie->offset] = t;
3951 ie->buf[ie->offset + 1] = l;
3952 memcpy(&ie->buf[ie->offset + 2], v, l);
3953 ie->offset += l + 2;
3958 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
3960 struct wl_ie *ie = wl_to_ie(wl);
3963 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
3964 WL_ERR(("ei_stream crosses buffer boundary\n"));
3967 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
3968 ie->offset += ie_size;
3973 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
3975 struct wl_ie *ie = wl_to_ie(wl);
3978 if (unlikely(ie->offset > dst_size)) {
3979 WL_ERR(("dst_size is not enough\n"));
3982 memcpy(dst, &ie->buf[0], ie->offset);
3987 static u32 wl_get_ielen(struct wl_priv *wl)
3989 struct wl_ie *ie = wl_to_ie(wl);
3994 static void wl_link_up(struct wl_priv *wl)
3999 static void wl_link_down(struct wl_priv *wl)
4001 struct wl_connect_info *conn_info = wl_to_conn(wl);
4003 wl->link_up = FALSE;
4004 kfree(conn_info->req_ie);
4005 conn_info->req_ie = NULL;
4006 conn_info->req_ie_len = 0;
4007 kfree(conn_info->resp_ie);
4008 conn_info->resp_ie = NULL;
4009 conn_info->resp_ie_len = 0;
4012 static void wl_lock_eq(struct wl_priv *wl)
4014 spin_lock_irq(&wl->eq_lock);
4017 static void wl_unlock_eq(struct wl_priv *wl)
4019 spin_unlock_irq(&wl->eq_lock);
4022 static void wl_init_eq_lock(struct wl_priv *wl)
4024 spin_lock_init(&wl->eq_lock);
4027 static void wl_delay(u32 ms)
4029 if (ms < 1000 / HZ) {
4037 static void wl_set_drvdata(struct wl_dev *dev, void *data)
4039 dev->driver_data = data;
4042 static void *wl_get_drvdata(struct wl_dev *dev)
4044 return dev->driver_data;
4047 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
4049 const struct firmware *fw_entry;
4054 fw_entry = wl->fw->fw_entry;
4056 if (fw_entry->size < wl->fw->ptr + size)
4057 size = fw_entry->size - wl->fw->ptr;
4059 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
4060 wl->fw->ptr += size;
4064 void wl_cfg80211_release_fw(void)
4069 release_firmware(wl->fw->fw_entry);
4073 void *wl_cfg80211_request_fw(s8 *file_name)
4076 const struct firmware *fw_entry = NULL;
4079 WL_DBG(("file name : \"%s\"\n", file_name));
4082 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
4083 err = request_firmware(&wl->fw->fw_entry, file_name,
4084 &wl_cfg80211_get_sdio_func()->dev);
4085 if (unlikely(err)) {
4086 WL_ERR(("Could not download fw (%d)\n", err));
4089 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
4090 fw_entry = wl->fw->fw_entry;
4092 WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
4095 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
4096 err = request_firmware(&wl->fw->fw_entry, file_name,
4097 &wl_cfg80211_get_sdio_func()->dev);
4098 if (unlikely(err)) {
4099 WL_ERR(("Could not download nvram (%d)\n", err));
4102 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
4103 fw_entry = wl->fw->fw_entry;
4105 WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
4109 WL_DBG(("Downloading already done. Nothing to do more\n"));
4114 if (unlikely(err)) {
4118 return (void *)fw_entry->data;
4121 s8 *wl_cfg80211_get_fwname(void)
4126 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4127 return wl->fw->fw_name;
4130 s8 *wl_cfg80211_get_nvramname(void)
4135 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4136 return wl->fw->nvram_name;
4139 static void wl_set_mpc(struct net_device *ndev, int mpc)
4143 err = wl_dev_intvar_set(ndev, "mpc", mpc);
4144 if (unlikely(err)) {
4145 WL_ERR(("fail to set mpc\n"));
4148 WL_DBG(("MPC : %d\n", mpc));