2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/kernel.h>
18 #include <linux/if_arp.h>
22 #include <bcmendian.h>
23 #include <proto/ethernet.h>
25 #include <asm/uaccess.h>
27 #include <dngl_stats.h>
32 #include <linux/kthread.h>
33 #include <linux/netdevice.h>
34 #include <linux/sched.h>
35 #include <linux/etherdevice.h>
36 #include <linux/wireless.h>
37 #include <linux/ieee80211.h>
38 #include <net/cfg80211.h>
40 #include <net/rtnetlink.h>
41 #include <linux/mmc/sdio_func.h>
42 #include <linux/firmware.h>
43 #include <wl_cfg80211.h>
45 static struct sdio_func *cfg80211_sdio_func;
46 static struct wl_dev *wl_cfg80211_dev;
48 u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
50 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin"
51 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
54 ** cfg80211_ops api/callback list
56 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
57 struct net_device *ndev,
58 enum nl80211_iftype type, u32 *flags,
59 struct vif_params *params);
60 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
61 struct cfg80211_scan_request *request,
62 struct cfg80211_ssid *this_ssid);
63 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
64 struct cfg80211_scan_request *request);
65 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
66 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
67 struct cfg80211_ibss_params *params);
68 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
69 struct net_device *dev);
70 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
71 struct net_device *dev, u8 *mac,
72 struct station_info *sinfo);
73 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
74 struct net_device *dev, bool enabled,
76 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
77 struct net_device *dev,
79 const struct cfg80211_bitrate_mask
81 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
82 struct cfg80211_connect_params *sme);
83 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
85 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
86 enum nl80211_tx_power_setting type,
88 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
89 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
90 struct net_device *dev,
92 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
93 u8 key_idx, bool pairwise, const u8 *mac_addr,
94 struct key_params *params);
95 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
96 u8 key_idx, bool pairwise, const u8 *mac_addr);
97 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
98 u8 key_idx, bool pairwise, const u8 *mac_addr,
99 void *cookie, void (*callback) (void *cookie,
103 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
104 struct net_device *dev,
106 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
107 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
108 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
109 struct cfg80211_pmksa *pmksa);
110 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
111 struct cfg80211_pmksa *pmksa);
112 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
113 struct net_device *dev);
115 ** event & event Q handlers for cfg80211 interfaces
117 static s32 wl_create_event_handler(struct wl_priv *wl);
118 static void wl_destroy_event_handler(struct wl_priv *wl);
119 static s32 wl_event_handler(void *data);
120 static void wl_init_eq(struct wl_priv *wl);
121 static void wl_flush_eq(struct wl_priv *wl);
122 static void wl_lock_eq(struct wl_priv *wl);
123 static void wl_unlock_eq(struct wl_priv *wl);
124 static void wl_init_eq_lock(struct wl_priv *wl);
125 static void wl_init_eloop_handler(struct wl_event_loop *el);
126 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
127 static s32 wl_enq_event(struct wl_priv *wl, u32 type,
128 const wl_event_msg_t *msg, void *data);
129 static void wl_put_event(struct wl_event_q *e);
130 static void wl_wakeup_event(struct wl_priv *wl);
131 static s32 wl_notify_connect_status(struct wl_priv *wl,
132 struct net_device *ndev,
133 const wl_event_msg_t *e, void *data);
134 static s32 wl_notify_roaming_status(struct wl_priv *wl,
135 struct net_device *ndev,
136 const wl_event_msg_t *e, void *data);
137 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
138 const wl_event_msg_t *e, void *data);
139 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
140 const wl_event_msg_t *e, void *data,
142 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
143 const wl_event_msg_t *e, void *data);
144 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
145 const wl_event_msg_t *e, void *data);
148 ** register/deregister sdio function
150 struct sdio_func *wl_cfg80211_get_sdio_func(void);
151 static void wl_clear_sdio_func(void);
156 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
158 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
160 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
161 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
163 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
167 ** cfg80211 set_wiphy_params utilities
169 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
170 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
171 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
174 ** wl profile utilities
176 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
177 void *data, s32 item);
178 static void *wl_read_prof(struct wl_priv *wl, s32 item);
179 static void wl_init_prof(struct wl_profile *prof);
182 ** cfg80211 connect utilites
184 static s32 wl_set_wpa_version(struct net_device *dev,
185 struct cfg80211_connect_params *sme);
186 static s32 wl_set_auth_type(struct net_device *dev,
187 struct cfg80211_connect_params *sme);
188 static s32 wl_set_set_cipher(struct net_device *dev,
189 struct cfg80211_connect_params *sme);
190 static s32 wl_set_key_mgmt(struct net_device *dev,
191 struct cfg80211_connect_params *sme);
192 static s32 wl_set_set_sharedkey(struct net_device *dev,
193 struct cfg80211_connect_params *sme);
194 static s32 wl_get_assoc_ies(struct wl_priv *wl);
195 static void wl_ch_to_chanspec(int ch,
196 struct wl_join_params *join_params, size_t *join_params_size);
199 ** information element utilities
201 static void wl_rst_ie(struct wl_priv *wl);
202 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
203 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
204 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
205 static u32 wl_get_ielen(struct wl_priv *wl);
207 static s32 wl_mode_to_nl80211_iftype(s32 mode);
209 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
211 static void wl_free_wdev(struct wl_priv *wl);
213 static s32 wl_inform_bss(struct wl_priv *wl);
214 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
215 static s32 wl_update_bss_info(struct wl_priv *wl);
217 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
218 u8 key_idx, const u8 *mac_addr,
219 struct key_params *params);
222 ** key indianess swap utilities
224 static void swap_key_from_BE(struct wl_wsec_key *key);
225 static void swap_key_to_BE(struct wl_wsec_key *key);
228 ** wl_priv memory init/deinit utilities
230 static s32 wl_init_priv_mem(struct wl_priv *wl);
231 static void wl_deinit_priv_mem(struct wl_priv *wl);
233 static void wl_delay(u32 ms);
236 ** store/restore cfg80211 instance data
238 static void wl_set_drvdata(struct wl_dev *dev, void *data);
239 static void *wl_get_drvdata(struct wl_dev *dev);
242 ** ibss mode utilities
244 static bool wl_is_ibssmode(struct wl_priv *wl);
245 static bool wl_is_ibssstarter(struct wl_priv *wl);
248 ** dongle up/down , default configuration utilities
250 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
251 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
252 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
253 static void wl_link_up(struct wl_priv *wl);
254 static void wl_link_down(struct wl_priv *wl);
255 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
256 static s32 __wl_cfg80211_up(struct wl_priv *wl);
257 static s32 __wl_cfg80211_down(struct wl_priv *wl);
258 static s32 wl_dongle_probecap(struct wl_priv *wl);
259 static void wl_init_conf(struct wl_conf *conf);
262 ** dongle configuration utilities
264 #ifndef EMBEDDED_PLATFORM
265 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
266 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
267 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
268 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
269 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
271 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
273 static s32 wl_dongle_eventmsg(struct net_device *ndev);
274 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
275 s32 scan_unassoc_time);
276 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
278 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
279 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
280 static s32 wl_update_wiphybands(struct wl_priv *wl);
281 #endif /* !EMBEDDED_PLATFORM */
282 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
287 static void wl_iscan_timer(unsigned long data);
288 static void wl_term_iscan(struct wl_priv *wl);
289 static s32 wl_init_iscan(struct wl_priv *wl);
290 static s32 wl_iscan_thread(void *data);
291 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
292 void *param, s32 paramlen, void *bufptr,
294 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
295 void *param, s32 paramlen, void *bufptr,
297 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
299 static s32 wl_do_iscan(struct wl_priv *wl);
300 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
301 static s32 wl_invoke_iscan(struct wl_priv *wl);
302 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
303 struct wl_scan_results **bss_list);
304 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
305 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
306 static s32 wl_iscan_done(struct wl_priv *wl);
307 static s32 wl_iscan_pending(struct wl_priv *wl);
308 static s32 wl_iscan_inprogress(struct wl_priv *wl);
309 static s32 wl_iscan_aborted(struct wl_priv *wl);
312 ** fw/nvram downloading handler
314 static void wl_init_fw(struct wl_fw_ctrl *fw);
317 * find most significant bit set
319 static __used u32 wl_find_msb(u16 bit16);
322 * update pmklist to dongle
324 static __used s32 wl_update_pmklist(struct net_device *dev,
325 struct wl_pmk_list *pmk_list, s32 err);
327 static void wl_set_mpc(struct net_device *ndev, int mpc);
332 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
333 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
335 #define WL_PRIV_GET() \
337 struct wl_iface *ci; \
338 if (unlikely(!(wl_cfg80211_dev && \
339 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
340 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
346 #define CHECK_SYS_UP() \
348 struct wl_priv *wl = wiphy_to_wl(wiphy); \
349 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
350 WL_INFO(("device is not ready : status (%d)\n", \
356 extern int dhd_wait_pend8021x(struct net_device *dev);
358 #if (WL_DBG_LEVEL > 0)
359 #define WL_DBG_ESTR_MAX 32
360 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
361 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
362 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
363 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
364 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
365 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
366 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
367 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
369 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
371 "RADIO", "PSM_WATCHDOG",
373 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
374 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
375 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
377 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
379 #endif /* WL_DBG_LEVEL */
381 #define CHAN2G(_channel, _freq, _flags) { \
382 .band = IEEE80211_BAND_2GHZ, \
383 .center_freq = (_freq), \
384 .hw_value = (_channel), \
386 .max_antenna_gain = 0, \
390 #define CHAN5G(_channel, _flags) { \
391 .band = IEEE80211_BAND_5GHZ, \
392 .center_freq = 5000 + (5 * (_channel)), \
393 .hw_value = (_channel), \
395 .max_antenna_gain = 0, \
399 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
400 #define RATETAB_ENT(_rateid, _flags) \
402 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
403 .hw_value = (_rateid), \
407 static struct ieee80211_rate __wl_rates[] = {
408 RATETAB_ENT(WLC_RATE_1M, 0),
409 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
410 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
411 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
412 RATETAB_ENT(WLC_RATE_6M, 0),
413 RATETAB_ENT(WLC_RATE_9M, 0),
414 RATETAB_ENT(WLC_RATE_12M, 0),
415 RATETAB_ENT(WLC_RATE_18M, 0),
416 RATETAB_ENT(WLC_RATE_24M, 0),
417 RATETAB_ENT(WLC_RATE_36M, 0),
418 RATETAB_ENT(WLC_RATE_48M, 0),
419 RATETAB_ENT(WLC_RATE_54M, 0),
422 #define wl_a_rates (__wl_rates + 4)
423 #define wl_a_rates_size 8
424 #define wl_g_rates (__wl_rates + 0)
425 #define wl_g_rates_size 12
427 static struct ieee80211_channel __wl_2ghz_channels[] = {
444 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
445 CHAN5G(34, 0), CHAN5G(36, 0),
446 CHAN5G(38, 0), CHAN5G(40, 0),
447 CHAN5G(42, 0), CHAN5G(44, 0),
448 CHAN5G(46, 0), CHAN5G(48, 0),
449 CHAN5G(52, 0), CHAN5G(56, 0),
450 CHAN5G(60, 0), CHAN5G(64, 0),
451 CHAN5G(100, 0), CHAN5G(104, 0),
452 CHAN5G(108, 0), CHAN5G(112, 0),
453 CHAN5G(116, 0), CHAN5G(120, 0),
454 CHAN5G(124, 0), CHAN5G(128, 0),
455 CHAN5G(132, 0), CHAN5G(136, 0),
456 CHAN5G(140, 0), CHAN5G(149, 0),
457 CHAN5G(153, 0), CHAN5G(157, 0),
458 CHAN5G(161, 0), CHAN5G(165, 0),
459 CHAN5G(184, 0), CHAN5G(188, 0),
460 CHAN5G(192, 0), CHAN5G(196, 0),
461 CHAN5G(200, 0), CHAN5G(204, 0),
462 CHAN5G(208, 0), CHAN5G(212, 0),
466 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
467 CHAN5G(32, 0), CHAN5G(34, 0),
468 CHAN5G(36, 0), CHAN5G(38, 0),
469 CHAN5G(40, 0), CHAN5G(42, 0),
470 CHAN5G(44, 0), CHAN5G(46, 0),
471 CHAN5G(48, 0), CHAN5G(50, 0),
472 CHAN5G(52, 0), CHAN5G(54, 0),
473 CHAN5G(56, 0), CHAN5G(58, 0),
474 CHAN5G(60, 0), CHAN5G(62, 0),
475 CHAN5G(64, 0), CHAN5G(66, 0),
476 CHAN5G(68, 0), CHAN5G(70, 0),
477 CHAN5G(72, 0), CHAN5G(74, 0),
478 CHAN5G(76, 0), CHAN5G(78, 0),
479 CHAN5G(80, 0), CHAN5G(82, 0),
480 CHAN5G(84, 0), CHAN5G(86, 0),
481 CHAN5G(88, 0), CHAN5G(90, 0),
482 CHAN5G(92, 0), CHAN5G(94, 0),
483 CHAN5G(96, 0), CHAN5G(98, 0),
484 CHAN5G(100, 0), CHAN5G(102, 0),
485 CHAN5G(104, 0), CHAN5G(106, 0),
486 CHAN5G(108, 0), CHAN5G(110, 0),
487 CHAN5G(112, 0), CHAN5G(114, 0),
488 CHAN5G(116, 0), CHAN5G(118, 0),
489 CHAN5G(120, 0), CHAN5G(122, 0),
490 CHAN5G(124, 0), CHAN5G(126, 0),
491 CHAN5G(128, 0), CHAN5G(130, 0),
492 CHAN5G(132, 0), CHAN5G(134, 0),
493 CHAN5G(136, 0), CHAN5G(138, 0),
494 CHAN5G(140, 0), CHAN5G(142, 0),
495 CHAN5G(144, 0), CHAN5G(145, 0),
496 CHAN5G(146, 0), CHAN5G(147, 0),
497 CHAN5G(148, 0), CHAN5G(149, 0),
498 CHAN5G(150, 0), CHAN5G(151, 0),
499 CHAN5G(152, 0), CHAN5G(153, 0),
500 CHAN5G(154, 0), CHAN5G(155, 0),
501 CHAN5G(156, 0), CHAN5G(157, 0),
502 CHAN5G(158, 0), CHAN5G(159, 0),
503 CHAN5G(160, 0), CHAN5G(161, 0),
504 CHAN5G(162, 0), CHAN5G(163, 0),
505 CHAN5G(164, 0), CHAN5G(165, 0),
506 CHAN5G(166, 0), CHAN5G(168, 0),
507 CHAN5G(170, 0), CHAN5G(172, 0),
508 CHAN5G(174, 0), CHAN5G(176, 0),
509 CHAN5G(178, 0), CHAN5G(180, 0),
510 CHAN5G(182, 0), CHAN5G(184, 0),
511 CHAN5G(186, 0), CHAN5G(188, 0),
512 CHAN5G(190, 0), CHAN5G(192, 0),
513 CHAN5G(194, 0), CHAN5G(196, 0),
514 CHAN5G(198, 0), CHAN5G(200, 0),
515 CHAN5G(202, 0), CHAN5G(204, 0),
516 CHAN5G(206, 0), CHAN5G(208, 0),
517 CHAN5G(210, 0), CHAN5G(212, 0),
518 CHAN5G(214, 0), CHAN5G(216, 0),
519 CHAN5G(218, 0), CHAN5G(220, 0),
520 CHAN5G(222, 0), CHAN5G(224, 0),
521 CHAN5G(226, 0), CHAN5G(228, 0),
524 static struct ieee80211_supported_band __wl_band_2ghz = {
525 .band = IEEE80211_BAND_2GHZ,
526 .channels = __wl_2ghz_channels,
527 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
528 .bitrates = wl_g_rates,
529 .n_bitrates = wl_g_rates_size,
532 static struct ieee80211_supported_band __wl_band_5ghz_a = {
533 .band = IEEE80211_BAND_5GHZ,
534 .channels = __wl_5ghz_a_channels,
535 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
536 .bitrates = wl_a_rates,
537 .n_bitrates = wl_a_rates_size,
540 static struct ieee80211_supported_band __wl_band_5ghz_n = {
541 .band = IEEE80211_BAND_5GHZ,
542 .channels = __wl_5ghz_n_channels,
543 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
544 .bitrates = wl_a_rates,
545 .n_bitrates = wl_a_rates_size,
548 static const u32 __wl_cipher_suites[] = {
549 WLAN_CIPHER_SUITE_WEP40,
550 WLAN_CIPHER_SUITE_WEP104,
551 WLAN_CIPHER_SUITE_TKIP,
552 WLAN_CIPHER_SUITE_CCMP,
553 WLAN_CIPHER_SUITE_AES_CMAC,
556 static void swap_key_from_BE(struct wl_wsec_key *key)
558 key->index = htod32(key->index);
559 key->len = htod32(key->len);
560 key->algo = htod32(key->algo);
561 key->flags = htod32(key->flags);
562 key->rxiv.hi = htod32(key->rxiv.hi);
563 key->rxiv.lo = htod16(key->rxiv.lo);
564 key->iv_initialized = htod32(key->iv_initialized);
567 static void swap_key_to_BE(struct wl_wsec_key *key)
569 key->index = dtoh32(key->index);
570 key->len = dtoh32(key->len);
571 key->algo = dtoh32(key->algo);
572 key->flags = dtoh32(key->flags);
573 key->rxiv.hi = dtoh32(key->rxiv.hi);
574 key->rxiv.lo = dtoh16(key->rxiv.lo);
575 key->iv_initialized = dtoh32(key->iv_initialized);
579 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
586 memset(&ioc, 0, sizeof(ioc));
590 strcpy(ifr.ifr_name, dev->name);
591 ifr.ifr_data = (caddr_t)&ioc;
595 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
602 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
603 enum nl80211_iftype type, u32 *flags,
604 struct vif_params *params)
606 struct wl_priv *wl = wiphy_to_wl(wiphy);
607 struct wireless_dev *wdev;
614 case NL80211_IFTYPE_MONITOR:
615 case NL80211_IFTYPE_WDS:
616 WL_ERR(("type (%d) : currently we do not support this type\n",
619 case NL80211_IFTYPE_ADHOC:
620 wl->conf->mode = WL_MODE_IBSS;
622 case NL80211_IFTYPE_STATION:
623 wl->conf->mode = WL_MODE_BSS;
629 infra = htod32(infra);
631 wdev = ndev->ieee80211_ptr;
633 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
634 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
636 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
639 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
641 WL_ERR(("WLC_SET_AP error (%d)\n", err));
645 /* -EINPROGRESS: Call commit handler */
649 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
651 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
652 params->bss_type = DOT11_BSSTYPE_ANY;
653 params->scan_type = 0;
654 params->nprobes = -1;
655 params->active_time = -1;
656 params->passive_time = -1;
657 params->home_time = -1;
658 params->channel_num = 0;
660 params->nprobes = htod32(params->nprobes);
661 params->active_time = htod32(params->active_time);
662 params->passive_time = htod32(params->passive_time);
663 params->home_time = htod32(params->home_time);
664 if (ssid && ssid->SSID_len)
665 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
670 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
671 s32 paramlen, void *bufptr, s32 buflen)
675 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
676 BUG_ON(unlikely(!iolen));
678 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
682 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
683 s32 paramlen, void *bufptr, s32 buflen)
687 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
688 BUG_ON(unlikely(!iolen));
690 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
694 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
697 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
698 struct wl_iscan_params *params;
701 if (ssid && ssid->SSID_len)
702 params_size += sizeof(struct wlc_ssid);
703 params = kzalloc(params_size, GFP_KERNEL);
704 if (unlikely(!params))
706 memset(params, 0, params_size);
707 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
709 wl_iscan_prep(¶ms->params, ssid);
711 params->version = htod32(ISCAN_REQ_VERSION);
712 params->action = htod16(action);
713 params->scan_duration = htod16(0);
715 /* params_size += offsetof(wl_iscan_params_t, params); */
716 err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
717 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
720 WL_INFO(("system busy : iscan canceled\n"));
722 WL_ERR(("error (%d)\n", err));
729 static s32 wl_do_iscan(struct wl_priv *wl)
731 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
732 struct net_device *ndev = wl_to_ndev(wl);
733 struct wlc_ssid ssid;
737 /* Broadcast scan by default */
738 memset(&ssid, 0, sizeof(ssid));
740 iscan->state = WL_ISCAN_STATE_SCANING;
742 passive_scan = wl->active_scan ? 0 : 1;
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));
750 wl->iscan_kickstart = true;
751 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
752 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
759 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
760 struct cfg80211_scan_request *request,
761 struct cfg80211_ssid *this_ssid)
763 struct wl_priv *wl = ndev_to_wl(ndev);
764 struct cfg80211_ssid *ssids;
765 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 passive_scan = wl->active_scan ? 0 : 1;
825 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
826 &passive_scan, sizeof(passive_scan));
828 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
832 err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
836 WL_INFO(("system busy : scan for \"%s\" "
837 "canceled\n", sr->ssid.SSID));
839 WL_ERR(("WLC_SCAN error (%d)\n", err));
849 clear_bit(WL_STATUS_SCANNING, &wl->status);
850 wl->scan_request = NULL;
855 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
856 struct cfg80211_scan_request *request)
861 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
863 WL_DBG(("scan error (%d)\n", err));
870 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
872 s8 buf[WLC_IOCTL_SMLEN];
877 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
878 BUG_ON(unlikely(!len));
880 err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
882 WL_ERR(("error (%d)\n", err));
889 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
892 s8 buf[WLC_IOCTL_SMLEN];
900 bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
902 BUG_ON(unlikely(!len));
903 err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
905 WL_ERR(("error (%d)\n", err));
907 *retval = dtoh32(var.val);
912 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
916 err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
918 WL_ERR(("Error (%d)\n", err));
924 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
928 err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
930 WL_ERR(("Error (%d)\n", err));
936 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
939 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
941 retry = htod32(retry);
942 err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
944 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
950 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
952 struct wl_priv *wl = wiphy_to_wl(wiphy);
953 struct net_device *ndev = wl_to_ndev(wl);
957 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
958 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
959 wl->conf->rts_threshold = wiphy->rts_threshold;
960 err = wl_set_rts(ndev, wl->conf->rts_threshold);
964 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
965 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
966 wl->conf->frag_threshold = wiphy->frag_threshold;
967 err = wl_set_frag(ndev, wl->conf->frag_threshold);
971 if (changed & WIPHY_PARAM_RETRY_LONG
972 && (wl->conf->retry_long != wiphy->retry_long)) {
973 wl->conf->retry_long = wiphy->retry_long;
974 err = wl_set_retry(ndev, wl->conf->retry_long, true);
978 if (changed & WIPHY_PARAM_RETRY_SHORT
979 && (wl->conf->retry_short != wiphy->retry_short)) {
980 wl->conf->retry_short = wiphy->retry_short;
981 err = wl_set_retry(ndev, wl->conf->retry_short, false);
991 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
992 struct cfg80211_ibss_params *params)
994 struct wl_priv *wl = wiphy_to_wl(wiphy);
995 struct cfg80211_bss *bss;
996 struct ieee80211_channel *chan;
997 struct wl_join_params join_params;
998 struct cfg80211_ssid ssid;
1003 if (params->bssid) {
1004 WL_ERR(("Invalid bssid\n"));
1007 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1009 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1010 ssid.ssid_len = params->ssid_len;
1013 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1019 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1020 rtnl_unlock(); /* to allow scan_inform to paropagate
1021 to cfg80211 plane */
1022 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1023 till scan done.... */
1025 bss = cfg80211_get_ibss(wiphy, NULL,
1026 params->ssid, params->ssid_len);
1029 wl->ibss_starter = false;
1030 WL_DBG(("Found IBSS\n"));
1032 wl->ibss_starter = true;
1034 chan = params->channel;
1036 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1038 ** Join with specific BSSID and cached SSID
1039 ** If SSID is zero join based on BSSID only
1041 memset(&join_params, 0, sizeof(join_params));
1042 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1044 join_params.ssid.SSID_len = htod32(params->ssid_len);
1046 memcpy(&join_params.params.bssid, params->bssid,
1049 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1051 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1052 sizeof(join_params));
1053 if (unlikely(err)) {
1054 WL_ERR(("Error (%d)\n", err));
1060 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1062 struct wl_priv *wl = wiphy_to_wl(wiphy);
1072 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1074 struct wl_priv *wl = ndev_to_wl(dev);
1075 struct wl_security *sec;
1079 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1080 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1081 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1082 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1084 val = WPA_AUTH_DISABLED;
1085 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1086 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1087 if (unlikely(err)) {
1088 WL_ERR(("set wpa_auth failed (%d)\n", err));
1091 sec = wl_read_prof(wl, WL_PROF_SEC);
1092 sec->wpa_versions = sme->crypto.wpa_versions;
1097 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1099 struct wl_priv *wl = ndev_to_wl(dev);
1100 struct wl_security *sec;
1104 switch (sme->auth_type) {
1105 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1107 WL_DBG(("open system\n"));
1109 case NL80211_AUTHTYPE_SHARED_KEY:
1111 WL_DBG(("shared key\n"));
1113 case NL80211_AUTHTYPE_AUTOMATIC:
1115 WL_DBG(("automatic\n"));
1117 case NL80211_AUTHTYPE_NETWORK_EAP:
1118 WL_DBG(("network eap\n"));
1121 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1125 err = wl_dev_intvar_set(dev, "auth", val);
1126 if (unlikely(err)) {
1127 WL_ERR(("set auth failed (%d)\n", err));
1130 sec = wl_read_prof(wl, WL_PROF_SEC);
1131 sec->auth_type = sme->auth_type;
1136 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1138 struct wl_priv *wl = ndev_to_wl(dev);
1139 struct wl_security *sec;
1144 if (sme->crypto.n_ciphers_pairwise) {
1145 switch (sme->crypto.ciphers_pairwise[0]) {
1146 case WLAN_CIPHER_SUITE_WEP40:
1147 case WLAN_CIPHER_SUITE_WEP104:
1150 case WLAN_CIPHER_SUITE_TKIP:
1151 pval = TKIP_ENABLED;
1153 case WLAN_CIPHER_SUITE_CCMP:
1156 case WLAN_CIPHER_SUITE_AES_CMAC:
1160 WL_ERR(("invalid cipher pairwise (%d)\n",
1161 sme->crypto.ciphers_pairwise[0]));
1165 if (sme->crypto.cipher_group) {
1166 switch (sme->crypto.cipher_group) {
1167 case WLAN_CIPHER_SUITE_WEP40:
1168 case WLAN_CIPHER_SUITE_WEP104:
1171 case WLAN_CIPHER_SUITE_TKIP:
1172 gval = TKIP_ENABLED;
1174 case WLAN_CIPHER_SUITE_CCMP:
1177 case WLAN_CIPHER_SUITE_AES_CMAC:
1181 WL_ERR(("invalid cipher group (%d)\n",
1182 sme->crypto.cipher_group));
1187 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1188 err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1189 if (unlikely(err)) {
1190 WL_ERR(("error (%d)\n", err));
1194 sec = wl_read_prof(wl, WL_PROF_SEC);
1195 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1196 sec->cipher_group = sme->crypto.cipher_group;
1202 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1204 struct wl_priv *wl = ndev_to_wl(dev);
1205 struct wl_security *sec;
1209 if (sme->crypto.n_akm_suites) {
1210 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1211 if (unlikely(err)) {
1212 WL_ERR(("could not get wpa_auth (%d)\n", err));
1215 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1216 switch (sme->crypto.akm_suites[0]) {
1217 case WLAN_AKM_SUITE_8021X:
1218 val = WPA_AUTH_UNSPECIFIED;
1220 case WLAN_AKM_SUITE_PSK:
1224 WL_ERR(("invalid cipher group (%d)\n",
1225 sme->crypto.cipher_group));
1228 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1229 switch (sme->crypto.akm_suites[0]) {
1230 case WLAN_AKM_SUITE_8021X:
1231 val = WPA2_AUTH_UNSPECIFIED;
1233 case WLAN_AKM_SUITE_PSK:
1234 val = WPA2_AUTH_PSK;
1237 WL_ERR(("invalid cipher group (%d)\n",
1238 sme->crypto.cipher_group));
1243 WL_DBG(("setting wpa_auth to %d\n", val));
1244 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1245 if (unlikely(err)) {
1246 WL_ERR(("could not set wpa_auth (%d)\n", err));
1250 sec = wl_read_prof(wl, WL_PROF_SEC);
1251 sec->wpa_auth = sme->crypto.akm_suites[0];
1257 wl_set_set_sharedkey(struct net_device *dev,
1258 struct cfg80211_connect_params *sme)
1260 struct wl_priv *wl = ndev_to_wl(dev);
1261 struct wl_security *sec;
1262 struct wl_wsec_key key;
1266 WL_DBG(("key len (%d)\n", sme->key_len));
1268 sec = wl_read_prof(wl, WL_PROF_SEC);
1269 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1270 sec->wpa_versions, sec->cipher_pairwise));
1272 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1273 NL80211_WPA_VERSION_2))
1274 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1275 WLAN_CIPHER_SUITE_WEP104))) {
1276 memset(&key, 0, sizeof(key));
1277 key.len = (u32) sme->key_len;
1278 key.index = (u32) sme->key_idx;
1279 if (unlikely(key.len > sizeof(key.data))) {
1280 WL_ERR(("Too long key length (%u)\n", key.len));
1283 memcpy(key.data, sme->key, key.len);
1284 key.flags = WL_PRIMARY_KEY;
1285 switch (sec->cipher_pairwise) {
1286 case WLAN_CIPHER_SUITE_WEP40:
1287 key.algo = CRYPTO_ALGO_WEP1;
1289 case WLAN_CIPHER_SUITE_WEP104:
1290 key.algo = CRYPTO_ALGO_WEP128;
1293 WL_ERR(("Invalid algorithm (%d)\n",
1294 sme->crypto.ciphers_pairwise[0]));
1297 /* Set the new key/index */
1298 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1299 key.len, key.index, key.algo));
1300 WL_DBG(("key \"%s\"\n", key.data));
1301 swap_key_from_BE(&key);
1302 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1304 if (unlikely(err)) {
1305 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1308 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1309 WL_DBG(("set auth_type to shared key\n"));
1310 val = 1; /* shared key */
1311 err = wl_dev_intvar_set(dev, "auth", val);
1312 if (unlikely(err)) {
1313 WL_ERR(("set auth failed (%d)\n", err));
1323 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1324 struct cfg80211_connect_params *sme)
1326 struct wl_priv *wl = wiphy_to_wl(wiphy);
1327 struct ieee80211_channel *chan = sme->channel;
1328 struct wl_join_params join_params;
1329 size_t join_params_size;
1334 if (unlikely(!sme->ssid)) {
1335 WL_ERR(("Invalid ssid\n"));
1339 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1340 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
1341 chan->center_freq));
1343 WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
1344 err = wl_set_wpa_version(dev, sme);
1348 err = wl_set_auth_type(dev, sme);
1352 err = wl_set_set_cipher(dev, sme);
1356 err = wl_set_key_mgmt(dev, sme);
1360 err = wl_set_set_sharedkey(dev, sme);
1364 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1366 ** Join with specific BSSID and cached SSID
1367 ** If SSID is zero join based on BSSID only
1369 memset(&join_params, 0, sizeof(join_params));
1370 join_params_size = sizeof(join_params.ssid);
1372 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1373 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1374 join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
1375 wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1376 memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1378 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1379 WL_DBG(("join_param_size %d\n", join_params_size));
1381 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1382 WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
1383 join_params.ssid.SSID_len));
1385 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1386 if (unlikely(err)) {
1387 WL_ERR(("error (%d)\n", err));
1390 set_bit(WL_STATUS_CONNECTING, &wl->status);
1396 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1399 struct wl_priv *wl = wiphy_to_wl(wiphy);
1404 WL_DBG(("Reason %d\n", reason_code));
1406 act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
1408 scbval.val = reason_code;
1409 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1410 scbval.val = htod32(scbval.val);
1411 err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1413 if (unlikely(err)) {
1414 WL_ERR(("error (%d)\n", err));
1423 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1424 enum nl80211_tx_power_setting type, s32 dbm)
1427 struct wl_priv *wl = wiphy_to_wl(wiphy);
1428 struct net_device *ndev = wl_to_ndev(wl);
1435 case NL80211_TX_POWER_AUTOMATIC:
1437 case NL80211_TX_POWER_LIMITED:
1439 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1443 case NL80211_TX_POWER_FIXED:
1445 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1450 /* Make sure radio is off or on as far as software is concerned */
1451 disable = WL_RADIO_SW_DISABLE << 16;
1452 disable = htod32(disable);
1453 err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1454 if (unlikely(err)) {
1455 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1462 txpwrmw = (u16) dbm;
1463 err = wl_dev_intvar_set(ndev, "qtxpower",
1464 (s32) (bcm_mw_to_qdbm(txpwrmw)));
1465 if (unlikely(err)) {
1466 WL_ERR(("qtxpower error (%d)\n", err));
1469 wl->conf->tx_power = dbm;
1474 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1476 struct wl_priv *wl = wiphy_to_wl(wiphy);
1477 struct net_device *ndev = wl_to_ndev(wl);
1483 err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1484 if (unlikely(err)) {
1485 WL_ERR(("error (%d)\n", err));
1488 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1489 *dbm = (s32) bcm_qdbm_to_mw(result);
1495 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1502 WL_DBG(("key index (%d)\n", key_idx));
1505 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1506 if (unlikely(err)) {
1507 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1510 wsec = dtoh32(wsec);
1511 if (wsec & WEP_ENABLED) {
1512 /* Just select a new current key */
1513 index = (u32) key_idx;
1514 index = htod32(index);
1515 err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
1517 if (unlikely(err)) {
1518 WL_ERR(("error (%d)\n", err));
1525 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1526 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1528 struct wl_wsec_key key;
1531 memset(&key, 0, sizeof(key));
1532 key.index = (u32) key_idx;
1533 /* Instead of bcast for ea address for default wep keys,
1534 driver needs it to be Null */
1535 if (!is_multicast_ether_addr(mac_addr))
1536 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1537 key.len = (u32) params->key_len;
1538 /* check for key index change */
1541 swap_key_from_BE(&key);
1542 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1543 if (unlikely(err)) {
1544 WL_ERR(("key delete error (%d)\n", err));
1548 if (key.len > sizeof(key.data)) {
1549 WL_ERR(("Invalid key length (%d)\n", key.len));
1553 WL_DBG(("Setting the key index %d\n", key.index));
1554 memcpy(key.data, params->key, key.len);
1556 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1558 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1559 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1560 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1563 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1564 if (params->seq && params->seq_len == 6) {
1567 ivptr = (u8 *) params->seq;
1568 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1569 (ivptr[3] << 8) | ivptr[2];
1570 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1571 key.iv_initialized = true;
1574 switch (params->cipher) {
1575 case WLAN_CIPHER_SUITE_WEP40:
1576 key.algo = CRYPTO_ALGO_WEP1;
1577 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1579 case WLAN_CIPHER_SUITE_WEP104:
1580 key.algo = CRYPTO_ALGO_WEP128;
1581 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1583 case WLAN_CIPHER_SUITE_TKIP:
1584 key.algo = CRYPTO_ALGO_TKIP;
1585 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1587 case WLAN_CIPHER_SUITE_AES_CMAC:
1588 key.algo = CRYPTO_ALGO_AES_CCM;
1589 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1591 case WLAN_CIPHER_SUITE_CCMP:
1592 key.algo = CRYPTO_ALGO_AES_CCM;
1593 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1596 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1599 swap_key_from_BE(&key);
1601 dhd_wait_pend8021x(dev);
1602 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1603 if (unlikely(err)) {
1604 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1612 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1613 u8 key_idx, bool pairwise, const u8 *mac_addr,
1614 struct key_params *params)
1616 struct wl_wsec_key key;
1621 WL_DBG(("key index (%d)\n", key_idx));
1625 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1626 memset(&key, 0, sizeof(key));
1628 key.len = (u32) params->key_len;
1629 key.index = (u32) key_idx;
1631 if (unlikely(key.len > sizeof(key.data))) {
1632 WL_ERR(("Too long key length (%u)\n", key.len));
1635 memcpy(key.data, params->key, key.len);
1637 key.flags = WL_PRIMARY_KEY;
1638 switch (params->cipher) {
1639 case WLAN_CIPHER_SUITE_WEP40:
1640 key.algo = CRYPTO_ALGO_WEP1;
1641 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1643 case WLAN_CIPHER_SUITE_WEP104:
1644 key.algo = CRYPTO_ALGO_WEP128;
1645 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1647 case WLAN_CIPHER_SUITE_TKIP:
1648 key.algo = CRYPTO_ALGO_TKIP;
1649 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1651 case WLAN_CIPHER_SUITE_AES_CMAC:
1652 key.algo = CRYPTO_ALGO_AES_CCM;
1653 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1655 case WLAN_CIPHER_SUITE_CCMP:
1656 key.algo = CRYPTO_ALGO_AES_CCM;
1657 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1660 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1664 /* Set the new key/index */
1665 swap_key_from_BE(&key);
1666 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1667 if (unlikely(err)) {
1668 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1673 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1674 if (unlikely(err)) {
1675 WL_ERR(("get wsec error (%d)\n", err));
1678 wsec &= ~(WEP_ENABLED);
1680 err = wl_dev_intvar_set(dev, "wsec", wsec);
1681 if (unlikely(err)) {
1682 WL_ERR(("set wsec error (%d)\n", err));
1686 val = 1; /* assume shared key. otherwise 0 */
1688 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1689 if (unlikely(err)) {
1690 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1697 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1698 u8 key_idx, bool pairwise, const u8 *mac_addr)
1700 struct wl_wsec_key key;
1706 memset(&key, 0, sizeof(key));
1708 key.index = (u32) key_idx;
1709 key.flags = WL_PRIMARY_KEY;
1710 key.algo = CRYPTO_ALGO_OFF;
1712 WL_DBG(("key index (%d)\n", key_idx));
1713 /* Set the new key/index */
1714 swap_key_from_BE(&key);
1715 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1716 if (unlikely(err)) {
1717 if (err == -EINVAL) {
1718 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1719 /* we ignore this key index in this case */
1720 WL_DBG(("invalid key index (%d)\n", key_idx));
1723 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1729 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1730 if (unlikely(err)) {
1731 WL_ERR(("get wsec error (%d)\n", err));
1734 wsec &= ~(WEP_ENABLED);
1736 err = wl_dev_intvar_set(dev, "wsec", wsec);
1737 if (unlikely(err)) {
1738 WL_ERR(("set wsec error (%d)\n", err));
1742 val = 0; /* assume open key. otherwise 1 */
1744 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1745 if (unlikely(err)) {
1746 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1753 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1754 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1755 void (*callback) (void *cookie, struct key_params * params))
1757 struct key_params params;
1758 struct wl_wsec_key key;
1759 struct wl_priv *wl = wiphy_to_wl(wiphy);
1760 struct wl_security *sec;
1764 WL_DBG(("key index (%d)\n", key_idx));
1767 memset(&key, 0, sizeof(key));
1768 key.index = key_idx;
1769 swap_key_to_BE(&key);
1770 memset(¶ms, 0, sizeof(params));
1771 params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
1772 memcpy(params.key, key.data, params.key_len);
1774 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1775 if (unlikely(err)) {
1776 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1779 wsec = dtoh32(wsec);
1782 sec = wl_read_prof(wl, WL_PROF_SEC);
1783 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1784 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1785 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1786 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1787 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1788 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1792 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1793 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1796 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1797 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1800 WL_ERR(("Invalid algo (0x%x)\n", wsec));
1804 callback(cookie, ¶ms);
1809 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1810 struct net_device *dev, u8 key_idx)
1812 WL_INFO(("Not supported\n"));
1818 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1819 u8 *mac, struct station_info *sinfo)
1821 struct wl_priv *wl = wiphy_to_wl(wiphy);
1829 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
1830 WL_ERR(("Wrong Mac address\n"));
1834 /* Report the current tx rate */
1835 err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1837 WL_ERR(("Could not get rate (%d)\n", err));
1839 rate = dtoh32(rate);
1840 sinfo->filled |= STATION_INFO_TX_BITRATE;
1841 sinfo->txrate.legacy = rate * 5;
1842 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1845 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1847 err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1849 if (unlikely(err)) {
1850 WL_ERR(("Could not get rssi (%d)\n", err));
1853 rssi = dtoh32(scb_val.val);
1854 sinfo->filled |= STATION_INFO_SIGNAL;
1855 sinfo->signal = rssi;
1856 WL_DBG(("RSSI %d dBm\n", rssi));
1863 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1864 bool enabled, s32 timeout)
1870 pm = enabled ? PM_FAST : PM_OFF;
1872 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1873 err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1874 if (unlikely(err)) {
1876 WL_DBG(("net_device is not ready yet\n"));
1878 WL_ERR(("error (%d)\n", err));
1884 static __used u32 wl_find_msb(u16 bit16)
1888 if (bit16 & 0xff00) {
1912 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1914 const struct cfg80211_bitrate_mask *mask)
1916 struct wl_rateset rateset;
1925 /* addr param is always NULL. ignore it */
1926 /* Get current rateset */
1927 err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1929 if (unlikely(err)) {
1930 WL_ERR(("could not get current rateset (%d)\n", err));
1934 rateset.count = dtoh32(rateset.count);
1936 legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
1938 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1940 val = wl_g_rates[legacy - 1].bitrate * 100000;
1942 if (val < rateset.count) {
1943 /* Select rate by rateset index */
1944 rate = rateset.rates[val] & 0x7f;
1946 /* Specified rate in bps */
1947 rate = val / 500000;
1950 WL_DBG(("rate %d mbps\n", (rate / 2)));
1954 * Set rate override,
1955 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1957 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1958 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1959 if (unlikely(err_bg && err_a)) {
1960 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
1961 return err_bg | err_a;
1967 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
1972 wl_invoke_iscan(wiphy_to_wl(wiphy));
1977 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
1979 struct wl_priv *wl = wiphy_to_wl(wiphy);
1980 struct net_device *ndev = wl_to_ndev(wl);
1985 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1987 if (wl->scan_request) {
1988 cfg80211_scan_done(wl->scan_request, true); /* true means
1990 wl_set_mpc(ndev, 1);
1991 wl->scan_request = NULL;
1993 clear_bit(WL_STATUS_SCANNING, &wl->status);
1994 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2000 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2005 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2006 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2007 WL_DBG(("PMKID[%d]: %pM =\n", i,
2008 &pmk_list->pmkids.pmkid[i].BSSID));
2009 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2010 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2014 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2022 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2023 struct cfg80211_pmksa *pmksa)
2025 struct wl_priv *wl = wiphy_to_wl(wiphy);
2030 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2031 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2034 if (i < WL_NUM_PMKIDS_MAX) {
2035 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2037 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2039 if (i == wl->pmk_list->pmkids.npmkid)
2040 wl->pmk_list->pmkids.npmkid++;
2044 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2045 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2046 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2048 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2052 err = wl_update_pmklist(dev, wl->pmk_list, err);
2058 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2059 struct cfg80211_pmksa *pmksa)
2061 struct wl_priv *wl = wiphy_to_wl(wiphy);
2062 struct _pmkid_list pmkid;
2067 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2068 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2070 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2071 &pmkid.pmkid[0].BSSID));
2072 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2073 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2076 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2078 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2082 if ((wl->pmk_list->pmkids.npmkid > 0)
2083 && (i < wl->pmk_list->pmkids.npmkid)) {
2084 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2085 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2086 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2087 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2089 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2090 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2093 wl->pmk_list->pmkids.npmkid--;
2098 err = wl_update_pmklist(dev, wl->pmk_list, err);
2105 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2107 struct wl_priv *wl = wiphy_to_wl(wiphy);
2111 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2112 err = wl_update_pmklist(dev, wl->pmk_list, err);
2117 static struct cfg80211_ops wl_cfg80211_ops = {
2118 .change_virtual_intf = wl_cfg80211_change_iface,
2119 .scan = wl_cfg80211_scan,
2120 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2121 .join_ibss = wl_cfg80211_join_ibss,
2122 .leave_ibss = wl_cfg80211_leave_ibss,
2123 .get_station = wl_cfg80211_get_station,
2124 .set_tx_power = wl_cfg80211_set_tx_power,
2125 .get_tx_power = wl_cfg80211_get_tx_power,
2126 .add_key = wl_cfg80211_add_key,
2127 .del_key = wl_cfg80211_del_key,
2128 .get_key = wl_cfg80211_get_key,
2129 .set_default_key = wl_cfg80211_config_default_key,
2130 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2131 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2132 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2133 .connect = wl_cfg80211_connect,
2134 .disconnect = wl_cfg80211_disconnect,
2135 .suspend = wl_cfg80211_suspend,
2136 .resume = wl_cfg80211_resume,
2137 .set_pmksa = wl_cfg80211_set_pmksa,
2138 .del_pmksa = wl_cfg80211_del_pmksa,
2139 .flush_pmksa = wl_cfg80211_flush_pmksa
2142 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2148 return NL80211_IFTYPE_STATION;
2150 return NL80211_IFTYPE_ADHOC;
2152 return NL80211_IFTYPE_UNSPECIFIED;
2158 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2161 struct wireless_dev *wdev;
2164 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2165 if (unlikely(!wdev)) {
2166 WL_ERR(("Could not allocate wireless device\n"));
2167 return ERR_PTR(-ENOMEM);
2170 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2171 if (unlikely(!wdev->wiphy)) {
2172 WL_ERR(("Couldn not allocate wiphy device\n"));
2176 set_wiphy_dev(wdev->wiphy, dev);
2177 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2178 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2179 wdev->wiphy->interface_modes =
2180 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2181 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2182 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2183 * it as 11a by default.
2184 * This will be updated with
2187 * if phy has 11n capability
2189 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2190 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2191 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2192 #ifndef WL_POWERSAVE_DISABLED
2193 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2198 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2199 #endif /* !WL_POWERSAVE_DISABLED */
2200 err = wiphy_register(wdev->wiphy);
2201 if (unlikely(err < 0)) {
2202 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2203 goto wiphy_register_out;
2208 wiphy_free(wdev->wiphy);
2213 return ERR_PTR(err);
2216 static void wl_free_wdev(struct wl_priv *wl)
2218 struct wireless_dev *wdev = wl_to_wdev(wl);
2220 if (unlikely(!wdev)) {
2221 WL_ERR(("wdev is invalid\n"));
2224 wiphy_unregister(wdev->wiphy);
2225 wiphy_free(wdev->wiphy);
2227 wl_to_wdev(wl) = NULL;
2230 static s32 wl_inform_bss(struct wl_priv *wl)
2232 struct wl_scan_results *bss_list;
2233 struct wl_bss_info *bi = NULL; /* must be initialized */
2237 bss_list = wl->bss_list;
2238 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2239 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2240 bss_list->version));
2243 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2244 bi = next_bss(bss_list, bi);
2245 for_each_bss(bss_list, bi, i) {
2246 err = wl_inform_single_bss(wl, bi);
2253 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2255 struct wiphy *wiphy = wl_to_wiphy(wl);
2256 struct ieee80211_mgmt *mgmt;
2257 struct ieee80211_channel *channel;
2258 struct ieee80211_supported_band *band;
2259 struct wl_cfg80211_bss_info *notif_bss_info;
2260 struct wl_scan_req *sr = wl_to_sr(wl);
2261 struct beacon_proberesp *beacon_proberesp;
2267 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
2268 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2272 kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2273 WL_BSS_INFO_MAX, GFP_KERNEL);
2274 if (unlikely(!notif_bss_info)) {
2275 WL_ERR(("notif_bss_info alloc failed\n"));
2278 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2279 notif_bss_info->channel =
2280 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
2282 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2283 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2285 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2286 notif_bss_info->rssi = bi->RSSI;
2287 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
2288 mgmt_type = wl->active_scan ?
2289 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
2290 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2291 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2294 beacon_proberesp = wl->active_scan ?
2295 (struct beacon_proberesp *)&mgmt->u.probe_resp :
2296 (struct beacon_proberesp *)&mgmt->u.beacon;
2297 beacon_proberesp->timestamp = 0;
2298 beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
2299 beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
2302 * wl_add_ie is not necessary because it can only add duplicated
2303 * SSID, rate information to frame_buf
2306 * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2307 * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2308 * bi->rateset.rates);
2310 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2311 wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
2312 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2313 notif_bss_info->frame_len =
2314 offsetof(struct ieee80211_mgmt,
2315 u.beacon.variable) + wl_get_ielen(wl);
2316 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2317 channel = ieee80211_get_channel(wiphy, freq);
2319 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
2321 notif_bss_info->rssi, notif_bss_info->channel,
2322 mgmt->u.beacon.capab_info, &bi->BSSID));
2324 signal = notif_bss_info->rssi * 100;
2325 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2327 (notif_bss_info->frame_len),
2328 signal, GFP_KERNEL))) {
2329 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2330 kfree(notif_bss_info);
2333 kfree(notif_bss_info);
2338 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2340 u32 event = ntoh32(e->event_type);
2341 u16 flags = ntoh16(e->flags);
2343 if (event == WLC_E_LINK) {
2344 if (flags & WLC_EVENT_MSG_LINK) {
2345 if (wl_is_ibssmode(wl)) {
2346 if (wl_is_ibssstarter(wl)) {
2357 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2359 u32 event = ntoh32(e->event_type);
2360 u16 flags = ntoh16(e->flags);
2362 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2364 } else if (event == WLC_E_LINK) {
2365 if (!(flags & WLC_EVENT_MSG_LINK))
2372 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2374 u32 event = ntoh32(e->event_type);
2375 u32 status = ntoh32(e->status);
2377 if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2378 if (status == WLC_E_STATUS_NO_NETWORKS)
2386 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2387 const wl_event_msg_t *e, void *data)
2392 if (wl_is_linkup(wl, e)) {
2394 if (wl_is_ibssmode(wl)) {
2395 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2397 WL_DBG(("joined in IBSS network\n"));
2399 wl_bss_connect_done(wl, ndev, e, data, true);
2400 WL_DBG(("joined in BSS network \"%s\"\n",
2401 ((struct wlc_ssid *)
2402 wl_read_prof(wl, WL_PROF_SSID))->SSID));
2405 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2406 } else if (wl_is_linkdown(wl, e)) {
2407 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2408 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2410 wl_init_prof(wl->profile);
2411 } else if (wl_is_nonetwork(wl, e)) {
2412 wl_bss_connect_done(wl, ndev, e, data, false);
2419 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2420 const wl_event_msg_t *e, void *data)
2425 wl_bss_roaming_done(wl, ndev, e, data);
2427 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2433 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2435 struct wl_priv *wl = ndev_to_wl(dev);
2438 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2439 BUG_ON(unlikely(!buflen));
2441 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2445 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2448 struct wl_priv *wl = ndev_to_wl(dev);
2452 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2453 BUG_ON(unlikely(!len));
2454 err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2456 if (unlikely(err)) {
2457 WL_ERR(("error (%d)\n", err));
2460 memcpy(buf, wl->ioctl_buf, buf_len);
2465 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2467 struct net_device *ndev = wl_to_ndev(wl);
2468 struct wl_assoc_ielen *assoc_info;
2469 struct wl_connect_info *conn_info = wl_to_conn(wl);
2474 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2476 if (unlikely(err)) {
2477 WL_ERR(("could not get assoc info (%d)\n", err));
2480 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2481 req_len = assoc_info->req_len;
2482 resp_len = assoc_info->resp_len;
2484 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2486 if (unlikely(err)) {
2487 WL_ERR(("could not get assoc req (%d)\n", err));
2490 conn_info->req_ie_len = req_len;
2492 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2494 conn_info->req_ie_len = 0;
2495 conn_info->req_ie = NULL;
2498 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2500 if (unlikely(err)) {
2501 WL_ERR(("could not get assoc resp (%d)\n", err));
2504 conn_info->resp_ie_len = resp_len;
2505 conn_info->resp_ie =
2506 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2508 conn_info->resp_ie_len = 0;
2509 conn_info->resp_ie = NULL;
2511 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2512 conn_info->resp_ie_len));
2517 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2518 size_t *join_params_size)
2520 chanspec_t chanspec = 0;
2523 join_params->params.chanspec_num = 1;
2524 join_params->params.chanspec_list[0] = ch;
2526 if (join_params->params.chanspec_list[0])
2527 chanspec |= WL_CHANSPEC_BAND_2G;
2529 chanspec |= WL_CHANSPEC_BAND_5G;
2531 chanspec |= WL_CHANSPEC_BW_20;
2532 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2534 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2535 join_params->params.chanspec_num * sizeof(chanspec_t);
2537 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2538 join_params->params.chanspec_list[0] |= chanspec;
2539 join_params->params.chanspec_list[0] =
2540 htodchanspec(join_params->params.chanspec_list[0]);
2542 join_params->params.chanspec_num =
2543 htod32(join_params->params.chanspec_num);
2545 WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
2546 join_params->params.chanspec_list[0], ch, chanspec));
2550 static s32 wl_update_bss_info(struct wl_priv *wl)
2552 struct cfg80211_bss *bss;
2553 struct wl_bss_info *bi;
2554 struct wlc_ssid *ssid;
2555 struct bcm_tlv *tim;
2556 u16 beacon_interval;
2562 if (wl_is_ibssmode(wl))
2565 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2567 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2568 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2569 WLAN_CAPABILITY_ESS);
2572 if (unlikely(!bss)) {
2573 WL_DBG(("Could not find the AP\n"));
2574 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2575 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2576 wl->extra_buf, WL_EXTRA_BUF_MAX);
2577 if (unlikely(err)) {
2578 WL_ERR(("Could not get bss info %d\n", err));
2579 goto update_bss_info_out;
2581 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2582 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2584 goto update_bss_info_out;
2586 err = wl_inform_single_bss(wl, bi);
2588 goto update_bss_info_out;
2590 ie = ((u8 *)bi) + bi->ie_offset;
2591 ie_len = bi->ie_length;
2592 beacon_interval = cpu_to_le16(bi->beacon_period);
2594 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
2595 ie = bss->information_elements;
2596 ie_len = bss->len_information_elements;
2597 beacon_interval = bss->beacon_interval;
2598 cfg80211_put_bss(bss);
2601 tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2603 dtim_period = tim->data[1];
2606 * active scan was done so we could not get dtim
2607 * information out of probe response.
2608 * so we speficially query dtim information to dongle.
2610 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD,
2611 &dtim_period, sizeof(dtim_period));
2612 if (unlikely(err)) {
2613 WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
2614 goto update_bss_info_out;
2618 wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
2619 wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2621 update_bss_info_out:
2627 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2628 const wl_event_msg_t *e, void *data)
2630 struct wl_connect_info *conn_info = wl_to_conn(wl);
2633 wl_get_assoc_ies(wl);
2634 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2635 wl_update_bss_info(wl);
2636 cfg80211_roamed(ndev,
2638 conn_info->req_ie, conn_info->req_ie_len,
2639 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2640 WL_DBG(("Report roaming result\n"));
2642 set_bit(WL_STATUS_CONNECTED, &wl->status);
2648 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2649 const wl_event_msg_t *e, void *data, bool completed)
2651 struct wl_connect_info *conn_info = wl_to_conn(wl);
2654 wl_get_assoc_ies(wl);
2655 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2656 wl_update_bss_info(wl);
2657 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2658 cfg80211_connect_result(ndev,
2661 conn_info->req_ie_len,
2663 conn_info->resp_ie_len,
2664 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2666 WL_DBG(("Report connect result - connection %s\n",
2667 completed ? "succeeded" : "failed"));
2669 cfg80211_roamed(ndev,
2671 conn_info->req_ie, conn_info->req_ie_len,
2672 conn_info->resp_ie, conn_info->resp_ie_len,
2674 WL_DBG(("Report roaming result\n"));
2676 set_bit(WL_STATUS_CONNECTED, &wl->status);
2682 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2683 const wl_event_msg_t *e, void *data)
2685 u16 flags = ntoh16(e->flags);
2686 enum nl80211_key_type key_type;
2689 if (flags & WLC_EVENT_MSG_GROUP)
2690 key_type = NL80211_KEYTYPE_GROUP;
2692 key_type = NL80211_KEYTYPE_PAIRWISE;
2694 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2702 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2703 const wl_event_msg_t *e, void *data)
2705 struct channel_info channel_inform;
2706 struct wl_scan_results *bss_list;
2707 u32 len = WL_SCAN_BUF_MAX;
2710 if (wl->iscan_on && wl->iscan_kickstart)
2711 return wl_wakeup_iscan(wl_to_iscan(wl));
2713 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2714 WL_ERR(("Scan complete while device not scanning\n"));
2717 if (unlikely(!wl->scan_request)) {
2720 err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2721 sizeof(channel_inform));
2722 if (unlikely(err)) {
2723 WL_ERR(("scan busy (%d)\n", err));
2726 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2727 if (unlikely(channel_inform.scan_channel)) {
2729 WL_DBG(("channel_inform.scan_channel (%d)\n",
2730 channel_inform.scan_channel));
2732 wl->bss_list = wl->scan_results;
2733 bss_list = wl->bss_list;
2734 memset(bss_list, 0, len);
2735 bss_list->buflen = htod32(len);
2736 err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
2737 if (unlikely(err)) {
2738 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2742 bss_list->buflen = dtoh32(bss_list->buflen);
2743 bss_list->version = dtoh32(bss_list->version);
2744 bss_list->count = dtoh32(bss_list->count);
2746 err = wl_inform_bss(wl);
2751 if (wl->scan_request) {
2752 cfg80211_scan_done(wl->scan_request, false);
2753 wl_set_mpc(ndev, 1);
2754 wl->scan_request = NULL;
2760 static void wl_init_conf(struct wl_conf *conf)
2762 conf->mode = (u32)-1;
2763 conf->frag_threshold = (u32)-1;
2764 conf->rts_threshold = (u32)-1;
2765 conf->retry_short = (u32)-1;
2766 conf->retry_long = (u32)-1;
2767 conf->tx_power = -1;
2770 static void wl_init_prof(struct wl_profile *prof)
2772 memset(prof, 0, sizeof(*prof));
2775 static void wl_init_eloop_handler(struct wl_event_loop *el)
2777 memset(el, 0, sizeof(*el));
2778 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2779 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2780 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2781 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2782 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2783 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2784 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2785 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2786 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2787 el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2790 static s32 wl_init_priv_mem(struct wl_priv *wl)
2792 wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2793 if (unlikely(!wl->scan_results)) {
2794 WL_ERR(("Scan results alloc failed\n"));
2795 goto init_priv_mem_out;
2797 wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2798 if (unlikely(!wl->conf)) {
2799 WL_ERR(("wl_conf alloc failed\n"));
2800 goto init_priv_mem_out;
2802 wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2803 if (unlikely(!wl->profile)) {
2804 WL_ERR(("wl_profile alloc failed\n"));
2805 goto init_priv_mem_out;
2807 wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2808 if (unlikely(!wl->bss_info)) {
2809 WL_ERR(("Bss information alloc failed\n"));
2810 goto init_priv_mem_out;
2812 wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2813 if (unlikely(!wl->scan_req_int)) {
2814 WL_ERR(("Scan req alloc failed\n"));
2815 goto init_priv_mem_out;
2817 wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2818 if (unlikely(!wl->ioctl_buf)) {
2819 WL_ERR(("Ioctl buf alloc failed\n"));
2820 goto init_priv_mem_out;
2822 wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2823 if (unlikely(!wl->extra_buf)) {
2824 WL_ERR(("Extra buf alloc failed\n"));
2825 goto init_priv_mem_out;
2827 wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2828 if (unlikely(!wl->iscan)) {
2829 WL_ERR(("Iscan buf alloc failed\n"));
2830 goto init_priv_mem_out;
2832 wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2833 if (unlikely(!wl->fw)) {
2834 WL_ERR(("fw object alloc failed\n"));
2835 goto init_priv_mem_out;
2837 wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2838 if (unlikely(!wl->pmk_list)) {
2839 WL_ERR(("pmk list alloc failed\n"));
2840 goto init_priv_mem_out;
2846 wl_deinit_priv_mem(wl);
2851 static void wl_deinit_priv_mem(struct wl_priv *wl)
2853 kfree(wl->scan_results);
2854 wl->scan_results = NULL;
2855 kfree(wl->bss_info);
2856 wl->bss_info = NULL;
2861 kfree(wl->scan_req_int);
2862 wl->scan_req_int = NULL;
2863 kfree(wl->ioctl_buf);
2864 wl->ioctl_buf = NULL;
2865 kfree(wl->extra_buf);
2866 wl->extra_buf = NULL;
2871 kfree(wl->pmk_list);
2872 wl->pmk_list = NULL;
2875 static s32 wl_create_event_handler(struct wl_priv *wl)
2877 sema_init(&wl->event_sync, 0);
2878 wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
2879 if (IS_ERR(wl->event_tsk)) {
2880 wl->event_tsk = NULL;
2881 WL_ERR(("failed to create event thread\n"));
2887 static void wl_destroy_event_handler(struct wl_priv *wl)
2889 if (wl->event_tsk) {
2890 send_sig(SIGTERM, wl->event_tsk, 1);
2891 kthread_stop(wl->event_tsk);
2892 wl->event_tsk = NULL;
2896 static void wl_term_iscan(struct wl_priv *wl)
2898 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2900 if (wl->iscan_on && iscan->tsk) {
2901 iscan->state = WL_ISCAN_STATE_IDLE;
2902 send_sig(SIGTERM, iscan->tsk, 1);
2903 kthread_stop(iscan->tsk);
2908 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2910 struct wl_priv *wl = iscan_to_wl(iscan);
2911 struct net_device *ndev = wl_to_ndev(wl);
2913 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2914 WL_ERR(("Scan complete while device not scanning\n"));
2917 if (likely(wl->scan_request)) {
2918 cfg80211_scan_done(wl->scan_request, aborted);
2919 wl_set_mpc(ndev, 1);
2920 wl->scan_request = NULL;
2922 wl->iscan_kickstart = false;
2925 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2927 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2928 WL_DBG(("wake up iscan\n"));
2937 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
2938 struct wl_scan_results **bss_list)
2940 struct wl_iscan_results list;
2941 struct wl_scan_results *results;
2942 struct wl_iscan_results *list_buf;
2945 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2946 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2947 results = &list_buf->results;
2948 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2949 results->version = 0;
2952 memset(&list, 0, sizeof(list));
2953 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2954 err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2955 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2957 if (unlikely(err)) {
2958 WL_ERR(("error (%d)\n", err));
2961 results->buflen = dtoh32(results->buflen);
2962 results->version = dtoh32(results->version);
2963 results->count = dtoh32(results->count);
2964 WL_DBG(("results->count = %d\n", results->count));
2965 WL_DBG(("results->buflen = %d\n", results->buflen));
2966 *status = dtoh32(list_buf->status);
2967 *bss_list = results;
2972 static s32 wl_iscan_done(struct wl_priv *wl)
2974 struct wl_iscan_ctrl *iscan = wl->iscan;
2977 iscan->state = WL_ISCAN_STATE_IDLE;
2980 wl_notify_iscan_complete(iscan, false);
2986 static s32 wl_iscan_pending(struct wl_priv *wl)
2988 struct wl_iscan_ctrl *iscan = wl->iscan;
2991 /* Reschedule the timer */
2992 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2993 iscan->timer_on = 1;
2998 static s32 wl_iscan_inprogress(struct wl_priv *wl)
3000 struct wl_iscan_ctrl *iscan = wl->iscan;
3005 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
3007 /* Reschedule the timer */
3008 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
3009 iscan->timer_on = 1;
3014 static s32 wl_iscan_aborted(struct wl_priv *wl)
3016 struct wl_iscan_ctrl *iscan = wl->iscan;
3019 iscan->state = WL_ISCAN_STATE_IDLE;
3021 wl_notify_iscan_complete(iscan, true);
3027 static s32 wl_iscan_thread(void *data)
3029 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3030 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3031 struct wl_priv *wl = iscan_to_wl(iscan);
3032 struct wl_iscan_eloop *el = &iscan->el;
3036 sched_setscheduler(current, SCHED_FIFO, ¶m);
3037 allow_signal(SIGTERM);
3038 status = WL_SCAN_RESULTS_PARTIAL;
3039 while (likely(!down_interruptible(&iscan->sync))) {
3040 if (kthread_should_stop())
3042 if (iscan->timer_on) {
3043 del_timer_sync(&iscan->timer);
3044 iscan->timer_on = 0;
3047 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
3048 if (unlikely(err)) {
3049 status = WL_SCAN_RESULTS_ABORTED;
3050 WL_ERR(("Abort iscan\n"));
3053 el->handler[status] (wl);
3055 if (iscan->timer_on) {
3056 del_timer_sync(&iscan->timer);
3057 iscan->timer_on = 0;
3059 WL_DBG(("%s was terminated\n", __func__));
3064 static void wl_iscan_timer(unsigned long data)
3066 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3069 iscan->timer_on = 0;
3070 WL_DBG(("timer expired\n"));
3071 wl_wakeup_iscan(iscan);
3075 static s32 wl_invoke_iscan(struct wl_priv *wl)
3077 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3080 if (wl->iscan_on && !iscan->tsk) {
3081 iscan->state = WL_ISCAN_STATE_IDLE;
3082 sema_init(&iscan->sync, 0);
3083 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3084 if (IS_ERR(iscan->tsk)) {
3085 WL_ERR(("Could not create iscan thread\n"));
3094 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
3096 memset(el, 0, sizeof(*el));
3097 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
3098 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
3099 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
3100 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
3101 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
3104 static s32 wl_init_iscan(struct wl_priv *wl)
3106 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3110 iscan->dev = wl_to_ndev(wl);
3111 iscan->state = WL_ISCAN_STATE_IDLE;
3112 wl_init_iscan_eloop(&iscan->el);
3113 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3114 init_timer(&iscan->timer);
3115 iscan->timer.data = (unsigned long) iscan;
3116 iscan->timer.function = wl_iscan_timer;
3117 sema_init(&iscan->sync, 0);
3118 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3119 if (IS_ERR(iscan->tsk)) {
3120 WL_ERR(("Could not create iscan thread\n"));
3130 static void wl_init_fw(struct wl_fw_ctrl *fw)
3132 fw->status = 0; /* init fw loading status.
3133 0 means nothing was loaded yet */
3136 static s32 wl_init_priv(struct wl_priv *wl)
3138 struct wiphy *wiphy = wl_to_wiphy(wl);
3141 wl->scan_request = NULL;
3142 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3143 wl->iscan_on = true; /* iscan on & off switch.
3144 we enable iscan per default */
3145 wl->roam_on = false; /* roam on & off switch.
3146 we enable roam per default */
3148 wl->iscan_kickstart = false;
3149 wl->active_scan = true; /* we do active scan for
3150 specific scan per default */
3151 wl->dongle_up = false; /* dongle is not up yet */
3153 err = wl_init_priv_mem(wl);
3156 if (unlikely(wl_create_event_handler(wl)))
3158 wl_init_eloop_handler(&wl->el);
3159 mutex_init(&wl->usr_sync);
3160 err = wl_init_iscan(wl);
3164 wl_init_conf(wl->conf);
3165 wl_init_prof(wl->profile);
3171 static void wl_deinit_priv(struct wl_priv *wl)
3173 wl_destroy_event_handler(wl);
3174 wl->dongle_up = false; /* dongle down */
3178 wl_deinit_priv_mem(wl);
3181 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3183 struct wireless_dev *wdev;
3185 struct wl_iface *ci;
3188 if (unlikely(!ndev)) {
3189 WL_ERR(("ndev is invaild\n"));
3192 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3193 if (unlikely(!wl_cfg80211_dev)) {
3194 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3197 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
3198 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
3202 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3203 wl = wdev_to_wl(wdev);
3206 ci = (struct wl_iface *)wl_to_ci(wl);
3208 ndev->ieee80211_ptr = wdev;
3209 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3210 wdev->netdev = ndev;
3211 err = wl_init_priv(wl);
3212 if (unlikely(err)) {
3213 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
3214 goto cfg80211_attach_out;
3216 wl_set_drvdata(wl_cfg80211_dev, ci);
3217 set_bit(WL_STATUS_READY, &wl->status);
3221 cfg80211_attach_out:
3226 void wl_cfg80211_detach(void)
3234 wl_set_drvdata(wl_cfg80211_dev, NULL);
3235 kfree(wl_cfg80211_dev);
3236 wl_cfg80211_dev = NULL;
3237 wl_clear_sdio_func();
3240 static void wl_wakeup_event(struct wl_priv *wl)
3242 up(&wl->event_sync);
3245 static s32 wl_event_handler(void *data)
3247 struct wl_priv *wl = (struct wl_priv *)data;
3248 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3249 struct wl_event_q *e;
3251 sched_setscheduler(current, SCHED_FIFO, ¶m);
3252 allow_signal(SIGTERM);
3253 while (likely(!down_interruptible(&wl->event_sync))) {
3254 if (kthread_should_stop())
3256 e = wl_deq_event(wl);
3258 WL_ERR(("eqeue empty..\n"));
3261 WL_DBG(("event type (%d)\n", e->etype));
3262 if (wl->el.handler[e->etype]) {
3263 wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3266 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
3270 WL_DBG(("%s was terminated\n", __func__));
3275 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
3277 u32 event_type = ntoh32(e->event_type);
3278 struct wl_priv *wl = ndev_to_wl(ndev);
3279 #if (WL_DBG_LEVEL > 0)
3280 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
3281 wl_dbg_estr[event_type] : (s8 *) "Unknown";
3282 #endif /* (WL_DBG_LEVEL > 0) */
3283 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
3284 if (likely(!wl_enq_event(wl, event_type, e, data)))
3285 wl_wakeup_event(wl);
3288 static void wl_init_eq(struct wl_priv *wl)
3290 wl_init_eq_lock(wl);
3291 INIT_LIST_HEAD(&wl->eq_list);
3294 static void wl_flush_eq(struct wl_priv *wl)
3296 struct wl_event_q *e;
3299 while (!list_empty(&wl->eq_list)) {
3300 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3301 list_del(&e->eq_list);
3308 * retrieve first queued event from head
3311 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3313 struct wl_event_q *e = NULL;
3316 if (likely(!list_empty(&wl->eq_list))) {
3317 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3318 list_del(&e->eq_list);
3326 ** push event to tail of the queue
3330 wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg,
3333 struct wl_event_q *e;
3336 e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
3338 WL_ERR(("event alloc failed\n"));
3343 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
3347 list_add_tail(&e->eq_list, &wl->eq_list);
3353 static void wl_put_event(struct wl_event_q *e)
3358 void wl_cfg80211_sdio_func(void *func)
3360 cfg80211_sdio_func = (struct sdio_func *)func;
3363 static void wl_clear_sdio_func(void)
3365 cfg80211_sdio_func = NULL;
3368 struct sdio_func *wl_cfg80211_get_sdio_func(void)
3370 return cfg80211_sdio_func;
3373 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
3380 case NL80211_IFTYPE_MONITOR:
3381 case NL80211_IFTYPE_WDS:
3382 WL_ERR(("type (%d) : currently we do not support this mode\n",
3386 case NL80211_IFTYPE_ADHOC:
3388 case NL80211_IFTYPE_STATION:
3393 WL_ERR(("invalid type (%d)\n", iftype));
3396 infra = htod32(infra);
3398 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
3399 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
3400 if (unlikely(err)) {
3401 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
3404 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
3405 if (unlikely(err)) {
3406 WL_ERR(("WLC_SET_AP error (%d)\n", err));
3410 return -EINPROGRESS;
3413 #ifndef EMBEDDED_PLATFORM
3414 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3422 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
3426 err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
3427 if (unlikely(err)) {
3428 WL_ERR(("WLC_UP error (%d)\n", err));
3433 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
3437 err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
3438 if (unlikely(err)) {
3439 WL_ERR(("WLC_SET_PM error (%d)\n", err));
3445 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
3447 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3451 /* Match Host and Dongle rx alignment */
3452 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3454 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3455 if (unlikely(err)) {
3456 WL_ERR(("txglomalign error (%d)\n", err));
3457 goto dongle_glom_out;
3459 /* disable glom option per default */
3460 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3461 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3462 if (unlikely(err)) {
3463 WL_ERR(("txglom error (%d)\n", err));
3464 goto dongle_glom_out;
3471 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3473 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3477 /* Setup timeout if Beacons are lost and roam is
3478 off to report link down */
3480 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
3482 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3483 if (unlikely(err)) {
3484 WL_ERR(("bcn_timeout error (%d)\n", err));
3485 goto dongle_rom_out;
3488 /* Enable/Disable built-in roaming to allow supplicant
3489 to take care of roaming */
3490 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
3491 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3492 if (unlikely(err)) {
3493 WL_ERR(("roam_off error (%d)\n", err));
3494 goto dongle_rom_out;
3500 static s32 wl_dongle_eventmsg(struct net_device *ndev)
3503 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3505 s8 eventmask[WL_EVENTING_MASK_LEN];
3508 /* Setup event_msgs */
3509 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3511 err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
3512 if (unlikely(err)) {
3513 WL_ERR(("Get event_msgs error (%d)\n", err));
3514 goto dongle_eventmsg_out;
3516 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3518 setbit(eventmask, WLC_E_SET_SSID);
3519 setbit(eventmask, WLC_E_PRUNE);
3520 setbit(eventmask, WLC_E_AUTH);
3521 setbit(eventmask, WLC_E_REASSOC);
3522 setbit(eventmask, WLC_E_REASSOC_IND);
3523 setbit(eventmask, WLC_E_DEAUTH_IND);
3524 setbit(eventmask, WLC_E_DISASSOC_IND);
3525 setbit(eventmask, WLC_E_DISASSOC);
3526 setbit(eventmask, WLC_E_JOIN);
3527 setbit(eventmask, WLC_E_ASSOC_IND);
3528 setbit(eventmask, WLC_E_PSK_SUP);
3529 setbit(eventmask, WLC_E_LINK);
3530 setbit(eventmask, WLC_E_NDIS_LINK);
3531 setbit(eventmask, WLC_E_MIC_ERROR);
3532 setbit(eventmask, WLC_E_PMKID_CACHE);
3533 setbit(eventmask, WLC_E_TXFAIL);
3534 setbit(eventmask, WLC_E_JOIN_START);
3535 setbit(eventmask, WLC_E_SCAN_COMPLETE);
3537 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3539 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3540 if (unlikely(err)) {
3541 WL_ERR(("Set event_msgs error (%d)\n", err));
3542 goto dongle_eventmsg_out;
3545 dongle_eventmsg_out:
3550 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3551 s32 scan_unassoc_time)
3555 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
3556 sizeof(scan_assoc_time));
3558 if (err == -EOPNOTSUPP) {
3559 WL_INFO(("Scan assoc time is not supported\n"));
3561 WL_ERR(("Scan assoc time error (%d)\n", err));
3563 goto dongle_scantime_out;
3565 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
3566 sizeof(scan_unassoc_time));
3568 if (err == -EOPNOTSUPP) {
3569 WL_INFO(("Scan unassoc time is not supported\n"));
3571 WL_ERR(("Scan unassoc time error (%d)\n", err));
3573 goto dongle_scantime_out;
3576 dongle_scantime_out:
3581 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
3583 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3587 /* Set ARP offload */
3588 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3589 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3591 if (err == -EOPNOTSUPP)
3592 WL_INFO(("arpoe is not supported\n"));
3594 WL_ERR(("arpoe error (%d)\n", err));
3596 goto dongle_offload_out;
3598 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3599 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3601 if (err == -EOPNOTSUPP)
3602 WL_INFO(("arp_ol is not supported\n"));
3604 WL_ERR(("arp_ol error (%d)\n", err));
3606 goto dongle_offload_out;
3613 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
3616 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3617 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3620 src = src + 2; /* Skip past 0x */
3621 if (strlen(src) % 2 != 0) {
3622 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3625 for (i = 0; *src != '\0'; i++) {
3627 strncpy(num, src, 2);
3629 dst[i] = (u8) simple_strtoul(num, NULL, 16);
3635 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
3637 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3640 struct wl_pkt_filter pkt_filter;
3641 struct wl_pkt_filter *pkt_filterp;
3649 /* add a default packet filter pattern */
3650 str = "pkt_filter_add";
3651 str_len = strlen(str);
3652 strncpy(buf, str, str_len);
3653 buf[str_len] = '\0';
3654 buf_len = str_len + 1;
3656 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3658 /* Parse packet filter id. */
3659 pkt_filter.id = htod32(100);
3661 /* Parse filter polarity. */
3662 pkt_filter.negate_match = htod32(0);
3664 /* Parse filter type. */
3665 pkt_filter.type = htod32(0);
3667 /* Parse pattern filter offset. */
3668 pkt_filter.u.pattern.offset = htod32(0);
3670 /* Parse pattern filter mask. */
3671 mask_size = htod32(wl_pattern_atoh("0xff",
3672 (char *)pkt_filterp->u.pattern.
3675 /* Parse pattern filter pattern. */
3676 pattern_size = htod32(wl_pattern_atoh("0x00",
3677 (char *)&pkt_filterp->u.pattern.
3678 mask_and_pattern[mask_size]));
3680 if (mask_size != pattern_size) {
3681 WL_ERR(("Mask and pattern not the same size\n"));
3683 goto dongle_filter_out;
3686 pkt_filter.u.pattern.size_bytes = mask_size;
3687 buf_len += WL_PKT_FILTER_FIXED_LEN;
3688 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3690 /* Keep-alive attributes are set in local
3691 * variable (keep_alive_pkt), and
3692 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3693 * guarantee that the buffer is properly aligned.
3695 memcpy((char *)pkt_filterp, &pkt_filter,
3696 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3698 err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
3700 if (err == -EOPNOTSUPP) {
3701 WL_INFO(("filter not supported\n"));
3703 WL_ERR(("filter (%d)\n", err));
3705 goto dongle_filter_out;
3708 /* set mode to allow pattern */
3709 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3711 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3713 if (err == -EOPNOTSUPP) {
3714 WL_INFO(("filter_mode not supported\n"));
3716 WL_ERR(("filter_mode (%d)\n", err));
3718 goto dongle_filter_out;
3724 #endif /* !EMBEDDED_PLATFORM */
3726 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
3729 #define DHD_SDALIGN 32
3731 struct net_device *ndev;
3732 struct wireless_dev *wdev;
3738 ndev = wl_to_ndev(wl);
3739 wdev = ndev->ieee80211_ptr;
3743 #ifndef EMBEDDED_PLATFORM
3744 err = wl_dongle_up(ndev, 0);
3746 goto default_conf_out;
3747 err = wl_dongle_country(ndev, 0);
3749 goto default_conf_out;
3750 err = wl_dongle_power(ndev, PM_FAST);
3752 goto default_conf_out;
3753 err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
3755 goto default_conf_out;
3756 err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
3758 goto default_conf_out;
3759 err = wl_dongle_eventmsg(ndev);
3761 goto default_conf_out;
3763 wl_dongle_scantime(ndev, 40, 80);
3764 wl_dongle_offload(ndev, 1, 0xf);
3765 wl_dongle_filter(ndev, 1);
3766 #endif /* !EMBEDDED_PLATFORM */
3768 err = wl_dongle_mode(ndev, wdev->iftype);
3769 if (unlikely(err && err != -EINPROGRESS))
3770 goto default_conf_out;
3771 err = wl_dongle_probecap(wl);
3773 goto default_conf_out;
3775 /* -EINPROGRESS: Call commit handler */
3781 wl->dongle_up = true;
3787 static s32 wl_update_wiphybands(struct wl_priv *wl)
3789 struct wiphy *wiphy;
3794 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
3796 if (unlikely(err)) {
3797 WL_ERR(("error (%d)\n", err));
3801 phy = ((char *)&phy_list)[1];
3802 WL_DBG(("%c phy\n", phy));
3803 if (phy == 'n' || phy == 'a') {
3804 wiphy = wl_to_wiphy(wl);
3805 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3811 static s32 __wl_cfg80211_up(struct wl_priv *wl)
3815 wl_debugfs_add_netdev_params(wl);
3817 err = wl_config_dongle(wl, false);
3821 wl_invoke_iscan(wl);
3822 set_bit(WL_STATUS_READY, &wl->status);
3826 static s32 __wl_cfg80211_down(struct wl_priv *wl)
3830 /* Check if cfg80211 interface is already down */
3831 if (!test_bit(WL_STATUS_READY, &wl->status))
3832 return err; /* it is even not ready */
3834 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3836 if (wl->scan_request) {
3837 cfg80211_scan_done(wl->scan_request, true); /* true
3839 /* wl_set_mpc(wl_to_ndev(wl), 1); */ /* BUG
3840 * this operation cannot help
3841 * but here because sdio
3842 * is already down through
3844 * Need to figure out how to
3845 * address this issue
3847 wl->scan_request = NULL;
3849 clear_bit(WL_STATUS_READY, &wl->status);
3850 clear_bit(WL_STATUS_SCANNING, &wl->status);
3851 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3852 clear_bit(WL_STATUS_CONNECTED, &wl->status);
3854 wl_debugfs_remove_netdev(wl);
3859 s32 wl_cfg80211_up(void)
3865 mutex_lock(&wl->usr_sync);
3866 err = __wl_cfg80211_up(wl);
3867 mutex_unlock(&wl->usr_sync);
3872 s32 wl_cfg80211_down(void)
3878 mutex_lock(&wl->usr_sync);
3879 err = __wl_cfg80211_down(wl);
3880 mutex_unlock(&wl->usr_sync);
3885 static s32 wl_dongle_probecap(struct wl_priv *wl)
3889 err = wl_update_wiphybands(wl);
3896 static void *wl_read_prof(struct wl_priv *wl, s32 item)
3900 return &wl->profile->sec;
3902 return &wl->profile->active;
3904 return &wl->profile->bssid;
3906 return &wl->profile->ssid;
3908 WL_ERR(("invalid item (%d)\n", item));
3913 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
3917 struct wlc_ssid *ssid;
3921 ssid = (wlc_ssid_t *) data;
3922 memset(wl->profile->ssid.SSID, 0,
3923 sizeof(wl->profile->ssid.SSID));
3924 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
3925 wl->profile->ssid.SSID_len = ssid->SSID_len;
3929 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
3931 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
3934 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
3937 wl->profile->active = *(bool *)data;
3939 case WL_PROF_BEACONINT:
3940 wl->profile->beacon_interval = *(u16 *)data;
3942 case WL_PROF_DTIMPERIOD:
3943 wl->profile->dtim_period = *(u8 *)data;
3946 WL_ERR(("unsupported item (%d)\n", item));
3954 void wl_cfg80211_dbg_level(u32 level)
3957 * prohibit to change debug level
3958 * by insmod parameter.
3959 * eventually debug level will be configured
3960 * in compile time by using CONFIG_XXX
3962 /* wl_dbg_level = level; */
3965 static bool wl_is_ibssmode(struct wl_priv *wl)
3967 return wl->conf->mode == WL_MODE_IBSS;
3970 static bool wl_is_ibssstarter(struct wl_priv *wl)
3972 return wl->ibss_starter;
3975 static void wl_rst_ie(struct wl_priv *wl)
3977 struct wl_ie *ie = wl_to_ie(wl);
3982 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
3984 struct wl_ie *ie = wl_to_ie(wl);
3987 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3988 WL_ERR(("ei crosses buffer boundary\n"));
3991 ie->buf[ie->offset] = t;
3992 ie->buf[ie->offset + 1] = l;
3993 memcpy(&ie->buf[ie->offset + 2], v, l);
3994 ie->offset += l + 2;
3999 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
4001 struct wl_ie *ie = wl_to_ie(wl);
4004 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
4005 WL_ERR(("ei_stream crosses buffer boundary\n"));
4008 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
4009 ie->offset += ie_size;
4014 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
4016 struct wl_ie *ie = wl_to_ie(wl);
4019 if (unlikely(ie->offset > dst_size)) {
4020 WL_ERR(("dst_size is not enough\n"));
4023 memcpy(dst, &ie->buf[0], ie->offset);
4028 static u32 wl_get_ielen(struct wl_priv *wl)
4030 struct wl_ie *ie = wl_to_ie(wl);
4035 static void wl_link_up(struct wl_priv *wl)
4040 static void wl_link_down(struct wl_priv *wl)
4042 struct wl_connect_info *conn_info = wl_to_conn(wl);
4044 wl->link_up = false;
4045 kfree(conn_info->req_ie);
4046 conn_info->req_ie = NULL;
4047 conn_info->req_ie_len = 0;
4048 kfree(conn_info->resp_ie);
4049 conn_info->resp_ie = NULL;
4050 conn_info->resp_ie_len = 0;
4053 static void wl_lock_eq(struct wl_priv *wl)
4055 spin_lock_irq(&wl->eq_lock);
4058 static void wl_unlock_eq(struct wl_priv *wl)
4060 spin_unlock_irq(&wl->eq_lock);
4063 static void wl_init_eq_lock(struct wl_priv *wl)
4065 spin_lock_init(&wl->eq_lock);
4068 static void wl_delay(u32 ms)
4070 if (ms < 1000 / HZ) {
4078 static void wl_set_drvdata(struct wl_dev *dev, void *data)
4080 dev->driver_data = data;
4083 static void *wl_get_drvdata(struct wl_dev *dev)
4085 return dev->driver_data;
4088 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
4090 const struct firmware *fw_entry;
4095 fw_entry = wl->fw->fw_entry;
4097 if (fw_entry->size < wl->fw->ptr + size)
4098 size = fw_entry->size - wl->fw->ptr;
4100 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
4101 wl->fw->ptr += size;
4105 void wl_cfg80211_release_fw(void)
4110 release_firmware(wl->fw->fw_entry);
4114 void *wl_cfg80211_request_fw(s8 *file_name)
4117 const struct firmware *fw_entry = NULL;
4120 WL_DBG(("file name : \"%s\"\n", file_name));
4123 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
4124 err = request_firmware(&wl->fw->fw_entry, file_name,
4125 &wl_cfg80211_get_sdio_func()->dev);
4126 if (unlikely(err)) {
4127 WL_ERR(("Could not download fw (%d)\n", err));
4130 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
4131 fw_entry = wl->fw->fw_entry;
4133 WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
4136 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
4137 err = request_firmware(&wl->fw->fw_entry, file_name,
4138 &wl_cfg80211_get_sdio_func()->dev);
4139 if (unlikely(err)) {
4140 WL_ERR(("Could not download nvram (%d)\n", err));
4143 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
4144 fw_entry = wl->fw->fw_entry;
4146 WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
4150 WL_DBG(("Downloading already done. Nothing to do more\n"));
4155 if (unlikely(err)) {
4159 return (void *)fw_entry->data;
4162 s8 *wl_cfg80211_get_fwname(void)
4167 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4168 return wl->fw->fw_name;
4171 s8 *wl_cfg80211_get_nvramname(void)
4176 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4177 return wl->fw->nvram_name;
4180 static void wl_set_mpc(struct net_device *ndev, int mpc)
4184 err = wl_dev_intvar_set(ndev, "mpc", mpc);
4185 if (unlikely(err)) {
4186 WL_ERR(("fail to set mpc\n"));
4189 WL_DBG(("MPC : %d\n", mpc));
4192 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
4194 char buf[10+IFNAMSIZ];
4198 sprintf(buf, "netdev:%s", wl_to_ndev(wl)->name);
4199 wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
4201 fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
4202 (u16 *)&wl->profile->beacon_interval);
4208 fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
4209 (u8 *)&wl->profile->dtim_period);
4219 static void wl_debugfs_remove_netdev(struct wl_priv *wl)
4221 debugfs_remove_recursive(wl->debugfsdir);
4222 wl->debugfsdir = NULL;