2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include <bcmendian.h>
23 #include <proto/ethernet.h>
25 #include <linux/if_arp.h>
26 #include <asm/uaccess.h>
28 #include <dngl_stats.h>
33 #include <proto/ethernet.h>
34 #include <dngl_stats.h>
37 #include <linux/kernel.h>
38 #include <linux/netdevice.h>
39 #include <linux/sched.h>
40 #include <linux/etherdevice.h>
41 #include <linux/wireless.h>
42 #include <linux/ieee80211.h>
43 #include <net/cfg80211.h>
45 #include <net/rtnetlink.h>
46 #include <linux/mmc/sdio_func.h>
47 #include <linux/firmware.h>
48 #include <wl_cfg80211.h>
50 static struct sdio_func *cfg80211_sdio_func = NULL;
51 static struct wl_dev *wl_cfg80211_dev = NULL;
53 uint32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
55 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
56 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
59 ** cfg80211_ops api/callback list
61 static int32 wl_cfg80211_change_iface(struct wiphy *wiphy,
62 struct net_device *ndev,
63 enum nl80211_iftype type, uint32 *flags,
64 struct vif_params *params);
65 static int32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
66 struct cfg80211_scan_request *request,
67 struct cfg80211_ssid *this_ssid);
68 static int32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
69 struct cfg80211_scan_request *request);
70 static int32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, uint32 changed);
71 static int32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
72 struct cfg80211_ibss_params *params);
73 static int32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
74 struct net_device *dev);
75 static int32 wl_cfg80211_get_station(struct wiphy *wiphy,
76 struct net_device *dev, u8 *mac,
77 struct station_info *sinfo);
78 static int32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
79 struct net_device *dev, bool enabled,
81 static int32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
82 struct net_device *dev,
84 const struct cfg80211_bitrate_mask
86 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
87 struct cfg80211_connect_params *sme);
88 static int32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
90 static int32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
91 enum nl80211_tx_power_setting type,
93 static int32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, int32 *dbm);
94 static int32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
95 struct net_device *dev,
97 static int32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
98 u8 key_idx, const u8 *mac_addr,
99 struct key_params *params);
100 static int32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
101 u8 key_idx, const u8 *mac_addr);
102 static int32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
103 u8 key_idx, const u8 *mac_addr,
104 void *cookie, void (*callback) (void *cookie,
108 static int32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
109 struct net_device *dev,
111 static int32 wl_cfg80211_resume(struct wiphy *wiphy);
112 static int32 wl_cfg80211_suspend(struct wiphy *wiphy);
113 static int32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
114 struct cfg80211_pmksa *pmksa);
115 static int32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
116 struct cfg80211_pmksa *pmksa);
117 static int32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
118 struct net_device *dev);
120 ** event & event Q handlers for cfg80211 interfaces
122 static int32 wl_create_event_handler(struct wl_priv *wl);
123 static void wl_destroy_event_handler(struct wl_priv *wl);
124 static int32 wl_event_handler(void *data);
125 static void wl_init_eq(struct wl_priv *wl);
126 static void wl_flush_eq(struct wl_priv *wl);
127 static void wl_lock_eq(struct wl_priv *wl);
128 static void wl_unlock_eq(struct wl_priv *wl);
129 static void wl_init_eq_lock(struct wl_priv *wl);
130 static void wl_init_eloop_handler(struct wl_event_loop *el);
131 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
132 static int32 wl_enq_event(struct wl_priv *wl, uint32 type,
133 const wl_event_msg_t *msg, void *data);
134 static void wl_put_event(struct wl_event_q *e);
135 static void wl_wakeup_event(struct wl_priv *wl);
136 static int32 wl_notify_connect_status(struct wl_priv *wl,
137 struct net_device *ndev,
138 const wl_event_msg_t *e, void *data);
139 static int32 wl_notify_roaming_status(struct wl_priv *wl,
140 struct net_device *ndev,
141 const wl_event_msg_t *e, void *data);
142 static int32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
143 const wl_event_msg_t *e, void *data);
144 static int32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
145 const wl_event_msg_t *e, void *data);
146 static int32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
147 const wl_event_msg_t *e, void *data);
148 static int32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
149 const wl_event_msg_t *e, void *data);
152 ** register/deregister sdio function
154 static struct sdio_func *wl_sdio_func(void);
155 static void wl_clear_sdio_func(void);
160 static int32 wl_dev_bufvar_get(struct net_device *dev, int8 *name, int8 *buf,
162 static __used int32 wl_dev_bufvar_set(struct net_device *dev, int8 *name,
163 int8 *buf, int32 len);
164 static int32 wl_dev_intvar_set(struct net_device *dev, int8 *name, int32 val);
165 static int32 wl_dev_intvar_get(struct net_device *dev, int8 *name,
167 static int32 wl_dev_ioctl(struct net_device *dev, uint32 cmd, void *arg,
171 ** cfg80211 set_wiphy_params utilities
173 static int32 wl_set_frag(struct net_device *dev, uint32 frag_threshold);
174 static int32 wl_set_rts(struct net_device *dev, uint32 frag_threshold);
175 static int32 wl_set_retry(struct net_device *dev, uint32 retry, bool l);
178 ** wl profile utilities
180 static int32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
181 void *data, int32 item);
182 static void *wl_read_prof(struct wl_priv *wl, int32 item);
183 static void wl_init_prof(struct wl_profile *prof);
186 ** cfg80211 connect utilites
188 static int32 wl_set_wpa_version(struct net_device *dev,
189 struct cfg80211_connect_params *sme);
190 static int32 wl_set_auth_type(struct net_device *dev,
191 struct cfg80211_connect_params *sme);
192 static int32 wl_set_set_cipher(struct net_device *dev,
193 struct cfg80211_connect_params *sme);
194 static int32 wl_set_key_mgmt(struct net_device *dev,
195 struct cfg80211_connect_params *sme);
196 static int32 wl_set_set_sharedkey(struct net_device *dev,
197 struct cfg80211_connect_params *sme);
198 static int32 wl_get_assoc_ies(struct wl_priv *wl);
201 ** information element utilities
203 static void wl_rst_ie(struct wl_priv *wl);
204 static int32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
205 static int32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, uint16 ie_size);
206 static int32 wl_cp_ie(struct wl_priv *wl, u8 *dst, uint16 dst_size);
207 static uint32 wl_get_ielen(struct wl_priv *wl);
209 static int32 wl_mode_to_nl80211_iftype(int32 mode);
211 static struct wireless_dev *wl_alloc_wdev(int32 sizeof_iface,
213 static void wl_free_wdev(struct wl_priv *wl);
215 static int32 wl_inform_bss(struct wl_priv *wl);
216 static int32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
217 static int32 wl_update_bss_info(struct wl_priv *wl);
219 static int32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
220 u8 key_idx, const u8 *mac_addr,
221 struct key_params *params);
224 ** key indianess swap utilities
226 static void swap_key_from_BE(struct wl_wsec_key *key);
227 static void swap_key_to_BE(struct wl_wsec_key *key);
230 ** wl_priv memory init/deinit utilities
232 static int32 wl_init_priv_mem(struct wl_priv *wl);
233 static void wl_deinit_priv_mem(struct wl_priv *wl);
235 static void wl_delay(uint32 ms);
238 ** store/restore cfg80211 instance data
240 static void wl_set_drvdata(struct wl_dev *dev, void *data);
241 static void *wl_get_drvdata(struct wl_dev *dev);
244 ** ibss mode utilities
246 static bool wl_is_ibssmode(struct wl_priv *wl);
247 static bool wl_is_ibssstarter(struct wl_priv *wl);
250 ** dongle up/down , default configuration utilities
252 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
253 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
254 static void wl_link_up(struct wl_priv *wl);
255 static void wl_link_down(struct wl_priv *wl);
256 static int32 wl_dongle_mode(struct net_device *ndev, int32 iftype);
257 static int32 __wl_cfg80211_up(struct wl_priv *wl);
258 static int32 __wl_cfg80211_down(struct wl_priv *wl);
259 static int32 wl_dongle_probecap(struct wl_priv *wl);
260 static void wl_init_conf(struct wl_conf *conf);
263 ** dongle configuration utilities
265 #ifndef EMBEDDED_PLATFORM
266 static int32 wl_dongle_mode(struct net_device *ndev, int32 iftype);
267 static int32 wl_dongle_country(struct net_device *ndev, u8 ccode);
268 static int32 wl_dongle_up(struct net_device *ndev, uint32 up);
269 static int32 wl_dongle_power(struct net_device *ndev, uint32 power_mode);
270 static int32 wl_dongle_glom(struct net_device *ndev, uint32 glom,
271 uint32 dongle_align);
272 static int32 wl_dongle_roam(struct net_device *ndev, uint32 roamvar,
274 static int32 wl_dongle_eventmsg(struct net_device *ndev);
275 static int32 wl_dongle_scantime(struct net_device *ndev, int32 scan_assoc_time,
276 int32 scan_unassoc_time);
277 static int32 wl_dongle_offload(struct net_device *ndev, int32 arpoe,
279 static int32 wl_pattern_atoh(int8 *src, int8 *dst);
280 static int32 wl_dongle_filter(struct net_device *ndev, uint32 filter_mode);
281 static int32 wl_update_wiphybands(struct wl_priv *wl);
282 #endif /* !EMBEDDED_PLATFORM */
283 static int32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
288 static void wl_iscan_timer(ulong data);
289 static void wl_term_iscan(struct wl_priv *wl);
290 static int32 wl_init_iscan(struct wl_priv *wl);
291 static int32 wl_iscan_thread(void *data);
292 static int32 wl_dev_iovar_setbuf(struct net_device *dev, int8 *iovar,
293 void *param, int32 paramlen, void *bufptr,
295 static int32 wl_dev_iovar_getbuf(struct net_device *dev, int8 *iovar,
296 void *param, int32 paramlen, void *bufptr,
298 static int32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
300 static int32 wl_do_iscan(struct wl_priv *wl);
301 static int32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
302 static int32 wl_invoke_iscan(struct wl_priv *wl);
303 static int32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status,
304 struct wl_scan_results **bss_list);
305 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
306 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
307 static int32 wl_iscan_done(struct wl_priv *wl);
308 static int32 wl_iscan_pending(struct wl_priv *wl);
309 static int32 wl_iscan_inprogress(struct wl_priv *wl);
310 static int32 wl_iscan_aborted(struct wl_priv *wl);
313 ** fw/nvram downloading handler
315 static void wl_init_fw(struct wl_fw_ctrl *fw);
318 * find most significant bit set
320 static __used uint32 wl_find_msb(uint16 bit16);
323 * update pmklist to dongle
325 static __used int32 wl_update_pmklist(struct net_device *dev,
326 struct wl_pmk_list *pmk_list, int32 err);
328 #define WL_PRIV_GET() \
330 struct wl_iface *ci; \
331 if (unlikely(!(wl_cfg80211_dev && \
332 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
333 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
339 #define CHECK_SYS_UP() \
341 struct wl_priv *wl = wiphy_to_wl(wiphy); \
342 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
343 WL_INFO(("device is not ready : status (%d)\n", \
349 extern int dhd_wait_pend8021x(struct net_device *dev);
351 #if (WL_DBG_LEVEL > 0)
352 #define WL_DBG_ESTR_MAX 32
353 static int8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
354 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
355 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
356 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
357 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
358 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
359 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
360 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
362 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
364 "RADIO", "PSM_WATCHDOG",
366 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
367 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
368 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
370 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
372 #endif /* WL_DBG_LEVEL */
374 #define CHAN2G(_channel, _freq, _flags) { \
375 .band = IEEE80211_BAND_2GHZ, \
376 .center_freq = (_freq), \
377 .hw_value = (_channel), \
379 .max_antenna_gain = 0, \
383 #define CHAN5G(_channel, _flags) { \
384 .band = IEEE80211_BAND_5GHZ, \
385 .center_freq = 5000 + (5 * (_channel)), \
386 .hw_value = (_channel), \
388 .max_antenna_gain = 0, \
392 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
393 #define RATETAB_ENT(_rateid, _flags) \
395 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
396 .hw_value = (_rateid), \
400 static struct ieee80211_rate __wl_rates[] = {
401 RATETAB_ENT(WLC_RATE_1M, 0),
402 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
403 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
404 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
405 RATETAB_ENT(WLC_RATE_6M, 0),
406 RATETAB_ENT(WLC_RATE_9M, 0),
407 RATETAB_ENT(WLC_RATE_12M, 0),
408 RATETAB_ENT(WLC_RATE_18M, 0),
409 RATETAB_ENT(WLC_RATE_24M, 0),
410 RATETAB_ENT(WLC_RATE_36M, 0),
411 RATETAB_ENT(WLC_RATE_48M, 0),
412 RATETAB_ENT(WLC_RATE_54M, 0),
415 #define wl_a_rates (__wl_rates + 4)
416 #define wl_a_rates_size 8
417 #define wl_g_rates (__wl_rates + 0)
418 #define wl_g_rates_size 12
420 static struct ieee80211_channel __wl_2ghz_channels[] = {
437 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
438 CHAN5G(34, 0), CHAN5G(36, 0),
439 CHAN5G(38, 0), CHAN5G(40, 0),
440 CHAN5G(42, 0), CHAN5G(44, 0),
441 CHAN5G(46, 0), CHAN5G(48, 0),
442 CHAN5G(52, 0), CHAN5G(56, 0),
443 CHAN5G(60, 0), CHAN5G(64, 0),
444 CHAN5G(100, 0), CHAN5G(104, 0),
445 CHAN5G(108, 0), CHAN5G(112, 0),
446 CHAN5G(116, 0), CHAN5G(120, 0),
447 CHAN5G(124, 0), CHAN5G(128, 0),
448 CHAN5G(132, 0), CHAN5G(136, 0),
449 CHAN5G(140, 0), CHAN5G(149, 0),
450 CHAN5G(153, 0), CHAN5G(157, 0),
451 CHAN5G(161, 0), CHAN5G(165, 0),
452 CHAN5G(184, 0), CHAN5G(188, 0),
453 CHAN5G(192, 0), CHAN5G(196, 0),
454 CHAN5G(200, 0), CHAN5G(204, 0),
455 CHAN5G(208, 0), CHAN5G(212, 0),
459 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
460 CHAN5G(32, 0), CHAN5G(34, 0),
461 CHAN5G(36, 0), CHAN5G(38, 0),
462 CHAN5G(40, 0), CHAN5G(42, 0),
463 CHAN5G(44, 0), CHAN5G(46, 0),
464 CHAN5G(48, 0), CHAN5G(50, 0),
465 CHAN5G(52, 0), CHAN5G(54, 0),
466 CHAN5G(56, 0), CHAN5G(58, 0),
467 CHAN5G(60, 0), CHAN5G(62, 0),
468 CHAN5G(64, 0), CHAN5G(66, 0),
469 CHAN5G(68, 0), CHAN5G(70, 0),
470 CHAN5G(72, 0), CHAN5G(74, 0),
471 CHAN5G(76, 0), CHAN5G(78, 0),
472 CHAN5G(80, 0), CHAN5G(82, 0),
473 CHAN5G(84, 0), CHAN5G(86, 0),
474 CHAN5G(88, 0), CHAN5G(90, 0),
475 CHAN5G(92, 0), CHAN5G(94, 0),
476 CHAN5G(96, 0), CHAN5G(98, 0),
477 CHAN5G(100, 0), CHAN5G(102, 0),
478 CHAN5G(104, 0), CHAN5G(106, 0),
479 CHAN5G(108, 0), CHAN5G(110, 0),
480 CHAN5G(112, 0), CHAN5G(114, 0),
481 CHAN5G(116, 0), CHAN5G(118, 0),
482 CHAN5G(120, 0), CHAN5G(122, 0),
483 CHAN5G(124, 0), CHAN5G(126, 0),
484 CHAN5G(128, 0), CHAN5G(130, 0),
485 CHAN5G(132, 0), CHAN5G(134, 0),
486 CHAN5G(136, 0), CHAN5G(138, 0),
487 CHAN5G(140, 0), CHAN5G(142, 0),
488 CHAN5G(144, 0), CHAN5G(145, 0),
489 CHAN5G(146, 0), CHAN5G(147, 0),
490 CHAN5G(148, 0), CHAN5G(149, 0),
491 CHAN5G(150, 0), CHAN5G(151, 0),
492 CHAN5G(152, 0), CHAN5G(153, 0),
493 CHAN5G(154, 0), CHAN5G(155, 0),
494 CHAN5G(156, 0), CHAN5G(157, 0),
495 CHAN5G(158, 0), CHAN5G(159, 0),
496 CHAN5G(160, 0), CHAN5G(161, 0),
497 CHAN5G(162, 0), CHAN5G(163, 0),
498 CHAN5G(164, 0), CHAN5G(165, 0),
499 CHAN5G(166, 0), CHAN5G(168, 0),
500 CHAN5G(170, 0), CHAN5G(172, 0),
501 CHAN5G(174, 0), CHAN5G(176, 0),
502 CHAN5G(178, 0), CHAN5G(180, 0),
503 CHAN5G(182, 0), CHAN5G(184, 0),
504 CHAN5G(186, 0), CHAN5G(188, 0),
505 CHAN5G(190, 0), CHAN5G(192, 0),
506 CHAN5G(194, 0), CHAN5G(196, 0),
507 CHAN5G(198, 0), CHAN5G(200, 0),
508 CHAN5G(202, 0), CHAN5G(204, 0),
509 CHAN5G(206, 0), CHAN5G(208, 0),
510 CHAN5G(210, 0), CHAN5G(212, 0),
511 CHAN5G(214, 0), CHAN5G(216, 0),
512 CHAN5G(218, 0), CHAN5G(220, 0),
513 CHAN5G(222, 0), CHAN5G(224, 0),
514 CHAN5G(226, 0), CHAN5G(228, 0),
517 static struct ieee80211_supported_band __wl_band_2ghz = {
518 .band = IEEE80211_BAND_2GHZ,
519 .channels = __wl_2ghz_channels,
520 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
521 .bitrates = wl_g_rates,
522 .n_bitrates = wl_g_rates_size,
525 static struct ieee80211_supported_band __wl_band_5ghz_a = {
526 .band = IEEE80211_BAND_5GHZ,
527 .channels = __wl_5ghz_a_channels,
528 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
529 .bitrates = wl_a_rates,
530 .n_bitrates = wl_a_rates_size,
533 static struct ieee80211_supported_band __wl_band_5ghz_n = {
534 .band = IEEE80211_BAND_5GHZ,
535 .channels = __wl_5ghz_n_channels,
536 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
537 .bitrates = wl_a_rates,
538 .n_bitrates = wl_a_rates_size,
541 static const uint32 __wl_cipher_suites[] = {
542 WLAN_CIPHER_SUITE_WEP40,
543 WLAN_CIPHER_SUITE_WEP104,
544 WLAN_CIPHER_SUITE_TKIP,
545 WLAN_CIPHER_SUITE_CCMP,
546 WLAN_CIPHER_SUITE_AES_CMAC,
549 static void swap_key_from_BE(struct wl_wsec_key *key)
551 key->index = htod32(key->index);
552 key->len = htod32(key->len);
553 key->algo = htod32(key->algo);
554 key->flags = htod32(key->flags);
555 key->rxiv.hi = htod32(key->rxiv.hi);
556 key->rxiv.lo = htod16(key->rxiv.lo);
557 key->iv_initialized = htod32(key->iv_initialized);
560 static void swap_key_to_BE(struct wl_wsec_key *key)
562 key->index = dtoh32(key->index);
563 key->len = dtoh32(key->len);
564 key->algo = dtoh32(key->algo);
565 key->flags = dtoh32(key->flags);
566 key->rxiv.hi = dtoh32(key->rxiv.hi);
567 key->rxiv.lo = dtoh16(key->rxiv.lo);
568 key->iv_initialized = dtoh32(key->iv_initialized);
572 wl_dev_ioctl(struct net_device *dev, uint32 cmd, void *arg, uint32 len)
579 memset(&ioc, 0, sizeof(ioc));
583 strcpy(ifr.ifr_name, dev->name);
584 ifr.ifr_data = (caddr_t)&ioc;
588 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
595 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
596 enum nl80211_iftype type, uint32 *flags,
597 struct vif_params *params)
599 struct wl_priv *wl = wiphy_to_wl(wiphy);
600 struct wireless_dev *wdev;
607 case NL80211_IFTYPE_MONITOR:
608 case NL80211_IFTYPE_WDS:
609 WL_ERR(("type (%d) : currently we do not support this type\n",
612 case NL80211_IFTYPE_ADHOC:
613 wl->conf->mode = WL_MODE_IBSS;
615 case NL80211_IFTYPE_STATION:
616 wl->conf->mode = WL_MODE_BSS;
622 infra = htod32(infra);
624 wdev = ndev->ieee80211_ptr;
626 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
628 ((err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra))))
630 unlikely((err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap))))) {
631 WL_ERR(("Error (%d)\n", err));
634 /* -EINPROGRESS: Call commit handler */
638 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
640 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
641 params->bss_type = DOT11_BSSTYPE_ANY;
642 params->scan_type = 0;
643 params->nprobes = -1;
644 params->active_time = -1;
645 params->passive_time = -1;
646 params->home_time = -1;
647 params->channel_num = 0;
649 params->nprobes = htod32(params->nprobes);
650 params->active_time = htod32(params->active_time);
651 params->passive_time = htod32(params->passive_time);
652 params->home_time = htod32(params->home_time);
653 if (ssid && ssid->SSID_len)
654 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
659 wl_dev_iovar_setbuf(struct net_device *dev, int8 * iovar, void *param,
660 int32 paramlen, void *bufptr, int32 buflen)
664 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
665 BUG_ON(unlikely(!iolen));
667 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
671 wl_dev_iovar_getbuf(struct net_device *dev, int8 * iovar, void *param,
672 int32 paramlen, void *bufptr, int32 buflen)
676 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
677 BUG_ON(unlikely(!iolen));
679 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
683 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, uint16 action)
686 (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params));
687 struct wl_iscan_params *params;
690 if (ssid && ssid->SSID_len)
691 params_size += sizeof(struct wlc_ssid);
692 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
693 if (unlikely(!params))
695 memset(params, 0, params_size);
696 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
698 wl_iscan_prep(¶ms->params, ssid);
700 params->version = htod32(ISCAN_REQ_VERSION);
701 params->action = htod16(action);
702 params->scan_duration = htod16(0);
704 /* params_size += OFFSETOF(wl_iscan_params_t, params); */
707 wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
708 iscan->ioctl_buf, WLC_IOCTL_SMLEN)))) {
710 WL_INFO(("system busy : iscan canceled\n"));
712 WL_ERR(("error (%d)\n", err));
719 static int32 wl_do_iscan(struct wl_priv *wl)
721 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
722 struct wlc_ssid ssid;
725 /* Broadcast scan by default */
726 memset(&ssid, 0, sizeof(ssid));
728 iscan->state = WL_ISCAN_STATE_SCANING;
730 if (wl->active_scan) {
731 int32 passive_scan = 0;
732 /* make it active scan */
735 wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
736 &passive_scan, sizeof(passive_scan))))) {
737 WL_DBG(("error (%d)\n", err));
741 wl->iscan_kickstart = TRUE;
742 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
743 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
750 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
751 struct cfg80211_scan_request *request,
752 struct cfg80211_ssid *this_ssid)
754 struct wl_priv *wl = ndev_to_wl(ndev);
755 struct cfg80211_ssid *ssids;
756 struct wl_scan_req *sr = wl_to_sr(wl);
762 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
763 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
766 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
767 WL_ERR(("Scanning being aborted : status (%d)\n",
774 if (request) { /* scan bss */
775 ssids = request->ssids;
776 n_ssids = min(request->n_ssids, WL_NUM_SCAN_MAX);
777 if (wl->iscan_on && n_ssids && !ssids->ssid_len) { /* for
779 * ssids->ssid_len has
780 * non-zero(ssid string)
782 * Otherwise this is 0.
783 * we do not iscan for
784 * specific scan request
788 } else { /* scan in ibss */
789 /* we don't do iscan in ibss */
793 wl->scan_request = request;
794 set_bit(WL_STATUS_SCANNING, &wl->status);
796 if (likely(!(err = wl_do_iscan(wl))))
801 WL_DBG(("n_ssid (%d), ssid \"%s\", ssid_len (%d)\n",
802 n_ssids, ssids->ssid, ssids->ssid_len));
803 memset(&sr->ssid, 0, sizeof(sr->ssid));
806 MIN(sizeof(sr->ssid.SSID), ssids->ssid_len);
807 if (sr->ssid.SSID_len) {
808 memcpy(sr->ssid.SSID, ssids->ssid,
810 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
811 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
812 sr->ssid.SSID, sr->ssid.SSID_len));
815 WL_DBG(("Broadcast scan\n"));
819 WL_DBG(("Broadcast scan\n"));
821 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
822 if (wl->active_scan) {
823 int32 pssive_scan = 0;
824 /* make it active scan */
827 wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
829 sizeof(pssive_scan))))) {
830 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n",
836 wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
837 sizeof(sr->ssid)))) {
839 WL_INFO(("system busy : scan for \"%s\" "
840 "canceled\n", sr->ssid.SSID));
842 WL_ERR(("WLC_SCAN error (%d)\n", err));
851 clear_bit(WL_STATUS_SCANNING, &wl->status);
852 wl->scan_request = NULL;
857 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
858 struct cfg80211_scan_request *request)
863 if (unlikely((err = __wl_cfg80211_scan(wiphy, ndev, request, NULL)))) {
864 WL_DBG(("scan error (%d)\n", err));
871 static int32 wl_dev_intvar_set(struct net_device *dev, int8 *name, int32 val)
873 int8 buf[WLC_IOCTL_SMLEN];
878 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
879 BUG_ON(unlikely(!len));
881 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len)))) {
882 WL_ERR(("error (%d)\n", err));
889 wl_dev_intvar_get(struct net_device *dev, int8 *name, int32 *retval)
892 int8 buf[WLC_IOCTL_SMLEN];
900 bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
902 BUG_ON(unlikely(!len));
903 if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len)))) {
904 WL_ERR(("error (%d)\n", err));
906 *retval = dtoh32(var.val);
911 static int32 wl_set_rts(struct net_device *dev, uint32 rts_threshold)
916 ((err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold)))) {
917 WL_ERR(("Error (%d)\n", err));
923 static int32 wl_set_frag(struct net_device *dev, uint32 frag_threshold)
928 ((err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold)))) {
929 WL_ERR(("Error (%d)\n", err));
935 static int32 wl_set_retry(struct net_device *dev, uint32 retry, bool l)
938 uint32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
940 retry = htod32(retry);
941 if (unlikely((err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry))))) {
942 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
948 static int32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, uint32 changed)
950 struct wl_priv *wl = wiphy_to_wl(wiphy);
951 struct net_device *ndev = wl_to_ndev(wl);
955 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
956 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
957 wl->conf->rts_threshold = wiphy->rts_threshold;
958 if (!(err = wl_set_rts(ndev, wl->conf->rts_threshold)))
961 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
962 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
963 wl->conf->frag_threshold = wiphy->frag_threshold;
964 if (!(err = wl_set_frag(ndev, wl->conf->frag_threshold)))
967 if (changed & WIPHY_PARAM_RETRY_LONG
968 && (wl->conf->retry_long != wiphy->retry_long)) {
969 wl->conf->retry_long = wiphy->retry_long;
970 if (!(err = wl_set_retry(ndev, wl->conf->retry_long, TRUE)))
973 if (changed & WIPHY_PARAM_RETRY_SHORT
974 && (wl->conf->retry_short != wiphy->retry_short)) {
975 wl->conf->retry_short = wiphy->retry_short;
976 if (!(err = wl_set_retry(ndev, wl->conf->retry_short, FALSE))) {
985 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
986 struct cfg80211_ibss_params *params)
988 struct wl_priv *wl = wiphy_to_wl(wiphy);
989 struct cfg80211_bss *bss;
990 struct ieee80211_channel *chan;
991 struct wl_join_params join_params;
992 struct cfg80211_ssid ssid;
993 int32 scan_retry = 0;
998 WL_ERR(("Invalid bssid\n"));
1001 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1003 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1004 ssid.ssid_len = params->ssid_len;
1007 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1013 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1014 rtnl_unlock(); /* to allow scan_inform to paropagate
1015 to cfg80211 plane */
1016 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1017 till scan done.... */
1019 bss = cfg80211_get_ibss(wiphy, NULL,
1020 params->ssid, params->ssid_len);
1023 wl->ibss_starter = FALSE;
1024 WL_DBG(("Found IBSS\n"));
1026 wl->ibss_starter = TRUE;
1028 if ((chan = params->channel))
1029 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1031 ** Join with specific BSSID and cached SSID
1032 ** If SSID is zero join based on BSSID only
1034 memset(&join_params, 0, sizeof(join_params));
1035 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1037 join_params.ssid.SSID_len = htod32(params->ssid_len);
1039 memcpy(&join_params.params.bssid, params->bssid,
1042 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1046 wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1047 sizeof(join_params))))) {
1048 WL_ERR(("Error (%d)\n", err));
1054 static int32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1056 struct wl_priv *wl = wiphy_to_wl(wiphy);
1066 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1068 struct wl_priv *wl = ndev_to_wl(dev);
1069 struct wl_security *sec;
1073 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1074 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1075 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1076 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1078 val = WPA_AUTH_DISABLED;
1079 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1080 if (unlikely((err = wl_dev_intvar_set(dev, "wpa_auth", val)))) {
1081 WL_ERR(("set wpa_auth failed (%d)\n", err));
1084 sec = wl_read_prof(wl, WL_PROF_SEC);
1085 sec->wpa_versions = sme->crypto.wpa_versions;
1090 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1092 struct wl_priv *wl = ndev_to_wl(dev);
1093 struct wl_security *sec;
1097 switch (sme->auth_type) {
1098 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1100 WL_DBG(("open system\n"));
1102 case NL80211_AUTHTYPE_SHARED_KEY:
1104 WL_DBG(("shared key\n"));
1106 case NL80211_AUTHTYPE_AUTOMATIC:
1108 WL_DBG(("automatic\n"));
1110 case NL80211_AUTHTYPE_NETWORK_EAP:
1111 WL_DBG(("network eap\n"));
1114 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1118 if (unlikely((err = wl_dev_intvar_set(dev, "auth", val)))) {
1119 WL_ERR(("set auth failed (%d)\n", err));
1122 sec = wl_read_prof(wl, WL_PROF_SEC);
1123 sec->auth_type = sme->auth_type;
1128 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1130 struct wl_priv *wl = ndev_to_wl(dev);
1131 struct wl_security *sec;
1136 if (sme->crypto.n_ciphers_pairwise) {
1137 switch (sme->crypto.ciphers_pairwise[0]) {
1138 case WLAN_CIPHER_SUITE_WEP40:
1139 case WLAN_CIPHER_SUITE_WEP104:
1142 case WLAN_CIPHER_SUITE_TKIP:
1143 pval = TKIP_ENABLED;
1145 case WLAN_CIPHER_SUITE_CCMP:
1148 case WLAN_CIPHER_SUITE_AES_CMAC:
1152 WL_ERR(("invalid cipher pairwise (%d)\n",
1153 sme->crypto.ciphers_pairwise[0]));
1157 if (sme->crypto.cipher_group) {
1158 switch (sme->crypto.cipher_group) {
1159 case WLAN_CIPHER_SUITE_WEP40:
1160 case WLAN_CIPHER_SUITE_WEP104:
1163 case WLAN_CIPHER_SUITE_TKIP:
1164 gval = TKIP_ENABLED;
1166 case WLAN_CIPHER_SUITE_CCMP:
1169 case WLAN_CIPHER_SUITE_AES_CMAC:
1173 WL_ERR(("invalid cipher group (%d)\n",
1174 sme->crypto.cipher_group));
1179 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1180 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", pval | gval)))) {
1181 WL_ERR(("error (%d)\n", err));
1185 sec = wl_read_prof(wl, WL_PROF_SEC);
1186 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1187 sec->cipher_group = sme->crypto.cipher_group;
1193 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1195 struct wl_priv *wl = ndev_to_wl(dev);
1196 struct wl_security *sec;
1200 if (sme->crypto.n_akm_suites) {
1201 if (unlikely((err = wl_dev_intvar_get(dev, "wpa_auth", &val)))) {
1202 WL_ERR(("could not get wpa_auth (%d)\n", err));
1205 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1206 switch (sme->crypto.akm_suites[0]) {
1207 case WLAN_AKM_SUITE_8021X:
1208 val = WPA_AUTH_UNSPECIFIED;
1210 case WLAN_AKM_SUITE_PSK:
1214 WL_ERR(("invalid cipher group (%d)\n",
1215 sme->crypto.cipher_group));
1218 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1219 switch (sme->crypto.akm_suites[0]) {
1220 case WLAN_AKM_SUITE_8021X:
1221 val = WPA2_AUTH_UNSPECIFIED;
1223 case WLAN_AKM_SUITE_PSK:
1224 val = WPA2_AUTH_PSK;
1227 WL_ERR(("invalid cipher group (%d)\n",
1228 sme->crypto.cipher_group));
1233 WL_DBG(("setting wpa_auth to %d\n", val));
1234 if (unlikely((err = wl_dev_intvar_set(dev, "wpa_auth", val)))) {
1235 WL_ERR(("could not set wpa_auth (%d)\n", err));
1239 sec = wl_read_prof(wl, WL_PROF_SEC);
1240 sec->wpa_auth = sme->crypto.akm_suites[0];
1246 wl_set_set_sharedkey(struct net_device *dev,
1247 struct cfg80211_connect_params *sme)
1249 struct wl_priv *wl = ndev_to_wl(dev);
1250 struct wl_security *sec;
1251 struct wl_wsec_key key;
1255 WL_DBG(("key len (%d)\n", sme->key_len));
1257 sec = wl_read_prof(wl, WL_PROF_SEC);
1258 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1259 sec->wpa_versions, sec->cipher_pairwise));
1261 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1262 NL80211_WPA_VERSION_2))
1263 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1264 WLAN_CIPHER_SUITE_WEP104))) {
1265 memset(&key, 0, sizeof(key));
1266 key.len = (uint32) sme->key_len;
1267 key.index = (uint32) sme->key_idx;
1268 if (unlikely(key.len > sizeof(key.data))) {
1269 WL_ERR(("Too long key length (%u)\n", key.len));
1272 memcpy(key.data, sme->key, key.len);
1273 key.flags = WL_PRIMARY_KEY;
1274 switch (sec->cipher_pairwise) {
1275 case WLAN_CIPHER_SUITE_WEP40:
1276 key.algo = CRYPTO_ALGO_WEP1;
1278 case WLAN_CIPHER_SUITE_WEP104:
1279 key.algo = CRYPTO_ALGO_WEP128;
1282 WL_ERR(("Invalid algorithm (%d)\n",
1283 sme->crypto.ciphers_pairwise[0]));
1286 /* Set the new key/index */
1287 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1288 key.len, key.index, key.algo));
1289 WL_DBG(("key \"%s\"\n", key.data));
1290 swap_key_from_BE(&key);
1293 wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1295 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1298 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1299 WL_DBG(("set auth_type to shared key\n"));
1300 val = 1; /* shared key */
1303 wl_dev_intvar_set(dev, "auth", val)))) {
1304 WL_ERR(("set auth failed (%d)\n", err));
1314 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1315 struct cfg80211_connect_params *sme)
1317 struct wl_priv *wl = wiphy_to_wl(wiphy);
1318 struct ieee80211_channel *chan = sme->channel;
1319 struct wlc_ssid ssid;
1323 if (unlikely(!sme->ssid)) {
1324 WL_ERR(("Invalid ssid\n"));
1328 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1329 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
1330 chan->center_freq));
1332 WL_DBG(("ie (%p), ie_len (%d)\n", sme->ie, sme->ie_len));
1333 if (unlikely((err = wl_set_wpa_version(dev, sme))))
1336 if (unlikely((err = wl_set_auth_type(dev, sme))))
1339 if (unlikely((err = wl_set_set_cipher(dev, sme))))
1342 if (unlikely((err = wl_set_key_mgmt(dev, sme))))
1345 if (unlikely((err = wl_set_set_sharedkey(dev, sme))))
1348 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1350 ** Join with specific BSSID and cached SSID
1351 ** If SSID is zero join based on BSSID only
1353 memset(&ssid, 0, sizeof(ssid));
1354 ssid.SSID_len = MIN(sizeof(ssid.SSID), sme->ssid_len);
1355 memcpy(ssid.SSID, sme->ssid, ssid.SSID_len);
1356 ssid.SSID_len = htod32(ssid.SSID_len);
1357 wl_update_prof(wl, NULL, &ssid, WL_PROF_SSID);
1358 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1359 WL_DBG(("ssid \"%s\", len (%d)\n", ssid.SSID, ssid.SSID_len));
1362 ((err = wl_dev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid))))) {
1363 WL_ERR(("error (%d)\n", err));
1366 set_bit(WL_STATUS_CONNECTING, &wl->status);
1372 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1375 struct wl_priv *wl = wiphy_to_wl(wiphy);
1380 WL_DBG(("Reason %d\n", reason_code));
1382 if (likely((act = *(bool *) wl_read_prof(wl, WL_PROF_ACT)))) {
1383 scbval.val = reason_code;
1384 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1385 scbval.val = htod32(scbval.val);
1386 if (unlikely((err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1387 sizeof(scb_val_t))))) {
1388 WL_ERR(("error (%d)\n", err));
1397 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1398 enum nl80211_tx_power_setting type, int32 dbm)
1401 struct wl_priv *wl = wiphy_to_wl(wiphy);
1402 struct net_device *ndev = wl_to_ndev(wl);
1409 case NL80211_TX_POWER_AUTOMATIC:
1411 case NL80211_TX_POWER_LIMITED:
1413 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1417 case NL80211_TX_POWER_FIXED:
1419 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1424 /* Make sure radio is off or on as far as software is concerned */
1425 disable = WL_RADIO_SW_DISABLE << 16;
1426 disable = htod32(disable);
1429 wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable))))) {
1430 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1437 txpwrmw = (uint16) dbm;
1438 if (unlikely((err = wl_dev_intvar_set(ndev, "qtxpower",
1439 (int32) (bcm_mw_to_qdbm
1441 WL_ERR(("qtxpower error (%d)\n", err));
1444 wl->conf->tx_power = dbm;
1449 static int32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, int32 *dbm)
1451 struct wl_priv *wl = wiphy_to_wl(wiphy);
1452 struct net_device *ndev = wl_to_ndev(wl);
1458 if (unlikely((err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm)))) {
1459 WL_ERR(("error (%d)\n", err));
1462 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1463 *dbm = (int32) bcm_qdbm_to_mw(result);
1469 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1476 WL_DBG(("key index (%d)\n", key_idx));
1480 (err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
1481 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1484 wsec = dtoh32(wsec);
1485 if (wsec & WEP_ENABLED) {
1486 /* Just select a new current key */
1487 index = (uint32) key_idx;
1488 index = htod32(index);
1489 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY,
1490 &index, sizeof(index))))) {
1491 WL_ERR(("error (%d)\n", err));
1498 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1499 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1501 struct wl_wsec_key key;
1504 memset(&key, 0, sizeof(key));
1505 key.index = (uint32) key_idx;
1506 /* Instead of bcast for ea address for default wep keys,
1507 driver needs it to be Null */
1508 if (!ETHER_ISMULTI(mac_addr))
1509 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1510 key.len = (uint32) params->key_len;
1511 /* check for key index change */
1514 swap_key_from_BE(&key);
1517 wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
1518 WL_ERR(("key delete error (%d)\n", err));
1522 if (key.len > sizeof(key.data)) {
1523 WL_ERR(("Invalid key length (%d)\n", key.len));
1527 WL_DBG(("Setting the key index %d\n", key.index));
1528 memcpy(key.data, params->key, key.len);
1530 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1532 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1533 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1534 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1537 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1538 if (params->seq && params->seq_len == 6) {
1541 ivptr = (u8 *) params->seq;
1542 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1543 (ivptr[3] << 8) | ivptr[2];
1544 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1545 key.iv_initialized = TRUE;
1548 switch (params->cipher) {
1549 case WLAN_CIPHER_SUITE_WEP40:
1550 key.algo = CRYPTO_ALGO_WEP1;
1551 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1553 case WLAN_CIPHER_SUITE_WEP104:
1554 key.algo = CRYPTO_ALGO_WEP128;
1555 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1557 case WLAN_CIPHER_SUITE_TKIP:
1558 key.algo = CRYPTO_ALGO_TKIP;
1559 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1561 case WLAN_CIPHER_SUITE_AES_CMAC:
1562 key.algo = CRYPTO_ALGO_AES_CCM;
1563 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1565 case WLAN_CIPHER_SUITE_CCMP:
1566 key.algo = CRYPTO_ALGO_AES_CCM;
1567 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1570 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1573 swap_key_from_BE(&key);
1575 dhd_wait_pend8021x(dev);
1578 wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
1579 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1587 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1588 u8 key_idx, const u8 *mac_addr,
1589 struct key_params *params)
1591 struct wl_wsec_key key;
1596 WL_DBG(("key index (%d)\n", key_idx));
1600 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1601 memset(&key, 0, sizeof(key));
1603 key.len = (uint32) params->key_len;
1604 key.index = (uint32) key_idx;
1606 if (unlikely(key.len > sizeof(key.data))) {
1607 WL_ERR(("Too long key length (%u)\n", key.len));
1610 memcpy(key.data, params->key, key.len);
1612 key.flags = WL_PRIMARY_KEY;
1613 switch (params->cipher) {
1614 case WLAN_CIPHER_SUITE_WEP40:
1615 key.algo = CRYPTO_ALGO_WEP1;
1616 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1618 case WLAN_CIPHER_SUITE_WEP104:
1619 key.algo = CRYPTO_ALGO_WEP128;
1620 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1622 case WLAN_CIPHER_SUITE_TKIP:
1623 key.algo = CRYPTO_ALGO_TKIP;
1624 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1626 case WLAN_CIPHER_SUITE_AES_CMAC:
1627 key.algo = CRYPTO_ALGO_AES_CCM;
1628 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1630 case WLAN_CIPHER_SUITE_CCMP:
1631 key.algo = CRYPTO_ALGO_AES_CCM;
1632 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1635 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1639 /* Set the new key/index */
1640 swap_key_from_BE(&key);
1641 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY,
1642 &key, sizeof(key))))) {
1643 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1648 if (unlikely((err = wl_dev_intvar_get(dev, "wsec", &wsec)))) {
1649 WL_ERR(("get wsec error (%d)\n", err));
1652 wsec &= ~(WEP_ENABLED);
1654 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", wsec)))) {
1655 WL_ERR(("set wsec error (%d)\n", err));
1659 val = 1; /* assume shared key. otherwise 0 */
1662 ((err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))) {
1663 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1670 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1671 u8 key_idx, const u8 *mac_addr)
1673 struct wl_wsec_key key;
1679 memset(&key, 0, sizeof(key));
1681 key.index = (uint32) key_idx;
1682 key.flags = WL_PRIMARY_KEY;
1683 key.algo = CRYPTO_ALGO_OFF;
1685 WL_DBG(("key index (%d)\n", key_idx));
1686 /* Set the new key/index */
1687 swap_key_from_BE(&key);
1688 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY,
1689 &key, sizeof(key))))) {
1690 if (err == -EINVAL) {
1691 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1692 /* we ignore this key index in this case */
1693 WL_DBG(("invalid key index (%d)\n", key_idx));
1696 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1702 if (unlikely((err = wl_dev_intvar_get(dev, "wsec", &wsec)))) {
1703 WL_ERR(("get wsec error (%d)\n", err));
1706 wsec &= ~(WEP_ENABLED);
1708 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", wsec)))) {
1709 WL_ERR(("set wsec error (%d)\n", err));
1713 val = 0; /* assume open key. otherwise 1 */
1716 ((err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))) {
1717 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1724 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1725 u8 key_idx, const u8 *mac_addr, void *cookie,
1726 void (*callback) (void *cookie, struct key_params * params))
1728 struct key_params params;
1729 struct wl_wsec_key key;
1730 struct wl_priv *wl = wiphy_to_wl(wiphy);
1731 struct wl_security *sec;
1735 WL_DBG(("key index (%d)\n", key_idx));
1738 memset(&key, 0, sizeof(key));
1739 key.index = key_idx;
1740 swap_key_to_BE(&key);
1741 memset(¶ms, 0, sizeof(params));
1742 params.key_len = (u8) MIN(DOT11_MAX_KEY_SIZE, key.len);
1743 memcpy(params.key, key.data, params.key_len);
1746 (err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
1747 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1750 wsec = dtoh32(wsec);
1753 sec = wl_read_prof(wl, WL_PROF_SEC);
1754 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1755 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1756 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1757 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1758 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1759 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1763 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1764 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1767 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1768 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1771 WL_ERR(("Invalid algo (0x%x)\n", wsec));
1775 callback(cookie, ¶ms);
1780 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1781 struct net_device *dev, u8 key_idx)
1783 WL_INFO(("Not supported\n"));
1789 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1790 u8 *mac, struct station_info *sinfo)
1792 struct wl_priv *wl = wiphy_to_wl(wiphy);
1800 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
1801 WL_ERR(("Wrong Mac address\n"));
1805 /* Report the current tx rate */
1806 if ((err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) {
1807 WL_ERR(("Could not get rate (%d)\n", err));
1809 rate = dtoh32(rate);
1810 sinfo->filled |= STATION_INFO_TX_BITRATE;
1811 sinfo->txrate.legacy = rate * 5;
1812 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1815 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1819 wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1820 sizeof(scb_val_t)))) {
1821 WL_ERR(("Could not get rssi (%d)\n", err));
1824 rssi = dtoh32(scb_val.val);
1825 sinfo->filled |= STATION_INFO_SIGNAL;
1826 sinfo->signal = rssi;
1827 WL_DBG(("RSSI %d dBm\n", rssi));
1834 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1835 bool enabled, int32 timeout)
1841 pm = enabled ? PM_FAST : PM_OFF;
1843 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1844 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm))))) {
1846 WL_DBG(("net_device is not ready yet\n"));
1848 WL_ERR(("error (%d)\n", err));
1854 static __used uint32 wl_find_msb(uint16 bit16)
1858 if (bit16 & 0xff00) {
1882 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1884 const struct cfg80211_bitrate_mask *mask)
1886 struct wl_rateset rateset;
1895 /* addr param is always NULL. ignore it */
1896 /* Get current rateset */
1897 if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1898 sizeof(rateset))))) {
1899 WL_ERR(("could not get current rateset (%d)\n", err));
1903 rateset.count = dtoh32(rateset.count);
1905 if (!(legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy)))
1906 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1908 val = wl_g_rates[legacy - 1].bitrate * 100000;
1910 if (val < rateset.count) {
1911 /* Select rate by rateset index */
1912 rate = rateset.rates[val] & 0x7f;
1914 /* Specified rate in bps */
1915 rate = val / 500000;
1918 WL_DBG(("rate %d mbps\n", (rate / 2)));
1922 * Set rate override,
1923 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1925 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1926 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1927 if (unlikely(err_bg && err_a)) {
1928 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
1929 return err_bg | err_a;
1935 static int32 wl_cfg80211_resume(struct wiphy *wiphy)
1940 wl_invoke_iscan(wiphy_to_wl(wiphy));
1945 static int32 wl_cfg80211_suspend(struct wiphy *wiphy)
1947 struct wl_priv *wl = wiphy_to_wl(wiphy);
1952 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1954 if (wl->scan_request) {
1955 cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE means
1957 wl->scan_request = NULL;
1959 clear_bit(WL_STATUS_SCANNING, &wl->status);
1960 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1966 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
1969 int8 eabuf[ETHER_ADDR_STR_LEN];
1972 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
1974 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
1975 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
1976 WL_DBG(("PMKID[%d]: %s =\n", i,
1977 bcm_ether_ntoa(&pmk_list->pmkids.pmkid[i].BSSID,
1979 for (j = 0; j < WPA2_PMKID_LEN; j++) {
1980 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
1984 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
1992 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
1993 struct cfg80211_pmksa *pmksa)
1995 struct wl_priv *wl = wiphy_to_wl(wiphy);
1996 int8 eabuf[ETHER_ADDR_STR_LEN];
2001 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
2002 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2003 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2006 if (i < WL_NUM_PMKIDS_MAX) {
2007 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2009 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2011 if (i == wl->pmk_list->pmkids.npmkid)
2012 wl->pmk_list->pmkids.npmkid++;
2016 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %s =\n",
2017 bcm_ether_ntoa(&wl->pmk_list->pmkids.
2018 pmkid[wl->pmk_list->pmkids.npmkid].BSSID,
2020 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2022 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2026 err = wl_update_pmklist(dev, wl->pmk_list, err);
2032 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2033 struct cfg80211_pmksa *pmksa)
2035 struct wl_priv *wl = wiphy_to_wl(wiphy);
2036 int8 eabuf[ETHER_ADDR_STR_LEN];
2037 struct _pmkid_list pmkid;
2042 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
2043 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2044 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2046 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %s =\n",
2047 bcm_ether_ntoa(&pmkid.pmkid[0].BSSID, eabuf)));
2048 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2049 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2052 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2054 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2058 if ((wl->pmk_list->pmkids.npmkid > 0)
2059 && (i < wl->pmk_list->pmkids.npmkid)) {
2060 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2061 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2062 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2063 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2065 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2066 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2069 wl->pmk_list->pmkids.npmkid--;
2074 err = wl_update_pmklist(dev, wl->pmk_list, err);
2081 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2083 struct wl_priv *wl = wiphy_to_wl(wiphy);
2087 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2088 err = wl_update_pmklist(dev, wl->pmk_list, err);
2093 static struct cfg80211_ops wl_cfg80211_ops = {
2094 .change_virtual_intf = wl_cfg80211_change_iface,
2095 .scan = wl_cfg80211_scan,
2096 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2097 .join_ibss = wl_cfg80211_join_ibss,
2098 .leave_ibss = wl_cfg80211_leave_ibss,
2099 .get_station = wl_cfg80211_get_station,
2100 .set_tx_power = wl_cfg80211_set_tx_power,
2101 .get_tx_power = wl_cfg80211_get_tx_power,
2102 .add_key = wl_cfg80211_add_key,
2103 .del_key = wl_cfg80211_del_key,
2104 .get_key = wl_cfg80211_get_key,
2105 .set_default_key = wl_cfg80211_config_default_key,
2106 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2107 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2108 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2109 .connect = wl_cfg80211_connect,
2110 .disconnect = wl_cfg80211_disconnect,
2111 .suspend = wl_cfg80211_suspend,
2112 .resume = wl_cfg80211_resume,
2113 .set_pmksa = wl_cfg80211_set_pmksa,
2114 .del_pmksa = wl_cfg80211_del_pmksa,
2115 .flush_pmksa = wl_cfg80211_flush_pmksa
2118 static int32 wl_mode_to_nl80211_iftype(int32 mode)
2124 return NL80211_IFTYPE_STATION;
2126 return NL80211_IFTYPE_ADHOC;
2128 return NL80211_IFTYPE_UNSPECIFIED;
2134 static struct wireless_dev *wl_alloc_wdev(int32 sizeof_iface,
2137 struct wireless_dev *wdev;
2140 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2141 if (unlikely(!wdev)) {
2142 WL_ERR(("Could not allocate wireless device\n"));
2143 return ERR_PTR(-ENOMEM);
2146 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2147 if (unlikely(!wdev->wiphy)) {
2148 WL_ERR(("Couldn not allocate wiphy device\n"));
2152 set_wiphy_dev(wdev->wiphy, dev);
2153 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2154 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2155 wdev->wiphy->interface_modes =
2156 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2157 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2158 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2159 * it as 11a by default.
2160 * This will be updated with
2163 * if phy has 11n capability
2165 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2166 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2167 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2168 #ifndef WL_POWERSAVE_DISABLED
2169 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2174 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2175 #endif /* !WL_POWERSAVE_DISABLED */
2176 if (unlikely(((err = wiphy_register(wdev->wiphy)) < 0))) {
2177 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2178 goto wiphy_register_out;
2183 wiphy_free(wdev->wiphy);
2188 return ERR_PTR(err);
2191 static void wl_free_wdev(struct wl_priv *wl)
2193 struct wireless_dev *wdev = wl_to_wdev(wl);
2195 if (unlikely(!wdev)) {
2196 WL_ERR(("wdev is invalid\n"));
2199 wiphy_unregister(wdev->wiphy);
2200 wiphy_free(wdev->wiphy);
2202 wl_to_wdev(wl) = NULL;
2205 static int32 wl_inform_bss(struct wl_priv *wl)
2207 struct wl_scan_results *bss_list;
2208 struct wl_bss_info *bi = NULL; /* must be initialized */
2212 bss_list = wl->bss_list;
2213 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2214 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2215 bss_list->version));
2218 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2219 bi = next_bss(bss_list, bi);
2220 for_each_bss(bss_list, bi, i) {
2221 if (unlikely(err = wl_inform_single_bss(wl, bi)))
2227 static int32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2229 struct wiphy *wiphy = wl_to_wiphy(wl);
2230 struct ieee80211_mgmt *mgmt;
2231 struct ieee80211_channel *channel;
2232 struct ieee80211_supported_band *band;
2233 struct wl_cfg80211_bss_info *notif_bss_info;
2234 struct wl_scan_req *sr = wl_to_sr(wl);
2239 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
2240 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2244 kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2245 WL_BSS_INFO_MAX, GFP_KERNEL);
2246 if (unlikely(!notif_bss_info)) {
2247 WL_ERR(("notif_bss_info alloc failed\n"));
2250 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2251 notif_bss_info->channel = CHSPEC_CHANNEL(bi->chanspec);
2252 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2253 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2255 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2256 notif_bss_info->rssi = bi->RSSI;
2257 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
2258 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2259 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2260 IEEE80211_STYPE_PROBE_RESP);
2262 mgmt->u.probe_resp.timestamp = 0;
2263 mgmt->u.probe_resp.beacon_int = cpu_to_le16(bi->beacon_period);
2264 mgmt->u.probe_resp.capab_info = cpu_to_le16(bi->capability);
2266 wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2267 wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2269 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2270 wl_cp_ie(wl, mgmt->u.probe_resp.variable, WL_BSS_INFO_MAX -
2271 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2272 notif_bss_info->frame_len =
2273 offsetof(struct ieee80211_mgmt,
2274 u.probe_resp.variable) + wl_get_ielen(wl);
2275 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2276 channel = ieee80211_get_channel(wiphy, freq);
2278 WL_DBG(("SSID : \"%s\", rssi (%d), capability : 0x04%x\n", bi->SSID,
2279 notif_bss_info->rssi, mgmt->u.probe_resp.capab_info));
2281 signal = notif_bss_info->rssi * 100;
2282 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2284 (notif_bss_info->frame_len),
2285 signal, GFP_KERNEL))) {
2286 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2287 kfree(notif_bss_info);
2290 kfree(notif_bss_info);
2295 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2297 uint32 event = ntoh32(e->event_type);
2298 uint16 flags = ntoh16(e->flags);
2300 if (event == WLC_E_JOIN || event == WLC_E_ASSOC_IND
2301 || event == WLC_E_REASSOC_IND) {
2303 } else if (event == WLC_E_LINK) {
2304 if (flags & WLC_EVENT_MSG_LINK) {
2305 if (wl_is_ibssmode(wl)) {
2306 if (wl_is_ibssstarter(wl)) {
2317 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2319 uint32 event = ntoh32(e->event_type);
2320 uint16 flags = ntoh16(e->flags);
2322 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2324 } else if (event == WLC_E_LINK) {
2325 if (!(flags & WLC_EVENT_MSG_LINK))
2333 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2334 const wl_event_msg_t *e, void *data)
2339 if (wl_is_linkup(wl, e)) {
2341 if (wl_is_ibssmode(wl)) {
2342 cfg80211_ibss_joined(ndev, (int8 *)&e->addr,
2344 WL_DBG(("joined in IBSS network\n"));
2346 wl_bss_connect_done(wl, ndev, e, data);
2347 WL_DBG(("joined in BSS network \"%s\"\n",
2348 ((struct wlc_ssid *)
2349 wl_read_prof(wl, WL_PROF_SSID))->SSID));
2352 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2353 } else if (wl_is_linkdown(wl, e)) {
2354 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2355 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2357 wl_init_prof(wl->profile);
2364 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2365 const wl_event_msg_t *e, void *data)
2370 wl_bss_roaming_done(wl, ndev, e, data);
2372 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2378 wl_dev_bufvar_set(struct net_device *dev, int8 *name, int8 *buf, int32 len)
2380 struct wl_priv *wl = ndev_to_wl(dev);
2383 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2384 BUG_ON(unlikely(!buflen));
2386 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2390 wl_dev_bufvar_get(struct net_device *dev, int8 *name, int8 *buf,
2393 struct wl_priv *wl = ndev_to_wl(dev);
2397 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2398 BUG_ON(unlikely(!len));
2401 wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2402 WL_IOCTL_LEN_MAX)))) {
2403 WL_ERR(("error (%d)\n", err));
2406 memcpy(buf, wl->ioctl_buf, buf_len);
2411 static int32 wl_get_assoc_ies(struct wl_priv *wl)
2413 struct net_device *ndev = wl_to_ndev(wl);
2414 struct wl_assoc_ielen *assoc_info;
2415 struct wl_connect_info *conn_info = wl_to_conn(wl);
2420 if (unlikely(err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2421 WL_ASSOC_INFO_MAX))) {
2422 WL_ERR(("could not get assoc info (%d)\n", err));
2425 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2426 req_len = assoc_info->req_len;
2427 resp_len = assoc_info->resp_len;
2431 wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2432 WL_ASSOC_INFO_MAX))) {
2433 WL_ERR(("could not get assoc req (%d)\n", err));
2436 conn_info->req_ie_len = req_len;
2438 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2440 conn_info->req_ie_len = 0;
2441 conn_info->req_ie = NULL;
2446 wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2447 WL_ASSOC_INFO_MAX))) {
2448 WL_ERR(("could not get assoc resp (%d)\n", err));
2451 conn_info->resp_ie_len = resp_len;
2452 conn_info->resp_ie =
2453 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2455 conn_info->resp_ie_len = 0;
2456 conn_info->resp_ie = NULL;
2458 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2459 conn_info->resp_ie_len));
2464 static int32 wl_update_bss_info(struct wl_priv *wl)
2466 struct cfg80211_bss *bss;
2467 struct wl_bss_info *bi;
2468 struct wlc_ssid *ssid;
2471 if (wl_is_ibssmode(wl))
2474 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2476 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (int8 *)&wl->bssid,
2477 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2478 WLAN_CAPABILITY_ESS);
2481 if (unlikely(!bss)) {
2482 WL_DBG(("Could not find the AP\n"));
2483 *(uint32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2486 wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2487 wl->extra_buf, WL_EXTRA_BUF_MAX))) {
2488 WL_ERR(("Could not get bss info %d\n", err));
2489 goto update_bss_info_out;
2491 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2492 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2494 goto update_bss_info_out;
2496 if (unlikely((err = wl_inform_single_bss(wl, bi))))
2497 goto update_bss_info_out;
2499 WL_DBG(("Found the AP in the list - "
2500 "BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
2501 bss->bssid[0], bss->bssid[1], bss->bssid[2],
2502 bss->bssid[3], bss->bssid[4], bss->bssid[5]));
2503 cfg80211_put_bss(bss);
2506 update_bss_info_out:
2512 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2513 const wl_event_msg_t *e, void *data)
2515 struct wl_connect_info *conn_info = wl_to_conn(wl);
2518 wl_get_assoc_ies(wl);
2519 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2520 wl_update_bss_info(wl);
2521 cfg80211_roamed(ndev,
2523 conn_info->req_ie, conn_info->req_ie_len,
2524 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2525 WL_DBG(("Report roaming result\n"));
2527 set_bit(WL_STATUS_CONNECTED, &wl->status);
2533 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2534 const wl_event_msg_t *e, void *data)
2536 struct wl_connect_info *conn_info = wl_to_conn(wl);
2539 wl_get_assoc_ies(wl);
2540 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2541 wl_update_bss_info(wl);
2542 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2543 cfg80211_connect_result(ndev,
2546 conn_info->req_ie_len,
2548 conn_info->resp_ie_len,
2549 WLAN_STATUS_SUCCESS, GFP_KERNEL);
2550 WL_DBG(("Report connect result\n"));
2552 cfg80211_roamed(ndev,
2554 conn_info->req_ie, conn_info->req_ie_len,
2555 conn_info->resp_ie, conn_info->resp_ie_len,
2557 WL_DBG(("Report roaming result\n"));
2559 set_bit(WL_STATUS_CONNECTED, &wl->status);
2565 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2566 const wl_event_msg_t *e, void *data)
2568 uint16 flags = ntoh16(e->flags);
2569 enum nl80211_key_type key_type;
2572 if (flags & WLC_EVENT_MSG_GROUP)
2573 key_type = NL80211_KEYTYPE_GROUP;
2575 key_type = NL80211_KEYTYPE_PAIRWISE;
2577 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2585 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2586 const wl_event_msg_t *e, void *data)
2588 struct channel_info channel_inform;
2589 struct wl_scan_results *bss_list;
2590 uint32 len = WL_SCAN_BUF_MAX;
2593 if (wl->iscan_on && wl->iscan_kickstart)
2594 return wl_wakeup_iscan(wl_to_iscan(wl));
2596 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2597 WL_ERR(("Scan complete while device not scanning\n"));
2600 if (unlikely(!wl->scan_request)) {
2603 if (unlikely((err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2604 sizeof(channel_inform))))) {
2605 WL_ERR(("scan busy (%d)\n", err));
2608 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2609 if (unlikely(channel_inform.scan_channel)) {
2611 WL_DBG(("channel_inform.scan_channel (%d)\n",
2612 channel_inform.scan_channel));
2614 wl->bss_list = wl->scan_results;
2615 bss_list = wl->bss_list;
2616 memset(bss_list, 0, len);
2617 bss_list->buflen = htod32(len);
2619 ((err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len)))) {
2620 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2624 bss_list->buflen = dtoh32(bss_list->buflen);
2625 bss_list->version = dtoh32(bss_list->version);
2626 bss_list->count = dtoh32(bss_list->count);
2628 if ((err = wl_inform_bss(wl)))
2632 if (wl->scan_request) {
2633 cfg80211_scan_done(wl->scan_request, FALSE);
2634 wl->scan_request = NULL;
2640 static void wl_init_conf(struct wl_conf *conf)
2642 conf->mode = (uint32)-1;
2643 conf->frag_threshold = (uint32)-1;
2644 conf->rts_threshold = (uint32)-1;
2645 conf->retry_short = (uint32)-1;
2646 conf->retry_long = (uint32)-1;
2650 static void wl_init_prof(struct wl_profile *prof)
2652 memset(prof, 0, sizeof(*prof));
2655 static void wl_init_eloop_handler(struct wl_event_loop *el)
2657 memset(el, 0, sizeof(*el));
2658 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2659 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2660 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2661 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2662 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2663 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2664 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2665 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2666 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2669 static int32 wl_init_priv_mem(struct wl_priv *wl)
2671 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2672 if (unlikely(!wl->scan_results)) {
2673 WL_ERR(("Scan results alloc failed\n"));
2674 goto init_priv_mem_out;
2676 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2677 if (unlikely(!wl->conf)) {
2678 WL_ERR(("wl_conf alloc failed\n"));
2679 goto init_priv_mem_out;
2681 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2682 if (unlikely(!wl->profile)) {
2683 WL_ERR(("wl_profile alloc failed\n"));
2684 goto init_priv_mem_out;
2686 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2687 if (unlikely(!wl->bss_info)) {
2688 WL_ERR(("Bss information alloc failed\n"));
2689 goto init_priv_mem_out;
2692 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2693 if (unlikely(!wl->scan_req_int)) {
2694 WL_ERR(("Scan req alloc failed\n"));
2695 goto init_priv_mem_out;
2697 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2698 if (unlikely(!wl->ioctl_buf)) {
2699 WL_ERR(("Ioctl buf alloc failed\n"));
2700 goto init_priv_mem_out;
2702 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2703 if (unlikely(!wl->extra_buf)) {
2704 WL_ERR(("Extra buf alloc failed\n"));
2705 goto init_priv_mem_out;
2707 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2708 if (unlikely(!wl->iscan)) {
2709 WL_ERR(("Iscan buf alloc failed\n"));
2710 goto init_priv_mem_out;
2712 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2713 if (unlikely(!wl->fw)) {
2714 WL_ERR(("fw object alloc failed\n"));
2715 goto init_priv_mem_out;
2717 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2718 if (unlikely(!wl->pmk_list)) {
2719 WL_ERR(("pmk list alloc failed\n"));
2720 goto init_priv_mem_out;
2726 wl_deinit_priv_mem(wl);
2731 static void wl_deinit_priv_mem(struct wl_priv *wl)
2733 kfree(wl->scan_results);
2734 wl->scan_results = NULL;
2735 kfree(wl->bss_info);
2736 wl->bss_info = NULL;
2741 kfree(wl->scan_req_int);
2742 wl->scan_req_int = NULL;
2743 kfree(wl->ioctl_buf);
2744 wl->ioctl_buf = NULL;
2745 kfree(wl->extra_buf);
2746 wl->extra_buf = NULL;
2751 kfree(wl->pmk_list);
2752 wl->pmk_list = NULL;
2755 static int32 wl_create_event_handler(struct wl_priv *wl)
2757 sema_init(&wl->event_sync, 0);
2758 init_completion(&wl->event_exit);
2760 (((wl->event_pid = kernel_thread(wl_event_handler, wl, 0)) < 0))) {
2761 WL_ERR(("failed to create event thread\n"));
2764 WL_DBG(("pid %d\n", wl->event_pid));
2768 static void wl_destroy_event_handler(struct wl_priv *wl)
2770 if (wl->event_pid >= 0) {
2771 KILL_PROC(wl->event_pid, SIGTERM);
2772 wait_for_completion(&wl->event_exit);
2776 static void wl_term_iscan(struct wl_priv *wl)
2778 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2780 if (wl->iscan_on && iscan->pid >= 0) {
2781 iscan->state = WL_ISCAN_STATE_IDLE;
2782 KILL_PROC(iscan->pid, SIGTERM);
2783 wait_for_completion(&iscan->exited);
2788 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2790 struct wl_priv *wl = iscan_to_wl(iscan);
2792 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2793 WL_ERR(("Scan complete while device not scanning\n"));
2796 if (likely(wl->scan_request)) {
2797 cfg80211_scan_done(wl->scan_request, aborted);
2798 wl->scan_request = NULL;
2800 wl->iscan_kickstart = FALSE;
2803 static int32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2805 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2806 WL_DBG(("wake up iscan\n"));
2815 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status,
2816 struct wl_scan_results **bss_list)
2818 struct wl_iscan_results list;
2819 struct wl_scan_results *results;
2820 struct wl_iscan_results *list_buf;
2823 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2824 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2825 results = &list_buf->results;
2826 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2827 results->version = 0;
2830 memset(&list, 0, sizeof(list));
2831 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2832 if (unlikely((err = wl_dev_iovar_getbuf(iscan->dev,
2835 WL_ISCAN_RESULTS_FIXED_SIZE,
2837 WL_ISCAN_BUF_MAX)))) {
2838 WL_ERR(("error (%d)\n", err));
2841 results->buflen = dtoh32(results->buflen);
2842 results->version = dtoh32(results->version);
2843 results->count = dtoh32(results->count);
2844 WL_DBG(("results->count = %d\n", results->count));
2845 WL_DBG(("results->buflen = %d\n", results->buflen));
2846 *status = dtoh32(list_buf->status);
2847 *bss_list = results;
2852 static int32 wl_iscan_done(struct wl_priv *wl)
2854 struct wl_iscan_ctrl *iscan = wl->iscan;
2857 iscan->state = WL_ISCAN_STATE_IDLE;
2860 wl_notify_iscan_complete(iscan, FALSE);
2866 static int32 wl_iscan_pending(struct wl_priv *wl)
2868 struct wl_iscan_ctrl *iscan = wl->iscan;
2871 /* Reschedule the timer */
2872 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2873 iscan->timer_on = 1;
2878 static int32 wl_iscan_inprogress(struct wl_priv *wl)
2880 struct wl_iscan_ctrl *iscan = wl->iscan;
2885 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
2887 /* Reschedule the timer */
2888 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2889 iscan->timer_on = 1;
2894 static int32 wl_iscan_aborted(struct wl_priv *wl)
2896 struct wl_iscan_ctrl *iscan = wl->iscan;
2899 iscan->state = WL_ISCAN_STATE_IDLE;
2901 wl_notify_iscan_complete(iscan, TRUE);
2907 static int32 wl_iscan_thread(void *data)
2909 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
2910 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
2911 struct wl_priv *wl = iscan_to_wl(iscan);
2912 struct wl_iscan_eloop *el = &iscan->el;
2916 sched_setscheduler(current, SCHED_FIFO, ¶m);
2917 status = WL_SCAN_RESULTS_PARTIAL;
2918 while (likely(!down_interruptible(&iscan->sync))) {
2919 if (iscan->timer_on) {
2920 del_timer_sync(&iscan->timer);
2921 iscan->timer_on = 0;
2926 wl_get_iscan_results(iscan, &status, &wl->bss_list)))) {
2927 status = WL_SCAN_RESULTS_ABORTED;
2928 WL_ERR(("Abort iscan\n"));
2931 el->handler[status] (wl);
2933 if (iscan->timer_on) {
2934 del_timer_sync(&iscan->timer);
2935 iscan->timer_on = 0;
2937 complete_and_exit(&iscan->exited, 0);
2942 static void wl_iscan_timer(ulong data)
2944 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
2947 iscan->timer_on = 0;
2948 WL_DBG(("timer expired\n"));
2949 wl_wakeup_iscan(iscan);
2953 static int32 wl_invoke_iscan(struct wl_priv *wl)
2955 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2958 if (wl->iscan_on && iscan->pid < 0) {
2959 iscan->state = WL_ISCAN_STATE_IDLE;
2960 sema_init(&iscan->sync, 0);
2961 init_completion(&iscan->exited);
2962 iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0);
2963 if (unlikely(iscan->pid < 0)) {
2964 WL_ERR(("Could not create iscan thread\n"));
2972 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
2974 memset(el, 0, sizeof(*el));
2975 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
2976 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
2977 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
2978 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
2979 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
2982 static int32 wl_init_iscan(struct wl_priv *wl)
2984 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2988 iscan->dev = wl_to_ndev(wl);
2989 iscan->state = WL_ISCAN_STATE_IDLE;
2990 wl_init_iscan_eloop(&iscan->el);
2991 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2992 init_timer(&iscan->timer);
2993 iscan->timer.data = (ulong) iscan;
2994 iscan->timer.function = wl_iscan_timer;
2995 sema_init(&iscan->sync, 0);
2996 init_completion(&iscan->exited);
2997 iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0);
2998 if (unlikely(iscan->pid < 0)) {
2999 WL_ERR(("Could not create iscan thread\n"));
3008 static void wl_init_fw(struct wl_fw_ctrl *fw)
3010 fw->status = 0; /* init fw loading status.
3011 0 means nothing was loaded yet */
3014 static int32 wl_init_priv(struct wl_priv *wl)
3016 struct wiphy *wiphy = wl_to_wiphy(wl);
3019 wl->scan_request = NULL;
3020 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3021 #ifndef WL_ISCAN_DISABLED
3022 wl->iscan_on = TRUE; /* iscan on & off switch.
3023 we enable iscan per default */
3025 wl->iscan_on = FALSE;
3026 #endif /* WL_ISCAN_DISABLED */
3027 #ifndef WL_ROAM_DISABLED
3028 wl->roam_on = TRUE; /* roam on & off switch.
3029 we enable roam per default */
3031 wl->roam_on = FALSE;
3032 #endif /* WL_ROAM_DISABLED */
3034 wl->iscan_kickstart = FALSE;
3035 wl->active_scan = TRUE; /* we do active scan for
3036 specific scan per default */
3037 wl->dongle_up = FALSE; /* dongle is not up yet */
3039 if (unlikely((err = wl_init_priv_mem(wl))))
3041 if (unlikely(wl_create_event_handler(wl)))
3043 wl_init_eloop_handler(&wl->el);
3044 mutex_init(&wl->usr_sync);
3045 if (unlikely((err = wl_init_iscan(wl))))
3048 wl_init_conf(wl->conf);
3049 wl_init_prof(wl->profile);
3055 static void wl_deinit_priv(struct wl_priv *wl)
3057 wl_destroy_event_handler(wl);
3058 wl->dongle_up = FALSE; /* dongle down */
3062 wl_deinit_priv_mem(wl);
3065 int32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3067 struct wireless_dev *wdev;
3069 struct wl_iface *ci;
3072 if (unlikely(!ndev)) {
3073 WL_ERR(("ndev is invaild\n"));
3076 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3077 if (unlikely(!wl_cfg80211_dev)) {
3078 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3081 WL_DBG(("func %p\n", wl_sdio_func()));
3082 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_sdio_func()->dev);
3083 if (unlikely(IS_ERR(wdev)))
3086 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3087 wl = wdev_to_wl(wdev);
3090 ci = (struct wl_iface *)wl_to_ci(wl);
3092 ndev->ieee80211_ptr = wdev;
3093 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3094 wdev->netdev = ndev;
3095 if (unlikely((err = wl_init_priv(wl)))) {
3096 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
3097 goto cfg80211_attach_out;
3099 wl_set_drvdata(wl_cfg80211_dev, ci);
3100 set_bit(WL_STATUS_READY, &wl->status);
3104 cfg80211_attach_out:
3109 void wl_cfg80211_detach(void)
3117 wl_set_drvdata(wl_cfg80211_dev, NULL);
3118 kfree(wl_cfg80211_dev);
3119 wl_cfg80211_dev = NULL;
3120 wl_clear_sdio_func();
3123 static void wl_wakeup_event(struct wl_priv *wl)
3125 up(&wl->event_sync);
3128 static int32 wl_event_handler(void *data)
3130 struct wl_priv *wl = (struct wl_priv *)data;
3131 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3132 struct wl_event_q *e;
3134 sched_setscheduler(current, SCHED_FIFO, ¶m);
3135 while (likely(!down_interruptible(&wl->event_sync))) {
3136 if (unlikely(!(e = wl_deq_event(wl)))) {
3137 WL_ERR(("eqeue empty..\n"));
3140 WL_DBG(("event type (%d)\n", e->etype));
3141 if (wl->el.handler[e->etype]) {
3142 wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3145 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
3149 complete_and_exit(&wl->event_exit, 0);
3153 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
3155 uint32 event_type = ntoh32(e->event_type);
3156 struct wl_priv *wl = ndev_to_wl(ndev);
3157 #if (WL_DBG_LEVEL > 0)
3158 int8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
3159 wl_dbg_estr[event_type] : (int8 *) "Unknown";
3160 #endif /* (WL_DBG_LEVEL > 0) */
3161 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
3162 if (likely(!wl_enq_event(wl, event_type, e, data)))
3163 wl_wakeup_event(wl);
3166 static void wl_init_eq(struct wl_priv *wl)
3168 wl_init_eq_lock(wl);
3169 INIT_LIST_HEAD(&wl->eq_list);
3172 static void wl_flush_eq(struct wl_priv *wl)
3174 struct wl_event_q *e;
3177 while (!list_empty(&wl->eq_list)) {
3178 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3179 list_del(&e->eq_list);
3186 * retrieve first queued event from head
3189 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3191 struct wl_event_q *e = NULL;
3194 if (likely(!list_empty(&wl->eq_list))) {
3195 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3196 list_del(&e->eq_list);
3204 ** push event to tail of the queue
3208 wl_enq_event(struct wl_priv *wl, uint32 event, const wl_event_msg_t *msg,
3211 struct wl_event_q *e;
3214 if (unlikely(!(e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL)))) {
3215 WL_ERR(("event alloc failed\n"));
3220 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
3224 list_add_tail(&e->eq_list, &wl->eq_list);
3230 static void wl_put_event(struct wl_event_q *e)
3235 void wl_cfg80211_sdio_func(void *func)
3237 cfg80211_sdio_func = (struct sdio_func *)func;
3240 static void wl_clear_sdio_func(void)
3242 cfg80211_sdio_func = NULL;
3245 static struct sdio_func *wl_sdio_func(void)
3247 return cfg80211_sdio_func;
3250 static int32 wl_dongle_mode(struct net_device *ndev, int32 iftype)
3257 case NL80211_IFTYPE_MONITOR:
3258 case NL80211_IFTYPE_WDS:
3259 WL_ERR(("type (%d) : currently we do not support this mode\n",
3263 case NL80211_IFTYPE_ADHOC:
3265 case NL80211_IFTYPE_STATION:
3270 WL_ERR(("invalid type (%d)\n", iftype));
3273 infra = htod32(infra);
3275 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
3277 (err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)))
3279 (err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap)))) {
3280 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
3284 return -EINPROGRESS;
3287 #ifndef EMBEDDED_PLATFORM
3288 static int32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3296 static int32 wl_dongle_up(struct net_device *ndev, uint32 up)
3300 if (unlikely(err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up)))) {
3301 WL_ERR(("WLC_UP error (%d)\n", err));
3306 static int32 wl_dongle_power(struct net_device *ndev, uint32 power_mode)
3312 wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode)))) {
3313 WL_ERR(("WLC_SET_PM error (%d)\n", err));
3319 wl_dongle_glom(struct net_device *ndev, uint32 glom, uint32 dongle_align)
3321 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3325 /* Match Host and Dongle rx alignment */
3326 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3329 (err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3330 WL_ERR(("txglomalign error (%d)\n", err));
3331 goto dongle_glom_out;
3333 /* disable glom option per default */
3334 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3336 (err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3337 WL_ERR(("txglom error (%d)\n", err));
3338 goto dongle_glom_out;
3345 wl_dongle_roam(struct net_device *ndev, uint32 roamvar, uint32 bcn_timeout)
3347 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3351 /* Setup timeout if Beacons are lost and roam is
3352 off to report link down */
3354 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
3358 wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3359 WL_ERR(("bcn_timeout error (%d)\n", err));
3360 goto dongle_rom_out;
3363 /* Enable/Disable built-in roaming to allow supplicant
3364 to take care of roaming */
3365 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
3367 (err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3368 WL_ERR(("roam_off error (%d)\n", err));
3369 goto dongle_rom_out;
3375 static int32 wl_dongle_eventmsg(struct net_device *ndev)
3378 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3380 int8 eventmask[WL_EVENTING_MASK_LEN];
3383 /* Setup event_msgs */
3384 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3387 (err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf)))) {
3388 WL_ERR(("Get event_msgs error (%d)\n", err));
3389 goto dongle_eventmsg_out;
3391 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3393 setbit(eventmask, WLC_E_SET_SSID);
3394 setbit(eventmask, WLC_E_PRUNE);
3395 setbit(eventmask, WLC_E_AUTH);
3396 setbit(eventmask, WLC_E_REASSOC);
3397 setbit(eventmask, WLC_E_REASSOC_IND);
3398 setbit(eventmask, WLC_E_DEAUTH_IND);
3399 setbit(eventmask, WLC_E_DISASSOC_IND);
3400 setbit(eventmask, WLC_E_DISASSOC);
3401 setbit(eventmask, WLC_E_JOIN);
3402 setbit(eventmask, WLC_E_ASSOC_IND);
3403 setbit(eventmask, WLC_E_PSK_SUP);
3404 setbit(eventmask, WLC_E_LINK);
3405 setbit(eventmask, WLC_E_NDIS_LINK);
3406 setbit(eventmask, WLC_E_MIC_ERROR);
3407 setbit(eventmask, WLC_E_PMKID_CACHE);
3408 setbit(eventmask, WLC_E_TXFAIL);
3409 setbit(eventmask, WLC_E_JOIN_START);
3410 setbit(eventmask, WLC_E_SCAN_COMPLETE);
3412 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3415 (err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3416 WL_ERR(("Set event_msgs error (%d)\n", err));
3417 goto dongle_eventmsg_out;
3420 dongle_eventmsg_out:
3425 wl_dongle_scantime(struct net_device *ndev, int32 scan_assoc_time,
3426 int32 scan_unassoc_time)
3431 wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
3432 sizeof(scan_assoc_time)))) {
3433 if (err == -EOPNOTSUPP) {
3434 WL_INFO(("Scan assoc time is not supported\n"));
3436 WL_ERR(("Scan assoc time error (%d)\n", err));
3438 goto dongle_scantime_out;
3441 wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
3442 sizeof(scan_unassoc_time)))) {
3443 if (err == -EOPNOTSUPP) {
3444 WL_INFO(("Scan unassoc time is not supported\n"));
3446 WL_ERR(("Scan unassoc time error (%d)\n", err));
3448 goto dongle_scantime_out;
3451 dongle_scantime_out:
3456 wl_dongle_offload(struct net_device *ndev, int32 arpoe, int32 arp_ol)
3458 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3462 /* Set ARP offload */
3463 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3464 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3465 if (err == -EOPNOTSUPP)
3466 WL_INFO(("arpoe is not supported\n"));
3468 WL_ERR(("arpoe error (%d)\n", err));
3470 goto dongle_offload_out;
3472 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3473 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3474 if (err == -EOPNOTSUPP)
3475 WL_INFO(("arp_ol is not supported\n"));
3477 WL_ERR(("arp_ol error (%d)\n", err));
3479 goto dongle_offload_out;
3486 static int32 wl_pattern_atoh(int8 *src, int8 *dst)
3488 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
3490 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3491 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3494 src = src + 2; /* Skip past 0x */
3495 if (strlen(src) % 2 != 0) {
3496 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3499 for (i = 0; *src != '\0'; i++) {
3501 strncpy(num, src, 2);
3503 dst[i] = (u8) strtoul(num, NULL, 16);
3509 static int32 wl_dongle_filter(struct net_device *ndev, uint32 filter_mode)
3511 int8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3514 struct wl_pkt_filter pkt_filter;
3515 struct wl_pkt_filter *pkt_filterp;
3519 uint32 pattern_size;
3523 /* add a default packet filter pattern */
3524 str = "pkt_filter_add";
3525 str_len = strlen(str);
3526 strncpy(buf, str, str_len);
3527 buf[str_len] = '\0';
3528 buf_len = str_len + 1;
3530 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3532 /* Parse packet filter id. */
3533 pkt_filter.id = htod32(100);
3535 /* Parse filter polarity. */
3536 pkt_filter.negate_match = htod32(0);
3538 /* Parse filter type. */
3539 pkt_filter.type = htod32(0);
3541 /* Parse pattern filter offset. */
3542 pkt_filter.u.pattern.offset = htod32(0);
3544 /* Parse pattern filter mask. */
3545 mask_size = htod32(wl_pattern_atoh("0xff",
3546 (char *)pkt_filterp->u.pattern.
3549 /* Parse pattern filter pattern. */
3550 pattern_size = htod32(wl_pattern_atoh("0x00",
3551 (char *)&pkt_filterp->u.pattern.
3552 mask_and_pattern[mask_size]));
3554 if (mask_size != pattern_size) {
3555 WL_ERR(("Mask and pattern not the same size\n"));
3557 goto dongle_filter_out;
3560 pkt_filter.u.pattern.size_bytes = mask_size;
3561 buf_len += WL_PKT_FILTER_FIXED_LEN;
3562 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3564 /* Keep-alive attributes are set in local
3565 * variable (keep_alive_pkt), and
3566 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3567 * guarantee that the buffer is properly aligned.
3569 memcpy((char *)pkt_filterp, &pkt_filter,
3570 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3572 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len))) {
3573 if (err == -EOPNOTSUPP) {
3574 WL_INFO(("filter not supported\n"));
3576 WL_ERR(("filter (%d)\n", err));
3578 goto dongle_filter_out;
3581 /* set mode to allow pattern */
3582 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3584 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3585 if (err == -EOPNOTSUPP) {
3586 WL_INFO(("filter_mode not supported\n"));
3588 WL_ERR(("filter_mode (%d)\n", err));
3590 goto dongle_filter_out;
3596 #endif /* !EMBEDDED_PLATFORM */
3598 int32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
3601 #define DHD_SDALIGN 32
3603 struct net_device *ndev;
3604 struct wireless_dev *wdev;
3610 ndev = wl_to_ndev(wl);
3611 wdev = ndev->ieee80211_ptr;
3615 #ifndef EMBEDDED_PLATFORM
3616 if (unlikely((err = wl_dongle_up(ndev, 0))))
3617 goto default_conf_out;
3618 if (unlikely((err = wl_dongle_country(ndev, 0))))
3619 goto default_conf_out;
3620 if (unlikely((err = wl_dongle_power(ndev, PM_FAST))))
3621 goto default_conf_out;
3622 if (unlikely((err = wl_dongle_glom(ndev, 0, DHD_SDALIGN))))
3623 goto default_conf_out;
3624 if (unlikely((err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3))))
3625 goto default_conf_out;
3626 if (unlikely((err = wl_dongle_eventmsg(ndev))))
3627 goto default_conf_out;
3629 wl_dongle_scantime(ndev, 40, 80);
3630 wl_dongle_offload(ndev, 1, 0xf);
3631 wl_dongle_filter(ndev, 1);
3632 #endif /* !EMBEDDED_PLATFORM */
3634 err = wl_dongle_mode(ndev, wdev->iftype);
3635 if (unlikely(err && err != -EINPROGRESS))
3636 goto default_conf_out;
3637 if (unlikely((err = wl_dongle_probecap(wl))))
3638 goto default_conf_out;
3640 /* -EINPROGRESS: Call commit handler */
3646 wl->dongle_up = TRUE;
3652 static int32 wl_update_wiphybands(struct wl_priv *wl)
3654 struct wiphy *wiphy;
3661 wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
3662 sizeof(phy_list)))) {
3663 WL_ERR(("error (%d)\n", err));
3667 phy = ((char *)&phy_list)[1];
3668 WL_DBG(("%c phy\n", phy));
3669 if (phy == 'n' || phy == 'a') {
3670 wiphy = wl_to_wiphy(wl);
3671 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3677 static int32 __wl_cfg80211_up(struct wl_priv *wl)
3681 if (unlikely(err = wl_config_dongle(wl, FALSE)))
3684 wl_invoke_iscan(wl);
3685 set_bit(WL_STATUS_READY, &wl->status);
3689 static int32 __wl_cfg80211_down(struct wl_priv *wl)
3693 /* Check if cfg80211 interface is already down */
3694 if (!test_bit(WL_STATUS_READY, &wl->status))
3695 return err; /* it is even not ready */
3697 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3699 if (wl->scan_request) {
3700 cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE
3702 wl->scan_request = NULL;
3704 clear_bit(WL_STATUS_READY, &wl->status);
3705 clear_bit(WL_STATUS_SCANNING, &wl->status);
3706 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3707 clear_bit(WL_STATUS_CONNECTED, &wl->status);
3712 int32 wl_cfg80211_up(void)
3718 mutex_lock(&wl->usr_sync);
3719 err = __wl_cfg80211_up(wl);
3720 mutex_unlock(&wl->usr_sync);
3725 int32 wl_cfg80211_down(void)
3731 mutex_lock(&wl->usr_sync);
3732 err = __wl_cfg80211_down(wl);
3733 mutex_unlock(&wl->usr_sync);
3738 static int32 wl_dongle_probecap(struct wl_priv *wl)
3742 if (unlikely((err = wl_update_wiphybands(wl))))
3748 static void *wl_read_prof(struct wl_priv *wl, int32 item)
3752 return &wl->profile->sec;
3754 return &wl->profile->active;
3756 return &wl->profile->bssid;
3758 return &wl->profile->ssid;
3760 WL_ERR(("invalid item (%d)\n", item));
3765 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
3769 struct wlc_ssid *ssid;
3773 ssid = (wlc_ssid_t *) data;
3774 memset(wl->profile->ssid.SSID, 0,
3775 sizeof(wl->profile->ssid.SSID));
3776 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
3777 wl->profile->ssid.SSID_len = ssid->SSID_len;
3781 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
3783 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
3786 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
3789 wl->profile->active = *(bool *) data;
3792 WL_ERR(("unsupported item (%d)\n", item));
3800 void wl_cfg80211_dbg_level(uint32 level)
3802 wl_dbg_level = level;
3805 static bool wl_is_ibssmode(struct wl_priv *wl)
3807 return wl->conf->mode == WL_MODE_IBSS;
3810 static bool wl_is_ibssstarter(struct wl_priv *wl)
3812 return wl->ibss_starter;
3815 static void wl_rst_ie(struct wl_priv *wl)
3817 struct wl_ie *ie = wl_to_ie(wl);
3822 static int32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
3824 struct wl_ie *ie = wl_to_ie(wl);
3827 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3828 WL_ERR(("ei crosses buffer boundary\n"));
3831 ie->buf[ie->offset] = t;
3832 ie->buf[ie->offset + 1] = l;
3833 memcpy(&ie->buf[ie->offset + 2], v, l);
3834 ie->offset += l + 2;
3839 static int32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, uint16 ie_size)
3841 struct wl_ie *ie = wl_to_ie(wl);
3844 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
3845 WL_ERR(("ei_stream crosses buffer boundary\n"));
3848 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
3849 ie->offset += ie_size;
3854 static int32 wl_cp_ie(struct wl_priv *wl, u8 *dst, uint16 dst_size)
3856 struct wl_ie *ie = wl_to_ie(wl);
3859 if (unlikely(ie->offset > dst_size)) {
3860 WL_ERR(("dst_size is not enough\n"));
3863 memcpy(dst, &ie->buf[0], ie->offset);
3868 static uint32 wl_get_ielen(struct wl_priv *wl)
3870 struct wl_ie *ie = wl_to_ie(wl);
3875 static void wl_link_up(struct wl_priv *wl)
3880 static void wl_link_down(struct wl_priv *wl)
3882 struct wl_connect_info *conn_info = wl_to_conn(wl);
3884 wl->link_up = FALSE;
3885 kfree(conn_info->req_ie);
3886 conn_info->req_ie = NULL;
3887 conn_info->req_ie_len = 0;
3888 kfree(conn_info->resp_ie);
3889 conn_info->resp_ie = NULL;
3890 conn_info->resp_ie_len = 0;
3893 static void wl_lock_eq(struct wl_priv *wl)
3895 spin_lock_irq(&wl->eq_lock);
3898 static void wl_unlock_eq(struct wl_priv *wl)
3900 spin_unlock_irq(&wl->eq_lock);
3903 static void wl_init_eq_lock(struct wl_priv *wl)
3905 spin_lock_init(&wl->eq_lock);
3908 static void wl_delay(uint32 ms)
3910 if (ms < 1000 / HZ) {
3918 static void wl_set_drvdata(struct wl_dev *dev, void *data)
3920 dev->driver_data = data;
3923 static void *wl_get_drvdata(struct wl_dev *dev)
3925 return dev->driver_data;
3928 int32 wl_cfg80211_read_fw(int8 *buf, uint32 size)
3930 const struct firmware *fw_entry;
3935 fw_entry = wl->fw->fw_entry;
3937 if (fw_entry->size < wl->fw->ptr + size)
3938 size = fw_entry->size - wl->fw->ptr;
3940 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
3941 wl->fw->ptr += size;
3945 void wl_cfg80211_release_fw(void)
3950 release_firmware(wl->fw->fw_entry);
3954 void *wl_cfg80211_request_fw(int8 *file_name)
3957 const struct firmware *fw_entry = NULL;
3960 WL_DBG(("file name : \"%s\"\n", file_name));
3963 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
3966 request_firmware(&wl->fw->fw_entry, file_name,
3967 &wl_sdio_func()->dev))) {
3968 WL_ERR(("Could not download fw (%d)\n", err));
3971 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
3972 fw_entry = wl->fw->fw_entry;
3974 WL_DBG(("fw size (%d), data (%p)\n", fw_entry->size,
3977 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
3980 request_firmware(&wl->fw->fw_entry, file_name,
3981 &wl_sdio_func()->dev))) {
3982 WL_ERR(("Could not download nvram (%d)\n", err));
3985 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
3986 fw_entry = wl->fw->fw_entry;
3988 WL_DBG(("nvram size (%d), data (%p)\n", fw_entry->size,
3992 WL_DBG(("Downloading already done. Nothing to do more\n"));
3997 if (unlikely(err)) {
4001 return (void *)fw_entry->data;
4004 int8 *wl_cfg80211_get_fwname(void)
4009 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4010 return wl->fw->fw_name;
4013 int8 *wl_cfg80211_get_nvramname(void)
4018 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4019 return wl->fw->nvram_name;