2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include <bcmendian.h>
23 #include <proto/ethernet.h>
25 #include <linux/if_arp.h>
26 #include <asm/uaccess.h>
28 #include <dngl_stats.h>
33 #include <proto/ethernet.h>
34 #include <dngl_stats.h>
37 #include <linux/kernel.h>
38 #include <linux/netdevice.h>
39 #include <linux/sched.h>
40 #include <linux/etherdevice.h>
41 #include <linux/wireless.h>
42 #include <linux/ieee80211.h>
43 #include <net/cfg80211.h>
45 #include <net/rtnetlink.h>
46 #include <linux/mmc/sdio_func.h>
47 #include <linux/firmware.h>
48 #include <wl_cfg80211.h>
50 static struct sdio_func *cfg80211_sdio_func;
51 static struct wl_dev *wl_cfg80211_dev;
53 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,
147 static int32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
148 const wl_event_msg_t *e, void *data);
149 static int32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
150 const wl_event_msg_t *e, void *data);
153 ** register/deregister sdio function
155 struct sdio_func *wl_cfg80211_get_sdio_func(void);
156 static void wl_clear_sdio_func(void);
161 static int32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
163 static __used int32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
165 static int32 wl_dev_intvar_set(struct net_device *dev, s8 *name, int32 val);
166 static int32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
168 static int32 wl_dev_ioctl(struct net_device *dev, uint32 cmd, void *arg,
172 ** cfg80211 set_wiphy_params utilities
174 static int32 wl_set_frag(struct net_device *dev, uint32 frag_threshold);
175 static int32 wl_set_rts(struct net_device *dev, uint32 frag_threshold);
176 static int32 wl_set_retry(struct net_device *dev, uint32 retry, bool l);
179 ** wl profile utilities
181 static int32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
182 void *data, int32 item);
183 static void *wl_read_prof(struct wl_priv *wl, int32 item);
184 static void wl_init_prof(struct wl_profile *prof);
187 ** cfg80211 connect utilites
189 static int32 wl_set_wpa_version(struct net_device *dev,
190 struct cfg80211_connect_params *sme);
191 static int32 wl_set_auth_type(struct net_device *dev,
192 struct cfg80211_connect_params *sme);
193 static int32 wl_set_set_cipher(struct net_device *dev,
194 struct cfg80211_connect_params *sme);
195 static int32 wl_set_key_mgmt(struct net_device *dev,
196 struct cfg80211_connect_params *sme);
197 static int32 wl_set_set_sharedkey(struct net_device *dev,
198 struct cfg80211_connect_params *sme);
199 static int32 wl_get_assoc_ies(struct wl_priv *wl);
202 ** information element utilities
204 static void wl_rst_ie(struct wl_priv *wl);
205 static int32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
206 static int32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, uint16 ie_size);
207 static int32 wl_cp_ie(struct wl_priv *wl, u8 *dst, uint16 dst_size);
208 static uint32 wl_get_ielen(struct wl_priv *wl);
210 static int32 wl_mode_to_nl80211_iftype(int32 mode);
212 static struct wireless_dev *wl_alloc_wdev(int32 sizeof_iface,
214 static void wl_free_wdev(struct wl_priv *wl);
216 static int32 wl_inform_bss(struct wl_priv *wl);
217 static int32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
218 static int32 wl_update_bss_info(struct wl_priv *wl);
220 static int32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
221 u8 key_idx, const u8 *mac_addr,
222 struct key_params *params);
225 ** key indianess swap utilities
227 static void swap_key_from_BE(struct wl_wsec_key *key);
228 static void swap_key_to_BE(struct wl_wsec_key *key);
231 ** wl_priv memory init/deinit utilities
233 static int32 wl_init_priv_mem(struct wl_priv *wl);
234 static void wl_deinit_priv_mem(struct wl_priv *wl);
236 static void wl_delay(uint32 ms);
239 ** store/restore cfg80211 instance data
241 static void wl_set_drvdata(struct wl_dev *dev, void *data);
242 static void *wl_get_drvdata(struct wl_dev *dev);
245 ** ibss mode utilities
247 static bool wl_is_ibssmode(struct wl_priv *wl);
248 static bool wl_is_ibssstarter(struct wl_priv *wl);
251 ** dongle up/down , default configuration utilities
253 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
254 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
255 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
256 static void wl_link_up(struct wl_priv *wl);
257 static void wl_link_down(struct wl_priv *wl);
258 static int32 wl_dongle_mode(struct net_device *ndev, int32 iftype);
259 static int32 __wl_cfg80211_up(struct wl_priv *wl);
260 static int32 __wl_cfg80211_down(struct wl_priv *wl);
261 static int32 wl_dongle_probecap(struct wl_priv *wl);
262 static void wl_init_conf(struct wl_conf *conf);
265 ** dongle configuration utilities
267 #ifndef EMBEDDED_PLATFORM
268 static int32 wl_dongle_mode(struct net_device *ndev, int32 iftype);
269 static int32 wl_dongle_country(struct net_device *ndev, u8 ccode);
270 static int32 wl_dongle_up(struct net_device *ndev, uint32 up);
271 static int32 wl_dongle_power(struct net_device *ndev, uint32 power_mode);
272 static int32 wl_dongle_glom(struct net_device *ndev, uint32 glom,
273 uint32 dongle_align);
274 static int32 wl_dongle_roam(struct net_device *ndev, uint32 roamvar,
276 static int32 wl_dongle_eventmsg(struct net_device *ndev);
277 static int32 wl_dongle_scantime(struct net_device *ndev, int32 scan_assoc_time,
278 int32 scan_unassoc_time);
279 static int32 wl_dongle_offload(struct net_device *ndev, int32 arpoe,
281 static int32 wl_pattern_atoh(s8 *src, s8 *dst);
282 static int32 wl_dongle_filter(struct net_device *ndev, uint32 filter_mode);
283 static int32 wl_update_wiphybands(struct wl_priv *wl);
284 #endif /* !EMBEDDED_PLATFORM */
285 static int32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
290 static void wl_iscan_timer(unsigned long data);
291 static void wl_term_iscan(struct wl_priv *wl);
292 static int32 wl_init_iscan(struct wl_priv *wl);
293 static int32 wl_iscan_thread(void *data);
294 static int32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar,
295 void *param, int32 paramlen, void *bufptr,
297 static int32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar,
298 void *param, int32 paramlen, void *bufptr,
300 static int32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
302 static int32 wl_do_iscan(struct wl_priv *wl);
303 static int32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
304 static int32 wl_invoke_iscan(struct wl_priv *wl);
305 static int32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status,
306 struct wl_scan_results **bss_list);
307 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
308 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
309 static int32 wl_iscan_done(struct wl_priv *wl);
310 static int32 wl_iscan_pending(struct wl_priv *wl);
311 static int32 wl_iscan_inprogress(struct wl_priv *wl);
312 static int32 wl_iscan_aborted(struct wl_priv *wl);
315 ** fw/nvram downloading handler
317 static void wl_init_fw(struct wl_fw_ctrl *fw);
320 * find most significant bit set
322 static __used uint32 wl_find_msb(uint16 bit16);
325 * update pmklist to dongle
327 static __used int32 wl_update_pmklist(struct net_device *dev,
328 struct wl_pmk_list *pmk_list, int32 err);
330 #define WL_PRIV_GET() \
332 struct wl_iface *ci; \
333 if (unlikely(!(wl_cfg80211_dev && \
334 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
335 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
341 #define CHECK_SYS_UP() \
343 struct wl_priv *wl = wiphy_to_wl(wiphy); \
344 if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \
345 WL_INFO(("device is not ready : status (%d)\n", \
351 extern int dhd_wait_pend8021x(struct net_device *dev);
353 #if (WL_DBG_LEVEL > 0)
354 #define WL_DBG_ESTR_MAX 32
355 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
356 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
357 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
358 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
359 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
360 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
361 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
362 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
364 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
366 "RADIO", "PSM_WATCHDOG",
368 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
369 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
370 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
372 "RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
374 #endif /* WL_DBG_LEVEL */
376 #define CHAN2G(_channel, _freq, _flags) { \
377 .band = IEEE80211_BAND_2GHZ, \
378 .center_freq = (_freq), \
379 .hw_value = (_channel), \
381 .max_antenna_gain = 0, \
385 #define CHAN5G(_channel, _flags) { \
386 .band = IEEE80211_BAND_5GHZ, \
387 .center_freq = 5000 + (5 * (_channel)), \
388 .hw_value = (_channel), \
390 .max_antenna_gain = 0, \
394 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
395 #define RATETAB_ENT(_rateid, _flags) \
397 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
398 .hw_value = (_rateid), \
402 static struct ieee80211_rate __wl_rates[] = {
403 RATETAB_ENT(WLC_RATE_1M, 0),
404 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
405 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
406 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
407 RATETAB_ENT(WLC_RATE_6M, 0),
408 RATETAB_ENT(WLC_RATE_9M, 0),
409 RATETAB_ENT(WLC_RATE_12M, 0),
410 RATETAB_ENT(WLC_RATE_18M, 0),
411 RATETAB_ENT(WLC_RATE_24M, 0),
412 RATETAB_ENT(WLC_RATE_36M, 0),
413 RATETAB_ENT(WLC_RATE_48M, 0),
414 RATETAB_ENT(WLC_RATE_54M, 0),
417 #define wl_a_rates (__wl_rates + 4)
418 #define wl_a_rates_size 8
419 #define wl_g_rates (__wl_rates + 0)
420 #define wl_g_rates_size 12
422 static struct ieee80211_channel __wl_2ghz_channels[] = {
439 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
440 CHAN5G(34, 0), CHAN5G(36, 0),
441 CHAN5G(38, 0), CHAN5G(40, 0),
442 CHAN5G(42, 0), CHAN5G(44, 0),
443 CHAN5G(46, 0), CHAN5G(48, 0),
444 CHAN5G(52, 0), CHAN5G(56, 0),
445 CHAN5G(60, 0), CHAN5G(64, 0),
446 CHAN5G(100, 0), CHAN5G(104, 0),
447 CHAN5G(108, 0), CHAN5G(112, 0),
448 CHAN5G(116, 0), CHAN5G(120, 0),
449 CHAN5G(124, 0), CHAN5G(128, 0),
450 CHAN5G(132, 0), CHAN5G(136, 0),
451 CHAN5G(140, 0), CHAN5G(149, 0),
452 CHAN5G(153, 0), CHAN5G(157, 0),
453 CHAN5G(161, 0), CHAN5G(165, 0),
454 CHAN5G(184, 0), CHAN5G(188, 0),
455 CHAN5G(192, 0), CHAN5G(196, 0),
456 CHAN5G(200, 0), CHAN5G(204, 0),
457 CHAN5G(208, 0), CHAN5G(212, 0),
461 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
462 CHAN5G(32, 0), CHAN5G(34, 0),
463 CHAN5G(36, 0), CHAN5G(38, 0),
464 CHAN5G(40, 0), CHAN5G(42, 0),
465 CHAN5G(44, 0), CHAN5G(46, 0),
466 CHAN5G(48, 0), CHAN5G(50, 0),
467 CHAN5G(52, 0), CHAN5G(54, 0),
468 CHAN5G(56, 0), CHAN5G(58, 0),
469 CHAN5G(60, 0), CHAN5G(62, 0),
470 CHAN5G(64, 0), CHAN5G(66, 0),
471 CHAN5G(68, 0), CHAN5G(70, 0),
472 CHAN5G(72, 0), CHAN5G(74, 0),
473 CHAN5G(76, 0), CHAN5G(78, 0),
474 CHAN5G(80, 0), CHAN5G(82, 0),
475 CHAN5G(84, 0), CHAN5G(86, 0),
476 CHAN5G(88, 0), CHAN5G(90, 0),
477 CHAN5G(92, 0), CHAN5G(94, 0),
478 CHAN5G(96, 0), CHAN5G(98, 0),
479 CHAN5G(100, 0), CHAN5G(102, 0),
480 CHAN5G(104, 0), CHAN5G(106, 0),
481 CHAN5G(108, 0), CHAN5G(110, 0),
482 CHAN5G(112, 0), CHAN5G(114, 0),
483 CHAN5G(116, 0), CHAN5G(118, 0),
484 CHAN5G(120, 0), CHAN5G(122, 0),
485 CHAN5G(124, 0), CHAN5G(126, 0),
486 CHAN5G(128, 0), CHAN5G(130, 0),
487 CHAN5G(132, 0), CHAN5G(134, 0),
488 CHAN5G(136, 0), CHAN5G(138, 0),
489 CHAN5G(140, 0), CHAN5G(142, 0),
490 CHAN5G(144, 0), CHAN5G(145, 0),
491 CHAN5G(146, 0), CHAN5G(147, 0),
492 CHAN5G(148, 0), CHAN5G(149, 0),
493 CHAN5G(150, 0), CHAN5G(151, 0),
494 CHAN5G(152, 0), CHAN5G(153, 0),
495 CHAN5G(154, 0), CHAN5G(155, 0),
496 CHAN5G(156, 0), CHAN5G(157, 0),
497 CHAN5G(158, 0), CHAN5G(159, 0),
498 CHAN5G(160, 0), CHAN5G(161, 0),
499 CHAN5G(162, 0), CHAN5G(163, 0),
500 CHAN5G(164, 0), CHAN5G(165, 0),
501 CHAN5G(166, 0), CHAN5G(168, 0),
502 CHAN5G(170, 0), CHAN5G(172, 0),
503 CHAN5G(174, 0), CHAN5G(176, 0),
504 CHAN5G(178, 0), CHAN5G(180, 0),
505 CHAN5G(182, 0), CHAN5G(184, 0),
506 CHAN5G(186, 0), CHAN5G(188, 0),
507 CHAN5G(190, 0), CHAN5G(192, 0),
508 CHAN5G(194, 0), CHAN5G(196, 0),
509 CHAN5G(198, 0), CHAN5G(200, 0),
510 CHAN5G(202, 0), CHAN5G(204, 0),
511 CHAN5G(206, 0), CHAN5G(208, 0),
512 CHAN5G(210, 0), CHAN5G(212, 0),
513 CHAN5G(214, 0), CHAN5G(216, 0),
514 CHAN5G(218, 0), CHAN5G(220, 0),
515 CHAN5G(222, 0), CHAN5G(224, 0),
516 CHAN5G(226, 0), CHAN5G(228, 0),
519 static struct ieee80211_supported_band __wl_band_2ghz = {
520 .band = IEEE80211_BAND_2GHZ,
521 .channels = __wl_2ghz_channels,
522 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
523 .bitrates = wl_g_rates,
524 .n_bitrates = wl_g_rates_size,
527 static struct ieee80211_supported_band __wl_band_5ghz_a = {
528 .band = IEEE80211_BAND_5GHZ,
529 .channels = __wl_5ghz_a_channels,
530 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
531 .bitrates = wl_a_rates,
532 .n_bitrates = wl_a_rates_size,
535 static struct ieee80211_supported_band __wl_band_5ghz_n = {
536 .band = IEEE80211_BAND_5GHZ,
537 .channels = __wl_5ghz_n_channels,
538 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
539 .bitrates = wl_a_rates,
540 .n_bitrates = wl_a_rates_size,
543 static const uint32 __wl_cipher_suites[] = {
544 WLAN_CIPHER_SUITE_WEP40,
545 WLAN_CIPHER_SUITE_WEP104,
546 WLAN_CIPHER_SUITE_TKIP,
547 WLAN_CIPHER_SUITE_CCMP,
548 WLAN_CIPHER_SUITE_AES_CMAC,
551 static void swap_key_from_BE(struct wl_wsec_key *key)
553 key->index = htod32(key->index);
554 key->len = htod32(key->len);
555 key->algo = htod32(key->algo);
556 key->flags = htod32(key->flags);
557 key->rxiv.hi = htod32(key->rxiv.hi);
558 key->rxiv.lo = htod16(key->rxiv.lo);
559 key->iv_initialized = htod32(key->iv_initialized);
562 static void swap_key_to_BE(struct wl_wsec_key *key)
564 key->index = dtoh32(key->index);
565 key->len = dtoh32(key->len);
566 key->algo = dtoh32(key->algo);
567 key->flags = dtoh32(key->flags);
568 key->rxiv.hi = dtoh32(key->rxiv.hi);
569 key->rxiv.lo = dtoh16(key->rxiv.lo);
570 key->iv_initialized = dtoh32(key->iv_initialized);
574 wl_dev_ioctl(struct net_device *dev, uint32 cmd, void *arg, uint32 len)
581 memset(&ioc, 0, sizeof(ioc));
585 strcpy(ifr.ifr_name, dev->name);
586 ifr.ifr_data = (caddr_t)&ioc;
590 err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
597 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
598 enum nl80211_iftype type, uint32 *flags,
599 struct vif_params *params)
601 struct wl_priv *wl = wiphy_to_wl(wiphy);
602 struct wireless_dev *wdev;
609 case NL80211_IFTYPE_MONITOR:
610 case NL80211_IFTYPE_WDS:
611 WL_ERR(("type (%d) : currently we do not support this type\n",
614 case NL80211_IFTYPE_ADHOC:
615 wl->conf->mode = WL_MODE_IBSS;
617 case NL80211_IFTYPE_STATION:
618 wl->conf->mode = WL_MODE_BSS;
624 infra = htod32(infra);
626 wdev = ndev->ieee80211_ptr;
628 WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
630 ((err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra))))
632 unlikely((err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap))))) {
633 WL_ERR(("Error (%d)\n", err));
636 /* -EINPROGRESS: Call commit handler */
640 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
642 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
643 params->bss_type = DOT11_BSSTYPE_ANY;
644 params->scan_type = 0;
645 params->nprobes = -1;
646 params->active_time = -1;
647 params->passive_time = -1;
648 params->home_time = -1;
649 params->channel_num = 0;
651 params->nprobes = htod32(params->nprobes);
652 params->active_time = htod32(params->active_time);
653 params->passive_time = htod32(params->passive_time);
654 params->home_time = htod32(params->home_time);
655 if (ssid && ssid->SSID_len)
656 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
661 wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param,
662 int32 paramlen, void *bufptr, int32 buflen)
666 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
667 BUG_ON(unlikely(!iolen));
669 return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
673 wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param,
674 int32 paramlen, void *bufptr, int32 buflen)
678 iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
679 BUG_ON(unlikely(!iolen));
681 return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
685 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, uint16 action)
688 (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params));
689 struct wl_iscan_params *params;
692 if (ssid && ssid->SSID_len)
693 params_size += sizeof(struct wlc_ssid);
694 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
695 if (unlikely(!params))
697 memset(params, 0, params_size);
698 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
700 wl_iscan_prep(¶ms->params, ssid);
702 params->version = htod32(ISCAN_REQ_VERSION);
703 params->action = htod16(action);
704 params->scan_duration = htod16(0);
706 /* params_size += OFFSETOF(wl_iscan_params_t, params); */
709 wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
710 iscan->ioctl_buf, WLC_IOCTL_SMLEN)))) {
712 WL_INFO(("system busy : iscan canceled\n"));
714 WL_ERR(("error (%d)\n", err));
721 static int32 wl_do_iscan(struct wl_priv *wl)
723 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
724 struct wlc_ssid ssid;
727 /* Broadcast scan by default */
728 memset(&ssid, 0, sizeof(ssid));
730 iscan->state = WL_ISCAN_STATE_SCANING;
732 if (wl->active_scan) {
733 int32 passive_scan = 0;
734 /* make it active scan */
737 wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
738 &passive_scan, sizeof(passive_scan))))) {
739 WL_DBG(("error (%d)\n", err));
743 wl->iscan_kickstart = TRUE;
744 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
745 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
752 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
753 struct cfg80211_scan_request *request,
754 struct cfg80211_ssid *this_ssid)
756 struct wl_priv *wl = ndev_to_wl(ndev);
757 struct cfg80211_ssid *ssids;
758 struct wl_scan_req *sr = wl_to_sr(wl);
763 if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
764 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
767 if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
768 WL_ERR(("Scanning being aborted : status (%d)\n",
775 if (request) { /* scan bss */
776 ssids = request->ssids;
777 if (wl->iscan_on && (!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 */
792 wl->scan_request = request;
793 set_bit(WL_STATUS_SCANNING, &wl->status);
795 if (likely(!(err = wl_do_iscan(wl))))
800 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
801 ssids->ssid, ssids->ssid_len));
802 memset(&sr->ssid, 0, sizeof(sr->ssid));
804 MIN(sizeof(sr->ssid.SSID), ssids->ssid_len);
805 if (sr->ssid.SSID_len) {
806 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
807 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
808 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
809 sr->ssid.SSID, sr->ssid.SSID_len));
812 WL_DBG(("Broadcast scan\n"));
814 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
815 if (wl->active_scan) {
816 int32 pssive_scan = 0;
817 /* make it active scan */
820 wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
822 sizeof(pssive_scan))))) {
823 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n",
829 wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid,
830 sizeof(sr->ssid)))) {
832 WL_INFO(("system busy : scan for \"%s\" "
833 "canceled\n", sr->ssid.SSID));
835 WL_ERR(("WLC_SCAN error (%d)\n", err));
844 clear_bit(WL_STATUS_SCANNING, &wl->status);
845 wl->scan_request = NULL;
850 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
851 struct cfg80211_scan_request *request)
856 if (unlikely((err = __wl_cfg80211_scan(wiphy, ndev, request, NULL)))) {
857 WL_DBG(("scan error (%d)\n", err));
864 static int32 wl_dev_intvar_set(struct net_device *dev, s8 *name, int32 val)
866 s8 buf[WLC_IOCTL_SMLEN];
871 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
872 BUG_ON(unlikely(!len));
874 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len)))) {
875 WL_ERR(("error (%d)\n", err));
882 wl_dev_intvar_get(struct net_device *dev, s8 *name, int32 *retval)
885 s8 buf[WLC_IOCTL_SMLEN];
893 bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
895 BUG_ON(unlikely(!len));
896 if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len)))) {
897 WL_ERR(("error (%d)\n", err));
899 *retval = dtoh32(var.val);
904 static int32 wl_set_rts(struct net_device *dev, uint32 rts_threshold)
909 ((err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold)))) {
910 WL_ERR(("Error (%d)\n", err));
916 static int32 wl_set_frag(struct net_device *dev, uint32 frag_threshold)
921 ((err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold)))) {
922 WL_ERR(("Error (%d)\n", err));
928 static int32 wl_set_retry(struct net_device *dev, uint32 retry, bool l)
931 uint32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
933 retry = htod32(retry);
934 if (unlikely((err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry))))) {
935 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
941 static int32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, uint32 changed)
943 struct wl_priv *wl = wiphy_to_wl(wiphy);
944 struct net_device *ndev = wl_to_ndev(wl);
948 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
949 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
950 wl->conf->rts_threshold = wiphy->rts_threshold;
951 if (!(err = wl_set_rts(ndev, wl->conf->rts_threshold)))
954 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
955 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
956 wl->conf->frag_threshold = wiphy->frag_threshold;
957 if (!(err = wl_set_frag(ndev, wl->conf->frag_threshold)))
960 if (changed & WIPHY_PARAM_RETRY_LONG
961 && (wl->conf->retry_long != wiphy->retry_long)) {
962 wl->conf->retry_long = wiphy->retry_long;
963 if (!(err = wl_set_retry(ndev, wl->conf->retry_long, TRUE)))
966 if (changed & WIPHY_PARAM_RETRY_SHORT
967 && (wl->conf->retry_short != wiphy->retry_short)) {
968 wl->conf->retry_short = wiphy->retry_short;
969 if (!(err = wl_set_retry(ndev, wl->conf->retry_short, FALSE))) {
978 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
979 struct cfg80211_ibss_params *params)
981 struct wl_priv *wl = wiphy_to_wl(wiphy);
982 struct cfg80211_bss *bss;
983 struct ieee80211_channel *chan;
984 struct wl_join_params join_params;
985 struct cfg80211_ssid ssid;
986 int32 scan_retry = 0;
991 WL_ERR(("Invalid bssid\n"));
994 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
996 memcpy(ssid.ssid, params->ssid, params->ssid_len);
997 ssid.ssid_len = params->ssid_len;
1000 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1006 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1007 rtnl_unlock(); /* to allow scan_inform to paropagate
1008 to cfg80211 plane */
1009 schedule_timeout_interruptible(4 * HZ); /* wait 4 secons
1010 till scan done.... */
1012 bss = cfg80211_get_ibss(wiphy, NULL,
1013 params->ssid, params->ssid_len);
1016 wl->ibss_starter = FALSE;
1017 WL_DBG(("Found IBSS\n"));
1019 wl->ibss_starter = TRUE;
1021 if ((chan = params->channel))
1022 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1024 ** Join with specific BSSID and cached SSID
1025 ** If SSID is zero join based on BSSID only
1027 memset(&join_params, 0, sizeof(join_params));
1028 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1030 join_params.ssid.SSID_len = htod32(params->ssid_len);
1032 memcpy(&join_params.params.bssid, params->bssid,
1035 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1039 wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
1040 sizeof(join_params))))) {
1041 WL_ERR(("Error (%d)\n", err));
1047 static int32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1049 struct wl_priv *wl = wiphy_to_wl(wiphy);
1059 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1061 struct wl_priv *wl = ndev_to_wl(dev);
1062 struct wl_security *sec;
1066 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1067 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1068 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1069 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1071 val = WPA_AUTH_DISABLED;
1072 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1073 if (unlikely((err = wl_dev_intvar_set(dev, "wpa_auth", val)))) {
1074 WL_ERR(("set wpa_auth failed (%d)\n", err));
1077 sec = wl_read_prof(wl, WL_PROF_SEC);
1078 sec->wpa_versions = sme->crypto.wpa_versions;
1083 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1085 struct wl_priv *wl = ndev_to_wl(dev);
1086 struct wl_security *sec;
1090 switch (sme->auth_type) {
1091 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1093 WL_DBG(("open system\n"));
1095 case NL80211_AUTHTYPE_SHARED_KEY:
1097 WL_DBG(("shared key\n"));
1099 case NL80211_AUTHTYPE_AUTOMATIC:
1101 WL_DBG(("automatic\n"));
1103 case NL80211_AUTHTYPE_NETWORK_EAP:
1104 WL_DBG(("network eap\n"));
1107 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1111 if (unlikely((err = wl_dev_intvar_set(dev, "auth", val)))) {
1112 WL_ERR(("set auth failed (%d)\n", err));
1115 sec = wl_read_prof(wl, WL_PROF_SEC);
1116 sec->auth_type = sme->auth_type;
1121 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1123 struct wl_priv *wl = ndev_to_wl(dev);
1124 struct wl_security *sec;
1129 if (sme->crypto.n_ciphers_pairwise) {
1130 switch (sme->crypto.ciphers_pairwise[0]) {
1131 case WLAN_CIPHER_SUITE_WEP40:
1132 case WLAN_CIPHER_SUITE_WEP104:
1135 case WLAN_CIPHER_SUITE_TKIP:
1136 pval = TKIP_ENABLED;
1138 case WLAN_CIPHER_SUITE_CCMP:
1141 case WLAN_CIPHER_SUITE_AES_CMAC:
1145 WL_ERR(("invalid cipher pairwise (%d)\n",
1146 sme->crypto.ciphers_pairwise[0]));
1150 if (sme->crypto.cipher_group) {
1151 switch (sme->crypto.cipher_group) {
1152 case WLAN_CIPHER_SUITE_WEP40:
1153 case WLAN_CIPHER_SUITE_WEP104:
1156 case WLAN_CIPHER_SUITE_TKIP:
1157 gval = TKIP_ENABLED;
1159 case WLAN_CIPHER_SUITE_CCMP:
1162 case WLAN_CIPHER_SUITE_AES_CMAC:
1166 WL_ERR(("invalid cipher group (%d)\n",
1167 sme->crypto.cipher_group));
1172 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1173 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", pval | gval)))) {
1174 WL_ERR(("error (%d)\n", err));
1178 sec = wl_read_prof(wl, WL_PROF_SEC);
1179 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1180 sec->cipher_group = sme->crypto.cipher_group;
1186 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1188 struct wl_priv *wl = ndev_to_wl(dev);
1189 struct wl_security *sec;
1193 if (sme->crypto.n_akm_suites) {
1194 if (unlikely((err = wl_dev_intvar_get(dev, "wpa_auth", &val)))) {
1195 WL_ERR(("could not get wpa_auth (%d)\n", err));
1198 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1199 switch (sme->crypto.akm_suites[0]) {
1200 case WLAN_AKM_SUITE_8021X:
1201 val = WPA_AUTH_UNSPECIFIED;
1203 case WLAN_AKM_SUITE_PSK:
1207 WL_ERR(("invalid cipher group (%d)\n",
1208 sme->crypto.cipher_group));
1211 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1212 switch (sme->crypto.akm_suites[0]) {
1213 case WLAN_AKM_SUITE_8021X:
1214 val = WPA2_AUTH_UNSPECIFIED;
1216 case WLAN_AKM_SUITE_PSK:
1217 val = WPA2_AUTH_PSK;
1220 WL_ERR(("invalid cipher group (%d)\n",
1221 sme->crypto.cipher_group));
1226 WL_DBG(("setting wpa_auth to %d\n", val));
1227 if (unlikely((err = wl_dev_intvar_set(dev, "wpa_auth", val)))) {
1228 WL_ERR(("could not set wpa_auth (%d)\n", err));
1232 sec = wl_read_prof(wl, WL_PROF_SEC);
1233 sec->wpa_auth = sme->crypto.akm_suites[0];
1239 wl_set_set_sharedkey(struct net_device *dev,
1240 struct cfg80211_connect_params *sme)
1242 struct wl_priv *wl = ndev_to_wl(dev);
1243 struct wl_security *sec;
1244 struct wl_wsec_key key;
1248 WL_DBG(("key len (%d)\n", sme->key_len));
1250 sec = wl_read_prof(wl, WL_PROF_SEC);
1251 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1252 sec->wpa_versions, sec->cipher_pairwise));
1254 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1255 NL80211_WPA_VERSION_2))
1256 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1257 WLAN_CIPHER_SUITE_WEP104))) {
1258 memset(&key, 0, sizeof(key));
1259 key.len = (uint32) sme->key_len;
1260 key.index = (uint32) sme->key_idx;
1261 if (unlikely(key.len > sizeof(key.data))) {
1262 WL_ERR(("Too long key length (%u)\n", key.len));
1265 memcpy(key.data, sme->key, key.len);
1266 key.flags = WL_PRIMARY_KEY;
1267 switch (sec->cipher_pairwise) {
1268 case WLAN_CIPHER_SUITE_WEP40:
1269 key.algo = CRYPTO_ALGO_WEP1;
1271 case WLAN_CIPHER_SUITE_WEP104:
1272 key.algo = CRYPTO_ALGO_WEP128;
1275 WL_ERR(("Invalid algorithm (%d)\n",
1276 sme->crypto.ciphers_pairwise[0]));
1279 /* Set the new key/index */
1280 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
1281 key.len, key.index, key.algo));
1282 WL_DBG(("key \"%s\"\n", key.data));
1283 swap_key_from_BE(&key);
1286 wl_dev_ioctl(dev, WLC_SET_KEY, &key,
1288 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1291 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1292 WL_DBG(("set auth_type to shared key\n"));
1293 val = 1; /* shared key */
1296 wl_dev_intvar_set(dev, "auth", val)))) {
1297 WL_ERR(("set auth failed (%d)\n", err));
1307 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1308 struct cfg80211_connect_params *sme)
1310 struct wl_priv *wl = wiphy_to_wl(wiphy);
1311 struct ieee80211_channel *chan = sme->channel;
1312 struct wlc_ssid ssid;
1316 if (unlikely(!sme->ssid)) {
1317 WL_ERR(("Invalid ssid\n"));
1321 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1322 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
1323 chan->center_freq));
1325 WL_DBG(("ie (%p), ie_len (%d)\n", sme->ie, sme->ie_len));
1326 if (unlikely((err = wl_set_wpa_version(dev, sme))))
1329 if (unlikely((err = wl_set_auth_type(dev, sme))))
1332 if (unlikely((err = wl_set_set_cipher(dev, sme))))
1335 if (unlikely((err = wl_set_key_mgmt(dev, sme))))
1338 if (unlikely((err = wl_set_set_sharedkey(dev, sme))))
1341 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
1343 ** Join with specific BSSID and cached SSID
1344 ** If SSID is zero join based on BSSID only
1346 memset(&ssid, 0, sizeof(ssid));
1347 ssid.SSID_len = MIN(sizeof(ssid.SSID), sme->ssid_len);
1348 memcpy(ssid.SSID, sme->ssid, ssid.SSID_len);
1349 ssid.SSID_len = htod32(ssid.SSID_len);
1350 wl_update_prof(wl, NULL, &ssid, WL_PROF_SSID);
1351 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1352 WL_DBG(("ssid \"%s\", len (%d)\n", ssid.SSID, ssid.SSID_len));
1355 ((err = wl_dev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid))))) {
1356 WL_ERR(("error (%d)\n", err));
1359 set_bit(WL_STATUS_CONNECTING, &wl->status);
1365 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
1368 struct wl_priv *wl = wiphy_to_wl(wiphy);
1373 WL_DBG(("Reason %d\n", reason_code));
1375 if (likely((act = *(bool *) wl_read_prof(wl, WL_PROF_ACT)))) {
1376 scbval.val = reason_code;
1377 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
1378 scbval.val = htod32(scbval.val);
1379 if (unlikely((err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
1380 sizeof(scb_val_t))))) {
1381 WL_ERR(("error (%d)\n", err));
1390 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
1391 enum nl80211_tx_power_setting type, int32 dbm)
1394 struct wl_priv *wl = wiphy_to_wl(wiphy);
1395 struct net_device *ndev = wl_to_ndev(wl);
1402 case NL80211_TX_POWER_AUTOMATIC:
1404 case NL80211_TX_POWER_LIMITED:
1406 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
1410 case NL80211_TX_POWER_FIXED:
1412 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
1417 /* Make sure radio is off or on as far as software is concerned */
1418 disable = WL_RADIO_SW_DISABLE << 16;
1419 disable = htod32(disable);
1422 wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable))))) {
1423 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
1430 txpwrmw = (uint16) dbm;
1431 if (unlikely((err = wl_dev_intvar_set(ndev, "qtxpower",
1432 (int32) (bcm_mw_to_qdbm
1434 WL_ERR(("qtxpower error (%d)\n", err));
1437 wl->conf->tx_power = dbm;
1442 static int32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, int32 *dbm)
1444 struct wl_priv *wl = wiphy_to_wl(wiphy);
1445 struct net_device *ndev = wl_to_ndev(wl);
1451 if (unlikely((err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm)))) {
1452 WL_ERR(("error (%d)\n", err));
1455 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1456 *dbm = (int32) bcm_qdbm_to_mw(result);
1462 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1469 WL_DBG(("key index (%d)\n", key_idx));
1473 (err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
1474 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1477 wsec = dtoh32(wsec);
1478 if (wsec & WEP_ENABLED) {
1479 /* Just select a new current key */
1480 index = (uint32) key_idx;
1481 index = htod32(index);
1482 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY,
1483 &index, sizeof(index))))) {
1484 WL_ERR(("error (%d)\n", err));
1491 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1492 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1494 struct wl_wsec_key key;
1497 memset(&key, 0, sizeof(key));
1498 key.index = (uint32) key_idx;
1499 /* Instead of bcast for ea address for default wep keys,
1500 driver needs it to be Null */
1501 if (!ETHER_ISMULTI(mac_addr))
1502 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
1503 key.len = (uint32) params->key_len;
1504 /* check for key index change */
1507 swap_key_from_BE(&key);
1510 wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
1511 WL_ERR(("key delete error (%d)\n", err));
1515 if (key.len > sizeof(key.data)) {
1516 WL_ERR(("Invalid key length (%d)\n", key.len));
1520 WL_DBG(("Setting the key index %d\n", key.index));
1521 memcpy(key.data, params->key, key.len);
1523 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1525 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1526 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1527 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1530 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1531 if (params->seq && params->seq_len == 6) {
1534 ivptr = (u8 *) params->seq;
1535 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1536 (ivptr[3] << 8) | ivptr[2];
1537 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1538 key.iv_initialized = TRUE;
1541 switch (params->cipher) {
1542 case WLAN_CIPHER_SUITE_WEP40:
1543 key.algo = CRYPTO_ALGO_WEP1;
1544 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1546 case WLAN_CIPHER_SUITE_WEP104:
1547 key.algo = CRYPTO_ALGO_WEP128;
1548 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1550 case WLAN_CIPHER_SUITE_TKIP:
1551 key.algo = CRYPTO_ALGO_TKIP;
1552 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1554 case WLAN_CIPHER_SUITE_AES_CMAC:
1555 key.algo = CRYPTO_ALGO_AES_CCM;
1556 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1558 case WLAN_CIPHER_SUITE_CCMP:
1559 key.algo = CRYPTO_ALGO_AES_CCM;
1560 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1563 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1566 swap_key_from_BE(&key);
1568 dhd_wait_pend8021x(dev);
1571 wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
1572 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1580 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1581 u8 key_idx, const u8 *mac_addr,
1582 struct key_params *params)
1584 struct wl_wsec_key key;
1589 WL_DBG(("key index (%d)\n", key_idx));
1593 return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1594 memset(&key, 0, sizeof(key));
1596 key.len = (uint32) params->key_len;
1597 key.index = (uint32) key_idx;
1599 if (unlikely(key.len > sizeof(key.data))) {
1600 WL_ERR(("Too long key length (%u)\n", key.len));
1603 memcpy(key.data, params->key, key.len);
1605 key.flags = WL_PRIMARY_KEY;
1606 switch (params->cipher) {
1607 case WLAN_CIPHER_SUITE_WEP40:
1608 key.algo = CRYPTO_ALGO_WEP1;
1609 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1611 case WLAN_CIPHER_SUITE_WEP104:
1612 key.algo = CRYPTO_ALGO_WEP128;
1613 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1615 case WLAN_CIPHER_SUITE_TKIP:
1616 key.algo = CRYPTO_ALGO_TKIP;
1617 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1619 case WLAN_CIPHER_SUITE_AES_CMAC:
1620 key.algo = CRYPTO_ALGO_AES_CCM;
1621 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1623 case WLAN_CIPHER_SUITE_CCMP:
1624 key.algo = CRYPTO_ALGO_AES_CCM;
1625 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
1628 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
1632 /* Set the new key/index */
1633 swap_key_from_BE(&key);
1634 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY,
1635 &key, sizeof(key))))) {
1636 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1641 if (unlikely((err = wl_dev_intvar_get(dev, "wsec", &wsec)))) {
1642 WL_ERR(("get wsec error (%d)\n", err));
1645 wsec &= ~(WEP_ENABLED);
1647 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", wsec)))) {
1648 WL_ERR(("set wsec error (%d)\n", err));
1652 val = 1; /* assume shared key. otherwise 0 */
1655 ((err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))) {
1656 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1663 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1664 u8 key_idx, const u8 *mac_addr)
1666 struct wl_wsec_key key;
1672 memset(&key, 0, sizeof(key));
1674 key.index = (uint32) key_idx;
1675 key.flags = WL_PRIMARY_KEY;
1676 key.algo = CRYPTO_ALGO_OFF;
1678 WL_DBG(("key index (%d)\n", key_idx));
1679 /* Set the new key/index */
1680 swap_key_from_BE(&key);
1681 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY,
1682 &key, sizeof(key))))) {
1683 if (err == -EINVAL) {
1684 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
1685 /* we ignore this key index in this case */
1686 WL_DBG(("invalid key index (%d)\n", key_idx));
1689 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
1695 if (unlikely((err = wl_dev_intvar_get(dev, "wsec", &wsec)))) {
1696 WL_ERR(("get wsec error (%d)\n", err));
1699 wsec &= ~(WEP_ENABLED);
1701 if (unlikely((err = wl_dev_intvar_set(dev, "wsec", wsec)))) {
1702 WL_ERR(("set wsec error (%d)\n", err));
1706 val = 0; /* assume open key. otherwise 1 */
1709 ((err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))) {
1710 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
1717 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1718 u8 key_idx, const u8 *mac_addr, void *cookie,
1719 void (*callback) (void *cookie, struct key_params * params))
1721 struct key_params params;
1722 struct wl_wsec_key key;
1723 struct wl_priv *wl = wiphy_to_wl(wiphy);
1724 struct wl_security *sec;
1728 WL_DBG(("key index (%d)\n", key_idx));
1731 memset(&key, 0, sizeof(key));
1732 key.index = key_idx;
1733 swap_key_to_BE(&key);
1734 memset(¶ms, 0, sizeof(params));
1735 params.key_len = (u8) MIN(DOT11_MAX_KEY_SIZE, key.len);
1736 memcpy(params.key, key.data, params.key_len);
1739 (err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
1740 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
1743 wsec = dtoh32(wsec);
1746 sec = wl_read_prof(wl, WL_PROF_SEC);
1747 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1748 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1749 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
1750 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1751 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1752 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
1756 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1757 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
1760 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1761 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
1764 WL_ERR(("Invalid algo (0x%x)\n", wsec));
1768 callback(cookie, ¶ms);
1773 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1774 struct net_device *dev, u8 key_idx)
1776 WL_INFO(("Not supported\n"));
1782 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1783 u8 *mac, struct station_info *sinfo)
1785 struct wl_priv *wl = wiphy_to_wl(wiphy);
1793 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
1794 WL_ERR(("Wrong Mac address\n"));
1798 /* Report the current tx rate */
1799 if ((err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) {
1800 WL_ERR(("Could not get rate (%d)\n", err));
1802 rate = dtoh32(rate);
1803 sinfo->filled |= STATION_INFO_TX_BITRATE;
1804 sinfo->txrate.legacy = rate * 5;
1805 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
1808 if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
1812 wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val,
1813 sizeof(scb_val_t)))) {
1814 WL_ERR(("Could not get rssi (%d)\n", err));
1817 rssi = dtoh32(scb_val.val);
1818 sinfo->filled |= STATION_INFO_SIGNAL;
1819 sinfo->signal = rssi;
1820 WL_DBG(("RSSI %d dBm\n", rssi));
1827 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1828 bool enabled, int32 timeout)
1834 pm = enabled ? PM_FAST : PM_OFF;
1836 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
1837 if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm))))) {
1839 WL_DBG(("net_device is not ready yet\n"));
1841 WL_ERR(("error (%d)\n", err));
1847 static __used uint32 wl_find_msb(uint16 bit16)
1851 if (bit16 & 0xff00) {
1875 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1877 const struct cfg80211_bitrate_mask *mask)
1879 struct wl_rateset rateset;
1888 /* addr param is always NULL. ignore it */
1889 /* Get current rateset */
1890 if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
1891 sizeof(rateset))))) {
1892 WL_ERR(("could not get current rateset (%d)\n", err));
1896 rateset.count = dtoh32(rateset.count);
1898 if (!(legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy)))
1899 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
1901 val = wl_g_rates[legacy - 1].bitrate * 100000;
1903 if (val < rateset.count) {
1904 /* Select rate by rateset index */
1905 rate = rateset.rates[val] & 0x7f;
1907 /* Specified rate in bps */
1908 rate = val / 500000;
1911 WL_DBG(("rate %d mbps\n", (rate / 2)));
1915 * Set rate override,
1916 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1918 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
1919 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
1920 if (unlikely(err_bg && err_a)) {
1921 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
1922 return err_bg | err_a;
1928 static int32 wl_cfg80211_resume(struct wiphy *wiphy)
1933 wl_invoke_iscan(wiphy_to_wl(wiphy));
1938 static int32 wl_cfg80211_suspend(struct wiphy *wiphy)
1940 struct wl_priv *wl = wiphy_to_wl(wiphy);
1945 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1947 if (wl->scan_request) {
1948 cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE means
1950 wl->scan_request = NULL;
1952 clear_bit(WL_STATUS_SCANNING, &wl->status);
1953 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
1959 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
1962 s8 eabuf[ETHER_ADDR_STR_LEN];
1965 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
1967 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
1968 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
1969 WL_DBG(("PMKID[%d]: %s =\n", i,
1970 bcm_ether_ntoa(&pmk_list->pmkids.pmkid[i].BSSID,
1972 for (j = 0; j < WPA2_PMKID_LEN; j++) {
1973 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
1977 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
1985 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
1986 struct cfg80211_pmksa *pmksa)
1988 struct wl_priv *wl = wiphy_to_wl(wiphy);
1989 s8 eabuf[ETHER_ADDR_STR_LEN];
1994 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
1995 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
1996 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
1999 if (i < WL_NUM_PMKIDS_MAX) {
2000 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2002 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2004 if (i == wl->pmk_list->pmkids.npmkid)
2005 wl->pmk_list->pmkids.npmkid++;
2009 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %s =\n",
2010 bcm_ether_ntoa(&wl->pmk_list->pmkids.
2011 pmkid[wl->pmk_list->pmkids.npmkid].BSSID,
2013 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2015 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2019 err = wl_update_pmklist(dev, wl->pmk_list, err);
2025 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2026 struct cfg80211_pmksa *pmksa)
2028 struct wl_priv *wl = wiphy_to_wl(wiphy);
2029 s8 eabuf[ETHER_ADDR_STR_LEN];
2030 struct _pmkid_list pmkid;
2035 memset(eabuf, 0, ETHER_ADDR_STR_LEN);
2036 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2037 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2039 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %s =\n",
2040 bcm_ether_ntoa(&pmkid.pmkid[0].BSSID, eabuf)));
2041 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2042 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2045 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2047 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2051 if ((wl->pmk_list->pmkids.npmkid > 0)
2052 && (i < wl->pmk_list->pmkids.npmkid)) {
2053 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2054 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2055 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2056 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2058 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2059 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2062 wl->pmk_list->pmkids.npmkid--;
2067 err = wl_update_pmklist(dev, wl->pmk_list, err);
2074 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2076 struct wl_priv *wl = wiphy_to_wl(wiphy);
2080 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2081 err = wl_update_pmklist(dev, wl->pmk_list, err);
2086 static struct cfg80211_ops wl_cfg80211_ops = {
2087 .change_virtual_intf = wl_cfg80211_change_iface,
2088 .scan = wl_cfg80211_scan,
2089 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
2090 .join_ibss = wl_cfg80211_join_ibss,
2091 .leave_ibss = wl_cfg80211_leave_ibss,
2092 .get_station = wl_cfg80211_get_station,
2093 .set_tx_power = wl_cfg80211_set_tx_power,
2094 .get_tx_power = wl_cfg80211_get_tx_power,
2095 .add_key = wl_cfg80211_add_key,
2096 .del_key = wl_cfg80211_del_key,
2097 .get_key = wl_cfg80211_get_key,
2098 .set_default_key = wl_cfg80211_config_default_key,
2099 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
2100 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
2101 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
2102 .connect = wl_cfg80211_connect,
2103 .disconnect = wl_cfg80211_disconnect,
2104 .suspend = wl_cfg80211_suspend,
2105 .resume = wl_cfg80211_resume,
2106 .set_pmksa = wl_cfg80211_set_pmksa,
2107 .del_pmksa = wl_cfg80211_del_pmksa,
2108 .flush_pmksa = wl_cfg80211_flush_pmksa
2111 static int32 wl_mode_to_nl80211_iftype(int32 mode)
2117 return NL80211_IFTYPE_STATION;
2119 return NL80211_IFTYPE_ADHOC;
2121 return NL80211_IFTYPE_UNSPECIFIED;
2127 static struct wireless_dev *wl_alloc_wdev(int32 sizeof_iface,
2130 struct wireless_dev *wdev;
2133 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2134 if (unlikely(!wdev)) {
2135 WL_ERR(("Could not allocate wireless device\n"));
2136 return ERR_PTR(-ENOMEM);
2139 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
2140 if (unlikely(!wdev->wiphy)) {
2141 WL_ERR(("Couldn not allocate wiphy device\n"));
2145 set_wiphy_dev(wdev->wiphy, dev);
2146 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2147 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2148 wdev->wiphy->interface_modes =
2149 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2150 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2151 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2152 * it as 11a by default.
2153 * This will be updated with
2156 * if phy has 11n capability
2158 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2159 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2160 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2161 #ifndef WL_POWERSAVE_DISABLED
2162 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2167 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2168 #endif /* !WL_POWERSAVE_DISABLED */
2169 if (unlikely(((err = wiphy_register(wdev->wiphy)) < 0))) {
2170 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
2171 goto wiphy_register_out;
2176 wiphy_free(wdev->wiphy);
2181 return ERR_PTR(err);
2184 static void wl_free_wdev(struct wl_priv *wl)
2186 struct wireless_dev *wdev = wl_to_wdev(wl);
2188 if (unlikely(!wdev)) {
2189 WL_ERR(("wdev is invalid\n"));
2192 wiphy_unregister(wdev->wiphy);
2193 wiphy_free(wdev->wiphy);
2195 wl_to_wdev(wl) = NULL;
2198 static int32 wl_inform_bss(struct wl_priv *wl)
2200 struct wl_scan_results *bss_list;
2201 struct wl_bss_info *bi = NULL; /* must be initialized */
2205 bss_list = wl->bss_list;
2206 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
2207 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
2208 bss_list->version));
2211 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
2212 bi = next_bss(bss_list, bi);
2213 for_each_bss(bss_list, bi, i) {
2214 if (unlikely(err = wl_inform_single_bss(wl, bi)))
2220 static int32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
2222 struct wiphy *wiphy = wl_to_wiphy(wl);
2223 struct ieee80211_mgmt *mgmt;
2224 struct ieee80211_channel *channel;
2225 struct ieee80211_supported_band *band;
2226 struct wl_cfg80211_bss_info *notif_bss_info;
2227 struct wl_scan_req *sr = wl_to_sr(wl);
2232 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
2233 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
2237 kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
2238 WL_BSS_INFO_MAX, GFP_KERNEL);
2239 if (unlikely(!notif_bss_info)) {
2240 WL_ERR(("notif_bss_info alloc failed\n"));
2243 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
2244 notif_bss_info->channel = CHSPEC_CHANNEL(bi->chanspec);
2245 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
2246 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2248 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2249 notif_bss_info->rssi = bi->RSSI;
2250 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
2251 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
2252 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2253 IEEE80211_STYPE_PROBE_RESP);
2255 mgmt->u.probe_resp.timestamp = 0;
2256 mgmt->u.probe_resp.beacon_int = cpu_to_le16(bi->beacon_period);
2257 mgmt->u.probe_resp.capab_info = cpu_to_le16(bi->capability);
2259 wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
2260 wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
2262 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
2263 wl_cp_ie(wl, mgmt->u.probe_resp.variable, WL_BSS_INFO_MAX -
2264 offsetof(struct wl_cfg80211_bss_info, frame_buf));
2265 notif_bss_info->frame_len =
2266 offsetof(struct ieee80211_mgmt,
2267 u.probe_resp.variable) + wl_get_ielen(wl);
2268 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
2269 channel = ieee80211_get_channel(wiphy, freq);
2271 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x\n",
2273 notif_bss_info->rssi, notif_bss_info->channel,
2274 mgmt->u.probe_resp.capab_info));
2276 signal = notif_bss_info->rssi * 100;
2277 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
2279 (notif_bss_info->frame_len),
2280 signal, GFP_KERNEL))) {
2281 WL_ERR(("cfg80211_inform_bss_frame error\n"));
2282 kfree(notif_bss_info);
2285 kfree(notif_bss_info);
2290 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
2292 uint32 event = ntoh32(e->event_type);
2293 uint16 flags = ntoh16(e->flags);
2295 if (event == WLC_E_JOIN || event == WLC_E_ASSOC_IND
2296 || event == WLC_E_REASSOC_IND) {
2298 } else if (event == WLC_E_LINK) {
2299 if (flags & WLC_EVENT_MSG_LINK) {
2300 if (wl_is_ibssmode(wl)) {
2301 if (wl_is_ibssstarter(wl)) {
2312 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
2314 uint32 event = ntoh32(e->event_type);
2315 uint16 flags = ntoh16(e->flags);
2317 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
2319 } else if (event == WLC_E_LINK) {
2320 if (!(flags & WLC_EVENT_MSG_LINK))
2327 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
2329 uint32 event = ntoh32(e->event_type);
2330 uint32 status = ntoh32(e->status);
2332 if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
2333 if (status == WLC_E_STATUS_NO_NETWORKS)
2341 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
2342 const wl_event_msg_t *e, void *data)
2347 if (wl_is_linkup(wl, e)) {
2349 if (wl_is_ibssmode(wl)) {
2350 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
2352 WL_DBG(("joined in IBSS network\n"));
2354 wl_bss_connect_done(wl, ndev, e, data, TRUE);
2355 WL_DBG(("joined in BSS network \"%s\"\n",
2356 ((struct wlc_ssid *)
2357 wl_read_prof(wl, WL_PROF_SSID))->SSID));
2360 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2361 } else if (wl_is_linkdown(wl, e)) {
2362 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
2363 clear_bit(WL_STATUS_CONNECTED, &wl->status);
2365 wl_init_prof(wl->profile);
2366 } else if (wl_is_nonetwork(wl, e)) {
2367 wl_bss_connect_done(wl, ndev, e, data, FALSE);
2374 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
2375 const wl_event_msg_t *e, void *data)
2380 wl_bss_roaming_done(wl, ndev, e, data);
2382 wl_update_prof(wl, e, &act, WL_PROF_ACT);
2388 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, int32 len)
2390 struct wl_priv *wl = ndev_to_wl(dev);
2393 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2394 BUG_ON(unlikely(!buflen));
2396 return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen);
2400 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2403 struct wl_priv *wl = ndev_to_wl(dev);
2407 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
2408 BUG_ON(unlikely(!len));
2411 wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
2412 WL_IOCTL_LEN_MAX)))) {
2413 WL_ERR(("error (%d)\n", err));
2416 memcpy(buf, wl->ioctl_buf, buf_len);
2421 static int32 wl_get_assoc_ies(struct wl_priv *wl)
2423 struct net_device *ndev = wl_to_ndev(wl);
2424 struct wl_assoc_ielen *assoc_info;
2425 struct wl_connect_info *conn_info = wl_to_conn(wl);
2430 if (unlikely(err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
2431 WL_ASSOC_INFO_MAX))) {
2432 WL_ERR(("could not get assoc info (%d)\n", err));
2435 assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
2436 req_len = assoc_info->req_len;
2437 resp_len = assoc_info->resp_len;
2441 wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
2442 WL_ASSOC_INFO_MAX))) {
2443 WL_ERR(("could not get assoc req (%d)\n", err));
2446 conn_info->req_ie_len = req_len;
2448 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
2450 conn_info->req_ie_len = 0;
2451 conn_info->req_ie = NULL;
2456 wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
2457 WL_ASSOC_INFO_MAX))) {
2458 WL_ERR(("could not get assoc resp (%d)\n", err));
2461 conn_info->resp_ie_len = resp_len;
2462 conn_info->resp_ie =
2463 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
2465 conn_info->resp_ie_len = 0;
2466 conn_info->resp_ie = NULL;
2468 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
2469 conn_info->resp_ie_len));
2474 static int32 wl_update_bss_info(struct wl_priv *wl)
2476 struct cfg80211_bss *bss;
2477 struct wl_bss_info *bi;
2478 struct wlc_ssid *ssid;
2481 if (wl_is_ibssmode(wl))
2484 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
2486 cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
2487 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
2488 WLAN_CAPABILITY_ESS);
2491 if (unlikely(!bss)) {
2492 WL_DBG(("Could not find the AP\n"));
2493 *(uint32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
2496 wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
2497 wl->extra_buf, WL_EXTRA_BUF_MAX))) {
2498 WL_ERR(("Could not get bss info %d\n", err));
2499 goto update_bss_info_out;
2501 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
2502 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
2504 goto update_bss_info_out;
2506 if (unlikely((err = wl_inform_single_bss(wl, bi))))
2507 goto update_bss_info_out;
2509 WL_DBG(("Found the AP in the list - "
2510 "BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
2511 bss->bssid[0], bss->bssid[1], bss->bssid[2],
2512 bss->bssid[3], bss->bssid[4], bss->bssid[5]));
2513 cfg80211_put_bss(bss);
2516 update_bss_info_out:
2522 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2523 const wl_event_msg_t *e, void *data)
2525 struct wl_connect_info *conn_info = wl_to_conn(wl);
2528 wl_get_assoc_ies(wl);
2529 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2530 wl_update_bss_info(wl);
2531 cfg80211_roamed(ndev,
2533 conn_info->req_ie, conn_info->req_ie_len,
2534 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2535 WL_DBG(("Report roaming result\n"));
2537 set_bit(WL_STATUS_CONNECTED, &wl->status);
2543 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2544 const wl_event_msg_t *e, void *data, bool completed)
2546 struct wl_connect_info *conn_info = wl_to_conn(wl);
2549 wl_get_assoc_ies(wl);
2550 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
2551 wl_update_bss_info(wl);
2552 if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
2553 cfg80211_connect_result(ndev,
2556 conn_info->req_ie_len,
2558 conn_info->resp_ie_len,
2559 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
2561 WL_DBG(("Report connect result - connection %s\n",
2562 completed ? "succeeded" : "failed"));
2564 cfg80211_roamed(ndev,
2566 conn_info->req_ie, conn_info->req_ie_len,
2567 conn_info->resp_ie, conn_info->resp_ie_len,
2569 WL_DBG(("Report roaming result\n"));
2571 set_bit(WL_STATUS_CONNECTED, &wl->status);
2577 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
2578 const wl_event_msg_t *e, void *data)
2580 uint16 flags = ntoh16(e->flags);
2581 enum nl80211_key_type key_type;
2584 if (flags & WLC_EVENT_MSG_GROUP)
2585 key_type = NL80211_KEYTYPE_GROUP;
2587 key_type = NL80211_KEYTYPE_PAIRWISE;
2589 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2597 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
2598 const wl_event_msg_t *e, void *data)
2600 struct channel_info channel_inform;
2601 struct wl_scan_results *bss_list;
2602 uint32 len = WL_SCAN_BUF_MAX;
2605 if (wl->iscan_on && wl->iscan_kickstart)
2606 return wl_wakeup_iscan(wl_to_iscan(wl));
2608 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2609 WL_ERR(("Scan complete while device not scanning\n"));
2612 if (unlikely(!wl->scan_request)) {
2615 if (unlikely((err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
2616 sizeof(channel_inform))))) {
2617 WL_ERR(("scan busy (%d)\n", err));
2620 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
2621 if (unlikely(channel_inform.scan_channel)) {
2623 WL_DBG(("channel_inform.scan_channel (%d)\n",
2624 channel_inform.scan_channel));
2626 wl->bss_list = wl->scan_results;
2627 bss_list = wl->bss_list;
2628 memset(bss_list, 0, len);
2629 bss_list->buflen = htod32(len);
2631 ((err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len)))) {
2632 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
2636 bss_list->buflen = dtoh32(bss_list->buflen);
2637 bss_list->version = dtoh32(bss_list->version);
2638 bss_list->count = dtoh32(bss_list->count);
2640 if ((err = wl_inform_bss(wl)))
2644 if (wl->scan_request) {
2645 cfg80211_scan_done(wl->scan_request, FALSE);
2646 wl->scan_request = NULL;
2652 static void wl_init_conf(struct wl_conf *conf)
2654 conf->mode = (uint32)-1;
2655 conf->frag_threshold = (uint32)-1;
2656 conf->rts_threshold = (uint32)-1;
2657 conf->retry_short = (uint32)-1;
2658 conf->retry_long = (uint32)-1;
2659 conf->tx_power = -1;
2662 static void wl_init_prof(struct wl_profile *prof)
2664 memset(prof, 0, sizeof(*prof));
2667 static void wl_init_eloop_handler(struct wl_event_loop *el)
2669 memset(el, 0, sizeof(*el));
2670 el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
2671 el->handler[WLC_E_JOIN] = wl_notify_connect_status;
2672 el->handler[WLC_E_LINK] = wl_notify_connect_status;
2673 el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
2674 el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
2675 el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
2676 el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
2677 el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
2678 el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
2679 el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
2682 static int32 wl_init_priv_mem(struct wl_priv *wl)
2684 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
2685 if (unlikely(!wl->scan_results)) {
2686 WL_ERR(("Scan results alloc failed\n"));
2687 goto init_priv_mem_out;
2689 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
2690 if (unlikely(!wl->conf)) {
2691 WL_ERR(("wl_conf alloc failed\n"));
2692 goto init_priv_mem_out;
2694 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
2695 if (unlikely(!wl->profile)) {
2696 WL_ERR(("wl_profile alloc failed\n"));
2697 goto init_priv_mem_out;
2699 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2700 if (unlikely(!wl->bss_info)) {
2701 WL_ERR(("Bss information alloc failed\n"));
2702 goto init_priv_mem_out;
2705 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
2706 if (unlikely(!wl->scan_req_int)) {
2707 WL_ERR(("Scan req alloc failed\n"));
2708 goto init_priv_mem_out;
2710 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
2711 if (unlikely(!wl->ioctl_buf)) {
2712 WL_ERR(("Ioctl buf alloc failed\n"));
2713 goto init_priv_mem_out;
2715 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
2716 if (unlikely(!wl->extra_buf)) {
2717 WL_ERR(("Extra buf alloc failed\n"));
2718 goto init_priv_mem_out;
2720 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
2721 if (unlikely(!wl->iscan)) {
2722 WL_ERR(("Iscan buf alloc failed\n"));
2723 goto init_priv_mem_out;
2725 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
2726 if (unlikely(!wl->fw)) {
2727 WL_ERR(("fw object alloc failed\n"));
2728 goto init_priv_mem_out;
2730 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
2731 if (unlikely(!wl->pmk_list)) {
2732 WL_ERR(("pmk list alloc failed\n"));
2733 goto init_priv_mem_out;
2739 wl_deinit_priv_mem(wl);
2744 static void wl_deinit_priv_mem(struct wl_priv *wl)
2746 kfree(wl->scan_results);
2747 wl->scan_results = NULL;
2748 kfree(wl->bss_info);
2749 wl->bss_info = NULL;
2754 kfree(wl->scan_req_int);
2755 wl->scan_req_int = NULL;
2756 kfree(wl->ioctl_buf);
2757 wl->ioctl_buf = NULL;
2758 kfree(wl->extra_buf);
2759 wl->extra_buf = NULL;
2764 kfree(wl->pmk_list);
2765 wl->pmk_list = NULL;
2768 static int32 wl_create_event_handler(struct wl_priv *wl)
2770 sema_init(&wl->event_sync, 0);
2771 init_completion(&wl->event_exit);
2773 (((wl->event_pid = kernel_thread(wl_event_handler, wl, 0)) < 0))) {
2774 WL_ERR(("failed to create event thread\n"));
2777 WL_DBG(("pid %d\n", wl->event_pid));
2781 static void wl_destroy_event_handler(struct wl_priv *wl)
2783 if (wl->event_pid >= 0) {
2784 KILL_PROC(wl->event_pid, SIGTERM);
2785 wait_for_completion(&wl->event_exit);
2789 static void wl_term_iscan(struct wl_priv *wl)
2791 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2793 if (wl->iscan_on && iscan->pid >= 0) {
2794 iscan->state = WL_ISCAN_STATE_IDLE;
2795 KILL_PROC(iscan->pid, SIGTERM);
2796 wait_for_completion(&iscan->exited);
2801 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
2803 struct wl_priv *wl = iscan_to_wl(iscan);
2805 if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
2806 WL_ERR(("Scan complete while device not scanning\n"));
2809 if (likely(wl->scan_request)) {
2810 cfg80211_scan_done(wl->scan_request, aborted);
2811 wl->scan_request = NULL;
2813 wl->iscan_kickstart = FALSE;
2816 static int32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
2818 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2819 WL_DBG(("wake up iscan\n"));
2828 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status,
2829 struct wl_scan_results **bss_list)
2831 struct wl_iscan_results list;
2832 struct wl_scan_results *results;
2833 struct wl_iscan_results *list_buf;
2836 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2837 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
2838 results = &list_buf->results;
2839 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
2840 results->version = 0;
2843 memset(&list, 0, sizeof(list));
2844 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
2845 if (unlikely((err = wl_dev_iovar_getbuf(iscan->dev,
2848 WL_ISCAN_RESULTS_FIXED_SIZE,
2850 WL_ISCAN_BUF_MAX)))) {
2851 WL_ERR(("error (%d)\n", err));
2854 results->buflen = dtoh32(results->buflen);
2855 results->version = dtoh32(results->version);
2856 results->count = dtoh32(results->count);
2857 WL_DBG(("results->count = %d\n", results->count));
2858 WL_DBG(("results->buflen = %d\n", results->buflen));
2859 *status = dtoh32(list_buf->status);
2860 *bss_list = results;
2865 static int32 wl_iscan_done(struct wl_priv *wl)
2867 struct wl_iscan_ctrl *iscan = wl->iscan;
2870 iscan->state = WL_ISCAN_STATE_IDLE;
2873 wl_notify_iscan_complete(iscan, FALSE);
2879 static int32 wl_iscan_pending(struct wl_priv *wl)
2881 struct wl_iscan_ctrl *iscan = wl->iscan;
2884 /* Reschedule the timer */
2885 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2886 iscan->timer_on = 1;
2891 static int32 wl_iscan_inprogress(struct wl_priv *wl)
2893 struct wl_iscan_ctrl *iscan = wl->iscan;
2898 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
2900 /* Reschedule the timer */
2901 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2902 iscan->timer_on = 1;
2907 static int32 wl_iscan_aborted(struct wl_priv *wl)
2909 struct wl_iscan_ctrl *iscan = wl->iscan;
2912 iscan->state = WL_ISCAN_STATE_IDLE;
2914 wl_notify_iscan_complete(iscan, TRUE);
2920 static int32 wl_iscan_thread(void *data)
2922 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
2923 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
2924 struct wl_priv *wl = iscan_to_wl(iscan);
2925 struct wl_iscan_eloop *el = &iscan->el;
2929 sched_setscheduler(current, SCHED_FIFO, ¶m);
2930 status = WL_SCAN_RESULTS_PARTIAL;
2931 while (likely(!down_interruptible(&iscan->sync))) {
2932 if (iscan->timer_on) {
2933 del_timer_sync(&iscan->timer);
2934 iscan->timer_on = 0;
2939 wl_get_iscan_results(iscan, &status, &wl->bss_list)))) {
2940 status = WL_SCAN_RESULTS_ABORTED;
2941 WL_ERR(("Abort iscan\n"));
2944 el->handler[status] (wl);
2946 if (iscan->timer_on) {
2947 del_timer_sync(&iscan->timer);
2948 iscan->timer_on = 0;
2950 complete_and_exit(&iscan->exited, 0);
2955 static void wl_iscan_timer(unsigned long data)
2957 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
2960 iscan->timer_on = 0;
2961 WL_DBG(("timer expired\n"));
2962 wl_wakeup_iscan(iscan);
2966 static int32 wl_invoke_iscan(struct wl_priv *wl)
2968 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
2971 if (wl->iscan_on && iscan->pid < 0) {
2972 iscan->state = WL_ISCAN_STATE_IDLE;
2973 sema_init(&iscan->sync, 0);
2974 init_completion(&iscan->exited);
2975 iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0);
2976 if (unlikely(iscan->pid < 0)) {
2977 WL_ERR(("Could not create iscan thread\n"));
2985 static void wl_init_iscan_eloop(struct wl_iscan_eloop *el)
2987 memset(el, 0, sizeof(*el));
2988 el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
2989 el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
2990 el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
2991 el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
2992 el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
2995 static int32 wl_init_iscan(struct wl_priv *wl)
2997 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
3001 iscan->dev = wl_to_ndev(wl);
3002 iscan->state = WL_ISCAN_STATE_IDLE;
3003 wl_init_iscan_eloop(&iscan->el);
3004 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
3005 init_timer(&iscan->timer);
3006 iscan->timer.data = (unsigned long) iscan;
3007 iscan->timer.function = wl_iscan_timer;
3008 sema_init(&iscan->sync, 0);
3009 init_completion(&iscan->exited);
3010 iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0);
3011 if (unlikely(iscan->pid < 0)) {
3012 WL_ERR(("Could not create iscan thread\n"));
3021 static void wl_init_fw(struct wl_fw_ctrl *fw)
3023 fw->status = 0; /* init fw loading status.
3024 0 means nothing was loaded yet */
3027 static int32 wl_init_priv(struct wl_priv *wl)
3029 struct wiphy *wiphy = wl_to_wiphy(wl);
3032 wl->scan_request = NULL;
3033 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
3034 #ifndef WL_ISCAN_DISABLED
3035 wl->iscan_on = TRUE; /* iscan on & off switch.
3036 we enable iscan per default */
3038 wl->iscan_on = FALSE;
3039 #endif /* WL_ISCAN_DISABLED */
3040 #ifndef WL_ROAM_DISABLED
3041 wl->roam_on = TRUE; /* roam on & off switch.
3042 we enable roam per default */
3044 wl->roam_on = FALSE;
3045 #endif /* WL_ROAM_DISABLED */
3047 wl->iscan_kickstart = FALSE;
3048 wl->active_scan = TRUE; /* we do active scan for
3049 specific scan per default */
3050 wl->dongle_up = FALSE; /* dongle is not up yet */
3052 if (unlikely((err = wl_init_priv_mem(wl))))
3054 if (unlikely(wl_create_event_handler(wl)))
3056 wl_init_eloop_handler(&wl->el);
3057 mutex_init(&wl->usr_sync);
3058 if (unlikely((err = wl_init_iscan(wl))))
3061 wl_init_conf(wl->conf);
3062 wl_init_prof(wl->profile);
3068 static void wl_deinit_priv(struct wl_priv *wl)
3070 wl_destroy_event_handler(wl);
3071 wl->dongle_up = FALSE; /* dongle down */
3075 wl_deinit_priv_mem(wl);
3078 int32 wl_cfg80211_attach(struct net_device *ndev, void *data)
3080 struct wireless_dev *wdev;
3082 struct wl_iface *ci;
3085 if (unlikely(!ndev)) {
3086 WL_ERR(("ndev is invaild\n"));
3089 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
3090 if (unlikely(!wl_cfg80211_dev)) {
3091 WL_ERR(("wl_cfg80211_dev is invalid\n"));
3094 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
3095 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
3096 if (unlikely(IS_ERR(wdev)))
3099 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
3100 wl = wdev_to_wl(wdev);
3103 ci = (struct wl_iface *)wl_to_ci(wl);
3105 ndev->ieee80211_ptr = wdev;
3106 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3107 wdev->netdev = ndev;
3108 if (unlikely((err = wl_init_priv(wl)))) {
3109 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
3110 goto cfg80211_attach_out;
3112 wl_set_drvdata(wl_cfg80211_dev, ci);
3113 set_bit(WL_STATUS_READY, &wl->status);
3117 cfg80211_attach_out:
3122 void wl_cfg80211_detach(void)
3130 wl_set_drvdata(wl_cfg80211_dev, NULL);
3131 kfree(wl_cfg80211_dev);
3132 wl_cfg80211_dev = NULL;
3133 wl_clear_sdio_func();
3136 static void wl_wakeup_event(struct wl_priv *wl)
3138 up(&wl->event_sync);
3141 static int32 wl_event_handler(void *data)
3143 struct wl_priv *wl = (struct wl_priv *)data;
3144 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3145 struct wl_event_q *e;
3147 sched_setscheduler(current, SCHED_FIFO, ¶m);
3148 while (likely(!down_interruptible(&wl->event_sync))) {
3149 if (unlikely(!(e = wl_deq_event(wl)))) {
3150 WL_ERR(("eqeue empty..\n"));
3153 WL_DBG(("event type (%d)\n", e->etype));
3154 if (wl->el.handler[e->etype]) {
3155 wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
3158 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
3162 complete_and_exit(&wl->event_exit, 0);
3166 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
3168 uint32 event_type = ntoh32(e->event_type);
3169 struct wl_priv *wl = ndev_to_wl(ndev);
3170 #if (WL_DBG_LEVEL > 0)
3171 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
3172 wl_dbg_estr[event_type] : (s8 *) "Unknown";
3173 #endif /* (WL_DBG_LEVEL > 0) */
3174 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
3175 if (likely(!wl_enq_event(wl, event_type, e, data)))
3176 wl_wakeup_event(wl);
3179 static void wl_init_eq(struct wl_priv *wl)
3181 wl_init_eq_lock(wl);
3182 INIT_LIST_HEAD(&wl->eq_list);
3185 static void wl_flush_eq(struct wl_priv *wl)
3187 struct wl_event_q *e;
3190 while (!list_empty(&wl->eq_list)) {
3191 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3192 list_del(&e->eq_list);
3199 * retrieve first queued event from head
3202 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
3204 struct wl_event_q *e = NULL;
3207 if (likely(!list_empty(&wl->eq_list))) {
3208 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
3209 list_del(&e->eq_list);
3217 ** push event to tail of the queue
3221 wl_enq_event(struct wl_priv *wl, uint32 event, const wl_event_msg_t *msg,
3224 struct wl_event_q *e;
3227 if (unlikely(!(e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL)))) {
3228 WL_ERR(("event alloc failed\n"));
3233 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
3237 list_add_tail(&e->eq_list, &wl->eq_list);
3243 static void wl_put_event(struct wl_event_q *e)
3248 void wl_cfg80211_sdio_func(void *func)
3250 cfg80211_sdio_func = (struct sdio_func *)func;
3253 static void wl_clear_sdio_func(void)
3255 cfg80211_sdio_func = NULL;
3258 struct sdio_func *wl_cfg80211_get_sdio_func(void)
3260 return cfg80211_sdio_func;
3263 static int32 wl_dongle_mode(struct net_device *ndev, int32 iftype)
3270 case NL80211_IFTYPE_MONITOR:
3271 case NL80211_IFTYPE_WDS:
3272 WL_ERR(("type (%d) : currently we do not support this mode\n",
3276 case NL80211_IFTYPE_ADHOC:
3278 case NL80211_IFTYPE_STATION:
3283 WL_ERR(("invalid type (%d)\n", iftype));
3286 infra = htod32(infra);
3288 WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
3290 (err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)))
3292 (err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap)))) {
3293 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
3297 return -EINPROGRESS;
3300 #ifndef EMBEDDED_PLATFORM
3301 static int32 wl_dongle_country(struct net_device *ndev, u8 ccode)
3309 static int32 wl_dongle_up(struct net_device *ndev, uint32 up)
3313 if (unlikely(err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up)))) {
3314 WL_ERR(("WLC_UP error (%d)\n", err));
3319 static int32 wl_dongle_power(struct net_device *ndev, uint32 power_mode)
3325 wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode)))) {
3326 WL_ERR(("WLC_SET_PM error (%d)\n", err));
3332 wl_dongle_glom(struct net_device *ndev, uint32 glom, uint32 dongle_align)
3334 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3338 /* Match Host and Dongle rx alignment */
3339 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
3342 (err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3343 WL_ERR(("txglomalign error (%d)\n", err));
3344 goto dongle_glom_out;
3346 /* disable glom option per default */
3347 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
3349 (err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3350 WL_ERR(("txglom error (%d)\n", err));
3351 goto dongle_glom_out;
3358 wl_dongle_roam(struct net_device *ndev, uint32 roamvar, uint32 bcn_timeout)
3360 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3364 /* Setup timeout if Beacons are lost and roam is
3365 off to report link down */
3367 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
3371 wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3372 WL_ERR(("bcn_timeout error (%d)\n", err));
3373 goto dongle_rom_out;
3376 /* Enable/Disable built-in roaming to allow supplicant
3377 to take care of roaming */
3378 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
3380 (err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3381 WL_ERR(("roam_off error (%d)\n", err));
3382 goto dongle_rom_out;
3388 static int32 wl_dongle_eventmsg(struct net_device *ndev)
3391 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3393 s8 eventmask[WL_EVENTING_MASK_LEN];
3396 /* Setup event_msgs */
3397 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3400 (err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf)))) {
3401 WL_ERR(("Get event_msgs error (%d)\n", err));
3402 goto dongle_eventmsg_out;
3404 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
3406 setbit(eventmask, WLC_E_SET_SSID);
3407 setbit(eventmask, WLC_E_PRUNE);
3408 setbit(eventmask, WLC_E_AUTH);
3409 setbit(eventmask, WLC_E_REASSOC);
3410 setbit(eventmask, WLC_E_REASSOC_IND);
3411 setbit(eventmask, WLC_E_DEAUTH_IND);
3412 setbit(eventmask, WLC_E_DISASSOC_IND);
3413 setbit(eventmask, WLC_E_DISASSOC);
3414 setbit(eventmask, WLC_E_JOIN);
3415 setbit(eventmask, WLC_E_ASSOC_IND);
3416 setbit(eventmask, WLC_E_PSK_SUP);
3417 setbit(eventmask, WLC_E_LINK);
3418 setbit(eventmask, WLC_E_NDIS_LINK);
3419 setbit(eventmask, WLC_E_MIC_ERROR);
3420 setbit(eventmask, WLC_E_PMKID_CACHE);
3421 setbit(eventmask, WLC_E_TXFAIL);
3422 setbit(eventmask, WLC_E_JOIN_START);
3423 setbit(eventmask, WLC_E_SCAN_COMPLETE);
3425 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
3428 (err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3429 WL_ERR(("Set event_msgs error (%d)\n", err));
3430 goto dongle_eventmsg_out;
3433 dongle_eventmsg_out:
3438 wl_dongle_scantime(struct net_device *ndev, int32 scan_assoc_time,
3439 int32 scan_unassoc_time)
3444 wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
3445 sizeof(scan_assoc_time)))) {
3446 if (err == -EOPNOTSUPP) {
3447 WL_INFO(("Scan assoc time is not supported\n"));
3449 WL_ERR(("Scan assoc time error (%d)\n", err));
3451 goto dongle_scantime_out;
3454 wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
3455 sizeof(scan_unassoc_time)))) {
3456 if (err == -EOPNOTSUPP) {
3457 WL_INFO(("Scan unassoc time is not supported\n"));
3459 WL_ERR(("Scan unassoc time error (%d)\n", err));
3461 goto dongle_scantime_out;
3464 dongle_scantime_out:
3469 wl_dongle_offload(struct net_device *ndev, int32 arpoe, int32 arp_ol)
3471 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3475 /* Set ARP offload */
3476 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
3477 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3478 if (err == -EOPNOTSUPP)
3479 WL_INFO(("arpoe is not supported\n"));
3481 WL_ERR(("arpoe error (%d)\n", err));
3483 goto dongle_offload_out;
3485 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
3486 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3487 if (err == -EOPNOTSUPP)
3488 WL_INFO(("arp_ol is not supported\n"));
3490 WL_ERR(("arp_ol error (%d)\n", err));
3492 goto dongle_offload_out;
3499 static int32 wl_pattern_atoh(s8 *src, s8 *dst)
3501 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
3503 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
3504 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
3507 src = src + 2; /* Skip past 0x */
3508 if (strlen(src) % 2 != 0) {
3509 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
3512 for (i = 0; *src != '\0'; i++) {
3514 strncpy(num, src, 2);
3516 dst[i] = (u8) strtoul(num, NULL, 16);
3522 static int32 wl_dongle_filter(struct net_device *ndev, uint32 filter_mode)
3524 s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" +
3527 struct wl_pkt_filter pkt_filter;
3528 struct wl_pkt_filter *pkt_filterp;
3532 uint32 pattern_size;
3536 /* add a default packet filter pattern */
3537 str = "pkt_filter_add";
3538 str_len = strlen(str);
3539 strncpy(buf, str, str_len);
3540 buf[str_len] = '\0';
3541 buf_len = str_len + 1;
3543 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
3545 /* Parse packet filter id. */
3546 pkt_filter.id = htod32(100);
3548 /* Parse filter polarity. */
3549 pkt_filter.negate_match = htod32(0);
3551 /* Parse filter type. */
3552 pkt_filter.type = htod32(0);
3554 /* Parse pattern filter offset. */
3555 pkt_filter.u.pattern.offset = htod32(0);
3557 /* Parse pattern filter mask. */
3558 mask_size = htod32(wl_pattern_atoh("0xff",
3559 (char *)pkt_filterp->u.pattern.
3562 /* Parse pattern filter pattern. */
3563 pattern_size = htod32(wl_pattern_atoh("0x00",
3564 (char *)&pkt_filterp->u.pattern.
3565 mask_and_pattern[mask_size]));
3567 if (mask_size != pattern_size) {
3568 WL_ERR(("Mask and pattern not the same size\n"));
3570 goto dongle_filter_out;
3573 pkt_filter.u.pattern.size_bytes = mask_size;
3574 buf_len += WL_PKT_FILTER_FIXED_LEN;
3575 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
3577 /* Keep-alive attributes are set in local
3578 * variable (keep_alive_pkt), and
3579 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
3580 * guarantee that the buffer is properly aligned.
3582 memcpy((char *)pkt_filterp, &pkt_filter,
3583 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
3585 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len))) {
3586 if (err == -EOPNOTSUPP) {
3587 WL_INFO(("filter not supported\n"));
3589 WL_ERR(("filter (%d)\n", err));
3591 goto dongle_filter_out;
3594 /* set mode to allow pattern */
3595 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
3597 if ((err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
3598 if (err == -EOPNOTSUPP) {
3599 WL_INFO(("filter_mode not supported\n"));
3601 WL_ERR(("filter_mode (%d)\n", err));
3603 goto dongle_filter_out;
3609 #endif /* !EMBEDDED_PLATFORM */
3611 int32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
3614 #define DHD_SDALIGN 32
3616 struct net_device *ndev;
3617 struct wireless_dev *wdev;
3623 ndev = wl_to_ndev(wl);
3624 wdev = ndev->ieee80211_ptr;
3628 #ifndef EMBEDDED_PLATFORM
3629 if (unlikely((err = wl_dongle_up(ndev, 0))))
3630 goto default_conf_out;
3631 if (unlikely((err = wl_dongle_country(ndev, 0))))
3632 goto default_conf_out;
3633 if (unlikely((err = wl_dongle_power(ndev, PM_FAST))))
3634 goto default_conf_out;
3635 if (unlikely((err = wl_dongle_glom(ndev, 0, DHD_SDALIGN))))
3636 goto default_conf_out;
3637 if (unlikely((err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3))))
3638 goto default_conf_out;
3639 if (unlikely((err = wl_dongle_eventmsg(ndev))))
3640 goto default_conf_out;
3642 wl_dongle_scantime(ndev, 40, 80);
3643 wl_dongle_offload(ndev, 1, 0xf);
3644 wl_dongle_filter(ndev, 1);
3645 #endif /* !EMBEDDED_PLATFORM */
3647 err = wl_dongle_mode(ndev, wdev->iftype);
3648 if (unlikely(err && err != -EINPROGRESS))
3649 goto default_conf_out;
3650 if (unlikely((err = wl_dongle_probecap(wl))))
3651 goto default_conf_out;
3653 /* -EINPROGRESS: Call commit handler */
3659 wl->dongle_up = TRUE;
3665 static int32 wl_update_wiphybands(struct wl_priv *wl)
3667 struct wiphy *wiphy;
3674 wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
3675 sizeof(phy_list)))) {
3676 WL_ERR(("error (%d)\n", err));
3680 phy = ((char *)&phy_list)[1];
3681 WL_DBG(("%c phy\n", phy));
3682 if (phy == 'n' || phy == 'a') {
3683 wiphy = wl_to_wiphy(wl);
3684 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3690 static int32 __wl_cfg80211_up(struct wl_priv *wl)
3694 if (unlikely(err = wl_config_dongle(wl, FALSE)))
3697 wl_invoke_iscan(wl);
3698 set_bit(WL_STATUS_READY, &wl->status);
3702 static int32 __wl_cfg80211_down(struct wl_priv *wl)
3706 /* Check if cfg80211 interface is already down */
3707 if (!test_bit(WL_STATUS_READY, &wl->status))
3708 return err; /* it is even not ready */
3710 set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3712 if (wl->scan_request) {
3713 cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE
3715 wl->scan_request = NULL;
3717 clear_bit(WL_STATUS_READY, &wl->status);
3718 clear_bit(WL_STATUS_SCANNING, &wl->status);
3719 clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
3720 clear_bit(WL_STATUS_CONNECTED, &wl->status);
3725 int32 wl_cfg80211_up(void)
3731 mutex_lock(&wl->usr_sync);
3732 err = __wl_cfg80211_up(wl);
3733 mutex_unlock(&wl->usr_sync);
3738 int32 wl_cfg80211_down(void)
3744 mutex_lock(&wl->usr_sync);
3745 err = __wl_cfg80211_down(wl);
3746 mutex_unlock(&wl->usr_sync);
3751 static int32 wl_dongle_probecap(struct wl_priv *wl)
3755 if (unlikely((err = wl_update_wiphybands(wl))))
3761 static void *wl_read_prof(struct wl_priv *wl, int32 item)
3765 return &wl->profile->sec;
3767 return &wl->profile->active;
3769 return &wl->profile->bssid;
3771 return &wl->profile->ssid;
3773 WL_ERR(("invalid item (%d)\n", item));
3778 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
3782 struct wlc_ssid *ssid;
3786 ssid = (wlc_ssid_t *) data;
3787 memset(wl->profile->ssid.SSID, 0,
3788 sizeof(wl->profile->ssid.SSID));
3789 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
3790 wl->profile->ssid.SSID_len = ssid->SSID_len;
3794 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
3796 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
3799 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
3802 wl->profile->active = *(bool *) data;
3805 WL_ERR(("unsupported item (%d)\n", item));
3813 void wl_cfg80211_dbg_level(uint32 level)
3816 * prohibit to change debug level
3817 * by insmod parameter.
3818 * eventually debug level will be configured
3819 * in compile time by using CONFIG_XXX
3821 /* wl_dbg_level = level; */
3824 static bool wl_is_ibssmode(struct wl_priv *wl)
3826 return wl->conf->mode == WL_MODE_IBSS;
3829 static bool wl_is_ibssstarter(struct wl_priv *wl)
3831 return wl->ibss_starter;
3834 static void wl_rst_ie(struct wl_priv *wl)
3836 struct wl_ie *ie = wl_to_ie(wl);
3841 static int32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
3843 struct wl_ie *ie = wl_to_ie(wl);
3846 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3847 WL_ERR(("ei crosses buffer boundary\n"));
3850 ie->buf[ie->offset] = t;
3851 ie->buf[ie->offset + 1] = l;
3852 memcpy(&ie->buf[ie->offset + 2], v, l);
3853 ie->offset += l + 2;
3858 static int32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, uint16 ie_size)
3860 struct wl_ie *ie = wl_to_ie(wl);
3863 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
3864 WL_ERR(("ei_stream crosses buffer boundary\n"));
3867 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
3868 ie->offset += ie_size;
3873 static int32 wl_cp_ie(struct wl_priv *wl, u8 *dst, uint16 dst_size)
3875 struct wl_ie *ie = wl_to_ie(wl);
3878 if (unlikely(ie->offset > dst_size)) {
3879 WL_ERR(("dst_size is not enough\n"));
3882 memcpy(dst, &ie->buf[0], ie->offset);
3887 static uint32 wl_get_ielen(struct wl_priv *wl)
3889 struct wl_ie *ie = wl_to_ie(wl);
3894 static void wl_link_up(struct wl_priv *wl)
3899 static void wl_link_down(struct wl_priv *wl)
3901 struct wl_connect_info *conn_info = wl_to_conn(wl);
3903 wl->link_up = FALSE;
3904 kfree(conn_info->req_ie);
3905 conn_info->req_ie = NULL;
3906 conn_info->req_ie_len = 0;
3907 kfree(conn_info->resp_ie);
3908 conn_info->resp_ie = NULL;
3909 conn_info->resp_ie_len = 0;
3912 static void wl_lock_eq(struct wl_priv *wl)
3914 spin_lock_irq(&wl->eq_lock);
3917 static void wl_unlock_eq(struct wl_priv *wl)
3919 spin_unlock_irq(&wl->eq_lock);
3922 static void wl_init_eq_lock(struct wl_priv *wl)
3924 spin_lock_init(&wl->eq_lock);
3927 static void wl_delay(uint32 ms)
3929 if (ms < 1000 / HZ) {
3937 static void wl_set_drvdata(struct wl_dev *dev, void *data)
3939 dev->driver_data = data;
3942 static void *wl_get_drvdata(struct wl_dev *dev)
3944 return dev->driver_data;
3947 int32 wl_cfg80211_read_fw(s8 *buf, uint32 size)
3949 const struct firmware *fw_entry;
3954 fw_entry = wl->fw->fw_entry;
3956 if (fw_entry->size < wl->fw->ptr + size)
3957 size = fw_entry->size - wl->fw->ptr;
3959 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
3960 wl->fw->ptr += size;
3964 void wl_cfg80211_release_fw(void)
3969 release_firmware(wl->fw->fw_entry);
3973 void *wl_cfg80211_request_fw(s8 *file_name)
3976 const struct firmware *fw_entry = NULL;
3979 WL_DBG(("file name : \"%s\"\n", file_name));
3982 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
3985 request_firmware(&wl->fw->fw_entry, file_name,
3986 &wl_cfg80211_get_sdio_func()->dev))) {
3987 WL_ERR(("Could not download fw (%d)\n", err));
3990 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
3991 fw_entry = wl->fw->fw_entry;
3993 WL_DBG(("fw size (%d), data (%p)\n", fw_entry->size,
3996 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
3999 request_firmware(&wl->fw->fw_entry, file_name,
4000 &wl_cfg80211_get_sdio_func()->dev))) {
4001 WL_ERR(("Could not download nvram (%d)\n", err));
4004 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
4005 fw_entry = wl->fw->fw_entry;
4007 WL_DBG(("nvram size (%d), data (%p)\n", fw_entry->size,
4011 WL_DBG(("Downloading already done. Nothing to do more\n"));
4016 if (unlikely(err)) {
4020 return (void *)fw_entry->data;
4023 s8 *wl_cfg80211_get_fwname(void)
4028 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
4029 return wl->fw->fw_name;
4032 s8 *wl_cfg80211_get_nvramname(void)
4037 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
4038 return wl->fw->nvram_name;