2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <linux/kernel.h>
23 #include <bcmendian.h>
24 #include <proto/ethernet.h>
26 #include <linux/if_arp.h>
27 #include <asm/uaccess.h>
29 #include <dngl_stats.h>
34 #include <proto/ethernet.h>
35 #include <dngl_stats.h>
38 #include <linux/kernel.h>
39 #include <linux/kthread.h>
40 #include <linux/netdevice.h>
41 #include <linux/sched.h>
42 #include <linux/etherdevice.h>
43 #include <linux/wireless.h>
44 #include <linux/ieee80211.h>
45 #include <net/cfg80211.h>
47 #include <net/rtnetlink.h>
48 #include <linux/mmc/sdio_func.h>
49 #include <linux/firmware.h>
50 #include <wl_cfg80211.h>
52 static struct sdio_func *cfg80211_sdio_func;
53 static struct wl_dev *wl_cfg80211_dev;
55 u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
57 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
58 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
61 ** cfg80211_ops api/callback list
63 static s32 wl_cfg80211_change_iface(struct wiphy *wiphy,
64 struct net_device *ndev,
65 enum nl80211_iftype type, u32 *flags,
66 struct vif_params *params);
67 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
68 struct cfg80211_scan_request *request,
69 struct cfg80211_ssid *this_ssid);
70 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
71 struct cfg80211_scan_request *request);
72 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
73 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
74 struct cfg80211_ibss_params *params);
75 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
76 struct net_device *dev);
77 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
78 struct net_device *dev, u8 *mac,
79 struct station_info *sinfo);
80 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
81 struct net_device *dev, bool enabled,
83 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
84 struct net_device *dev,
86 const struct cfg80211_bitrate_mask
88 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
89 struct cfg80211_connect_params *sme);
90 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
92 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
93 enum nl80211_tx_power_setting type,
95 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
96 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
97 struct net_device *dev,
99 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
100 u8 key_idx, const u8 *mac_addr,
101 struct key_params *params);
102 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
103 u8 key_idx, const u8 *mac_addr);
104 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
105 u8 key_idx, const u8 *mac_addr,
106 void *cookie, void (*callback) (void *cookie,
110 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
111 struct net_device *dev,
113 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
114 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
115 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
116 struct cfg80211_pmksa *pmksa);
117 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
118 struct cfg80211_pmksa *pmksa);
119 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
120 struct net_device *dev);
122 ** event & event Q handlers for cfg80211 interfaces
124 static s32 wl_create_event_handler(struct wl_priv *wl);
125 static void wl_destroy_event_handler(struct wl_priv *wl);
126 static s32 wl_event_handler(void *data);
127 static void wl_init_eq(struct wl_priv *wl);
128 static void wl_flush_eq(struct wl_priv *wl);
129 static void wl_lock_eq(struct wl_priv *wl);
130 static void wl_unlock_eq(struct wl_priv *wl);
131 static void wl_init_eq_lock(struct wl_priv *wl);
132 static void wl_init_eloop_handler(struct wl_event_loop *el);
133 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
134 static s32 wl_enq_event(struct wl_priv *wl, u32 type,
135 const wl_event_msg_t *msg, void *data);
136 static void wl_put_event(struct wl_event_q *e);
137 static void wl_wakeup_event(struct wl_priv *wl);
138 static s32 wl_notify_connect_status(struct wl_priv *wl,
139 struct net_device *ndev,
140 const wl_event_msg_t *e, void *data);
141 static s32 wl_notify_roaming_status(struct wl_priv *wl,
142 struct net_device *ndev,
143 const wl_event_msg_t *e, void *data);
144 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
145 const wl_event_msg_t *e, void *data);
146 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
147 const wl_event_msg_t *e, void *data,
149 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
150 const wl_event_msg_t *e, void *data);
151 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
152 const wl_event_msg_t *e, void *data);
155 ** register/deregister sdio function
157 struct sdio_func *wl_cfg80211_get_sdio_func(void);
158 static void wl_clear_sdio_func(void);
163 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
165 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
167 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
168 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
170 static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg,
174 ** cfg80211 set_wiphy_params utilities
176 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
177 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
178 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
181 ** wl profile utilities
183 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
184 void *data, s32 item);
185 static void *wl_read_prof(struct wl_priv *wl, s32 item);
186 static void wl_init_prof(struct wl_profile *prof);
189 ** cfg80211 connect utilites
191 static s32 wl_set_wpa_version(struct net_device *dev,
192 struct cfg80211_connect_params *sme);
193 static s32 wl_set_auth_type(struct net_device *dev,
194 struct cfg80211_connect_params *sme);
195 static s32 wl_set_set_cipher(struct net_device *dev,
196 struct cfg80211_connect_params *sme);
197 static s32 wl_set_key_mgmt(struct net_device *dev,
198 struct cfg80211_connect_params *sme);
199 static s32 wl_set_set_sharedkey(struct net_device *dev,
200 struct cfg80211_connect_params *sme);
201 static s32 wl_get_assoc_ies(struct wl_priv *wl);
202 static void wl_ch_to_chanspec(int ch,
203 struct wl_join_params *join_params, size_t *join_params_size);
206 ** information element utilities
208 static void wl_rst_ie(struct wl_priv *wl);
209 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
210 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
211 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
212 static u32 wl_get_ielen(struct wl_priv *wl);
214 static s32 wl_mode_to_nl80211_iftype(s32 mode);
216 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
218 static void wl_free_wdev(struct wl_priv *wl);
220 static s32 wl_inform_bss(struct wl_priv *wl);
221 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
222 static s32 wl_update_bss_info(struct wl_priv *wl);
224 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
225 u8 key_idx, const u8 *mac_addr,
226 struct key_params *params);
229 ** key indianess swap utilities
231 static void swap_key_from_BE(struct wl_wsec_key *key);
232 static void swap_key_to_BE(struct wl_wsec_key *key);
235 ** wl_priv memory init/deinit utilities
237 static s32 wl_init_priv_mem(struct wl_priv *wl);
238 static void wl_deinit_priv_mem(struct wl_priv *wl);
240 static void wl_delay(u32 ms);
243 ** store/restore cfg80211 instance data
245 static void wl_set_drvdata(struct wl_dev *dev, void *data);
246 static void *wl_get_drvdata(struct wl_dev *dev);
249 ** ibss mode utilities
251 static bool wl_is_ibssmode(struct wl_priv *wl);
252 static bool wl_is_ibssstarter(struct wl_priv *wl);
255 ** dongle up/down , default configuration utilities
257 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
258 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
259 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
260 static void wl_link_up(struct wl_priv *wl);
261 static void wl_link_down(struct wl_priv *wl);
262 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
263 static s32 __wl_cfg80211_up(struct wl_priv *wl);
264 static s32 __wl_cfg80211_down(struct wl_priv *wl);
265 static s32 wl_dongle_probecap(struct wl_priv *wl);
266 static void wl_init_conf(struct wl_conf *conf);
269 ** dongle configuration utilities
271 #ifndef EMBEDDED_PLATFORM
272 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
273 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
274 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
275 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
276 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
278 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
280 static s32 wl_dongle_eventmsg(struct net_device *ndev);
281 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
282 s32 scan_unassoc_time);
283 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
285 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
286 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
287 static s32 wl_update_wiphybands(struct wl_priv *wl);
288 #endif /* !EMBEDDED_PLATFORM */
289 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
294 static void wl_iscan_timer(unsigned long data);
295 static void wl_term_iscan(struct wl_priv *wl);
296 static s32 wl_init_iscan(struct wl_priv *wl);
297 static s32 wl_iscan_thread(void *data);
298 static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
299 void *param, s32 paramlen, void *bufptr,
301 static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
302 void *param, s32 paramlen, void *bufptr,
304 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
306 static s32 wl_do_iscan(struct wl_priv *wl);
307 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
308 static s32 wl_invoke_iscan(struct wl_priv *wl);
309 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
310 struct wl_scan_results **bss_list);
311 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
312 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
313 static s32 wl_iscan_done(struct wl_priv *wl);
314 static s32 wl_iscan_pending(struct wl_priv *wl);
315 static s32 wl_iscan_inprogress(struct wl_priv *wl);
316 static s32 wl_iscan_aborted(struct wl_priv *wl);
319 ** fw/nvram downloading handler
321 static void wl_init_fw(struct wl_fw_ctrl *fw);
324 * find most significant bit set
326 static __used u32 wl_find_msb(u16 bit16);
329 * update pmklist to dongle
331 static __used s32 wl_update_pmklist(struct net_device *dev,
332 struct wl_pmk_list *pmk_list, s32 err);
334 static void wl_set_mpc(struct net_device *ndev, int mpc);
336 #define WL_PRIV_GET() \
338 struct wl_iface *ci; \
339 if (unlikely(!(wl_cfg80211_dev && \
340 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
341 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
347 #define CHECK_SYS_UP() \
349 struct wl_priv *wl = wiphy_to_wl(wiphy); \
350 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
351 WL_INFO(("device is not ready : status (%d)\n", \
357 extern int dhd_wait_pend8021x(struct net_device *dev);
359 #if (WL_DBG_LEVEL > 0)
360 #define WL_DBG_ESTR_MAX 32
361 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
362 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
363 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
364 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
365 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
366 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
367 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
368 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
370 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
372 "RADIO", "PSM_WATCHDOG",
374 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
375 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
376 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
378 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
380 #endif /* WL_DBG_LEVEL */
382 #define CHAN2G(_channel, _freq, _flags) { \
383 .band = IEEE80211_BAND_2GHZ, \
384 .center_freq = (_freq), \
385 .hw_value = (_channel), \
387 .max_antenna_gain = 0, \
391 #define CHAN5G(_channel, _flags) { \
392 .band = IEEE80211_BAND_5GHZ, \
393 .center_freq = 5000 + (5 * (_channel)), \
394 .hw_value = (_channel), \
396 .max_antenna_gain = 0, \
400 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
401 #define RATETAB_ENT(_rateid, _flags) \
403 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
404 .hw_value = (_rateid), \
408 static struct ieee80211_rate __wl_rates[] = {
409 RATETAB_ENT(WLC_RATE_1M, 0),
410 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
411 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
412 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
413 RATETAB_ENT(WLC_RATE_6M, 0),
414 RATETAB_ENT(WLC_RATE_9M, 0),
415 RATETAB_ENT(WLC_RATE_12M, 0),
416 RATETAB_ENT(WLC_RATE_18M, 0),
417 RATETAB_ENT(WLC_RATE_24M, 0),
418 RATETAB_ENT(WLC_RATE_36M, 0),
419 RATETAB_ENT(WLC_RATE_48M, 0),
420 RATETAB_ENT(WLC_RATE_54M, 0),
423 #define wl_a_rates (__wl_rates + 4)
424 #define wl_a_rates_size 8
425 #define wl_g_rates (__wl_rates + 0)
426 #define wl_g_rates_size 12
428 static struct ieee80211_channel __wl_2ghz_channels[] = {
445 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
446 CHAN5G(34, 0), CHAN5G(36, 0),
447 CHAN5G(38, 0), CHAN5G(40, 0),
448 CHAN5G(42, 0), CHAN5G(44, 0),
449 CHAN5G(46, 0), CHAN5G(48, 0),
450 CHAN5G(52, 0), CHAN5G(56, 0),
451 CHAN5G(60, 0), CHAN5G(64, 0),
452 CHAN5G(100, 0), CHAN5G(104, 0),
453 CHAN5G(108, 0), CHAN5G(112, 0),
454 CHAN5G(116, 0), CHAN5G(120, 0),
455 CHAN5G(124, 0), CHAN5G(128, 0),
456 CHAN5G(132, 0), CHAN5G(136, 0),
457 CHAN5G(140, 0), CHAN5G(149, 0),
458 CHAN5G(153, 0), CHAN5G(157, 0),
459 CHAN5G(161, 0), CHAN5G(165, 0),
460 CHAN5G(184, 0), CHAN5G(188, 0),
461 CHAN5G(192, 0), CHAN5G(196, 0),
462 CHAN5G(200, 0), CHAN5G(204, 0),
463 CHAN5G(208, 0), CHAN5G(212, 0),
467 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
468 CHAN5G(32, 0), CHAN5G(34, 0),
469 CHAN5G(36, 0), CHAN5G(38, 0),
470 CHAN5G(40, 0), CHAN5G(42, 0),
471 CHAN5G(44, 0), CHAN5G(46, 0),
472 CHAN5G(48, 0), CHAN5G(50, 0),
473 CHAN5G(52, 0), CHAN5G(54, 0),
474 CHAN5G(56, 0), CHAN5G(58, 0),
475 CHAN5G(60, 0), CHAN5G(62, 0),
476 CHAN5G(64, 0), CHAN5G(66, 0),
477 CHAN5G(68, 0), CHAN5G(70, 0),
478 CHAN5G(72, 0), CHAN5G(74, 0),
479 CHAN5G(76, 0), CHAN5G(78, 0),
480 CHAN5G(80, 0), CHAN5G(82, 0),
481 CHAN5G(84, 0), CHAN5G(86, 0),
482 CHAN5G(88, 0), CHAN5G(90, 0),
483 CHAN5G(92, 0), CHAN5G(94, 0),
484 CHAN5G(96, 0), CHAN5G(98, 0),
485 CHAN5G(100, 0), CHAN5G(102, 0),
486 CHAN5G(104, 0), CHAN5G(106, 0),
487 CHAN5G(108, 0), CHAN5G(110, 0),
488 CHAN5G(112, 0), CHAN5G(114, 0),
489 CHAN5G(116, 0), CHAN5G(118, 0),
490 CHAN5G(120, 0), CHAN5G(122, 0),
491 CHAN5G(124, 0), CHAN5G(126, 0),
492 CHAN5G(128, 0), CHAN5G(130, 0),
493 CHAN5G(132, 0), CHAN5G(134, 0),
494 CHAN5G(136, 0), CHAN5G(138, 0),
495 CHAN5G(140, 0), CHAN5G(142, 0),
496 CHAN5G(144, 0), CHAN5G(145, 0),
497 CHAN5G(146, 0), CHAN5G(147, 0),
498 CHAN5G(148, 0), CHAN5G(149, 0),
499 CHAN5G(150, 0), CHAN5G(151, 0),
500 CHAN5G(152, 0), CHAN5G(153, 0),
501 CHAN5G(154, 0), CHAN5G(155, 0),
502 CHAN5G(156, 0), CHAN5G(157, 0),
503 CHAN5G(158, 0), CHAN5G(159, 0),
504 CHAN5G(160, 0), CHAN5G(161, 0),
505 CHAN5G(162, 0), CHAN5G(163, 0),
506 CHAN5G(164, 0), CHAN5G(165, 0),
507 CHAN5G(166, 0), CHAN5G(168, 0),
508 CHAN5G(170, 0), CHAN5G(172, 0),
509 CHAN5G(174, 0), CHAN5G(176, 0),
510 CHAN5G(178, 0), CHAN5G(180, 0),
511 CHAN5G(182, 0), CHAN5G(184, 0),
512 CHAN5G(186, 0), CHAN5G(188, 0),
513 CHAN5G(190, 0), CHAN5G(192, 0),
514 CHAN5G(194, 0), CHAN5G(196, 0),
515 CHAN5G(198, 0), CHAN5G(200, 0),
516 CHAN5G(202, 0), CHAN5G(204, 0),
517 CHAN5G(206, 0), CHAN5G(208, 0),
518 CHAN5G(210, 0), CHAN5G(212, 0),
519 CHAN5G(214, 0), CHAN5G(216, 0),
520 CHAN5G(218, 0), CHAN5G(220, 0),
521 CHAN5G(222, 0), CHAN5G(224, 0),
522 CHAN5G(226, 0), CHAN5G(228, 0),
525 static struct ieee80211_supported_band __wl_band_2ghz = {
526 .band = IEEE80211_BAND_2GHZ,
527 .channels = __wl_2ghz_channels,
528 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
529 .bitrates = wl_g_rates,
530 .n_bitrates = wl_g_rates_size,
533 static struct ieee80211_supported_band __wl_band_5ghz_a = {
534 .band = IEEE80211_BAND_5GHZ,
535 .channels = __wl_5ghz_a_channels,
536 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
537 .bitrates = wl_a_rates,
538 .n_bitrates = wl_a_rates_size,
541 static struct ieee80211_supported_band __wl_band_5ghz_n = {
542 .band = IEEE80211_BAND_5GHZ,
543 .channels = __wl_5ghz_n_channels,
544 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
545 .bitrates = wl_a_rates,
546 .n_bitrates = wl_a_rates_size,
549 static const u32 __wl_cipher_suites[] = {
550 WLAN_CIPHER_SUITE_WEP40,
551 WLAN_CIPHER_SUITE_WEP104,
552 WLAN_CIPHER_SUITE_TKIP,
553 WLAN_CIPHER_SUITE_CCMP,
554 WLAN_CIPHER_SUITE_AES_CMAC,
557 static void swap_key_from_BE(struct wl_wsec_key *key)
559 key->index = htod32(key->index);
560 key->len = htod32(key->len);
561 key->algo = htod32(key->algo);
562 key->flags = htod32(key->flags);
563 key->rxiv.hi = htod32(key->rxiv.hi);
564 key->rxiv.lo = htod16(key->rxiv.lo);
565 key->iv_initialized = htod32(key->iv_initialized);
568 static void swap_key_to_BE(struct wl_wsec_key *key)
570 key->index = dtoh32(key->index);
571 key->len = dtoh32(key->len);
572 key->algo = dtoh32(key->algo);
573 key->flags = dtoh32(key->flags);
574 key->rxiv.hi = dtoh32(key->rxiv.hi);
575 key->rxiv.lo = dtoh16(key->rxiv.lo);
576 key->iv_initialized = dtoh32(key->iv_initialized);
580 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len)
587 memset(&ioc, 0, sizeof(ioc));
591 strcpy(ifr.ifr_name, dev->name);
592 ifr.ifr_data = (caddr_t)&ioc;
596 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
603 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
604 enum nl80211_iftype type, u32 *flags,
605 struct vif_params *params)
607 struct wl_priv *wl = wiphy_to_wl(wiphy);
608 struct wireless_dev *wdev;
615 case NL80211_IFTYPE_MONITOR:
616 case NL80211_IFTYPE_WDS:
617 WL_ERR(("type (%d) : currently we do not support this type\n",
620 case NL80211_IFTYPE_ADHOC:
621 wl->conf->mode = WL_MODE_IBSS;
623 case NL80211_IFTYPE_STATION:
624 wl->conf->mode = WL_MODE_BSS;
630 infra = htod32(infra);
632 wdev = ndev->ieee80211_ptr;
634 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
635 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
637 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
640 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
642 WL_ERR(("WLC_SET_AP error (%d)\n", err));
646 /* -EINPROGRESS: Call commit handler */
650 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
652 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
653 params->bss_type = DOT11_BSSTYPE_ANY;
654 params->scan_type = 0;
655 params->nprobes = -1;
656 params->active_time = -1;
657 params->passive_time = -1;
658 params->home_time = -1;
659 params->channel_num = 0;
661 params->nprobes = htod32(params->nprobes);
662 params->active_time = htod32(params->active_time);
663 params->passive_time = htod32(params->passive_time);
664 params->home_time = htod32(params->home_time);
665 if (ssid && ssid->SSID_len)
666 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
671 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
672 s32 paramlen, void *bufptr, s32 buflen)
676 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
677 BUG_ON(unlikely(!iolen));
679 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
683 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
684 s32 paramlen, void *bufptr, s32 buflen)
688 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
689 BUG_ON(unlikely(!iolen));
691 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
695 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
698 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
699 struct wl_iscan_params *params;
702 if (ssid && ssid->SSID_len)
703 params_size += sizeof(struct wlc_ssid);
704 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
705 if (unlikely(!params))
707 memset(params, 0, params_size);
708 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
710 wl_iscan_prep(¶ms->params, ssid);
712 params->version = htod32(ISCAN_REQ_VERSION);
713 params->action = htod16(action);
714 params->scan_duration = htod16(0);
716 /* params_size += offsetof(wl_iscan_params_t, params); */
717 err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
718 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
721 WL_INFO(("system busy : iscan canceled\n"));
723 WL_ERR(("error (%d)\n", err));
730 static s32 wl_do_iscan(struct wl_priv *wl)
732 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
733 struct net_device *ndev = wl_to_ndev(wl);
734 struct wlc_ssid ssid;
738 /* Broadcast scan by default */
739 memset(&ssid, 0, sizeof(ssid));
741 iscan->state = WL_ISCAN_STATE_SCANING;
743 passive_scan = wl->active_scan ? 0 : 1;
744 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
745 &passive_scan, sizeof(passive_scan));
747 WL_DBG(("error (%d)\n", err));
751 wl->iscan_kickstart = true;
752 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
753 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
760 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
761 struct cfg80211_scan_request *request,
762 struct cfg80211_ssid *this_ssid)
764 struct wl_priv *wl = ndev_to_wl(ndev);
765 struct cfg80211_ssid *ssids;
766 struct wl_scan_req *sr = wl_to_sr(wl);
772 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
773 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
776 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
777 WL_ERR(("Scanning being aborted : status (%d)\n",
784 if (request) { /* scan bss */
785 ssids = request->ssids;
786 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) { /* for
788 * ssids->ssid_len has
789 * non-zero(ssid string)
791 * Otherwise this is 0.
792 * we do not iscan for
793 * specific scan request
797 } else { /* scan in ibss */
798 /* we don't do iscan in ibss */
801 wl->scan_request = request;
802 set_bit(WL_STATUS_SCANNING, &wl->status);
804 err = wl_do_iscan(wl);
810 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
811 ssids->ssid, ssids->ssid_len));
812 memset(&sr->ssid, 0, sizeof(sr->ssid));
814 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
815 if (sr->ssid.SSID_len) {
816 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
817 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
818 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
819 sr->ssid.SSID, sr->ssid.SSID_len));
822 WL_DBG(("Broadcast scan\n"));
824 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
825 passive_scan = wl->active_scan ? 0 : 1;
826 err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
827 &passive_scan, sizeof(passive_scan));
829 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
833 err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
837 WL_INFO(("system busy : scan for \"%s\" "
838 "canceled\n", sr->ssid.SSID));
840 WL_ERR(("WLC_SCAN error (%d)\n", err));
850 clear_bit(WL_STATUS_SCANNING, &wl->status);
851 wl->scan_request = NULL;
856 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
857 struct cfg80211_scan_request *request)
862 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
864 WL_DBG(("scan error (%d)\n", err));
871 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
873 s8 buf[WLC_IOCTL_SMLEN];
878 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
879 BUG_ON(unlikely(!len));
881 err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
883 WL_ERR(("error (%d)\n", err));
890 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
893 s8 buf[WLC_IOCTL_SMLEN];
901 bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
903 BUG_ON(unlikely(!len));
904 err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
906 WL_ERR(("error (%d)\n", err));
908 *retval = dtoh32(var.val);
913 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
917 err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
919 WL_ERR(("Error (%d)\n", err));
925 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
929 err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
931 WL_ERR(("Error (%d)\n", err));
937 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
940 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
942 retry = htod32(retry);
943 err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry));
945 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
951 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
953 struct wl_priv *wl = wiphy_to_wl(wiphy);
954 struct net_device *ndev = wl_to_ndev(wl);
958 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
959 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
960 wl->conf->rts_threshold = wiphy->rts_threshold;
961 err = wl_set_rts(ndev, wl->conf->rts_threshold);
965 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
966 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
967 wl->conf->frag_threshold = wiphy->frag_threshold;
968 err = wl_set_frag(ndev, wl->conf->frag_threshold);
972 if (changed & WIPHY_PARAM_RETRY_LONG
973 && (wl->conf->retry_long != wiphy->retry_long)) {
974 wl->conf->retry_long = wiphy->retry_long;
975 err = wl_set_retry(ndev, wl->conf->retry_long, true);
979 if (changed & WIPHY_PARAM_RETRY_SHORT
980 && (wl->conf->retry_short != wiphy->retry_short)) {
981 wl->conf->retry_short = wiphy->retry_short;
982 err = wl_set_retry(ndev, wl->conf->retry_short, false);
992 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
993 struct cfg80211_ibss_params *params)
995 struct wl_priv *wl = wiphy_to_wl(wiphy);
996 struct cfg80211_bss *bss;
997 struct ieee80211_channel *chan;
998 struct wl_join_params join_params;
999 struct cfg80211_ssid ssid;
1004 if (params->bssid) {
1005 WL_ERR(("Invalid bssid\n"));
1008 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1010 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1011 ssid.ssid_len = params->ssid_len;
1014 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1020 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1021 rtnl_unlock(); /* to allow scan_inform to paropagate
1022 to cfg80211 plane */
1023 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1024 till scan done.... */
1026 bss = cfg80211_get_ibss(wiphy, NULL,
1027 params->ssid, params->ssid_len);
1030 wl->ibss_starter = false;
1031 WL_DBG(("Found IBSS\n"));
1033 wl->ibss_starter = true;
1035 chan = params->channel;
1037 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1039 ** Join with specific BSSID and cached SSID
1040 ** If SSID is zero join based on BSSID only
1042 memset(&join_params, 0, sizeof(join_params));
1043 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1045 join_params.ssid.SSID_len = htod32(params->ssid_len);
1047 memcpy(&join_params.params.bssid, params->bssid,
1050 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1052 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1053 sizeof(join_params));
1054 if (unlikely(err)) {
1055 WL_ERR(("Error (%d)\n", err));
1061 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1063 struct wl_priv *wl = wiphy_to_wl(wiphy);
1073 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1075 struct wl_priv *wl = ndev_to_wl(dev);
1076 struct wl_security *sec;
1080 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1081 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1082 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1083 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1085 val = WPA_AUTH_DISABLED;
1086 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1087 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1088 if (unlikely(err)) {
1089 WL_ERR(("set wpa_auth failed (%d)\n", err));
1092 sec = wl_read_prof(wl, WL_PROF_SEC);
1093 sec->wpa_versions = sme->crypto.wpa_versions;
1098 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1100 struct wl_priv *wl = ndev_to_wl(dev);
1101 struct wl_security *sec;
1105 switch (sme->auth_type) {
1106 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1108 WL_DBG(("open system\n"));
1110 case NL80211_AUTHTYPE_SHARED_KEY:
1112 WL_DBG(("shared key\n"));
1114 case NL80211_AUTHTYPE_AUTOMATIC:
1116 WL_DBG(("automatic\n"));
1118 case NL80211_AUTHTYPE_NETWORK_EAP:
1119 WL_DBG(("network eap\n"));
1122 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1126 err = wl_dev_intvar_set(dev, "auth", val);
1127 if (unlikely(err)) {
1128 WL_ERR(("set auth failed (%d)\n", err));
1131 sec = wl_read_prof(wl, WL_PROF_SEC);
1132 sec->auth_type = sme->auth_type;
1137 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1139 struct wl_priv *wl = ndev_to_wl(dev);
1140 struct wl_security *sec;
1145 if (sme->crypto.n_ciphers_pairwise) {
1146 switch (sme->crypto.ciphers_pairwise[0]) {
1147 case WLAN_CIPHER_SUITE_WEP40:
1148 case WLAN_CIPHER_SUITE_WEP104:
1151 case WLAN_CIPHER_SUITE_TKIP:
1152 pval = TKIP_ENABLED;
1154 case WLAN_CIPHER_SUITE_CCMP:
1157 case WLAN_CIPHER_SUITE_AES_CMAC:
1161 WL_ERR(("invalid cipher pairwise (%d)\n",
1162 sme->crypto.ciphers_pairwise[0]));
1166 if (sme->crypto.cipher_group) {
1167 switch (sme->crypto.cipher_group) {
1168 case WLAN_CIPHER_SUITE_WEP40:
1169 case WLAN_CIPHER_SUITE_WEP104:
1172 case WLAN_CIPHER_SUITE_TKIP:
1173 gval = TKIP_ENABLED;
1175 case WLAN_CIPHER_SUITE_CCMP:
1178 case WLAN_CIPHER_SUITE_AES_CMAC:
1182 WL_ERR(("invalid cipher group (%d)\n",
1183 sme->crypto.cipher_group));
1188 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1189 err = wl_dev_intvar_set(dev, "wsec", pval | gval);
1190 if (unlikely(err)) {
1191 WL_ERR(("error (%d)\n", err));
1195 sec = wl_read_prof(wl, WL_PROF_SEC);
1196 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1197 sec->cipher_group = sme->crypto.cipher_group;
1203 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1205 struct wl_priv *wl = ndev_to_wl(dev);
1206 struct wl_security *sec;
1210 if (sme->crypto.n_akm_suites) {
1211 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1212 if (unlikely(err)) {
1213 WL_ERR(("could not get wpa_auth (%d)\n", err));
1216 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1217 switch (sme->crypto.akm_suites[0]) {
1218 case WLAN_AKM_SUITE_8021X:
1219 val = WPA_AUTH_UNSPECIFIED;
1221 case WLAN_AKM_SUITE_PSK:
1225 WL_ERR(("invalid cipher group (%d)\n",
1226 sme->crypto.cipher_group));
1229 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1230 switch (sme->crypto.akm_suites[0]) {
1231 case WLAN_AKM_SUITE_8021X:
1232 val = WPA2_AUTH_UNSPECIFIED;
1234 case WLAN_AKM_SUITE_PSK:
1235 val = WPA2_AUTH_PSK;
1238 WL_ERR(("invalid cipher group (%d)\n",
1239 sme->crypto.cipher_group));
1244 WL_DBG(("setting wpa_auth to %d\n", val));
1245 err = wl_dev_intvar_set(dev, "wpa_auth", val);
1246 if (unlikely(err)) {
1247 WL_ERR(("could not set wpa_auth (%d)\n", err));
1251 sec = wl_read_prof(wl, WL_PROF_SEC);
1252 sec->wpa_auth = sme->crypto.akm_suites[0];
1258 wl_set_set_sharedkey(struct net_device *dev,
1259 struct cfg80211_connect_params *sme)
1261 struct wl_priv *wl = ndev_to_wl(dev);
1262 struct wl_security *sec;
1263 struct wl_wsec_key key;
1267 WL_DBG(("key len (%d)\n", sme->key_len));
1269 sec = wl_read_prof(wl, WL_PROF_SEC);
1270 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1271 sec->wpa_versions, sec->cipher_pairwise));
1273 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1274 NL80211_WPA_VERSION_2))
1275 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1276 WLAN_CIPHER_SUITE_WEP104))) {
1277 memset(&key, 0, sizeof(key));
1278 key.len = (u32) sme->key_len;
1279 key.index = (u32) sme->key_idx;
1280 if (unlikely(key.len > sizeof(key.data))) {
1281 WL_ERR(("Too long key length (%u)\n", key.len));
1284 memcpy(key.data, sme->key, key.len);
1285 key.flags = WL_PRIMARY_KEY;
1286 switch (sec->cipher_pairwise) {
1287 case WLAN_CIPHER_SUITE_WEP40:
1288 key.algo = CRYPTO_ALGO_WEP1;
1290 case WLAN_CIPHER_SUITE_WEP104:
1291 key.algo = CRYPTO_ALGO_WEP128;
1294 WL_ERR(("Invalid algorithm (%d)\n",
1295 sme->crypto.ciphers_pairwise[0]));
1298 /* Set the new key/index */
1299 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1300 key.len, key.index, key.algo));
1301 WL_DBG(("key \"%s\"\n", key.data));
1302 swap_key_from_BE(&key);
1303 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1305 if (unlikely(err)) {
1306 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1309 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1310 WL_DBG(("set auth_type to shared key\n"));
1311 val = 1; /* shared key */
1312 err = wl_dev_intvar_set(dev, "auth", val);
1313 if (unlikely(err)) {
1314 WL_ERR(("set auth failed (%d)\n", err));
1324 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1325 struct cfg80211_connect_params *sme)
1327 struct wl_priv *wl = wiphy_to_wl(wiphy);
1328 struct ieee80211_channel *chan = sme->channel;
1329 struct wl_join_params join_params;
1330 size_t join_params_size;
1335 if (unlikely(!sme->ssid)) {
1336 WL_ERR(("Invalid ssid\n"));
1340 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1341 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
1342 chan->center_freq));
1344 WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
1345 err = wl_set_wpa_version(dev, sme);
1349 err = wl_set_auth_type(dev, sme);
1353 err = wl_set_set_cipher(dev, sme);
1357 err = wl_set_key_mgmt(dev, sme);
1361 err = wl_set_set_sharedkey(dev, sme);
1365 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1367 ** Join with specific BSSID and cached SSID
1368 ** If SSID is zero join based on BSSID only
1370 memset(&join_params, 0, sizeof(join_params));
1371 join_params_size = sizeof(join_params.ssid);
1373 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
1374 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
1375 join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
1376 wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
1377 memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1379 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
1380 WL_DBG(("join_param_size %d\n", join_params_size));
1382 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1383 WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
1384 join_params.ssid.SSID_len));
1386 err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
1387 if (unlikely(err)) {
1388 WL_ERR(("error (%d)\n", err));
1391 set_bit(WL_STATUS_CONNECTING, &wl->status);
1397 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1400 struct wl_priv *wl = wiphy_to_wl(wiphy);
1405 WL_DBG(("Reason %d\n", reason_code));
1407 act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
1409 scbval.val = reason_code;
1410 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1411 scbval.val = htod32(scbval.val);
1412 err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1414 if (unlikely(err)) {
1415 WL_ERR(("error (%d)\n", err));
1424 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1425 enum nl80211_tx_power_setting type, s32 dbm)
1428 struct wl_priv *wl = wiphy_to_wl(wiphy);
1429 struct net_device *ndev = wl_to_ndev(wl);
1436 case NL80211_TX_POWER_AUTOMATIC:
1438 case NL80211_TX_POWER_LIMITED:
1440 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1444 case NL80211_TX_POWER_FIXED:
1446 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1451 /* Make sure radio is off or on as far as software is concerned */
1452 disable = WL_RADIO_SW_DISABLE << 16;
1453 disable = htod32(disable);
1454 err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
1455 if (unlikely(err)) {
1456 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1463 txpwrmw = (u16) dbm;
1464 err = wl_dev_intvar_set(ndev, "qtxpower",
1465 (s32) (bcm_mw_to_qdbm(txpwrmw)));
1466 if (unlikely(err)) {
1467 WL_ERR(("qtxpower error (%d)\n", err));
1470 wl->conf->tx_power = dbm;
1475 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1477 struct wl_priv *wl = wiphy_to_wl(wiphy);
1478 struct net_device *ndev = wl_to_ndev(wl);
1484 err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1485 if (unlikely(err)) {
1486 WL_ERR(("error (%d)\n", err));
1489 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1490 *dbm = (s32) bcm_qdbm_to_mw(result);
1496 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1503 WL_DBG(("key index (%d)\n", key_idx));
1506 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1507 if (unlikely(err)) {
1508 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1511 wsec = dtoh32(wsec);
1512 if (wsec & WEP_ENABLED) {
1513 /* Just select a new current key */
1514 index = (u32) key_idx;
1515 index = htod32(index);
1516 err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
1518 if (unlikely(err)) {
1519 WL_ERR(("error (%d)\n", err));
1526 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1527 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1529 struct wl_wsec_key key;
1532 memset(&key, 0, sizeof(key));
1533 key.index = (u32) key_idx;
1534 /* Instead of bcast for ea address for default wep keys,
1535 driver needs it to be Null */
1536 if (!ETHER_ISMULTI(mac_addr))
1537 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1538 key.len = (u32) params->key_len;
1539 /* check for key index change */
1542 swap_key_from_BE(&key);
1543 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1544 if (unlikely(err)) {
1545 WL_ERR(("key delete error (%d)\n", err));
1549 if (key.len > sizeof(key.data)) {
1550 WL_ERR(("Invalid key length (%d)\n", key.len));
1554 WL_DBG(("Setting the key index %d\n", key.index));
1555 memcpy(key.data, params->key, key.len);
1557 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1559 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1560 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1561 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1564 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1565 if (params->seq && params->seq_len == 6) {
1568 ivptr = (u8 *) params->seq;
1569 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1570 (ivptr[3] << 8) | ivptr[2];
1571 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1572 key.iv_initialized = true;
1575 switch (params->cipher) {
1576 case WLAN_CIPHER_SUITE_WEP40:
1577 key.algo = CRYPTO_ALGO_WEP1;
1578 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1580 case WLAN_CIPHER_SUITE_WEP104:
1581 key.algo = CRYPTO_ALGO_WEP128;
1582 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1584 case WLAN_CIPHER_SUITE_TKIP:
1585 key.algo = CRYPTO_ALGO_TKIP;
1586 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1588 case WLAN_CIPHER_SUITE_AES_CMAC:
1589 key.algo = CRYPTO_ALGO_AES_CCM;
1590 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1592 case WLAN_CIPHER_SUITE_CCMP:
1593 key.algo = CRYPTO_ALGO_AES_CCM;
1594 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1597 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1600 swap_key_from_BE(&key);
1602 dhd_wait_pend8021x(dev);
1603 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1604 if (unlikely(err)) {
1605 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1613 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1614 u8 key_idx, const u8 *mac_addr,
1615 struct key_params *params)
1617 struct wl_wsec_key key;
1622 WL_DBG(("key index (%d)\n", key_idx));
1626 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1627 memset(&key, 0, sizeof(key));
1629 key.len = (u32) params->key_len;
1630 key.index = (u32) key_idx;
1632 if (unlikely(key.len > sizeof(key.data))) {
1633 WL_ERR(("Too long key length (%u)\n", key.len));
1636 memcpy(key.data, params->key, key.len);
1638 key.flags = WL_PRIMARY_KEY;
1639 switch (params->cipher) {
1640 case WLAN_CIPHER_SUITE_WEP40:
1641 key.algo = CRYPTO_ALGO_WEP1;
1642 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1644 case WLAN_CIPHER_SUITE_WEP104:
1645 key.algo = CRYPTO_ALGO_WEP128;
1646 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1648 case WLAN_CIPHER_SUITE_TKIP:
1649 key.algo = CRYPTO_ALGO_TKIP;
1650 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1652 case WLAN_CIPHER_SUITE_AES_CMAC:
1653 key.algo = CRYPTO_ALGO_AES_CCM;
1654 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1656 case WLAN_CIPHER_SUITE_CCMP:
1657 key.algo = CRYPTO_ALGO_AES_CCM;
1658 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1661 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1665 /* Set the new key/index */
1666 swap_key_from_BE(&key);
1667 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1668 if (unlikely(err)) {
1669 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1674 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1675 if (unlikely(err)) {
1676 WL_ERR(("get wsec error (%d)\n", err));
1679 wsec &= ~(WEP_ENABLED);
1681 err = wl_dev_intvar_set(dev, "wsec", wsec);
1682 if (unlikely(err)) {
1683 WL_ERR(("set wsec error (%d)\n", err));
1687 val = 1; /* assume shared key. otherwise 0 */
1689 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1690 if (unlikely(err)) {
1691 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1698 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1699 u8 key_idx, const u8 *mac_addr)
1701 struct wl_wsec_key key;
1707 memset(&key, 0, sizeof(key));
1709 key.index = (u32) key_idx;
1710 key.flags = WL_PRIMARY_KEY;
1711 key.algo = CRYPTO_ALGO_OFF;
1713 WL_DBG(("key index (%d)\n", key_idx));
1714 /* Set the new key/index */
1715 swap_key_from_BE(&key);
1716 err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
1717 if (unlikely(err)) {
1718 if (err == -EINVAL) {
1719 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1720 /* we ignore this key index in this case */
1721 WL_DBG(("invalid key index (%d)\n", key_idx));
1724 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1730 err = wl_dev_intvar_get(dev, "wsec", &wsec);
1731 if (unlikely(err)) {
1732 WL_ERR(("get wsec error (%d)\n", err));
1735 wsec &= ~(WEP_ENABLED);
1737 err = wl_dev_intvar_set(dev, "wsec", wsec);
1738 if (unlikely(err)) {
1739 WL_ERR(("set wsec error (%d)\n", err));
1743 val = 0; /* assume open key. otherwise 1 */
1745 err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
1746 if (unlikely(err)) {
1747 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1754 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1755 u8 key_idx, const u8 *mac_addr, void *cookie,
1756 void (*callback) (void *cookie, struct key_params * params))
1758 struct key_params params;
1759 struct wl_wsec_key key;
1760 struct wl_priv *wl = wiphy_to_wl(wiphy);
1761 struct wl_security *sec;
1765 WL_DBG(("key index (%d)\n", key_idx));
1768 memset(&key, 0, sizeof(key));
1769 key.index = key_idx;
1770 swap_key_to_BE(&key);
1771 memset(¶ms, 0, sizeof(params));
1772 params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
1773 memcpy(params.key, key.data, params.key_len);
1775 err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
1776 if (unlikely(err)) {
1777 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1780 wsec = dtoh32(wsec);
1783 sec = wl_read_prof(wl, WL_PROF_SEC);
1784 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1785 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1786 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1787 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1788 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1789 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1793 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1794 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1797 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1798 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1801 WL_ERR(("Invalid algo (0x%x)\n", wsec));
1805 callback(cookie, ¶ms);
1810 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1811 struct net_device *dev, u8 key_idx)
1813 WL_INFO(("Not supported\n"));
1819 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1820 u8 *mac, struct station_info *sinfo)
1822 struct wl_priv *wl = wiphy_to_wl(wiphy);
1830 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
1831 WL_ERR(("Wrong Mac address\n"));
1835 /* Report the current tx rate */
1836 err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate));
1838 WL_ERR(("Could not get rate (%d)\n", err));
1840 rate = dtoh32(rate);
1841 sinfo->filled |= STATION_INFO_TX_BITRATE;
1842 sinfo->txrate.legacy = rate * 5;
1843 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1846 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1848 err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1850 if (unlikely(err)) {
1851 WL_ERR(("Could not get rssi (%d)\n", err));
1854 rssi = dtoh32(scb_val.val);
1855 sinfo->filled |= STATION_INFO_SIGNAL;
1856 sinfo->signal = rssi;
1857 WL_DBG(("RSSI %d dBm\n", rssi));
1864 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1865 bool enabled, s32 timeout)
1871 pm = enabled ? PM_FAST : PM_OFF;
1873 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1874 err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
1875 if (unlikely(err)) {
1877 WL_DBG(("net_device is not ready yet\n"));
1879 WL_ERR(("error (%d)\n", err));
1885 static __used u32 wl_find_msb(u16 bit16)
1889 if (bit16 & 0xff00) {
1913 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1915 const struct cfg80211_bitrate_mask *mask)
1917 struct wl_rateset rateset;
1926 /* addr param is always NULL. ignore it */
1927 /* Get current rateset */
1928 err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1930 if (unlikely(err)) {
1931 WL_ERR(("could not get current rateset (%d)\n", err));
1935 rateset.count = dtoh32(rateset.count);
1937 legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
1939 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1941 val = wl_g_rates[legacy - 1].bitrate * 100000;
1943 if (val < rateset.count) {
1944 /* Select rate by rateset index */
1945 rate = rateset.rates[val] & 0x7f;
1947 /* Specified rate in bps */
1948 rate = val / 500000;
1951 WL_DBG(("rate %d mbps\n", (rate / 2)));
1955 * Set rate override,
1956 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1958 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1959 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1960 if (unlikely(err_bg && err_a)) {
1961 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
1962 return err_bg | err_a;
1968 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
1973 wl_invoke_iscan(wiphy_to_wl(wiphy));
1978 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
1980 struct wl_priv *wl = wiphy_to_wl(wiphy);
1981 struct net_device *ndev = wl_to_ndev(wl);
1986 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1988 if (wl->scan_request) {
1989 cfg80211_scan_done(wl->scan_request, true); /* true means
1991 wl_set_mpc(ndev, 1);
1992 wl->scan_request = NULL;
1994 clear_bit(WL_STATUS_SCANNING, &wl->status);
1995 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
2001 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2006 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2007 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2008 WL_DBG(("PMKID[%d]: %pM =\n", i,
2009 &pmk_list->pmkids.pmkid[i].BSSID));
2010 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2011 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2015 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2023 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2024 struct cfg80211_pmksa *pmksa)
2026 struct wl_priv *wl = wiphy_to_wl(wiphy);
2031 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2032 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2035 if (i < WL_NUM_PMKIDS_MAX) {
2036 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2038 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2040 if (i == wl->pmk_list->pmkids.npmkid)
2041 wl->pmk_list->pmkids.npmkid++;
2045 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2046 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2047 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2049 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2053 err = wl_update_pmklist(dev, wl->pmk_list, err);
2059 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2060 struct cfg80211_pmksa *pmksa)
2062 struct wl_priv *wl = wiphy_to_wl(wiphy);
2063 struct _pmkid_list pmkid;
2068 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2069 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2071 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2072 &pmkid.pmkid[0].BSSID));
2073 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2074 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2077 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2079 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2083 if ((wl->pmk_list->pmkids.npmkid > 0)
2084 && (i < wl->pmk_list->pmkids.npmkid)) {
2085 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2086 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2087 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2088 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2090 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2091 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2094 wl->pmk_list->pmkids.npmkid--;
2099 err = wl_update_pmklist(dev, wl->pmk_list, err);
2106 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2108 struct wl_priv *wl = wiphy_to_wl(wiphy);
2112 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2113 err = wl_update_pmklist(dev, wl->pmk_list, err);
2118 static struct cfg80211_ops wl_cfg80211_ops = {
2119 .change_virtual_intf = wl_cfg80211_change_iface,
2120 .scan = wl_cfg80211_scan,
2121 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2122 .join_ibss = wl_cfg80211_join_ibss,
2123 .leave_ibss = wl_cfg80211_leave_ibss,
2124 .get_station = wl_cfg80211_get_station,
2125 .set_tx_power = wl_cfg80211_set_tx_power,
2126 .get_tx_power = wl_cfg80211_get_tx_power,
2127 .add_key = wl_cfg80211_add_key,
2128 .del_key = wl_cfg80211_del_key,
2129 .get_key = wl_cfg80211_get_key,
2130 .set_default_key = wl_cfg80211_config_default_key,
2131 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2132 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2133 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2134 .connect = wl_cfg80211_connect,
2135 .disconnect = wl_cfg80211_disconnect,
2136 .suspend = wl_cfg80211_suspend,
2137 .resume = wl_cfg80211_resume,
2138 .set_pmksa = wl_cfg80211_set_pmksa,
2139 .del_pmksa = wl_cfg80211_del_pmksa,
2140 .flush_pmksa = wl_cfg80211_flush_pmksa
2143 static s32 wl_mode_to_nl80211_iftype(s32 mode)
2149 return NL80211_IFTYPE_STATION;
2151 return NL80211_IFTYPE_ADHOC;
2153 return NL80211_IFTYPE_UNSPECIFIED;
2159 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
2162 struct wireless_dev *wdev;
2165 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2166 if (unlikely(!wdev)) {
2167 WL_ERR(("Could not allocate wireless device\n"));
2168 return ERR_PTR(-ENOMEM);
2171 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2172 if (unlikely(!wdev->wiphy)) {
2173 WL_ERR(("Couldn not allocate wiphy device\n"));
2177 set_wiphy_dev(wdev->wiphy, dev);
2178 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2179 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2180 wdev->wiphy->interface_modes =
2181 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2182 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2183 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2184 * it as 11a by default.
2185 * This will be updated with
2188 * if phy has 11n capability
2190 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2191 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2192 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2193 #ifndef WL_POWERSAVE_DISABLED
2194 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2199 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2200 #endif /* !WL_POWERSAVE_DISABLED */
2201 err = wiphy_register(wdev->wiphy);
2202 if (unlikely(err < 0)) {
2203 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2204 goto wiphy_register_out;
2209 wiphy_free(wdev->wiphy);
2214 return ERR_PTR(err);
2217 static void wl_free_wdev(struct wl_priv *wl)
2219 struct wireless_dev *wdev = wl_to_wdev(wl);
2221 if (unlikely(!wdev)) {
2222 WL_ERR(("wdev is invalid\n"));
2225 wiphy_unregister(wdev->wiphy);
2226 wiphy_free(wdev->wiphy);
2228 wl_to_wdev(wl) = NULL;
2231 static s32 wl_inform_bss(struct wl_priv *wl)
2233 struct wl_scan_results *bss_list;
2234 struct wl_bss_info *bi = NULL; /* must be initialized */
2238 bss_list = wl->bss_list;
2239 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2240 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2241 bss_list->version));
2244 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2245 bi = next_bss(bss_list, bi);
2246 for_each_bss(bss_list, bi, i) {
2247 err = wl_inform_single_bss(wl, bi);
2254 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2256 struct wiphy *wiphy = wl_to_wiphy(wl);
2257 struct ieee80211_mgmt *mgmt;
2258 struct ieee80211_channel *channel;
2259 struct ieee80211_supported_band *band;
2260 struct wl_cfg80211_bss_info *notif_bss_info;
2261 struct wl_scan_req *sr = wl_to_sr(wl);
2262 struct beacon_proberesp *beacon_proberesp;
2268 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
2269 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2273 kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2274 WL_BSS_INFO_MAX, GFP_KERNEL);
2275 if (unlikely(!notif_bss_info)) {
2276 WL_ERR(("notif_bss_info alloc failed\n"));
2279 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2280 notif_bss_info->channel =
2281 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
2283 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2284 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2286 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2287 notif_bss_info->rssi = bi->RSSI;
2288 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
2289 mgmt_type = wl->active_scan ?
2290 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
2291 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2292 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2295 beacon_proberesp = wl->active_scan ?
2296 (struct beacon_proberesp *)&mgmt->u.probe_resp :
2297 (struct beacon_proberesp *)&mgmt->u.beacon;
2298 beacon_proberesp->timestamp = 0;
2299 beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
2300 beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
2303 * wl_add_ie is not necessary because it can only add duplicated
2304 * SSID, rate information to frame_buf
2307 * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2308 * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2309 * bi->rateset.rates);
2311 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2312 wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
2313 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2314 notif_bss_info->frame_len =
2315 offsetof(struct ieee80211_mgmt,
2316 u.beacon.variable) + wl_get_ielen(wl);
2317 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2318 channel = ieee80211_get_channel(wiphy, freq);
2320 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
2322 notif_bss_info->rssi, notif_bss_info->channel,
2323 mgmt->u.beacon.capab_info, &bi->BSSID));
2325 signal = notif_bss_info->rssi * 100;
2326 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2328 (notif_bss_info->frame_len),
2329 signal, GFP_KERNEL))) {
2330 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2331 kfree(notif_bss_info);
2334 kfree(notif_bss_info);
2339 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2341 u32 event = ntoh32(e->event_type);
2342 u16 flags = ntoh16(e->flags);
2344 if (event == WLC_E_LINK) {
2345 if (flags & WLC_EVENT_MSG_LINK) {
2346 if (wl_is_ibssmode(wl)) {
2347 if (wl_is_ibssstarter(wl)) {
2358 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2360 u32 event = ntoh32(e->event_type);
2361 u16 flags = ntoh16(e->flags);
2363 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2365 } else if (event == WLC_E_LINK) {
2366 if (!(flags & WLC_EVENT_MSG_LINK))
2373 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2375 u32 event = ntoh32(e->event_type);
2376 u32 status = ntoh32(e->status);
2378 if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2379 if (status == WLC_E_STATUS_NO_NETWORKS)
2387 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2388 const wl_event_msg_t *e, void *data)
2393 if (wl_is_linkup(wl, e)) {
2395 if (wl_is_ibssmode(wl)) {
2396 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2398 WL_DBG(("joined in IBSS network\n"));
2400 wl_bss_connect_done(wl, ndev, e, data, true);
2401 WL_DBG(("joined in BSS network \"%s\"\n",
2402 ((struct wlc_ssid *)
2403 wl_read_prof(wl, WL_PROF_SSID))->SSID));
2406 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2407 } else if (wl_is_linkdown(wl, e)) {
2408 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2409 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2411 wl_init_prof(wl->profile);
2412 } else if (wl_is_nonetwork(wl, e)) {
2413 wl_bss_connect_done(wl, ndev, e, data, false);
2420 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2421 const wl_event_msg_t *e, void *data)
2426 wl_bss_roaming_done(wl, ndev, e, data);
2428 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2434 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2436 struct wl_priv *wl = ndev_to_wl(dev);
2439 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2440 BUG_ON(unlikely(!buflen));
2442 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2446 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2449 struct wl_priv *wl = ndev_to_wl(dev);
2453 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2454 BUG_ON(unlikely(!len));
2455 err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2457 if (unlikely(err)) {
2458 WL_ERR(("error (%d)\n", err));
2461 memcpy(buf, wl->ioctl_buf, buf_len);
2466 static s32 wl_get_assoc_ies(struct wl_priv *wl)
2468 struct net_device *ndev = wl_to_ndev(wl);
2469 struct wl_assoc_ielen *assoc_info;
2470 struct wl_connect_info *conn_info = wl_to_conn(wl);
2475 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2477 if (unlikely(err)) {
2478 WL_ERR(("could not get assoc info (%d)\n", err));
2481 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2482 req_len = assoc_info->req_len;
2483 resp_len = assoc_info->resp_len;
2485 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2487 if (unlikely(err)) {
2488 WL_ERR(("could not get assoc req (%d)\n", err));
2491 conn_info->req_ie_len = req_len;
2493 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2495 conn_info->req_ie_len = 0;
2496 conn_info->req_ie = NULL;
2499 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2501 if (unlikely(err)) {
2502 WL_ERR(("could not get assoc resp (%d)\n", err));
2505 conn_info->resp_ie_len = resp_len;
2506 conn_info->resp_ie =
2507 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2509 conn_info->resp_ie_len = 0;
2510 conn_info->resp_ie = NULL;
2512 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2513 conn_info->resp_ie_len));
2518 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
2519 size_t *join_params_size)
2521 chanspec_t chanspec = 0;
2524 join_params->params.chanspec_num = 1;
2525 join_params->params.chanspec_list[0] = ch;
2527 if (join_params->params.chanspec_list[0])
2528 chanspec |= WL_CHANSPEC_BAND_2G;
2530 chanspec |= WL_CHANSPEC_BAND_5G;
2532 chanspec |= WL_CHANSPEC_BW_20;
2533 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
2535 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
2536 join_params->params.chanspec_num * sizeof(chanspec_t);
2538 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2539 join_params->params.chanspec_list[0] |= chanspec;
2540 join_params->params.chanspec_list[0] =
2541 htodchanspec(join_params->params.chanspec_list[0]);
2543 join_params->params.chanspec_num =
2544 htod32(join_params->params.chanspec_num);
2546 WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
2547 join_params->params.chanspec_list[0], ch, chanspec));
2551 static s32 wl_update_bss_info(struct wl_priv *wl)
2553 struct cfg80211_bss *bss;
2554 struct wl_bss_info *bi;
2555 struct wlc_ssid *ssid;
2558 if (wl_is_ibssmode(wl))
2561 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2563 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2564 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2565 WLAN_CAPABILITY_ESS);
2568 if (unlikely(!bss)) {
2569 WL_DBG(("Could not find the AP\n"));
2570 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2571 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2572 wl->extra_buf, WL_EXTRA_BUF_MAX);
2573 if (unlikely(err)) {
2574 WL_ERR(("Could not get bss info %d\n", err));
2575 goto update_bss_info_out;
2577 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2578 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2580 goto update_bss_info_out;
2582 err = wl_inform_single_bss(wl, bi);
2584 goto update_bss_info_out;
2586 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
2587 cfg80211_put_bss(bss);
2590 update_bss_info_out:
2596 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2597 const wl_event_msg_t *e, void *data)
2599 struct wl_connect_info *conn_info = wl_to_conn(wl);
2602 wl_get_assoc_ies(wl);
2603 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2604 wl_update_bss_info(wl);
2605 cfg80211_roamed(ndev,
2607 conn_info->req_ie, conn_info->req_ie_len,
2608 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2609 WL_DBG(("Report roaming result\n"));
2611 set_bit(WL_STATUS_CONNECTED, &wl->status);
2617 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2618 const wl_event_msg_t *e, void *data, bool completed)
2620 struct wl_connect_info *conn_info = wl_to_conn(wl);
2623 wl_get_assoc_ies(wl);
2624 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2625 wl_update_bss_info(wl);
2626 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2627 cfg80211_connect_result(ndev,
2630 conn_info->req_ie_len,
2632 conn_info->resp_ie_len,
2633 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2635 WL_DBG(("Report connect result - connection %s\n",
2636 completed ? "succeeded" : "failed"));
2638 cfg80211_roamed(ndev,
2640 conn_info->req_ie, conn_info->req_ie_len,
2641 conn_info->resp_ie, conn_info->resp_ie_len,
2643 WL_DBG(("Report roaming result\n"));
2645 set_bit(WL_STATUS_CONNECTED, &wl->status);
2651 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2652 const wl_event_msg_t *e, void *data)
2654 u16 flags = ntoh16(e->flags);
2655 enum nl80211_key_type key_type;
2658 if (flags & WLC_EVENT_MSG_GROUP)
2659 key_type = NL80211_KEYTYPE_GROUP;
2661 key_type = NL80211_KEYTYPE_PAIRWISE;
2663 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2671 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2672 const wl_event_msg_t *e, void *data)
2674 struct channel_info channel_inform;
2675 struct wl_scan_results *bss_list;
2676 u32 len = WL_SCAN_BUF_MAX;
2679 if (wl->iscan_on && wl->iscan_kickstart)
2680 return wl_wakeup_iscan(wl_to_iscan(wl));
2682 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2683 WL_ERR(("Scan complete while device not scanning\n"));
2686 if (unlikely(!wl->scan_request)) {
2689 err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2690 sizeof(channel_inform));
2691 if (unlikely(err)) {
2692 WL_ERR(("scan busy (%d)\n", err));
2695 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2696 if (unlikely(channel_inform.scan_channel)) {
2698 WL_DBG(("channel_inform.scan_channel (%d)\n",
2699 channel_inform.scan_channel));
2701 wl->bss_list = wl->scan_results;
2702 bss_list = wl->bss_list;
2703 memset(bss_list, 0, len);
2704 bss_list->buflen = htod32(len);
2705 err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
2706 if (unlikely(err)) {
2707 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2711 bss_list->buflen = dtoh32(bss_list->buflen);
2712 bss_list->version = dtoh32(bss_list->version);
2713 bss_list->count = dtoh32(bss_list->count);
2715 err = wl_inform_bss(wl);
2720 if (wl->scan_request) {
2721 cfg80211_scan_done(wl->scan_request, false);
2722 wl_set_mpc(ndev, 1);
2723 wl->scan_request = NULL;
2729 static void wl_init_conf(struct wl_conf *conf)
2731 conf->mode = (u32)-1;
2732 conf->frag_threshold = (u32)-1;
2733 conf->rts_threshold = (u32)-1;
2734 conf->retry_short = (u32)-1;
2735 conf->retry_long = (u32)-1;
2736 conf->tx_power = -1;
2739 static void wl_init_prof(struct wl_profile *prof)
2741 memset(prof, 0, sizeof(*prof));
2744 static void wl_init_eloop_handler(struct wl_event_loop *el)
2746 memset(el, 0, sizeof(*el));
2747 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2748 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2749 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2750 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2751 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2752 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2753 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2754 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2755 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2756 el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2759 static s32 wl_init_priv_mem(struct wl_priv *wl)
2761 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2762 if (unlikely(!wl->scan_results)) {
2763 WL_ERR(("Scan results alloc failed\n"));
2764 goto init_priv_mem_out;
2766 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2767 if (unlikely(!wl->conf)) {
2768 WL_ERR(("wl_conf alloc failed\n"));
2769 goto init_priv_mem_out;
2771 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2772 if (unlikely(!wl->profile)) {
2773 WL_ERR(("wl_profile alloc failed\n"));
2774 goto init_priv_mem_out;
2776 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2777 if (unlikely(!wl->bss_info)) {
2778 WL_ERR(("Bss information alloc failed\n"));
2779 goto init_priv_mem_out;
2782 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2783 if (unlikely(!wl->scan_req_int)) {
2784 WL_ERR(("Scan req alloc failed\n"));
2785 goto init_priv_mem_out;
2787 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2788 if (unlikely(!wl->ioctl_buf)) {
2789 WL_ERR(("Ioctl buf alloc failed\n"));
2790 goto init_priv_mem_out;
2792 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2793 if (unlikely(!wl->extra_buf)) {
2794 WL_ERR(("Extra buf alloc failed\n"));
2795 goto init_priv_mem_out;
2797 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2798 if (unlikely(!wl->iscan)) {
2799 WL_ERR(("Iscan buf alloc failed\n"));
2800 goto init_priv_mem_out;
2802 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2803 if (unlikely(!wl->fw)) {
2804 WL_ERR(("fw object alloc failed\n"));
2805 goto init_priv_mem_out;
2807 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2808 if (unlikely(!wl->pmk_list)) {
2809 WL_ERR(("pmk list alloc failed\n"));
2810 goto init_priv_mem_out;
2816 wl_deinit_priv_mem(wl);
2821 static void wl_deinit_priv_mem(struct wl_priv *wl)
2823 kfree(wl->scan_results);
2824 wl->scan_results = NULL;
2825 kfree(wl->bss_info);
2826 wl->bss_info = NULL;
2831 kfree(wl->scan_req_int);
2832 wl->scan_req_int = NULL;
2833 kfree(wl->ioctl_buf);
2834 wl->ioctl_buf = NULL;
2835 kfree(wl->extra_buf);
2836 wl->extra_buf = NULL;
2841 kfree(wl->pmk_list);
2842 wl->pmk_list = NULL;
2845 static s32 wl_create_event_handler(struct wl_priv *wl)
2847 sema_init(&wl->event_sync, 0);
2848 wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
2849 if (IS_ERR(wl->event_tsk)) {
2850 wl->event_tsk = NULL;
2851 WL_ERR(("failed to create event thread\n"));
2857 static void wl_destroy_event_handler(struct wl_priv *wl)
2859 if (wl->event_tsk) {
2860 send_sig(SIGTERM, wl->event_tsk, 1);
2861 kthread_stop(wl->event_tsk);
2862 wl->event_tsk = NULL;
2866 static void wl_term_iscan(struct wl_priv *wl)
2868 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2870 if (wl->iscan_on && iscan->tsk) {
2871 iscan->state = WL_ISCAN_STATE_IDLE;
2872 send_sig(SIGTERM, iscan->tsk, 1);
2873 kthread_stop(iscan->tsk);
2878 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2880 struct wl_priv *wl = iscan_to_wl(iscan);
2881 struct net_device *ndev = wl_to_ndev(wl);
2883 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2884 WL_ERR(("Scan complete while device not scanning\n"));
2887 if (likely(wl->scan_request)) {
2888 cfg80211_scan_done(wl->scan_request, aborted);
2889 wl_set_mpc(ndev, 1);
2890 wl->scan_request = NULL;
2892 wl->iscan_kickstart = false;
2895 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2897 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2898 WL_DBG(("wake up iscan\n"));
2907 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
2908 struct wl_scan_results **bss_list)
2910 struct wl_iscan_results list;
2911 struct wl_scan_results *results;
2912 struct wl_iscan_results *list_buf;
2915 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2916 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2917 results = &list_buf->results;
2918 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2919 results->version = 0;
2922 memset(&list, 0, sizeof(list));
2923 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2924 err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2925 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2927 if (unlikely(err)) {
2928 WL_ERR(("error (%d)\n", err));
2931 results->buflen = dtoh32(results->buflen);
2932 results->version = dtoh32(results->version);
2933 results->count = dtoh32(results->count);
2934 WL_DBG(("results->count = %d\n", results->count));
2935 WL_DBG(("results->buflen = %d\n", results->buflen));
2936 *status = dtoh32(list_buf->status);
2937 *bss_list = results;
2942 static s32 wl_iscan_done(struct wl_priv *wl)
2944 struct wl_iscan_ctrl *iscan = wl->iscan;
2947 iscan->state = WL_ISCAN_STATE_IDLE;
2950 wl_notify_iscan_complete(iscan, false);
2956 static s32 wl_iscan_pending(struct wl_priv *wl)
2958 struct wl_iscan_ctrl *iscan = wl->iscan;
2961 /* Reschedule the timer */
2962 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2963 iscan->timer_on = 1;
2968 static s32 wl_iscan_inprogress(struct wl_priv *wl)
2970 struct wl_iscan_ctrl *iscan = wl->iscan;
2975 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
2977 /* Reschedule the timer */
2978 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2979 iscan->timer_on = 1;
2984 static s32 wl_iscan_aborted(struct wl_priv *wl)
2986 struct wl_iscan_ctrl *iscan = wl->iscan;
2989 iscan->state = WL_ISCAN_STATE_IDLE;
2991 wl_notify_iscan_complete(iscan, true);
2997 static s32 wl_iscan_thread(void *data)
2999 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3000 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3001 struct wl_priv *wl = iscan_to_wl(iscan);
3002 struct wl_iscan_eloop *el = &iscan->el;
3006 sched_setscheduler(current, SCHED_FIFO, ¶m);
3007 allow_signal(SIGTERM);
3008 status = WL_SCAN_RESULTS_PARTIAL;
3009 while (likely(!down_interruptible(&iscan->sync))) {
3010 if (kthread_should_stop())
3012 if (iscan->timer_on) {
3013 del_timer_sync(&iscan->timer);
3014 iscan->timer_on = 0;
3017 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
3018 if (unlikely(err)) {
3019 status = WL_SCAN_RESULTS_ABORTED;
3020 WL_ERR(("Abort iscan\n"));
3023 el->handler[status] (wl);
3025 if (iscan->timer_on) {
3026 del_timer_sync(&iscan->timer);
3027 iscan->timer_on = 0;
3029 WL_DBG(("%s was terminated\n", __func__));
3034 static void wl_iscan_timer(unsigned long data)
3036 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
3039 iscan->timer_on = 0;
3040 WL_DBG(("timer expired\n"));
3041 wl_wakeup_iscan(iscan);
3045 static s32 wl_invoke_iscan(struct wl_priv *wl)
3047 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3050 if (wl->iscan_on && !iscan->tsk) {
3051 iscan->state = WL_ISCAN_STATE_IDLE;
3052 sema_init(&iscan->sync, 0);
3053 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3054 if (IS_ERR(iscan->tsk)) {
3055 WL_ERR(("Could not create iscan thread\n"));
3064 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
3066 memset(el, 0, sizeof(*el));
3067 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
3068 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
3069 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
3070 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
3071 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
3074 static s32 wl_init_iscan(struct wl_priv *wl)
3076 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3080 iscan->dev = wl_to_ndev(wl);
3081 iscan->state = WL_ISCAN_STATE_IDLE;
3082 wl_init_iscan_eloop(&iscan->el);
3083 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3084 init_timer(&iscan->timer);
3085 iscan->timer.data = (unsigned long) iscan;
3086 iscan->timer.function = wl_iscan_timer;
3087 sema_init(&iscan->sync, 0);
3088 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
3089 if (IS_ERR(iscan->tsk)) {
3090 WL_ERR(("Could not create iscan thread\n"));
3100 static void wl_init_fw(struct wl_fw_ctrl *fw)
3102 fw->status = 0; /* init fw loading status.
3103 0 means nothing was loaded yet */
3106 static s32 wl_init_priv(struct wl_priv *wl)
3108 struct wiphy *wiphy = wl_to_wiphy(wl);
3111 wl->scan_request = NULL;
3112 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3113 wl->iscan_on = true; /* iscan on & off switch.
3114 we enable iscan per default */
3115 wl->roam_on = false; /* roam on & off switch.
3116 we enable roam per default */
3118 wl->iscan_kickstart = false;
3119 wl->active_scan = true; /* we do active scan for
3120 specific scan per default */
3121 wl->dongle_up = false; /* dongle is not up yet */
3123 err = wl_init_priv_mem(wl);
3126 if (unlikely(wl_create_event_handler(wl)))
3128 wl_init_eloop_handler(&wl->el);
3129 mutex_init(&wl->usr_sync);
3130 err = wl_init_iscan(wl);
3134 wl_init_conf(wl->conf);
3135 wl_init_prof(wl->profile);
3141 static void wl_deinit_priv(struct wl_priv *wl)
3143 wl_destroy_event_handler(wl);
3144 wl->dongle_up = false; /* dongle down */
3148 wl_deinit_priv_mem(wl);
3151 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3153 struct wireless_dev *wdev;
3155 struct wl_iface *ci;
3158 if (unlikely(!ndev)) {
3159 WL_ERR(("ndev is invaild\n"));
3162 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3163 if (unlikely(!wl_cfg80211_dev)) {
3164 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3167 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
3168 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
3169 if (unlikely(IS_ERR(wdev)))
3172 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3173 wl = wdev_to_wl(wdev);
3176 ci = (struct wl_iface *)wl_to_ci(wl);
3178 ndev->ieee80211_ptr = wdev;
3179 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3180 wdev->netdev = ndev;
3181 err = wl_init_priv(wl);
3182 if (unlikely(err)) {
3183 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
3184 goto cfg80211_attach_out;
3186 wl_set_drvdata(wl_cfg80211_dev, ci);
3187 set_bit(WL_STATUS_READY, &wl->status);
3191 cfg80211_attach_out:
3196 void wl_cfg80211_detach(void)
3204 wl_set_drvdata(wl_cfg80211_dev, NULL);
3205 kfree(wl_cfg80211_dev);
3206 wl_cfg80211_dev = NULL;
3207 wl_clear_sdio_func();
3210 static void wl_wakeup_event(struct wl_priv *wl)
3212 up(&wl->event_sync);
3215 static s32 wl_event_handler(void *data)
3217 struct wl_priv *wl = (struct wl_priv *)data;
3218 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3219 struct wl_event_q *e;
3221 sched_setscheduler(current, SCHED_FIFO, ¶m);
3222 allow_signal(SIGTERM);
3223 while (likely(!down_interruptible(&wl->event_sync))) {
3224 if (kthread_should_stop())
3226 e = wl_deq_event(wl);
3228 WL_ERR(("eqeue empty..\n"));
3231 WL_DBG(("event type (%d)\n", e->etype));
3232 if (wl->el.handler[e->etype]) {
3233 wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3236 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
3240 WL_DBG(("%s was terminated\n", __func__));
3245 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
3247 u32 event_type = ntoh32(e->event_type);
3248 struct wl_priv *wl = ndev_to_wl(ndev);
3249 #if (WL_DBG_LEVEL > 0)
3250 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
3251 wl_dbg_estr[event_type] : (s8 *) "Unknown";
3252 #endif /* (WL_DBG_LEVEL > 0) */
3253 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
3254 if (likely(!wl_enq_event(wl, event_type, e, data)))
3255 wl_wakeup_event(wl);
3258 static void wl_init_eq(struct wl_priv *wl)
3260 wl_init_eq_lock(wl);
3261 INIT_LIST_HEAD(&wl->eq_list);
3264 static void wl_flush_eq(struct wl_priv *wl)
3266 struct wl_event_q *e;
3269 while (!list_empty(&wl->eq_list)) {
3270 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3271 list_del(&e->eq_list);
3278 * retrieve first queued event from head
3281 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3283 struct wl_event_q *e = NULL;
3286 if (likely(!list_empty(&wl->eq_list))) {
3287 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3288 list_del(&e->eq_list);
3296 ** push event to tail of the queue
3300 wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg,
3303 struct wl_event_q *e;
3306 e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL);
3308 WL_ERR(("event alloc failed\n"));
3313 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
3317 list_add_tail(&e->eq_list, &wl->eq_list);
3323 static void wl_put_event(struct wl_event_q *e)
3328 void wl_cfg80211_sdio_func(void *func)
3330 cfg80211_sdio_func = (struct sdio_func *)func;
3333 static void wl_clear_sdio_func(void)
3335 cfg80211_sdio_func = NULL;
3338 struct sdio_func *wl_cfg80211_get_sdio_func(void)
3340 return cfg80211_sdio_func;
3343 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
3350 case NL80211_IFTYPE_MONITOR:
3351 case NL80211_IFTYPE_WDS:
3352 WL_ERR(("type (%d) : currently we do not support this mode\n",
3356 case NL80211_IFTYPE_ADHOC:
3358 case NL80211_IFTYPE_STATION:
3363 WL_ERR(("invalid type (%d)\n", iftype));
3366 infra = htod32(infra);
3368 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
3369 err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
3370 if (unlikely(err)) {
3371 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
3374 err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
3375 if (unlikely(err)) {
3376 WL_ERR(("WLC_SET_AP error (%d)\n", err));
3380 return -EINPROGRESS;
3383 #ifndef EMBEDDED_PLATFORM
3384 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3392 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
3396 err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up));
3397 if (unlikely(err)) {
3398 WL_ERR(("WLC_UP error (%d)\n", err));
3403 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
3407 err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
3408 if (unlikely(err)) {
3409 WL_ERR(("WLC_SET_PM error (%d)\n", err));
3415 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
3417 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3421 /* Match Host and Dongle rx alignment */
3422 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3424 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3425 if (unlikely(err)) {
3426 WL_ERR(("txglomalign error (%d)\n", err));
3427 goto dongle_glom_out;
3429 /* disable glom option per default */
3430 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3431 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3432 if (unlikely(err)) {
3433 WL_ERR(("txglom error (%d)\n", err));
3434 goto dongle_glom_out;
3441 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3443 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3447 /* Setup timeout if Beacons are lost and roam is
3448 off to report link down */
3450 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
3452 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3453 if (unlikely(err)) {
3454 WL_ERR(("bcn_timeout error (%d)\n", err));
3455 goto dongle_rom_out;
3458 /* Enable/Disable built-in roaming to allow supplicant
3459 to take care of roaming */
3460 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
3461 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3462 if (unlikely(err)) {
3463 WL_ERR(("roam_off error (%d)\n", err));
3464 goto dongle_rom_out;
3470 static s32 wl_dongle_eventmsg(struct net_device *ndev)
3473 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3475 s8 eventmask[WL_EVENTING_MASK_LEN];
3478 /* Setup event_msgs */
3479 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3481 err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
3482 if (unlikely(err)) {
3483 WL_ERR(("Get event_msgs error (%d)\n", err));
3484 goto dongle_eventmsg_out;
3486 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3488 setbit(eventmask, WLC_E_SET_SSID);
3489 setbit(eventmask, WLC_E_PRUNE);
3490 setbit(eventmask, WLC_E_AUTH);
3491 setbit(eventmask, WLC_E_REASSOC);
3492 setbit(eventmask, WLC_E_REASSOC_IND);
3493 setbit(eventmask, WLC_E_DEAUTH_IND);
3494 setbit(eventmask, WLC_E_DISASSOC_IND);
3495 setbit(eventmask, WLC_E_DISASSOC);
3496 setbit(eventmask, WLC_E_JOIN);
3497 setbit(eventmask, WLC_E_ASSOC_IND);
3498 setbit(eventmask, WLC_E_PSK_SUP);
3499 setbit(eventmask, WLC_E_LINK);
3500 setbit(eventmask, WLC_E_NDIS_LINK);
3501 setbit(eventmask, WLC_E_MIC_ERROR);
3502 setbit(eventmask, WLC_E_PMKID_CACHE);
3503 setbit(eventmask, WLC_E_TXFAIL);
3504 setbit(eventmask, WLC_E_JOIN_START);
3505 setbit(eventmask, WLC_E_SCAN_COMPLETE);
3507 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3509 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3510 if (unlikely(err)) {
3511 WL_ERR(("Set event_msgs error (%d)\n", err));
3512 goto dongle_eventmsg_out;
3515 dongle_eventmsg_out:
3520 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3521 s32 scan_unassoc_time)
3525 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
3526 sizeof(scan_assoc_time));
3528 if (err == -EOPNOTSUPP) {
3529 WL_INFO(("Scan assoc time is not supported\n"));
3531 WL_ERR(("Scan assoc time error (%d)\n", err));
3533 goto dongle_scantime_out;
3535 err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
3536 sizeof(scan_unassoc_time));
3538 if (err == -EOPNOTSUPP) {
3539 WL_INFO(("Scan unassoc time is not supported\n"));
3541 WL_ERR(("Scan unassoc time error (%d)\n", err));
3543 goto dongle_scantime_out;
3546 dongle_scantime_out:
3551 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
3553 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3557 /* Set ARP offload */
3558 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3559 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3561 if (err == -EOPNOTSUPP)
3562 WL_INFO(("arpoe is not supported\n"));
3564 WL_ERR(("arpoe error (%d)\n", err));
3566 goto dongle_offload_out;
3568 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3569 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3571 if (err == -EOPNOTSUPP)
3572 WL_INFO(("arp_ol is not supported\n"));
3574 WL_ERR(("arp_ol error (%d)\n", err));
3576 goto dongle_offload_out;
3583 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
3586 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3587 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3590 src = src + 2; /* Skip past 0x */
3591 if (strlen(src) % 2 != 0) {
3592 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3595 for (i = 0; *src != '\0'; i++) {
3597 strncpy(num, src, 2);
3599 dst[i] = (u8) simple_strtoul(num, NULL, 16);
3605 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
3607 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3610 struct wl_pkt_filter pkt_filter;
3611 struct wl_pkt_filter *pkt_filterp;
3619 /* add a default packet filter pattern */
3620 str = "pkt_filter_add";
3621 str_len = strlen(str);
3622 strncpy(buf, str, str_len);
3623 buf[str_len] = '\0';
3624 buf_len = str_len + 1;
3626 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3628 /* Parse packet filter id. */
3629 pkt_filter.id = htod32(100);
3631 /* Parse filter polarity. */
3632 pkt_filter.negate_match = htod32(0);
3634 /* Parse filter type. */
3635 pkt_filter.type = htod32(0);
3637 /* Parse pattern filter offset. */
3638 pkt_filter.u.pattern.offset = htod32(0);
3640 /* Parse pattern filter mask. */
3641 mask_size = htod32(wl_pattern_atoh("0xff",
3642 (char *)pkt_filterp->u.pattern.
3645 /* Parse pattern filter pattern. */
3646 pattern_size = htod32(wl_pattern_atoh("0x00",
3647 (char *)&pkt_filterp->u.pattern.
3648 mask_and_pattern[mask_size]));
3650 if (mask_size != pattern_size) {
3651 WL_ERR(("Mask and pattern not the same size\n"));
3653 goto dongle_filter_out;
3656 pkt_filter.u.pattern.size_bytes = mask_size;
3657 buf_len += WL_PKT_FILTER_FIXED_LEN;
3658 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3660 /* Keep-alive attributes are set in local
3661 * variable (keep_alive_pkt), and
3662 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3663 * guarantee that the buffer is properly aligned.
3665 memcpy((char *)pkt_filterp, &pkt_filter,
3666 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3668 err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len);
3670 if (err == -EOPNOTSUPP) {
3671 WL_INFO(("filter not supported\n"));
3673 WL_ERR(("filter (%d)\n", err));
3675 goto dongle_filter_out;
3678 /* set mode to allow pattern */
3679 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3681 err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
3683 if (err == -EOPNOTSUPP) {
3684 WL_INFO(("filter_mode not supported\n"));
3686 WL_ERR(("filter_mode (%d)\n", err));
3688 goto dongle_filter_out;
3694 #endif /* !EMBEDDED_PLATFORM */
3696 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
3699 #define DHD_SDALIGN 32
3701 struct net_device *ndev;
3702 struct wireless_dev *wdev;
3708 ndev = wl_to_ndev(wl);
3709 wdev = ndev->ieee80211_ptr;
3713 #ifndef EMBEDDED_PLATFORM
3714 err = wl_dongle_up(ndev, 0);
3716 goto default_conf_out;
3717 err = wl_dongle_country(ndev, 0);
3719 goto default_conf_out;
3720 err = wl_dongle_power(ndev, PM_FAST);
3722 goto default_conf_out;
3723 err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
3725 goto default_conf_out;
3726 err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
3728 goto default_conf_out;
3729 err = wl_dongle_eventmsg(ndev);
3731 goto default_conf_out;
3733 wl_dongle_scantime(ndev, 40, 80);
3734 wl_dongle_offload(ndev, 1, 0xf);
3735 wl_dongle_filter(ndev, 1);
3736 #endif /* !EMBEDDED_PLATFORM */
3738 err = wl_dongle_mode(ndev, wdev->iftype);
3739 if (unlikely(err && err != -EINPROGRESS))
3740 goto default_conf_out;
3741 err = wl_dongle_probecap(wl);
3743 goto default_conf_out;
3745 /* -EINPROGRESS: Call commit handler */
3751 wl->dongle_up = true;
3757 static s32 wl_update_wiphybands(struct wl_priv *wl)
3759 struct wiphy *wiphy;
3764 err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
3766 if (unlikely(err)) {
3767 WL_ERR(("error (%d)\n", err));
3771 phy = ((char *)&phy_list)[1];
3772 WL_DBG(("%c phy\n", phy));
3773 if (phy == 'n' || phy == 'a') {
3774 wiphy = wl_to_wiphy(wl);
3775 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3781 static s32 __wl_cfg80211_up(struct wl_priv *wl)
3785 err = wl_config_dongle(wl, false);
3789 wl_invoke_iscan(wl);
3790 set_bit(WL_STATUS_READY, &wl->status);
3794 static s32 __wl_cfg80211_down(struct wl_priv *wl)
3798 /* Check if cfg80211 interface is already down */
3799 if (!test_bit(WL_STATUS_READY, &wl->status))
3800 return err; /* it is even not ready */
3802 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3804 if (wl->scan_request) {
3805 cfg80211_scan_done(wl->scan_request, true); /* true
3807 /* wl_set_mpc(wl_to_ndev(wl), 1); */ /* BUG
3808 * this operation cannot help
3809 * but here because sdio
3810 * is already down through
3812 * Need to figure out how to
3813 * address this issue
3815 wl->scan_request = NULL;
3817 clear_bit(WL_STATUS_READY, &wl->status);
3818 clear_bit(WL_STATUS_SCANNING, &wl->status);
3819 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3820 clear_bit(WL_STATUS_CONNECTED, &wl->status);
3825 s32 wl_cfg80211_up(void)
3831 mutex_lock(&wl->usr_sync);
3832 err = __wl_cfg80211_up(wl);
3833 mutex_unlock(&wl->usr_sync);
3838 s32 wl_cfg80211_down(void)
3844 mutex_lock(&wl->usr_sync);
3845 err = __wl_cfg80211_down(wl);
3846 mutex_unlock(&wl->usr_sync);
3851 static s32 wl_dongle_probecap(struct wl_priv *wl)
3855 err = wl_update_wiphybands(wl);
3862 static void *wl_read_prof(struct wl_priv *wl, s32 item)
3866 return &wl->profile->sec;
3868 return &wl->profile->active;
3870 return &wl->profile->bssid;
3872 return &wl->profile->ssid;
3874 WL_ERR(("invalid item (%d)\n", item));
3879 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
3883 struct wlc_ssid *ssid;
3887 ssid = (wlc_ssid_t *) data;
3888 memset(wl->profile->ssid.SSID, 0,
3889 sizeof(wl->profile->ssid.SSID));
3890 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
3891 wl->profile->ssid.SSID_len = ssid->SSID_len;
3895 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
3897 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
3900 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
3903 wl->profile->active = *(bool *) data;
3906 WL_ERR(("unsupported item (%d)\n", item));
3914 void wl_cfg80211_dbg_level(u32 level)
3917 * prohibit to change debug level
3918 * by insmod parameter.
3919 * eventually debug level will be configured
3920 * in compile time by using CONFIG_XXX
3922 /* wl_dbg_level = level; */
3925 static bool wl_is_ibssmode(struct wl_priv *wl)
3927 return wl->conf->mode == WL_MODE_IBSS;
3930 static bool wl_is_ibssstarter(struct wl_priv *wl)
3932 return wl->ibss_starter;
3935 static void wl_rst_ie(struct wl_priv *wl)
3937 struct wl_ie *ie = wl_to_ie(wl);
3942 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
3944 struct wl_ie *ie = wl_to_ie(wl);
3947 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3948 WL_ERR(("ei crosses buffer boundary\n"));
3951 ie->buf[ie->offset] = t;
3952 ie->buf[ie->offset + 1] = l;
3953 memcpy(&ie->buf[ie->offset + 2], v, l);
3954 ie->offset += l + 2;
3959 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
3961 struct wl_ie *ie = wl_to_ie(wl);
3964 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
3965 WL_ERR(("ei_stream crosses buffer boundary\n"));
3968 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
3969 ie->offset += ie_size;
3974 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
3976 struct wl_ie *ie = wl_to_ie(wl);
3979 if (unlikely(ie->offset > dst_size)) {
3980 WL_ERR(("dst_size is not enough\n"));
3983 memcpy(dst, &ie->buf[0], ie->offset);
3988 static u32 wl_get_ielen(struct wl_priv *wl)
3990 struct wl_ie *ie = wl_to_ie(wl);
3995 static void wl_link_up(struct wl_priv *wl)
4000 static void wl_link_down(struct wl_priv *wl)
4002 struct wl_connect_info *conn_info = wl_to_conn(wl);
4004 wl->link_up = false;
4005 kfree(conn_info->req_ie);
4006 conn_info->req_ie = NULL;
4007 conn_info->req_ie_len = 0;
4008 kfree(conn_info->resp_ie);
4009 conn_info->resp_ie = NULL;
4010 conn_info->resp_ie_len = 0;
4013 static void wl_lock_eq(struct wl_priv *wl)
4015 spin_lock_irq(&wl->eq_lock);
4018 static void wl_unlock_eq(struct wl_priv *wl)
4020 spin_unlock_irq(&wl->eq_lock);
4023 static void wl_init_eq_lock(struct wl_priv *wl)
4025 spin_lock_init(&wl->eq_lock);
4028 static void wl_delay(u32 ms)
4030 if (ms < 1000 / HZ) {
4038 static void wl_set_drvdata(struct wl_dev *dev, void *data)
4040 dev->driver_data = data;
4043 static void *wl_get_drvdata(struct wl_dev *dev)
4045 return dev->driver_data;
4048 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
4050 const struct firmware *fw_entry;
4055 fw_entry = wl->fw->fw_entry;
4057 if (fw_entry->size < wl->fw->ptr + size)
4058 size = fw_entry->size - wl->fw->ptr;
4060 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
4061 wl->fw->ptr += size;
4065 void wl_cfg80211_release_fw(void)
4070 release_firmware(wl->fw->fw_entry);
4074 void *wl_cfg80211_request_fw(s8 *file_name)
4077 const struct firmware *fw_entry = NULL;
4080 WL_DBG(("file name : \"%s\"\n", file_name));
4083 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
4084 err = request_firmware(&wl->fw->fw_entry, file_name,
4085 &wl_cfg80211_get_sdio_func()->dev);
4086 if (unlikely(err)) {
4087 WL_ERR(("Could not download fw (%d)\n", err));
4090 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
4091 fw_entry = wl->fw->fw_entry;
4093 WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
4096 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
4097 err = request_firmware(&wl->fw->fw_entry, file_name,
4098 &wl_cfg80211_get_sdio_func()->dev);
4099 if (unlikely(err)) {
4100 WL_ERR(("Could not download nvram (%d)\n", err));
4103 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
4104 fw_entry = wl->fw->fw_entry;
4106 WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
4110 WL_DBG(("Downloading already done. Nothing to do more\n"));
4115 if (unlikely(err)) {
4119 return (void *)fw_entry->data;
4122 s8 *wl_cfg80211_get_fwname(void)
4127 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4128 return wl->fw->fw_name;
4131 s8 *wl_cfg80211_get_nvramname(void)
4136 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4137 return wl->fw->nvram_name;
4140 static void wl_set_mpc(struct net_device *ndev, int mpc)
4144 err = wl_dev_intvar_set(ndev, "mpc", mpc);
4145 if (unlikely(err)) {
4146 WL_ERR(("fail to set mpc\n"));
4149 WL_DBG(("MPC : %d\n", mpc));