2 * Linux cfg80211 driver
4 * Copyright (C) 1999-2011, Broadcom Corporation
6 * Unless you and Broadcom execute a separate written software license
7 * agreement governing use of this software, this software is licensed to you
8 * under the terms of the GNU General Public License version 2 (the "GPL"),
9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 * following added to such license:
12 * As a special exception, the copyright holders of this software give you
13 * permission to link this software with independent modules, and to copy and
14 * distribute the resulting executable under terms of your choice, provided that
15 * you also meet, for each linked independent module, the terms and conditions of
16 * the license of that module. An independent module is a module which is not
17 * derived from this software. The special exception does not apply to any
18 * modifications of the software.
20 * Notwithstanding the above, under no circumstances may you combine this
21 * software in any way with any other Broadcom software provided under a license
22 * other than the GPL, without Broadcom's express prior written consent.
24 * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $
30 #include <linux/kernel.h>
33 * sys proc file will be REMOVED in next release
35 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
36 #include <linux/sysctl.h>
41 #include <bcmendian.h>
42 #include <proto/ethernet.h>
43 #include <proto/802.11.h>
44 #include <linux/if_arp.h>
45 #include <asm/uaccess.h>
47 #include <dngl_stats.h>
52 #include <proto/ethernet.h>
53 #include <dngl_stats.h>
56 #include <linux/kernel.h>
57 #include <linux/kthread.h>
58 #include <linux/netdevice.h>
59 #include <linux/sched.h>
60 #include <linux/etherdevice.h>
61 #include <linux/wireless.h>
62 #include <linux/ieee80211.h>
63 #include <linux/wait.h>
64 #include <net/cfg80211.h>
66 #include <net/rtnetlink.h>
67 #include <linux/mmc/sdio_func.h>
68 #include <linux/firmware.h>
72 #include <wldev_common.h>
73 #include <wl_cfg80211.h>
74 #include <wl_cfgp2p.h>
76 static struct sdio_func *cfg80211_sdio_func;
77 static struct wl_dev *wl_cfg80211_dev;
79 u32 wl_dbg_level = WL_DBG_ERR;
81 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
82 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
83 #define WL_TRACE(a) printk("%s ", __FUNCTION__); printk a
84 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
85 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
86 #define MAX_WAIT_TIME 3000
87 static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
89 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
90 #define MAC_STRING_LEN (sizeof(u8) * 17)
91 u8 wl_sysctl_macstring[2][MAC_STRING_LEN];
93 static ctl_table wl_sysctl_child[] = {
95 .procname = "p2p_dev_addr",
96 .data = &wl_sysctl_macstring[0],
97 .maxlen = MAC_STRING_LEN,
100 .proc_handler = proc_dostring,
103 .procname = "p2p_int_addr",
104 .data = &wl_sysctl_macstring[1],
105 .maxlen = MAC_STRING_LEN,
108 .proc_handler = proc_dostring,
112 static ctl_table wl_sysctl_table[] = {
118 .child = wl_sysctl_child,
119 .proc_handler = NULL,
123 static struct ctl_table_header *wl_sysctl_hdr;
124 #endif /* CONFIG_SYSCTL */
126 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
127 * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
128 * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165).
129 * With respect to these flags, wpa_supplicant doesn't start p2p operations on 5GHz channels.
130 * All the chnages in world regulatory domain are to be done here.
132 static const struct ieee80211_regdomain brcm_regdom = {
136 /* IEEE 802.11b/g, channels 1..11 */
137 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
138 /* IEEE 802.11b/g, channels 12..13. No HT40
141 REG_RULE(2467-10, 2472+10, 20, 6, 20,
142 NL80211_RRF_PASSIVE_SCAN |
143 NL80211_RRF_NO_IBSS),
144 /* IEEE 802.11 channel 14 - Only JP enables
145 * this and for 802.11b only
147 REG_RULE(2484-10, 2484+10, 20, 6, 20,
148 NL80211_RRF_PASSIVE_SCAN |
149 NL80211_RRF_NO_IBSS |
150 NL80211_RRF_NO_OFDM),
151 /* IEEE 802.11a, channel 36..48 */
152 REG_RULE(5180-10, 5240+10, 40, 6, 20, 0),
154 /* NB: 5260 MHz - 5700 MHz requies DFS */
156 /* IEEE 802.11a, channel 149..165 */
157 REG_RULE(5745-10, 5825+10, 40, 6, 20, 0), }
161 /* Data Element Definitions */
162 #define WPS_ID_CONFIG_METHODS 0x1008
163 #define WPS_ID_REQ_TYPE 0x103A
164 #define WPS_ID_DEVICE_NAME 0x1011
165 #define WPS_ID_VERSION 0x104A
166 #define WPS_ID_DEVICE_PWD_ID 0x1012
167 #define WPS_ID_REQ_DEV_TYPE 0x106A
168 #define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053
169 #define WPS_ID_PRIM_DEV_TYPE 0x1054
171 /* Device Password ID */
172 #define DEV_PW_DEFAULT 0x0000
173 #define DEV_PW_USER_SPECIFIED 0x0001,
174 #define DEV_PW_MACHINE_SPECIFIED 0x0002
175 #define DEV_PW_REKEY 0x0003
176 #define DEV_PW_PUSHBUTTON 0x0004
177 #define DEV_PW_REGISTRAR_SPECIFIED 0x0005
180 #define WPS_CONFIG_USBA 0x0001
181 #define WPS_CONFIG_ETHERNET 0x0002
182 #define WPS_CONFIG_LABEL 0x0004
183 #define WPS_CONFIG_DISPLAY 0x0008
184 #define WPS_CONFIG_EXT_NFC_TOKEN 0x0010
185 #define WPS_CONFIG_INT_NFC_TOKEN 0x0020
186 #define WPS_CONFIG_NFC_INTERFACE 0x0040
187 #define WPS_CONFIG_PUSHBUTTON 0x0080
188 #define WPS_CONFIG_KEYPAD 0x0100
189 #define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
190 #define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
191 #define WPS_CONFIG_VIRT_DISPLAY 0x2008
192 #define WPS_CONFIG_PHY_DISPLAY 0x4008
195 * cfg80211_ops api/callback list
197 static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
198 const struct ether_addr *sa, const struct ether_addr *bssid,
199 u8 **pheader, u32 *body_len, u8 *pbody);
200 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
201 struct cfg80211_scan_request *request,
202 struct cfg80211_ssid *this_ssid);
203 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
204 struct cfg80211_scan_request *request);
205 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
206 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
207 struct cfg80211_ibss_params *params);
208 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
209 struct net_device *dev);
210 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
211 struct net_device *dev, u8 *mac,
212 struct station_info *sinfo);
213 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
214 struct net_device *dev, bool enabled,
216 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
217 struct cfg80211_connect_params *sme);
218 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
220 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
221 enum nl80211_tx_power_setting type,
223 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
224 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
225 struct net_device *dev,
226 u8 key_idx, bool unicast, bool multicast);
227 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
228 u8 key_idx, bool pairwise, const u8 *mac_addr,
229 struct key_params *params);
230 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
231 u8 key_idx, bool pairwise, const u8 *mac_addr);
232 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
233 u8 key_idx, bool pairwise, const u8 *mac_addr,
234 void *cookie, void (*callback) (void *cookie,
235 struct key_params *params));
236 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
237 struct net_device *dev, u8 key_idx);
238 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
239 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
240 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
242 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
244 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
245 struct cfg80211_pmksa *pmksa);
246 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
247 struct cfg80211_pmksa *pmksa);
248 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
249 struct net_device *dev);
250 static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted);
252 * event & event Q handlers for cfg80211 interfaces
254 static s32 wl_create_event_handler(struct wl_priv *wl);
255 static void wl_destroy_event_handler(struct wl_priv *wl);
256 static s32 wl_event_handler(void *data);
257 static void wl_init_eq(struct wl_priv *wl);
258 static void wl_flush_eq(struct wl_priv *wl);
259 static void wl_lock_eq(struct wl_priv *wl);
260 static void wl_unlock_eq(struct wl_priv *wl);
261 static void wl_init_eq_lock(struct wl_priv *wl);
262 static void wl_init_event_handler(struct wl_priv *wl);
263 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
264 static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
265 const wl_event_msg_t *msg, void *data);
266 static void wl_put_event(struct wl_event_q *e);
267 static void wl_wakeup_event(struct wl_priv *wl);
268 static s32 wl_notify_connect_status(struct wl_priv *wl,
269 struct net_device *ndev,
270 const wl_event_msg_t *e, void *data);
271 static s32 wl_notify_roaming_status(struct wl_priv *wl,
272 struct net_device *ndev,
273 const wl_event_msg_t *e, void *data);
274 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
275 const wl_event_msg_t *e, void *data);
276 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
277 const wl_event_msg_t *e, void *data, bool completed);
278 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
279 const wl_event_msg_t *e, void *data);
280 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
281 const wl_event_msg_t *e, void *data);
283 * register/deregister sdio function
285 struct sdio_func *wl_cfg80211_get_sdio_func(void);
286 static void wl_clear_sdio_func(void);
291 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
293 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
295 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
296 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
300 * cfg80211 set_wiphy_params utilities
302 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
303 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
304 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
307 * wl profile utilities
309 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
310 void *data, s32 item);
311 static void *wl_read_prof(struct wl_priv *wl, s32 item);
312 static void wl_init_prof(struct wl_profile *prof);
315 * cfg80211 connect utilites
317 static s32 wl_set_wpa_version(struct net_device *dev,
318 struct cfg80211_connect_params *sme);
319 static s32 wl_set_auth_type(struct net_device *dev,
320 struct cfg80211_connect_params *sme);
321 static s32 wl_set_set_cipher(struct net_device *dev,
322 struct cfg80211_connect_params *sme);
323 static s32 wl_set_key_mgmt(struct net_device *dev,
324 struct cfg80211_connect_params *sme);
325 static s32 wl_set_set_sharedkey(struct net_device *dev,
326 struct cfg80211_connect_params *sme);
327 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev);
328 static void wl_ch_to_chanspec(int ch,
329 struct wl_join_params *join_params, size_t *join_params_size);
332 * information element utilities
334 static void wl_rst_ie(struct wl_priv *wl);
335 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
336 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
337 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
338 static u32 wl_get_ielen(struct wl_priv *wl);
340 static s32 wl_mode_to_nl80211_iftype(s32 mode);
342 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
344 static void wl_free_wdev(struct wl_priv *wl);
346 static s32 wl_inform_bss(struct wl_priv *wl);
347 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
348 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev);
350 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
351 u8 key_idx, const u8 *mac_addr,
352 struct key_params *params);
354 * key indianess swap utilities
356 static void swap_key_from_BE(struct wl_wsec_key *key);
357 static void swap_key_to_BE(struct wl_wsec_key *key);
360 * wl_priv memory init/deinit utilities
362 static s32 wl_init_priv_mem(struct wl_priv *wl);
363 static void wl_deinit_priv_mem(struct wl_priv *wl);
365 static void wl_delay(u32 ms);
368 * store/restore cfg80211 instance data
370 static void wl_set_drvdata(struct wl_dev *dev, void *data);
371 static void *wl_get_drvdata(struct wl_dev *dev);
374 * ibss mode utilities
376 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
377 static __used bool wl_is_ibssstarter(struct wl_priv *wl);
380 * dongle up/down , default configuration utilities
382 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
383 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
384 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
385 static void wl_link_up(struct wl_priv *wl);
386 static void wl_link_down(struct wl_priv *wl);
387 static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
388 static s32 __wl_cfg80211_up(struct wl_priv *wl);
389 static s32 __wl_cfg80211_down(struct wl_priv *wl);
390 static s32 wl_dongle_probecap(struct wl_priv *wl);
391 static void wl_init_conf(struct wl_conf *conf);
392 static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
393 static s32 wl_dongle_eventmsg(struct net_device *ndev);
396 * dongle configuration utilities
398 #ifndef EMBEDDED_PLATFORM
399 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
400 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
401 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
402 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
404 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
406 static s32 wl_dongle_eventmsg(struct net_device *ndev);
407 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
408 s32 scan_unassoc_time);
409 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
411 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
412 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
413 static s32 wl_update_wiphybands(struct wl_priv *wl);
414 #endif /* !EMBEDDED_PLATFORM */
415 static __used void wl_dongle_poweron(struct wl_priv *wl);
416 static __used void wl_dongle_poweroff(struct wl_priv *wl);
417 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
422 static void wl_iscan_timer(unsigned long data);
423 static void wl_term_iscan(struct wl_priv *wl);
424 static s32 wl_init_scan(struct wl_priv *wl);
425 static s32 wl_iscan_thread(void *data);
426 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
428 static s32 wl_do_iscan(struct wl_priv *wl);
429 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
430 static s32 wl_invoke_iscan(struct wl_priv *wl);
431 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
432 struct wl_scan_results **bss_list);
433 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
434 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan);
435 static s32 wl_iscan_done(struct wl_priv *wl);
436 static s32 wl_iscan_pending(struct wl_priv *wl);
437 static s32 wl_iscan_inprogress(struct wl_priv *wl);
438 static s32 wl_iscan_aborted(struct wl_priv *wl);
441 * fw/nvram downloading handler
443 static void wl_init_fw(struct wl_fw_ctrl *fw);
446 * find most significant bit set
448 static __used u32 wl_find_msb(u16 bit16);
451 * update pmklist to dongle
453 static __used s32 wl_update_pmklist(struct net_device *dev,
454 struct wl_pmk_list *pmk_list, s32 err);
459 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
460 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
465 static int wl_setup_rfkill(struct wl_priv *wl, bool setup);
466 static int wl_rfkill_set(void *data, bool blocked);
469 * Some external functions, TODO: move them to dhd_linux.h
471 int dhd_add_monitor(char *name, struct net_device **new_ndev);
472 int dhd_del_monitor(struct net_device *ndev);
473 int dhd_monitor_init(void *dhd_pub);
474 int dhd_monitor_uninit(void);
475 int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
477 #define WL_PRIV_GET() \
479 struct wl_iface *ci = NULL; \
480 if (unlikely(!(wl_cfg80211_dev && \
481 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
482 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
488 #define CHECK_SYS_UP() \
490 struct wl_priv *wl = WL_PRIV_GET(); \
491 if (unlikely(!wl_get_drv_status(wl, READY))) { \
492 WL_INFO(("device is not ready : status (%d)\n", \
499 #define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
500 (akm) == RSN_AKM_UNSPECIFIED || \
501 (akm) == RSN_AKM_PSK)
504 extern int dhd_wait_pend8021x(struct net_device *dev);
506 #if (WL_DBG_LEVEL > 0)
507 #define WL_DBG_ESTR_MAX 50
508 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
509 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
510 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
511 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
512 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
513 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
514 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
515 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
517 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
519 "RADIO", "PSM_WATCHDOG", "WLC_E_CCX_ASSOC_START", "WLC_E_CCX_ASSOC_ABORT",
521 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
522 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
523 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
524 "WLC_E_BTA_HCI_EVENT", "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE",
525 "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG",
526 "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND",
527 "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED",
528 "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT",
529 "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE",
530 "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP",
531 "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE"
533 #endif /* WL_DBG_LEVEL */
535 #define CHAN2G(_channel, _freq, _flags) { \
536 .band = IEEE80211_BAND_2GHZ, \
537 .center_freq = (_freq), \
538 .hw_value = (_channel), \
540 .max_antenna_gain = 0, \
544 #define CHAN5G(_channel, _flags) { \
545 .band = IEEE80211_BAND_5GHZ, \
546 .center_freq = 5000 + (5 * (_channel)), \
547 .hw_value = (_channel), \
549 .max_antenna_gain = 0, \
553 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
554 #define RATETAB_ENT(_rateid, _flags) \
556 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
557 .hw_value = (_rateid), \
561 static struct ieee80211_rate __wl_rates[] = {
562 RATETAB_ENT(WLC_RATE_1M, 0),
563 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
564 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
565 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
566 RATETAB_ENT(WLC_RATE_6M, 0),
567 RATETAB_ENT(WLC_RATE_9M, 0),
568 RATETAB_ENT(WLC_RATE_12M, 0),
569 RATETAB_ENT(WLC_RATE_18M, 0),
570 RATETAB_ENT(WLC_RATE_24M, 0),
571 RATETAB_ENT(WLC_RATE_36M, 0),
572 RATETAB_ENT(WLC_RATE_48M, 0),
573 RATETAB_ENT(WLC_RATE_54M, 0)
576 #define wl_a_rates (__wl_rates + 4)
577 #define wl_a_rates_size 8
578 #define wl_g_rates (__wl_rates + 0)
579 #define wl_g_rates_size 12
581 static struct ieee80211_channel __wl_2ghz_channels[] = {
598 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
599 CHAN5G(34, 0), CHAN5G(36, 0),
600 CHAN5G(38, 0), CHAN5G(40, 0),
601 CHAN5G(42, 0), CHAN5G(44, 0),
602 CHAN5G(46, 0), CHAN5G(48, 0),
603 CHAN5G(52, 0), CHAN5G(56, 0),
604 CHAN5G(60, 0), CHAN5G(64, 0),
605 CHAN5G(100, 0), CHAN5G(104, 0),
606 CHAN5G(108, 0), CHAN5G(112, 0),
607 CHAN5G(116, 0), CHAN5G(120, 0),
608 CHAN5G(124, 0), CHAN5G(128, 0),
609 CHAN5G(132, 0), CHAN5G(136, 0),
610 CHAN5G(140, 0), CHAN5G(149, 0),
611 CHAN5G(153, 0), CHAN5G(157, 0),
612 CHAN5G(161, 0), CHAN5G(165, 0),
613 CHAN5G(184, 0), CHAN5G(188, 0),
614 CHAN5G(192, 0), CHAN5G(196, 0),
615 CHAN5G(200, 0), CHAN5G(204, 0),
616 CHAN5G(208, 0), CHAN5G(212, 0),
620 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
621 CHAN5G(32, 0), CHAN5G(34, 0),
622 CHAN5G(36, 0), CHAN5G(38, 0),
623 CHAN5G(40, 0), CHAN5G(42, 0),
624 CHAN5G(44, 0), CHAN5G(46, 0),
625 CHAN5G(48, 0), CHAN5G(50, 0),
626 CHAN5G(52, 0), CHAN5G(54, 0),
627 CHAN5G(56, 0), CHAN5G(58, 0),
628 CHAN5G(60, 0), CHAN5G(62, 0),
629 CHAN5G(64, 0), CHAN5G(66, 0),
630 CHAN5G(68, 0), CHAN5G(70, 0),
631 CHAN5G(72, 0), CHAN5G(74, 0),
632 CHAN5G(76, 0), CHAN5G(78, 0),
633 CHAN5G(80, 0), CHAN5G(82, 0),
634 CHAN5G(84, 0), CHAN5G(86, 0),
635 CHAN5G(88, 0), CHAN5G(90, 0),
636 CHAN5G(92, 0), CHAN5G(94, 0),
637 CHAN5G(96, 0), CHAN5G(98, 0),
638 CHAN5G(100, 0), CHAN5G(102, 0),
639 CHAN5G(104, 0), CHAN5G(106, 0),
640 CHAN5G(108, 0), CHAN5G(110, 0),
641 CHAN5G(112, 0), CHAN5G(114, 0),
642 CHAN5G(116, 0), CHAN5G(118, 0),
643 CHAN5G(120, 0), CHAN5G(122, 0),
644 CHAN5G(124, 0), CHAN5G(126, 0),
645 CHAN5G(128, 0), CHAN5G(130, 0),
646 CHAN5G(132, 0), CHAN5G(134, 0),
647 CHAN5G(136, 0), CHAN5G(138, 0),
648 CHAN5G(140, 0), CHAN5G(142, 0),
649 CHAN5G(144, 0), CHAN5G(145, 0),
650 CHAN5G(146, 0), CHAN5G(147, 0),
651 CHAN5G(148, 0), CHAN5G(149, 0),
652 CHAN5G(150, 0), CHAN5G(151, 0),
653 CHAN5G(152, 0), CHAN5G(153, 0),
654 CHAN5G(154, 0), CHAN5G(155, 0),
655 CHAN5G(156, 0), CHAN5G(157, 0),
656 CHAN5G(158, 0), CHAN5G(159, 0),
657 CHAN5G(160, 0), CHAN5G(161, 0),
658 CHAN5G(162, 0), CHAN5G(163, 0),
659 CHAN5G(164, 0), CHAN5G(165, 0),
660 CHAN5G(166, 0), CHAN5G(168, 0),
661 CHAN5G(170, 0), CHAN5G(172, 0),
662 CHAN5G(174, 0), CHAN5G(176, 0),
663 CHAN5G(178, 0), CHAN5G(180, 0),
664 CHAN5G(182, 0), CHAN5G(184, 0),
665 CHAN5G(186, 0), CHAN5G(188, 0),
666 CHAN5G(190, 0), CHAN5G(192, 0),
667 CHAN5G(194, 0), CHAN5G(196, 0),
668 CHAN5G(198, 0), CHAN5G(200, 0),
669 CHAN5G(202, 0), CHAN5G(204, 0),
670 CHAN5G(206, 0), CHAN5G(208, 0),
671 CHAN5G(210, 0), CHAN5G(212, 0),
672 CHAN5G(214, 0), CHAN5G(216, 0),
673 CHAN5G(218, 0), CHAN5G(220, 0),
674 CHAN5G(222, 0), CHAN5G(224, 0),
675 CHAN5G(226, 0), CHAN5G(228, 0)
678 static struct ieee80211_supported_band __wl_band_2ghz = {
679 .band = IEEE80211_BAND_2GHZ,
680 .channels = __wl_2ghz_channels,
681 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
682 .bitrates = wl_g_rates,
683 .n_bitrates = wl_g_rates_size
686 static struct ieee80211_supported_band __wl_band_5ghz_a = {
687 .band = IEEE80211_BAND_5GHZ,
688 .channels = __wl_5ghz_a_channels,
689 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
690 .bitrates = wl_a_rates,
691 .n_bitrates = wl_a_rates_size
694 static struct ieee80211_supported_band __wl_band_5ghz_n = {
695 .band = IEEE80211_BAND_5GHZ,
696 .channels = __wl_5ghz_n_channels,
697 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
698 .bitrates = wl_a_rates,
699 .n_bitrates = wl_a_rates_size
702 static const u32 __wl_cipher_suites[] = {
703 WLAN_CIPHER_SUITE_WEP40,
704 WLAN_CIPHER_SUITE_WEP104,
705 WLAN_CIPHER_SUITE_TKIP,
706 WLAN_CIPHER_SUITE_CCMP,
707 WLAN_CIPHER_SUITE_AES_CMAC
710 /* There isn't a lot of sense in it, but you can transmit anything you like */
711 static const struct ieee80211_txrx_stypes
712 wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
713 [NL80211_IFTYPE_ADHOC] = {
715 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
717 [NL80211_IFTYPE_STATION] = {
719 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
720 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
722 [NL80211_IFTYPE_AP] = {
724 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
725 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
726 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
727 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
728 BIT(IEEE80211_STYPE_AUTH >> 4) |
729 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
730 BIT(IEEE80211_STYPE_ACTION >> 4)
732 [NL80211_IFTYPE_AP_VLAN] = {
735 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
736 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
737 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
738 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
739 BIT(IEEE80211_STYPE_AUTH >> 4) |
740 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
741 BIT(IEEE80211_STYPE_ACTION >> 4)
743 [NL80211_IFTYPE_P2P_CLIENT] = {
745 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
746 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
748 [NL80211_IFTYPE_P2P_GO] = {
750 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
751 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
752 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
753 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
754 BIT(IEEE80211_STYPE_AUTH >> 4) |
755 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
756 BIT(IEEE80211_STYPE_ACTION >> 4)
760 static void swap_key_from_BE(struct wl_wsec_key *key)
762 key->index = htod32(key->index);
763 key->len = htod32(key->len);
764 key->algo = htod32(key->algo);
765 key->flags = htod32(key->flags);
766 key->rxiv.hi = htod32(key->rxiv.hi);
767 key->rxiv.lo = htod16(key->rxiv.lo);
768 key->iv_initialized = htod32(key->iv_initialized);
771 static void swap_key_to_BE(struct wl_wsec_key *key)
773 key->index = dtoh32(key->index);
774 key->len = dtoh32(key->len);
775 key->algo = dtoh32(key->algo);
776 key->flags = dtoh32(key->flags);
777 key->rxiv.hi = dtoh32(key->rxiv.hi);
778 key->rxiv.lo = dtoh16(key->rxiv.lo);
779 key->iv_initialized = dtoh32(key->iv_initialized);
782 /* For debug: Dump the contents of the encoded wps ie buffe */
784 wl_validate_wps_ie(char *wps_ie, bool *pbc)
786 #define WPS_IE_FIXED_LEN 6
787 u16 len = (u16) wps_ie[TLV_LEN_OFF];
788 u8 *subel = wps_ie+ WPS_IE_FIXED_LEN;
792 u8 *valptr = (uint8*) &val;
794 WL_DBG(("wps_ie len=%d\n", len));
796 len -= 4; /* for the WPS IE's OUI, oui_type fields */
798 while (len >= 4) { /* must have attr id, attr len fields */
799 valptr[0] = *subel++;
800 valptr[1] = *subel++;
801 subelt_id = HTON16(val);
803 valptr[0] = *subel++;
804 valptr[1] = *subel++;
805 subelt_len = HTON16(val);
807 len -= 4; /* for the attr id, attr len fields */
808 len -= subelt_len; /* for the remaining fields in this attribute */
809 WL_DBG((" subel=%p, subelt_id=0x%x subelt_len=%u\n",
810 subel, subelt_id, subelt_len));
812 if (subelt_id == WPS_ID_VERSION) {
813 WL_DBG((" attr WPS_ID_VERSION: %u\n", *subel));
814 } else if (subelt_id == WPS_ID_REQ_TYPE) {
815 WL_DBG((" attr WPS_ID_REQ_TYPE: %u\n", *subel));
816 } else if (subelt_id == WPS_ID_CONFIG_METHODS) {
818 valptr[1] = *(subel + 1);
819 WL_DBG((" attr WPS_ID_CONFIG_METHODS: %x\n", HTON16(val)));
820 } else if (subelt_id == WPS_ID_DEVICE_NAME) {
822 memcpy(devname, subel, subelt_len);
823 devname[subelt_len] = '\0';
824 WL_DBG((" attr WPS_ID_DEVICE_NAME: %s (len %u)\n",
825 devname, subelt_len));
826 } else if (subelt_id == WPS_ID_DEVICE_PWD_ID) {
828 valptr[1] = *(subel + 1);
829 WL_DBG((" attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val)));
830 *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false;
831 } else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) {
833 valptr[1] = *(subel + 1);
834 WL_DBG((" attr WPS_ID_PRIM_DEV_TYPE: cat=%u \n", HTON16(val)));
835 valptr[0] = *(subel + 6);
836 valptr[1] = *(subel + 7);
837 WL_DBG((" attr WPS_ID_PRIM_DEV_TYPE: subcat=%u\n", HTON16(val)));
838 } else if (subelt_id == WPS_ID_REQ_DEV_TYPE) {
840 valptr[1] = *(subel + 1);
841 WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: cat=%u\n", HTON16(val)));
842 valptr[0] = *(subel + 6);
843 valptr[1] = *(subel + 7);
844 WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val)));
845 } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) {
847 valptr[1] = *(subel + 1);
848 WL_DBG((" attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS"
849 ": cat=%u\n", HTON16(val)));
851 WL_DBG((" unknown attr 0x%x\n", subelt_id));
858 static struct net_device* wl_cfg80211_add_monitor_if(char *name)
861 struct net_device* ndev = NULL;
863 ret = dhd_add_monitor(name, &ndev);
864 WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev));
868 static struct net_device *
869 wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
870 enum nl80211_iftype type, u32 *flags,
871 struct vif_params *params)
879 struct wl_priv *wl = WL_PRIV_GET();
880 struct net_device *_ndev;
881 dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
882 int (*net_attach)(dhd_pub_t *dhdp, int ifidx);
884 WL_DBG(("if name: %s, type: %d\n", name, type));
886 case NL80211_IFTYPE_ADHOC:
887 case NL80211_IFTYPE_AP_VLAN:
888 case NL80211_IFTYPE_WDS:
889 case NL80211_IFTYPE_MESH_POINT:
890 WL_ERR(("Unsupported interface type\n"));
893 case NL80211_IFTYPE_MONITOR:
894 return wl_cfg80211_add_monitor_if(name);
895 case NL80211_IFTYPE_P2P_CLIENT:
896 case NL80211_IFTYPE_STATION:
897 wlif_type = WL_P2P_IF_CLIENT;
900 case NL80211_IFTYPE_P2P_GO:
901 case NL80211_IFTYPE_AP:
902 wlif_type = WL_P2P_IF_GO;
906 WL_ERR(("Unsupported interface type\n"));
912 WL_ERR(("name is NULL\n"));
915 if (wl->p2p_supported && (wlif_type != -1)) {
916 if (wl_get_p2p_status(wl, IF_DELETING) == 1) {
917 /* wait till IF_DEL is complete
918 * release the lock for the unregister to proceed
921 WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n",
923 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
924 (wl_get_p2p_status(wl, IF_DELETING) == false),
925 msecs_to_jiffies(MAX_WAIT_TIME));
927 /* put back the rtnl_lock again */
930 WL_ERR(("IF DEL is Success\n"));
933 WL_ERR(("%s: timeount < 0, return -EAGAIN\n", __func__));
934 return ERR_PTR(-EAGAIN);
937 if (!p2p_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
939 wl_cfgp2p_set_firm_p2p(wl);
940 wl_cfgp2p_init_discovery(wl);
943 memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
944 strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
945 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
947 /* Temporary use channel 11, in case GO will be changed with set_channel API */
948 chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
950 /* For P2P mode, use P2P-specific driver features to create the
951 * bss: "wl p2p_ifadd"
953 wl_set_p2p_status(wl, IF_ADD);
954 err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
957 return ERR_PTR(-ENOMEM);
959 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
960 (wl_get_p2p_status(wl, IF_ADD) == false),
961 msecs_to_jiffies(MAX_WAIT_TIME));
962 if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
964 struct wireless_dev *vwdev;
965 vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
966 if (unlikely(!vwdev)) {
967 WL_ERR(("Could not allocate wireless device\n"));
968 return ERR_PTR(-ENOMEM);
970 vwdev->wiphy = wl->wdev->wiphy;
971 WL_INFO((" virtual interface(%s) is created \n", wl->p2p->vir_ifname));
972 index = alloc_idx_vwdev(wl);
973 wl->vwdev[index] = vwdev;
975 (wlif_type == WL_P2P_IF_CLIENT) ? NL80211_IFTYPE_STATION
977 _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
978 _ndev->ieee80211_ptr = vwdev;
979 SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
980 vwdev->netdev = _ndev;
981 wl_set_drv_status(wl, READY);
982 wl->p2p->vif_created = true;
983 set_mode_by_netdev(wl, _ndev, mode);
984 wl = wdev_to_wl(vwdev);
985 net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
987 if (net_attach && !net_attach(dhd, _ndev->ifindex))
988 WL_DBG((" virtual interface(%s) is "
989 "created\n", wl->p2p->vir_ifname));
998 wl_clr_p2p_status(wl, IF_ADD);
999 WL_ERR((" virtual interface(%s) is not created \n", wl->p2p->vir_ifname));
1000 memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
1001 wl->p2p->vif_created = false;
1005 return ERR_PTR(-ENODEV);
1010 wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
1012 struct ether_addr p2p_mac;
1013 struct wl_priv *wl = WL_PRIV_GET();
1017 if (wl->p2p_supported) {
1018 memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
1019 if (wl->p2p->vif_created) {
1020 if (wl_get_drv_status(wl, SCANNING)) {
1021 wl_cfg80211_scan_abort(wl, dev);
1024 wl_cfgp2p_ifdel(wl, &p2p_mac);
1025 wl_set_p2p_status(wl, IF_DELETING);
1027 /* Wait for any pending scan req to get aborted from the sysioc context */
1028 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
1029 (wl->scan_request == false),
1030 msecs_to_jiffies(MAX_WAIT_TIME));
1032 if (timeout > 0 && (!wl->scan_request)) {
1033 WL_DBG(("IFDEL Operations Done"));
1035 WL_ERR(("IFDEL didn't complete properly"));
1037 ret = dhd_del_monitor(dev);
1044 wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
1045 enum nl80211_iftype type, u32 *flags,
1046 struct vif_params *params)
1055 struct wl_priv *wl = WL_PRIV_GET();
1056 WL_DBG(("Enter \n"));
1058 case NL80211_IFTYPE_MONITOR:
1059 case NL80211_IFTYPE_WDS:
1060 case NL80211_IFTYPE_MESH_POINT:
1062 WL_ERR(("type (%d) : currently we do not support this type\n",
1065 case NL80211_IFTYPE_ADHOC:
1066 mode = WL_MODE_IBSS;
1068 case NL80211_IFTYPE_STATION:
1069 case NL80211_IFTYPE_P2P_CLIENT:
1073 case NL80211_IFTYPE_AP:
1074 case NL80211_IFTYPE_AP_VLAN:
1075 case NL80211_IFTYPE_P2P_GO:
1085 set_mode_by_netdev(wl, ndev, mode);
1086 if (wl->p2p_supported && wl->p2p->vif_created) {
1087 WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
1089 chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
1090 wlif_type = ap ? WL_P2P_IF_GO : WL_P2P_IF_CLIENT;
1091 WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n",
1092 ndev->name, ap, infra, type));
1093 wl_set_p2p_status(wl, IF_CHANGING);
1094 wl_clr_p2p_status(wl, IF_CHANGED);
1095 err = wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
1096 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
1097 (wl_get_p2p_status(wl, IF_CHANGED) == true),
1098 msecs_to_jiffies(MAX_WAIT_TIME));
1099 set_mode_by_netdev(wl, ndev, mode);
1100 wl_clr_p2p_status(wl, IF_CHANGING);
1101 wl_clr_p2p_status(wl, IF_CHANGED);
1102 } else if (ndev == wl_to_prmry_ndev(wl) &&
1103 !wl_get_drv_status(wl, AP_CREATED)) {
1104 wl_set_drv_status(wl, AP_CREATING);
1106 !(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) {
1107 WL_ERR(("struct ap_saved_ie allocation failed\n"));
1111 WL_ERR(("Cannot change the interface for GO or SOFTAP\n"));
1116 ndev->ieee80211_ptr->iftype = type;
1121 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx,
1122 int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
1124 struct wl_priv *wl = WL_PRIV_GET();
1127 WL_ERR(("net is NULL\n"));
1130 if (wl->p2p_supported) {
1131 WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
1132 "new name: %s\n", net->name, wl->p2p->vir_ifname));
1133 /* Assign the net device to CONNECT BSSCFG */
1134 strncpy(net->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
1135 wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
1136 wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) =
1137 P2PAPI_BSSCFG_CONNECTION;
1138 wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach;
1139 wl_clr_p2p_status(wl, IF_ADD);
1141 wake_up_interruptible(&wl->dongle_event_wait);
1147 wl_cfg80211_ifdel_ops(struct net_device *net)
1149 struct wl_priv *wl = WL_PRIV_GET();
1151 if (!net || !net->name) {
1152 WL_DBG(("net is NULL\n"));
1156 if ((wl->p2p->vif_created) && (wl->scan_request)) {
1158 /* Abort any pending scan requests */
1159 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
1161 WL_INFO(("ESCAN COMPLETED\n"));
1162 wl_notify_escan_complete(wl, true);
1166 /* Wake up any waiting thread */
1167 wake_up_interruptible(&wl->dongle_event_wait);
1173 wl_cfg80211_notify_ifdel(struct net_device *net)
1175 struct wl_priv *wl = WL_PRIV_GET();
1178 if (wl->p2p->vif_created) {
1181 WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
1182 net->name, wl->p2p->vir_ifname));
1184 memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
1185 index = wl_cfgp2p_find_idx(wl, net);
1186 wl_to_p2p_bss_ndev(wl, index) = NULL;
1187 wl_to_p2p_bss_bssidx(wl, index) = 0;
1188 wl->p2p->vif_created = false;
1189 set_mode_by_netdev(wl, net, -1);
1190 wl_cfgp2p_clear_management_ie(wl,
1192 index = get_idx_vwdev_by_netdev(wl, net);
1193 WL_DBG(("index : %d\n", index));
1195 free_vwdev_by_index(wl, index);
1199 wl_clr_p2p_status(wl, IF_DELETING);
1201 /* Wake up any waiting thread */
1202 wake_up_interruptible(&wl->dongle_event_wait);
1208 wl_cfg80211_is_progress_ifadd(void)
1210 s32 is_progress = 0;
1211 struct wl_priv *wl = WL_PRIV_GET();
1212 if (wl_get_p2p_status(wl, IF_ADD))
1218 wl_cfg80211_is_progress_ifchange(void)
1220 s32 is_progress = 0;
1221 struct wl_priv *wl = WL_PRIV_GET();
1222 if (wl_get_p2p_status(wl, IF_CHANGING))
1229 wl_cfg80211_notify_ifchange(void)
1231 struct wl_priv *wl = WL_PRIV_GET();
1232 if (wl_get_p2p_status(wl, IF_CHANGING)) {
1233 wl_set_p2p_status(wl, IF_CHANGED);
1234 wake_up_interruptible(&wl->dongle_event_wait);
1239 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
1241 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
1242 params->bss_type = DOT11_BSSTYPE_ANY;
1243 params->scan_type = 0;
1244 params->nprobes = -1;
1245 params->active_time = -1;
1246 params->passive_time = -1;
1247 params->home_time = -1;
1248 params->channel_num = 0;
1250 params->nprobes = htod32(params->nprobes);
1251 params->active_time = htod32(params->active_time);
1252 params->passive_time = htod32(params->passive_time);
1253 params->home_time = htod32(params->home_time);
1254 if (ssid && ssid->SSID_len)
1255 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
1260 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
1263 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
1264 struct wl_iscan_params *params;
1267 if (ssid && ssid->SSID_len)
1268 params_size += sizeof(struct wlc_ssid);
1269 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
1270 if (unlikely(!params))
1272 memset(params, 0, params_size);
1273 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
1275 wl_iscan_prep(¶ms->params, ssid);
1277 params->version = htod32(ISCAN_REQ_VERSION);
1278 params->action = htod16(action);
1279 params->scan_duration = htod16(0);
1281 /* params_size += offsetof(wl_iscan_params_t, params); */
1282 err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
1283 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
1284 if (unlikely(err)) {
1285 if (err == -EBUSY) {
1286 WL_INFO(("system busy : iscan canceled\n"));
1288 WL_ERR(("error (%d)\n", err));
1295 static s32 wl_do_iscan(struct wl_priv *wl)
1297 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
1298 struct net_device *ndev = wl_to_prmry_ndev(wl);
1299 struct wlc_ssid ssid;
1303 /* Broadcast scan by default */
1304 memset(&ssid, 0, sizeof(ssid));
1306 iscan->state = WL_ISCAN_STATE_SCANING;
1308 passive_scan = wl->active_scan ? 0 : 1;
1309 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1310 &passive_scan, sizeof(passive_scan), false);
1311 if (unlikely(err)) {
1312 WL_DBG(("error (%d)\n", err));
1315 wl->iscan_kickstart = true;
1316 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
1317 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
1318 iscan->timer_on = 1;
1324 wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint16 action)
1327 s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
1328 wl_escan_params_t *params;
1329 struct cfg80211_scan_request *scan_request = wl->scan_request;
1331 s32 search_state = WL_P2P_DISC_ST_SCAN;
1333 u16 *default_chan_list = NULL;
1334 WL_DBG(("Enter \n"));
1337 if (!wl->p2p_supported || ((ndev == wl_to_prmry_ndev(wl)) &&
1339 /* LEGACY SCAN TRIGGER */
1340 WL_DBG(("LEGACY SCAN START\n"));
1341 if (ssid && ssid->SSID_len) {
1342 params_size += sizeof(wlc_ssid_t);
1344 params = (wl_escan_params_t *) kmalloc(params_size, GFP_KERNEL);
1349 memset(params, 0, params_size);
1350 memcpy(¶ms->params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1351 params->params.bss_type = DOT11_BSSTYPE_ANY;
1352 params->params.scan_type = 0;
1353 params->params.nprobes = htod32(-1);
1354 params->params.active_time = htod32(-1);
1355 params->params.passive_time = htod32(-1);
1356 params->params.home_time = htod32(-1);
1357 params->params.channel_num = 0;
1358 if (ssid && ssid->SSID_len) {
1359 memcpy(params->params.ssid.SSID, ssid->SSID, ssid->SSID_len);
1360 params->params.ssid.SSID_len = htod32(ssid->SSID_len);
1362 params->version = htod32(ESCAN_REQ_VERSION);
1363 params->action = htod16(action);
1364 params->sync_id = htod16(0x1234);
1365 wldev_iovar_setbuf(ndev, "escan", params, params_size,
1366 wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
1369 else if (p2p_on(wl) && p2p_scan(wl)) {
1370 /* P2P SCAN TRIGGER */
1371 if (scan_request && scan_request->n_channels) {
1372 num_chans = scan_request->n_channels;
1373 WL_INFO((" chann number : %d\n", num_chans));
1374 default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
1376 if (default_chan_list == NULL) {
1377 WL_ERR(("channel list allocation failed \n"));
1381 for (i = 0; i < num_chans; i++)
1383 default_chan_list[i] =
1384 ieee80211_frequency_to_channel(
1385 scan_request->channels[i]->center_freq);
1387 if (num_chans == 3 && (
1388 (default_chan_list[0] == SOCIAL_CHAN_1) &&
1389 (default_chan_list[1] == SOCIAL_CHAN_2) &&
1390 (default_chan_list[2] == SOCIAL_CHAN_3))) {
1391 /* SOCIAL CHANNELS 1, 6, 11 */
1392 search_state = WL_P2P_DISC_ST_SEARCH;
1393 WL_INFO(("P2P SEARCH PHASE START \n"));
1395 WL_INFO(("P2P SCAN STATE START \n"));
1399 err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list,
1400 search_state, action,
1401 wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
1402 kfree(default_chan_list);
1410 wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wlc_ssid_t *ssid)
1414 wl_scan_results_t *results;
1415 WL_DBG(("Enter \n"));
1417 wl->escan_info.wiphy = wiphy;
1418 wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
1419 passive_scan = wl->active_scan ? 0 : 1;
1420 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1421 &passive_scan, sizeof(passive_scan), false);
1422 if (unlikely(err)) {
1423 WL_DBG(("error (%d)\n", err));
1426 results = (wl_scan_results_t *) wl->escan_info.escan_buf;
1427 results->version = 0;
1429 results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
1431 wl_run_escan(wl, ndev, ssid, WL_SCAN_ACTION_START);
1436 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
1437 struct cfg80211_scan_request *request,
1438 struct cfg80211_ssid *this_ssid)
1440 struct wl_priv *wl = WL_PRIV_GET();
1441 struct cfg80211_ssid *ssids;
1442 struct wl_scan_req *sr = wl_to_sr(wl);
1443 wlc_ssid_t ssid_info;
1450 if (unlikely(wl_get_drv_status(wl, SCANNING))) {
1451 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
1454 if (unlikely(wl_get_drv_status(wl, SCAN_ABORTING))) {
1455 WL_ERR(("Scanning being aborted : status (%d)\n",
1460 WL_DBG(("wiphy (%p)\n", wiphy));
1464 if (request) { /* scan bss */
1465 ssids = request->ssids;
1466 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) {
1468 } else if (wl->escan_on) {
1470 if (ssids->ssid_len && IS_P2P_SSID(ssids->ssid)) {
1471 if (wl->p2p_supported) {
1472 /* p2p scan trigger */
1473 if (p2p_on(wl) == false) {
1474 /* p2p on at the first time */
1476 wl_cfgp2p_set_firm_p2p(wl);
1478 p2p_scan(wl) = true;
1482 /* legacy scan trigger
1483 * So, we have to disable p2p discovery if p2p discovery is on
1485 if (wl->p2p_supported) {
1486 p2p_scan(wl) = false;
1487 /* If Netdevice is not equals to primary and p2p is on
1488 * , we will do p2p scan using P2PAPI_BSSCFG_DEVICE.
1490 if (p2p_on(wl) && (ndev != wl_to_prmry_ndev(wl)))
1491 p2p_scan(wl) = true;
1493 if (p2p_scan(wl) == false) {
1494 if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
1495 err = wl_cfgp2p_discover_enable_search(wl,
1497 if (unlikely(err)) {
1506 } else { /* scan in ibss */
1507 /* we don't do iscan in ibss */
1510 wl->scan_request = request;
1511 wl_set_drv_status(wl, SCANNING);
1513 err = wl_do_iscan(wl);
1518 } else if (escan_req) {
1519 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
1520 ssids->ssid, ssids->ssid_len));
1522 memcpy(ssid_info.SSID, ssids->ssid, ssids->ssid_len);
1523 ssid_info.SSID_len = ssids->ssid_len;
1524 if (wl->p2p_supported) {
1525 if (p2p_on(wl) && p2p_scan(wl)) {
1527 err = wl_cfgp2p_enable_discovery(wl, ndev,
1528 request->ie, request->ie_len);
1530 if (unlikely(err)) {
1535 err = wl_do_escan(wl, wiphy, ndev, &ssid_info);
1543 memset(&sr->ssid, 0, sizeof(sr->ssid));
1545 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
1546 if (sr->ssid.SSID_len) {
1547 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
1548 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
1549 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
1550 sr->ssid.SSID, sr->ssid.SSID_len));
1553 WL_DBG(("Broadcast scan\n"));
1555 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
1556 passive_scan = wl->active_scan ? 0 : 1;
1557 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1558 &passive_scan, sizeof(passive_scan), false);
1559 if (unlikely(err)) {
1560 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
1563 err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
1564 sizeof(sr->ssid), false);
1566 if (err == -EBUSY) {
1567 WL_INFO(("system busy : scan for \"%s\" "
1568 "canceled\n", sr->ssid.SSID));
1570 WL_ERR(("WLC_SCAN error (%d)\n", err));
1579 wl_clr_drv_status(wl, SCANNING);
1580 wl->scan_request = NULL;
1585 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
1586 struct cfg80211_scan_request *request)
1590 WL_DBG(("Enter \n"));
1592 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
1593 if (unlikely(err)) {
1594 WL_ERR(("scan error (%d)\n", err));
1601 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
1603 s8 buf[WLC_IOCTL_SMLEN];
1608 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
1609 BUG_ON(unlikely(!len));
1611 err = wldev_ioctl(dev, WLC_SET_VAR, buf, len, false);
1612 if (unlikely(err)) {
1613 WL_ERR(("error (%d)\n", err));
1620 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
1623 s8 buf[WLC_IOCTL_SMLEN];
1630 len = bcm_mkiovar(name, (char *)(&data_null), 0,
1631 (char *)(&var), sizeof(var.buf));
1632 BUG_ON(unlikely(!len));
1633 err = wldev_ioctl(dev, WLC_GET_VAR, &var, len, false);
1634 if (unlikely(err)) {
1635 WL_ERR(("error (%d)\n", err));
1637 *retval = dtoh32(var.val);
1642 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
1646 err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
1647 if (unlikely(err)) {
1648 WL_ERR(("Error (%d)\n", err));
1654 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
1658 err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
1659 if (unlikely(err)) {
1660 WL_ERR(("Error (%d)\n", err));
1666 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
1669 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
1671 retry = htod32(retry);
1672 err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), false);
1673 if (unlikely(err)) {
1674 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
1680 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1682 struct wl_priv *wl = wiphy_to_wl(wiphy);
1683 struct net_device *ndev = wl_to_prmry_ndev(wl);
1687 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1688 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
1689 wl->conf->rts_threshold = wiphy->rts_threshold;
1690 err = wl_set_rts(ndev, wl->conf->rts_threshold);
1694 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1695 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
1696 wl->conf->frag_threshold = wiphy->frag_threshold;
1697 err = wl_set_frag(ndev, wl->conf->frag_threshold);
1701 if (changed & WIPHY_PARAM_RETRY_LONG &&
1702 (wl->conf->retry_long != wiphy->retry_long)) {
1703 wl->conf->retry_long = wiphy->retry_long;
1704 err = wl_set_retry(ndev, wl->conf->retry_long, true);
1708 if (changed & WIPHY_PARAM_RETRY_SHORT &&
1709 (wl->conf->retry_short != wiphy->retry_short)) {
1710 wl->conf->retry_short = wiphy->retry_short;
1711 err = wl_set_retry(ndev, wl->conf->retry_short, false);
1721 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1722 struct cfg80211_ibss_params *params)
1724 struct wl_priv *wl = WL_PRIV_GET();
1725 struct cfg80211_bss *bss;
1726 struct ieee80211_channel *chan;
1727 struct wl_join_params join_params;
1728 struct cfg80211_ssid ssid;
1734 if (params->bssid) {
1735 WL_ERR(("Invalid bssid\n"));
1738 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1740 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1741 ssid.ssid_len = params->ssid_len;
1744 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1750 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1751 /* to allow scan_inform to propagate to cfg80211 plane */
1754 /* wait 4 secons till scan done.... */
1755 schedule_timeout_interruptible(4 * HZ);
1757 bss = cfg80211_get_ibss(wiphy, NULL,
1758 params->ssid, params->ssid_len);
1761 wl->ibss_starter = false;
1762 WL_DBG(("Found IBSS\n"));
1764 wl->ibss_starter = true;
1766 chan = params->channel;
1768 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1770 * Join with specific BSSID and cached SSID
1771 * If SSID is zero join based on BSSID only
1773 memset(&join_params, 0, sizeof(join_params));
1774 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1776 join_params.ssid.SSID_len = htod32(params->ssid_len);
1778 memcpy(&join_params.params.bssid, params->bssid,
1781 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1783 err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
1784 sizeof(join_params), false);
1785 if (unlikely(err)) {
1786 WL_ERR(("Error (%d)\n", err));
1792 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1794 struct wl_priv *wl = WL_PRIV_GET();
1804 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1806 struct wl_priv *wl = WL_PRIV_GET();
1807 struct wl_security *sec;
1810 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1812 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1813 val = WPA_AUTH_PSK; /* | WPA_AUTH_UNSPECIFIED; */
1814 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1815 val = WPA2_AUTH_PSK; /* | WPA2_AUTH_UNSPECIFIED ; */
1817 val = WPA_AUTH_DISABLED;
1819 if (is_wps_conn(sme))
1820 val = WPA_AUTH_DISABLED;
1822 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1823 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
1824 if (unlikely(err)) {
1825 WL_ERR(("set wpa_auth failed (%d)\n", err));
1828 sec = wl_read_prof(wl, WL_PROF_SEC);
1829 sec->wpa_versions = sme->crypto.wpa_versions;
1834 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1836 struct wl_priv *wl = WL_PRIV_GET();
1837 struct wl_security *sec;
1840 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1841 switch (sme->auth_type) {
1842 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1844 WL_DBG(("open system\n"));
1846 case NL80211_AUTHTYPE_SHARED_KEY:
1848 WL_DBG(("shared key\n"));
1850 case NL80211_AUTHTYPE_AUTOMATIC:
1852 WL_DBG(("automatic\n"));
1854 case NL80211_AUTHTYPE_NETWORK_EAP:
1855 WL_DBG(("network eap\n"));
1858 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1862 err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
1863 if (unlikely(err)) {
1864 WL_ERR(("set auth failed (%d)\n", err));
1867 sec = wl_read_prof(wl, WL_PROF_SEC);
1868 sec->auth_type = sme->auth_type;
1873 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1875 struct wl_priv *wl = WL_PRIV_GET();
1876 struct wl_security *sec;
1880 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1882 if (sme->crypto.n_ciphers_pairwise) {
1883 switch (sme->crypto.ciphers_pairwise[0]) {
1884 case WLAN_CIPHER_SUITE_WEP40:
1885 case WLAN_CIPHER_SUITE_WEP104:
1888 case WLAN_CIPHER_SUITE_TKIP:
1889 pval = TKIP_ENABLED;
1891 case WLAN_CIPHER_SUITE_CCMP:
1894 case WLAN_CIPHER_SUITE_AES_CMAC:
1898 WL_ERR(("invalid cipher pairwise (%d)\n",
1899 sme->crypto.ciphers_pairwise[0]));
1903 if (sme->crypto.cipher_group) {
1904 switch (sme->crypto.cipher_group) {
1905 case WLAN_CIPHER_SUITE_WEP40:
1906 case WLAN_CIPHER_SUITE_WEP104:
1909 case WLAN_CIPHER_SUITE_TKIP:
1910 gval = TKIP_ENABLED;
1912 case WLAN_CIPHER_SUITE_CCMP:
1915 case WLAN_CIPHER_SUITE_AES_CMAC:
1919 WL_ERR(("invalid cipher group (%d)\n",
1920 sme->crypto.cipher_group));
1925 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1927 if (is_wps_conn(sme)) {
1928 err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
1930 err = wldev_iovar_setint_bsscfg(dev, "wsec", pval | gval, bssidx);
1932 if (unlikely(err)) {
1933 WL_ERR(("error (%d)\n", err));
1937 sec = wl_read_prof(wl, WL_PROF_SEC);
1938 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1939 sec->cipher_group = sme->crypto.cipher_group;
1945 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1947 struct wl_priv *wl = WL_PRIV_GET();
1948 struct wl_security *sec;
1951 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1953 if (sme->crypto.n_akm_suites) {
1954 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1955 if (unlikely(err)) {
1956 WL_ERR(("could not get wpa_auth (%d)\n", err));
1959 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1960 switch (sme->crypto.akm_suites[0]) {
1961 case WLAN_AKM_SUITE_8021X:
1962 val = WPA_AUTH_UNSPECIFIED;
1964 case WLAN_AKM_SUITE_PSK:
1968 WL_ERR(("invalid cipher group (%d)\n",
1969 sme->crypto.cipher_group));
1972 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1973 switch (sme->crypto.akm_suites[0]) {
1974 case WLAN_AKM_SUITE_8021X:
1975 val = WPA2_AUTH_UNSPECIFIED;
1977 case WLAN_AKM_SUITE_PSK:
1978 val = WPA2_AUTH_PSK;
1981 WL_ERR(("invalid cipher group (%d)\n",
1982 sme->crypto.cipher_group));
1987 WL_DBG(("setting wpa_auth to %d\n", val));
1989 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
1990 if (unlikely(err)) {
1991 WL_ERR(("could not set wpa_auth (%d)\n", err));
1995 sec = wl_read_prof(wl, WL_PROF_SEC);
1996 sec->wpa_auth = sme->crypto.akm_suites[0];
2002 wl_set_set_sharedkey(struct net_device *dev,
2003 struct cfg80211_connect_params *sme)
2005 struct wl_priv *wl = WL_PRIV_GET();
2006 struct wl_security *sec;
2007 struct wl_wsec_key key;
2010 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2012 WL_DBG(("key len (%d)\n", sme->key_len));
2014 sec = wl_read_prof(wl, WL_PROF_SEC);
2015 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
2016 sec->wpa_versions, sec->cipher_pairwise));
2017 if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 |
2018 NL80211_WPA_VERSION_2)) &&
2019 (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
2020 WLAN_CIPHER_SUITE_WEP104))) {
2021 memset(&key, 0, sizeof(key));
2022 key.len = (u32) sme->key_len;
2023 key.index = (u32) sme->key_idx;
2024 if (unlikely(key.len > sizeof(key.data))) {
2025 WL_ERR(("Too long key length (%u)\n", key.len));
2028 memcpy(key.data, sme->key, key.len);
2029 key.flags = WL_PRIMARY_KEY;
2030 switch (sec->cipher_pairwise) {
2031 case WLAN_CIPHER_SUITE_WEP40:
2032 key.algo = CRYPTO_ALGO_WEP1;
2034 case WLAN_CIPHER_SUITE_WEP104:
2035 key.algo = CRYPTO_ALGO_WEP128;
2038 WL_ERR(("Invalid algorithm (%d)\n",
2039 sme->crypto.ciphers_pairwise[0]));
2042 /* Set the new key/index */
2043 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
2044 key.len, key.index, key.algo));
2045 WL_DBG(("key \"%s\"\n", key.data));
2046 swap_key_from_BE(&key);
2047 err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
2048 ioctlbuf, sizeof(ioctlbuf), bssidx);
2049 if (unlikely(err)) {
2050 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2053 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
2054 WL_DBG(("set auth_type to shared key\n"));
2055 val = 1; /* shared key */
2056 err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
2057 if (unlikely(err)) {
2058 WL_ERR(("set auth failed (%d)\n", err));
2068 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
2069 struct cfg80211_connect_params *sme)
2071 struct wl_priv *wl = WL_PRIV_GET();
2072 struct ieee80211_channel *chan = sme->channel;
2073 struct wl_join_params join_params;
2074 size_t join_params_size;
2081 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
2083 if (wl->scan_request) {
2084 wl_cfg80211_scan_abort(wl, dev);
2087 if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
2088 /* we only allow to connect using virtual interface in case of P2P */
2089 if (p2p_on(wl) && is_wps_conn(sme)) {
2090 WL_DBG(("p2p index : %d\n", wl_cfgp2p_find_idx(wl, dev)));
2091 /* Have to apply WPS IE + P2P IE in assoc req frame */
2092 wl_cfgp2p_set_management_ie(wl, dev,
2093 wl_cfgp2p_find_idx(wl, dev), VNDR_IE_PRBREQ_FLAG,
2094 wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie,
2095 wl_to_p2p_bss_saved_ie(wl,
2096 P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
2097 wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
2098 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
2099 } else if (p2p_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
2100 /* This is the connect req after WPS is done [credentials exchanged]
2101 * currently identified with WPA_VERSION_2 .
2102 * Update the previously set IEs with
2103 * the newly received IEs from Supplicant. This will remove the WPS IE from
2106 wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
2107 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
2111 WL_INFO(("No P2PIE in beacon \n"));
2114 if (unlikely(!sme->ssid)) {
2115 WL_ERR(("Invalid ssid\n"));
2119 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
2120 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
2121 chan->center_freq));
2123 WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
2124 err = wl_set_wpa_version(dev, sme);
2128 err = wl_set_auth_type(dev, sme);
2132 err = wl_set_set_cipher(dev, sme);
2136 err = wl_set_key_mgmt(dev, sme);
2140 err = wl_set_set_sharedkey(dev, sme);
2144 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
2146 * Join with specific BSSID and cached SSID
2147 * If SSID is zero join based on BSSID only
2149 memset(&join_params, 0, sizeof(join_params));
2150 join_params_size = sizeof(join_params.ssid);
2152 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
2153 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
2154 join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
2155 wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
2156 memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
2158 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
2159 WL_DBG(("join_param_size %d\n", join_params_size));
2161 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
2162 WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
2163 join_params.ssid.SSID_len));
2165 err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, false);
2166 if (unlikely(err)) {
2167 WL_ERR(("error (%d)\n", err));
2170 wl_set_drv_status(wl, CONNECTING);
2176 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
2179 struct wl_priv *wl = WL_PRIV_GET();
2184 WL_ERR(("Reason %d\n\n\n", reason_code));
2186 act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
2188 scbval.val = reason_code;
2189 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
2190 scbval.val = htod32(scbval.val);
2191 err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
2192 sizeof(scb_val_t), false);
2193 if (unlikely(err)) {
2194 WL_ERR(("error (%d)\n", err));
2203 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
2204 enum nl80211_tx_power_setting type, s32 dbm)
2207 struct wl_priv *wl = WL_PRIV_GET();
2208 struct net_device *ndev = wl_to_prmry_ndev(wl);
2215 case NL80211_TX_POWER_AUTOMATIC:
2217 case NL80211_TX_POWER_LIMITED:
2219 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
2223 case NL80211_TX_POWER_FIXED:
2225 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
2230 /* Make sure radio is off or on as far as software is concerned */
2231 disable = WL_RADIO_SW_DISABLE << 16;
2232 disable = htod32(disable);
2233 err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), false);
2234 if (unlikely(err)) {
2235 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
2242 txpwrmw = (u16) dbm;
2243 err = wl_dev_intvar_set(ndev, "qtxpower",
2244 (s32) (bcm_mw_to_qdbm(txpwrmw)));
2245 if (unlikely(err)) {
2246 WL_ERR(("qtxpower error (%d)\n", err));
2249 wl->conf->tx_power = dbm;
2254 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
2256 struct wl_priv *wl = WL_PRIV_GET();
2257 struct net_device *ndev = wl_to_prmry_ndev(wl);
2263 err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
2264 if (unlikely(err)) {
2265 WL_ERR(("error (%d)\n", err));
2268 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
2269 *dbm = (s32) bcm_qdbm_to_mw(result);
2275 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
2276 u8 key_idx, bool unicast, bool multicast)
2278 struct wl_priv *wl = WL_PRIV_GET();
2282 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2284 WL_DBG(("key index (%d)\n", key_idx));
2286 err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2287 if (unlikely(err)) {
2288 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
2291 if (wsec & WEP_ENABLED) {
2292 /* Just select a new current key */
2293 index = (u32) key_idx;
2294 index = htod32(index);
2295 err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
2296 sizeof(index), false);
2297 if (unlikely(err)) {
2298 WL_ERR(("error (%d)\n", err));
2305 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
2306 u8 key_idx, const u8 *mac_addr, struct key_params *params)
2308 struct wl_priv *wl = WL_PRIV_GET();
2309 struct wl_wsec_key key;
2311 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2312 s32 mode = get_mode_by_netdev(wl, dev);
2313 memset(&key, 0, sizeof(key));
2314 key.index = (u32) key_idx;
2316 if (!ETHER_ISMULTI(mac_addr))
2317 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
2318 key.len = (u32) params->key_len;
2320 /* check for key index change */
2323 swap_key_from_BE(&key);
2324 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2325 sizeof(ioctlbuf), bssidx);
2326 if (unlikely(err)) {
2327 WL_ERR(("key delete error (%d)\n", err));
2331 if (key.len > sizeof(key.data)) {
2332 WL_ERR(("Invalid key length (%d)\n", key.len));
2335 WL_DBG(("Setting the key index %d\n", key.index));
2336 memcpy(key.data, params->key, key.len);
2338 if ((mode == WL_MODE_BSS) &&
2339 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2341 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2342 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2343 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2346 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2347 if (params->seq && params->seq_len == 6) {
2350 ivptr = (u8 *) params->seq;
2351 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2352 (ivptr[3] << 8) | ivptr[2];
2353 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2354 key.iv_initialized = true;
2357 switch (params->cipher) {
2358 case WLAN_CIPHER_SUITE_WEP40:
2359 key.algo = CRYPTO_ALGO_WEP1;
2360 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2362 case WLAN_CIPHER_SUITE_WEP104:
2363 key.algo = CRYPTO_ALGO_WEP128;
2364 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2366 case WLAN_CIPHER_SUITE_TKIP:
2367 key.algo = CRYPTO_ALGO_TKIP;
2368 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2370 case WLAN_CIPHER_SUITE_AES_CMAC:
2371 key.algo = CRYPTO_ALGO_AES_CCM;
2372 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2374 case WLAN_CIPHER_SUITE_CCMP:
2375 key.algo = CRYPTO_ALGO_AES_CCM;
2376 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
2379 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
2382 swap_key_from_BE(&key);
2383 #ifdef CONFIG_WIRELESS_EXT
2384 dhd_wait_pend8021x(dev);
2386 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2387 sizeof(ioctlbuf), bssidx);
2388 if (unlikely(err)) {
2389 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2397 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
2398 u8 key_idx, bool pairwise, const u8 *mac_addr,
2399 struct key_params *params)
2401 struct wl_wsec_key key;
2407 struct wl_priv *wl = WL_PRIV_GET();
2408 s32 mode = get_mode_by_netdev(wl, dev);
2409 WL_DBG(("key index (%d)\n", key_idx));
2412 bssidx = wl_cfgp2p_find_idx(wl, dev);
2415 wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
2418 memset(&key, 0, sizeof(key));
2420 key.len = (u32) params->key_len;
2421 key.index = (u32) key_idx;
2423 if (unlikely(key.len > sizeof(key.data))) {
2424 WL_ERR(("Too long key length (%u)\n", key.len));
2427 memcpy(key.data, params->key, key.len);
2429 key.flags = WL_PRIMARY_KEY;
2430 switch (params->cipher) {
2431 case WLAN_CIPHER_SUITE_WEP40:
2432 key.algo = CRYPTO_ALGO_WEP1;
2434 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2436 case WLAN_CIPHER_SUITE_WEP104:
2437 key.algo = CRYPTO_ALGO_WEP128;
2439 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2441 case WLAN_CIPHER_SUITE_TKIP:
2442 key.algo = CRYPTO_ALGO_TKIP;
2444 /* wpa_supplicant switches the third and fourth quarters of the TKIP key */
2445 if (mode == WL_MODE_BSS) {
2446 bcopy(&key.data[24], keybuf, sizeof(keybuf));
2447 bcopy(&key.data[16], &key.data[24], sizeof(keybuf));
2448 bcopy(keybuf, &key.data[16], sizeof(keybuf));
2450 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2452 case WLAN_CIPHER_SUITE_AES_CMAC:
2453 key.algo = CRYPTO_ALGO_AES_CCM;
2455 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2457 case WLAN_CIPHER_SUITE_CCMP:
2458 key.algo = CRYPTO_ALGO_AES_CCM;
2460 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
2463 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
2467 /* Set the new key/index */
2468 swap_key_from_BE(&key);
2469 err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2470 sizeof(ioctlbuf), bssidx);
2471 if (unlikely(err)) {
2472 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2477 err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2478 if (unlikely(err)) {
2479 WL_ERR(("get wsec error (%d)\n", err));
2484 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
2485 if (unlikely(err)) {
2486 WL_ERR(("set wsec error (%d)\n", err));
2491 /* TODO: Removed in P2P, check later --lm */
2492 val = 1; /* assume shared key. otherwise 0 */
2494 err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), false);
2495 if (unlikely(err)) {
2496 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
2504 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
2505 u8 key_idx, bool pairwise, const u8 *mac_addr)
2507 struct wl_wsec_key key;
2508 struct wl_priv *wl = WL_PRIV_GET();
2510 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2512 WL_DBG(("Enter\n"));
2514 memset(&key, 0, sizeof(key));
2516 key.index = (u32) key_idx;
2517 key.flags = WL_PRIMARY_KEY;
2518 key.algo = CRYPTO_ALGO_OFF;
2520 WL_DBG(("key index (%d)\n", key_idx));
2521 /* Set the new key/index */
2522 swap_key_from_BE(&key);
2523 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2524 sizeof(ioctlbuf), bssidx);
2525 if (unlikely(err)) {
2526 if (err == -EINVAL) {
2527 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
2528 /* we ignore this key index in this case */
2529 WL_DBG(("invalid key index (%d)\n", key_idx));
2532 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2538 /* TODO: Removed in P2P twig, check later --lin */
2539 val = 0; /* assume open key. otherwise 1 */
2541 err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), false);
2542 if (unlikely(err)) {
2543 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
2551 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
2552 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2553 void (*callback) (void *cookie, struct key_params * params))
2555 struct key_params params;
2556 struct wl_wsec_key key;
2557 struct wl_priv *wl = WL_PRIV_GET();
2558 struct wl_security *sec;
2561 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2563 WL_DBG(("key index (%d)\n", key_idx));
2565 memset(&key, 0, sizeof(key));
2566 key.index = key_idx;
2567 swap_key_to_BE(&key);
2568 memset(¶ms, 0, sizeof(params));
2569 params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
2570 memcpy(params.key, key.data, params.key_len);
2572 wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2573 if (unlikely(err)) {
2574 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
2577 switch (wsec & ~SES_OW_ENABLED) {
2579 sec = wl_read_prof(wl, WL_PROF_SEC);
2580 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2581 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2582 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2583 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2584 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2585 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2589 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2590 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2593 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2594 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2597 WL_ERR(("Invalid algo (0x%x)\n", wsec));
2601 callback(cookie, ¶ms);
2606 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2607 struct net_device *dev, u8 key_idx)
2609 WL_INFO(("Not supported\n"));
2615 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
2616 u8 *mac, struct station_info *sinfo)
2618 struct wl_priv *wl = WL_PRIV_GET();
2626 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
2627 WL_ERR(("Wrong Mac address\n"));
2631 /* Report the current tx rate */
2632 err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
2634 WL_ERR(("Could not get rate (%d)\n", err));
2636 rate = dtoh32(rate);
2637 sinfo->filled |= STATION_INFO_TX_BITRATE;
2638 sinfo->txrate.legacy = rate * 5;
2639 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
2642 if (wl_get_drv_status(wl, CONNECTED)) {
2643 memset(&scb_val, 0, sizeof(scb_val));
2645 err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
2646 sizeof(scb_val_t), false);
2647 if (unlikely(err)) {
2648 WL_ERR(("Could not get rssi (%d)\n", err));
2651 rssi = dtoh32(scb_val.val);
2652 sinfo->filled |= STATION_INFO_SIGNAL;
2653 sinfo->signal = rssi;
2654 WL_DBG(("RSSI %d dBm\n", rssi));
2657 #if defined(ANDROID_WIRELESS_PATCH)
2658 err = wldev_ioctl(dev, WLC_GET_RATE, &sinfo->link_speed, sizeof(sinfo->link_speed), false);
2659 sinfo->link_speed = sinfo->link_speed / 2; /* Convert internal 500Kbps to Mpbs */
2661 sinfo->filled |= STATION_LINK_SPEED;
2663 WL_ERR(("WLC_GET_RATE failed\n"));
2670 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2671 bool enabled, s32 timeout)
2677 pm = enabled ? PM_FAST : PM_OFF;
2679 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
2680 err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), false);
2681 if (unlikely(err)) {
2683 WL_DBG(("net_device is not ready yet\n"));
2685 WL_ERR(("error (%d)\n", err));
2691 static __used u32 wl_find_msb(u16 bit16)
2695 if (bit16 & 0xff00) {
2718 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
2720 struct wl_priv *wl = WL_PRIV_GET();
2723 if (unlikely(!wl_get_drv_status(wl, READY))) {
2724 WL_INFO(("device is not ready : status (%d)\n",
2729 wl_invoke_iscan(wl);
2734 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
2735 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2737 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
2740 struct wl_priv *wl = WL_PRIV_GET();
2743 if (unlikely(!wl_get_drv_status(wl, READY))) {
2744 WL_INFO(("device is not ready : status (%d)\n",
2749 wl_set_drv_status(wl, SCAN_ABORTING);
2751 if (wl->scan_request) {
2752 cfg80211_scan_done(wl->scan_request, true);
2753 wl->scan_request = NULL;
2755 wl_clr_drv_status(wl, SCANNING);
2756 wl_clr_drv_status(wl, SCAN_ABORTING);
2762 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2766 struct wl_priv *wl = WL_PRIV_GET();
2767 struct net_device *primary_dev = wl_to_prmry_ndev(wl);
2769 /* Firmware is supporting pmk list only for STA interface i.e. primary interface
2770 * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
2771 * Do we really need to support PMK cache in P2P in firmware?
2773 if (primary_dev != dev) {
2774 WL_ERR(("Not supporting Flushing pmklist on virtual"
2775 " interfaces than primary interface\n"));
2779 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2780 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2781 WL_DBG(("PMKID[%d]: %pM =\n", i,
2782 &pmk_list->pmkids.pmkid[i].BSSID));
2783 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2784 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2788 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2796 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2797 struct cfg80211_pmksa *pmksa)
2799 struct wl_priv *wl = WL_PRIV_GET();
2804 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2805 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2808 if (i < WL_NUM_PMKIDS_MAX) {
2809 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2811 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2813 if (i == wl->pmk_list->pmkids.npmkid)
2814 wl->pmk_list->pmkids.npmkid++;
2818 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2819 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2820 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2822 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2826 err = wl_update_pmklist(dev, wl->pmk_list, err);
2832 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2833 struct cfg80211_pmksa *pmksa)
2835 struct wl_priv *wl = WL_PRIV_GET();
2836 struct _pmkid_list pmkid;
2841 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2842 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2844 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2845 &pmkid.pmkid[0].BSSID));
2846 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2847 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2850 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2852 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2856 if ((wl->pmk_list->pmkids.npmkid > 0) &&
2857 (i < wl->pmk_list->pmkids.npmkid)) {
2858 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2859 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2860 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2861 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2863 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2864 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2867 wl->pmk_list->pmkids.npmkid--;
2872 err = wl_update_pmklist(dev, wl->pmk_list, err);
2879 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2881 struct wl_priv *wl = WL_PRIV_GET();
2884 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2885 err = wl_update_pmklist(dev, wl->pmk_list, err);
2891 wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
2893 wl_scan_params_t *params;
2897 *out_params_size = 0;
2899 /* Our scan params only need space for 1 channel and 0 ssids */
2900 params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16);
2901 params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL);
2902 if (params == NULL) {
2903 WL_ERR(("%s: mem alloc failed (%d bytes)\n", __func__, params_size));
2906 memset(params, 0, params_size);
2907 params->nprobes = nprobes;
2909 num_chans = (channel == 0) ? 0 : 1;
2911 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
2912 params->bss_type = DOT11_BSSTYPE_ANY;
2913 params->scan_type = DOT11_SCANTYPE_ACTIVE;
2914 params->nprobes = htod32(1);
2915 params->active_time = htod32(-1);
2916 params->passive_time = htod32(-1);
2917 params->home_time = htod32(10);
2918 params->channel_list[0] = htodchanspec(channel);
2920 /* Our scan params have 1 channel and 0 ssids */
2921 params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
2922 (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
2924 *out_params_size = params_size; /* rtn size to the caller */
2928 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
2930 wl_scan_params_t *params;
2934 WL_DBG(("Enter\n"));
2936 /* Our scan params only need space for 1 channel and 0 ssids */
2937 params = wl_cfg80211_scan_alloc_params(-1, 0, ¶ms_size);
2938 if (params == NULL) {
2939 WL_ERR(("scan params allocation failed \n"));
2942 /* Do a scan abort to stop the driver's scan engine */
2943 err = wldev_ioctl(ndev, WLC_SCAN, params, params_size, false);
2945 WL_ERR(("scan abort failed \n"));
2951 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
2952 struct ieee80211_channel * channel,
2953 enum nl80211_channel_type channel_type,
2954 unsigned int duration, u64 *cookie)
2959 struct wl_priv *wl = WL_PRIV_GET();
2960 dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
2961 WL_DBG(("Enter, netdev_ifidx: %d \n", dev->ifindex));
2962 if (likely(wl_get_drv_status(wl, SCANNING))) {
2963 wl_cfg80211_scan_abort(wl, dev);
2966 target_channel = ieee80211_frequency_to_channel(channel->center_freq);
2967 memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel));
2968 wl->remain_on_chan_type = channel_type;
2969 wl->cache_cookie = *cookie;
2970 cfg80211_ready_on_channel(dev, *cookie, channel,
2971 channel_type, duration, GFP_KERNEL);
2973 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
2975 /* In case of p2p_listen command, supplicant send remain_on_channel
2976 * without turning on P2P
2979 err = wl_cfgp2p_enable_discovery(wl, dev, NULL, 0);
2981 if (unlikely(err)) {
2987 wl_cfgp2p_discover_listen(wl, target_channel, duration);
2995 wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
2999 WL_DBG((" enter ) netdev_ifidx: %d \n", dev->ifindex));
3004 wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
3005 struct ieee80211_channel *channel, bool offchan,
3006 enum nl80211_channel_type channel_type,
3007 bool channel_type_valid, unsigned int wait,
3008 const u8* buf, size_t len, u64 *cookie)
3010 wl_action_frame_t *action_frame;
3011 wl_af_params_t *af_params;
3012 wifi_p2p_ie_t *p2p_ie;
3013 wpa_ie_fixed_t *wps_ie;
3014 const struct ieee80211_mgmt *mgmt;
3015 struct wl_priv *wl = WL_PRIV_GET();
3016 dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
3023 WL_DBG(("Enter \n"));
3024 /* find bssidx based on ndev */
3025 bssidx = wl_cfgp2p_find_idx(wl, dev);
3026 /* cookie generation */
3027 *cookie = (unsigned long) buf;
3031 WL_ERR(("Can not find the bssidx for dev( %p )\n", dev));
3034 if (wl->p2p_supported && p2p_on(wl)) {
3035 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
3036 /* Suspend P2P discovery search-listen to prevent it from changing the
3039 if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) {
3040 WL_ERR(("Can not disable discovery mode\n"));
3045 mgmt = (const struct ieee80211_mgmt *) buf;
3046 fc = mgmt->frame_control;
3047 if (fc != IEEE80211_STYPE_ACTION) {
3048 if (fc == IEEE80211_STYPE_PROBE_RESP) {
3049 s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3050 s32 ie_len = len - ie_offset;
3051 if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)(buf + ie_offset), ie_len))
3053 /* Total length of P2P Information Element */
3054 p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
3055 /* Have to change p2p device address in dev_info attribute
3056 * because Supplicant use primary eth0 address
3058 #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3059 wl_cfg80211_change_ifaddr((u8 *)p2p_ie,
3060 &wl->p2p_dev_addr, P2P_SEID_DEV_INFO);
3063 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len))
3065 /* Order of Vendor IE is 1) WPS IE +
3066 * 2) P2P IE created by supplicant
3067 * So, it is ok to find start address of WPS IE
3068 * to save IEs to firmware
3070 wpsie_len = wps_ie->length + sizeof(wps_ie->length) +
3071 sizeof(wps_ie->tag);
3072 wl_cfgp2p_set_management_ie(wl, dev, bssidx,
3073 VNDR_IE_PRBRSP_FLAG,
3074 (u8 *)wps_ie, wpsie_len + p2pie_len);
3075 /* remove WLC_E_PROBREQ_MSG event to prevent HOSTAPD
3076 * from responding many probe request
3080 cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_KERNEL);
3083 /* Abort the dwell time of any previous off-channel action frame that may
3084 * be still in effect. Sending off-channel action frames relies on the
3085 * driver's scan engine. If a previous off-channel action frame tx is
3086 * still in progress (including the dwell time), then this new action
3087 * frame will not be sent out.
3089 wl_cfg80211_scan_abort(wl, dev);
3091 af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
3093 if (af_params == NULL)
3095 WL_ERR(("unable to allocate frame\n"));
3099 action_frame = &af_params->action_frame;
3101 /* Add the packet Id */
3102 action_frame->packetId = (u32) action_frame;
3103 WL_DBG(("action frame %d\n", action_frame->packetId));
3105 memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN);
3106 memcpy(&af_params->BSSID, &mgmt->bssid[0], ETHER_ADDR_LEN);
3108 /* Add the length exepted for 802.11 header */
3109 action_frame->len = len - DOT11_MGMT_HDR_LEN;
3110 WL_DBG(("action_frame->len: %d\n", action_frame->len));
3112 /* Add the channel */
3113 af_params->channel =
3114 ieee80211_frequency_to_channel(channel->center_freq);
3116 /* Add the dwell time
3117 * Dwell time to stay off-channel to wait for a response action frame
3118 * after transmitting an GO Negotiation action frame
3120 af_params->dwell_time = WL_DWELL_TIME;
3122 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
3124 if (wl->p2p->vif_created) {
3125 wifi_p2p_pub_act_frame_t *act_frm =
3126 (wifi_p2p_pub_act_frame_t *) (action_frame->data);
3128 * Have to change intented address from GO REQ or GO RSP and INVITE REQ
3129 * because wpa-supplicant use eth0 primary address
3131 if ((act_frm->subtype == P2P_PAF_GON_REQ)||
3132 (act_frm->subtype == P2P_PAF_GON_RSP)||
3133 (act_frm->subtype == P2P_PAF_GON_CONF)||
3134 (act_frm->subtype == P2P_PAF_INVITE_REQ)) {
3135 p2p_ie = wl_cfgp2p_find_p2pie(act_frm->elts,
3136 action_frame->len - P2P_PUB_AF_FIXED_LEN);
3137 #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3138 wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.int_addr,
3139 P2P_SEID_INTINTADDR);
3140 wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
3142 wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
3148 ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true;
3149 cfg80211_mgmt_tx_status(dev, *cookie, buf, len, ack, GFP_KERNEL);
3158 wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev,
3159 u16 frame_type, bool reg)
3162 WL_DBG(("%s: frame_type: %x, reg: %d\n", __func__, frame_type, reg));
3164 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3172 wl_cfg80211_change_bss(struct wiphy *wiphy,
3173 struct net_device *dev,
3174 struct bss_parameters *params)
3176 if (params->use_cts_prot >= 0) {
3179 if (params->use_short_preamble >= 0) {
3182 if (params->use_short_slot_time >= 0) {
3185 if (params->basic_rates) {
3188 if (params->ap_isolate >= 0) {
3191 if (params->ht_opmode >= 0) {
3198 wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
3199 struct ieee80211_channel *chan,
3200 enum nl80211_channel_type channel_type)
3205 channel = ieee80211_frequency_to_channel(chan->center_freq);
3206 WL_DBG(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
3207 dev->ifindex, channel_type, channel));
3208 wldev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel), false);
3214 wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
3218 u16 auth = 0; /* d11 open authentication */
3225 wpa_suite_mcast_t *mcast;
3226 wpa_suite_ucast_t *ucast;
3227 wpa_suite_auth_key_mgmt_t *mgmt;
3231 WL_DBG(("Enter \n"));
3233 /* check the mcast cipher */
3234 mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN];
3236 switch (tmp[DOT11_OUI_LEN]) {
3237 case WPA_CIPHER_NONE:
3240 case WPA_CIPHER_WEP_40:
3241 case WPA_CIPHER_WEP_104:
3244 case WPA_CIPHER_TKIP:
3245 gval = TKIP_ENABLED;
3247 case WPA_CIPHER_AES_CCM:
3251 WL_ERR(("No Security Info\n"));
3254 len -= WPA_SUITE_LEN;
3255 /* check the unicast cipher */
3256 ucast = (wpa_suite_ucast_t *)&mcast[1];
3257 count = ltoh16_ua(&ucast->count);
3258 tmp = ucast->list[0].oui;
3259 switch (tmp[DOT11_OUI_LEN]) {
3260 case WPA_CIPHER_NONE:
3263 case WPA_CIPHER_WEP_40:
3264 case WPA_CIPHER_WEP_104:
3267 case WPA_CIPHER_TKIP:
3268 pval = TKIP_ENABLED;
3270 case WPA_CIPHER_AES_CCM:
3274 WL_ERR(("No Security Info\n"));
3276 /* FOR WPS , set SEC_OW_ENABLED */
3277 wsec = (pval | gval | SES_OW_ENABLED);
3279 mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[1];
3280 count = ltoh16_ua(&mgmt->count);
3281 tmp = (u8 *)&mgmt->list[0];
3282 switch (tmp[DOT11_OUI_LEN]) {
3284 wpa_auth = WPA_AUTH_NONE;
3286 case RSN_AKM_UNSPECIFIED:
3287 wpa_auth = WPA2_AUTH_UNSPECIFIED;
3290 wpa_auth = WPA2_AUTH_PSK;
3293 WL_ERR(("No Key Mgmt Info\n"));
3296 err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
3298 WL_ERR(("auth error %d\n", err));
3302 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
3304 WL_ERR(("wsec error %d\n", err));
3307 /* set upper-layer auth */
3308 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
3310 WL_ERR(("wpa_auth error %d\n", err));
3318 wl_validate_wpaie(struct net_device *dev, wpa_ie_fixed_t *wpaie, s32 bssidx)
3320 wpa_suite_mcast_t *mcast;
3321 wpa_suite_ucast_t *ucast;
3322 wpa_suite_auth_key_mgmt_t *mgmt;
3323 u16 auth = 0; /* d11 open authentication */
3336 WL_DBG(("Enter \n"));
3337 len = wpaie->length; /* value length */
3338 len -= WPA_IE_TAG_FIXED_LEN;
3339 /* check for multicast cipher suite */
3340 if (len < WPA_SUITE_LEN) {
3341 WL_INFO(("no multicast cipher suite\n"));
3345 /* pick up multicast cipher */
3346 mcast = (wpa_suite_mcast_t *)&wpaie[1];
3347 len -= WPA_SUITE_LEN;
3348 if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) {
3349 if (IS_WPA_CIPHER(mcast->type)) {
3351 switch (mcast->type) {
3352 case WPA_CIPHER_NONE:
3355 case WPA_CIPHER_WEP_40:
3356 case WPA_CIPHER_WEP_104:
3359 case WPA_CIPHER_TKIP:
3362 case WPA_CIPHER_AES_CCM:
3366 WL_ERR(("No Security Info\n"));
3371 /* Check for unicast suite(s) */
3372 if (len < WPA_IE_SUITE_COUNT_LEN) {
3373 WL_INFO(("no unicast suite\n"));
3376 /* walk thru unicast cipher list and pick up what we recognize */
3377 ucast = (wpa_suite_ucast_t *)&mcast[1];
3378 count = ltoh16_ua(&ucast->count);
3379 len -= WPA_IE_SUITE_COUNT_LEN;
3380 for (i = 0; i < count && len >= WPA_SUITE_LEN;
3381 i++, len -= WPA_SUITE_LEN) {
3382 if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
3383 if (IS_WPA_CIPHER(ucast->list[i].type)) {
3385 switch (ucast->list[i].type) {
3386 case WPA_CIPHER_NONE:
3389 case WPA_CIPHER_WEP_40:
3390 case WPA_CIPHER_WEP_104:
3393 case WPA_CIPHER_TKIP:
3396 case WPA_CIPHER_AES_CCM:
3400 WL_ERR(("No Security Info\n"));
3406 len -= (count - i) * WPA_SUITE_LEN;
3407 /* Check for auth key management suite(s) */
3408 if (len < WPA_IE_SUITE_COUNT_LEN) {
3409 WL_INFO((" no auth key mgmt suite\n"));
3412 /* walk thru auth management suite list and pick up what we recognize */
3413 mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count];
3414 count = ltoh16_ua(&mgmt->count);
3415 len -= WPA_IE_SUITE_COUNT_LEN;
3416 for (i = 0; i < count && len >= WPA_SUITE_LEN;
3417 i++, len -= WPA_SUITE_LEN) {
3418 if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
3419 if (IS_WPA_AKM(mgmt->list[i].type)) {
3421 switch (mgmt->list[i].type) {
3423 tmp = WPA_AUTH_NONE;
3425 case RSN_AKM_UNSPECIFIED:
3426 tmp = WPA_AUTH_UNSPECIFIED;
3432 WL_ERR(("No Key Mgmt Info\n"));
3439 /* FOR WPS , set SEC_OW_ENABLED */
3440 wsec = (pval | gval | SES_OW_ENABLED);
3442 err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
3444 WL_ERR(("auth error %d\n", err));
3448 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
3450 WL_ERR(("wsec error %d\n", err));
3453 /* set upper-layer auth */
3454 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
3456 WL_ERR(("wpa_auth error %d\n", err));
3464 wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
3465 struct beacon_parameters *info)
3470 struct wl_priv *wl = WL_PRIV_GET();
3471 struct wl_join_params join_params;
3472 wpa_ie_fixed_t *wps_ie;
3473 wpa_ie_fixed_t *wpa_ie;
3475 wifi_p2p_ie_t *p2p_ie;
3476 bool is_bssup = false;
3477 bool update_bss = false;
3481 u8 beacon_ie[IE_MAX_LEN];
3483 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
3485 s32 join_params_size = 0;
3487 WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
3488 info->interval, info->dtim_period, info->head_len, info->tail_len));
3489 if (wl->p2p_supported && p2p_on(wl) &&
3490 (bssidx >= wl_to_p2p_bss_bssidx(wl,
3491 P2PAPI_BSSCFG_CONNECTION))) {
3492 memset(beacon_ie, 0, sizeof(beacon_ie));
3493 /* We don't need to set beacon for P2P_GO,
3494 * but need to parse ssid from beacon_parameters
3495 * because there is no way to set ssid
3497 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3499 if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
3500 info->head_len - ie_offset,
3501 DOT11_MNG_SSID_ID)) != NULL) {
3502 memcpy(wl->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len);
3503 wl->p2p->ssid.SSID_len = ssid_ie->len;
3504 WL_DBG(("SSID (%s) in Head \n", ssid_ie->data));
3507 WL_ERR(("No SSID in beacon \n"));
3510 /* find the WPSIE */
3511 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
3512 wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
3514 * Should be compared with saved ie before saving it
3516 wl_validate_wps_ie((char *) wps_ie, &pbc);
3517 memcpy(beacon_ie, wps_ie, wpsie_len);
3519 WL_ERR(("No WPSIE in beacon \n"));
3523 /* find the P2PIE */
3524 if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)info->tail, info->tail_len)) != NULL) {
3525 /* Total length of P2P Information Element */
3526 p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
3527 #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3528 /* Have to change device address in dev_id attribute because Supplicant
3529 * use primary eth0 address
3531 wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr, P2P_SEID_DEV_ID);
3533 memcpy(&beacon_ie[wpsie_len], p2p_ie, p2pie_len);
3536 WL_ERR(("No P2PIE in beacon \n"));
3538 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3539 beacon_ie, wpsie_len + p2pie_len);
3540 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_ASSOCRSP_FLAG,
3541 beacon_ie, wpsie_len + p2pie_len);
3543 /* find the RSN_IE */
3544 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3545 DOT11_MNG_RSN_ID)) != NULL) {
3546 WL_DBG((" WPA2 IE is found\n"));
3548 is_bssup = wl_cfgp2p_bss_isup(dev, bssidx);
3550 if (!is_bssup && (wpa2_ie != NULL)) {
3551 if ((err = wl_validate_wpa2ie(dev, wpa2_ie, bssidx)) < 0) {
3552 WL_ERR(("WPA2 IE parsing error"));
3555 err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
3557 WL_ERR(("SET INFRA error %d\n", err));
3560 err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p->ssid,
3561 sizeof(wl->p2p->ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
3563 WL_ERR(("GO SSID setting error %d\n", err));
3566 if ((err = wl_cfgp2p_bss(dev, bssidx, 1)) < 0) {
3567 WL_ERR(("GO Bring up error %d\n", err));
3571 } else if (wl_get_drv_status(wl, AP_CREATING)) {
3572 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3575 if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
3576 info->head_len - ie_offset,
3577 DOT11_MNG_SSID_ID)) != NULL) {
3578 memset(&ssid, 0, sizeof(wlc_ssid_t));
3579 memcpy(ssid.SSID, ssid_ie->data, ssid_ie->len);
3580 WL_DBG(("SSID is (%s) in Head \n", ssid.SSID));
3581 ssid.SSID_len = ssid_ie->len;
3582 wldev_iovar_setint(dev, "mpc", 0);
3583 wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), false);
3584 wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
3585 wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), false);
3586 /* find the RSN_IE */
3587 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3588 DOT11_MNG_RSN_ID)) != NULL) {
3589 WL_DBG((" WPA2 IE is found\n"));
3591 /* find the WPA_IE */
3592 if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail,
3593 info->tail_len)) != NULL) {
3594 WL_DBG((" WPA IE is found\n"));
3596 if ((wpa_ie != NULL || wpa2_ie != NULL)) {
3597 if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 ||
3598 wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
3599 wl->ap_info->security_mode = false;
3602 wl->ap_info->security_mode = true;
3603 kfree(wl->ap_info->rsn_ie);
3604 kfree(wl->ap_info->wpa_ie);
3605 kfree(wl->ap_info->wps_ie);
3606 if (wpa_ie != NULL) {
3608 wl->ap_info->rsn_ie = NULL;
3609 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3610 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3614 wl->ap_info->wpa_ie = NULL;
3615 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3616 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3620 wl->ap_info->security_mode = false;
3621 /* find the WPSIE */
3622 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail,
3623 info->tail_len)) != NULL) {
3624 wpsie_len = wps_ie->length +WPA_RSN_IE_TAG_FIXED_LEN;
3626 * Should be compared with saved ie before saving it
3628 wl_validate_wps_ie((char *) wps_ie, &pbc);
3629 memcpy(beacon_ie, wps_ie, wpsie_len);
3630 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3631 beacon_ie, wpsie_len);
3632 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
3633 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3634 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3636 WL_DBG(("No WPSIE in beacon \n"));
3638 wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), false);
3640 memset(&join_params, 0, sizeof(join_params));
3641 /* join parameters starts with ssid */
3642 join_params_size = sizeof(join_params.ssid);
3643 memcpy(join_params.ssid.SSID, ssid.SSID, ssid.SSID_len);
3644 join_params.ssid.SSID_len = htod32(ssid.SSID_len);
3646 if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
3647 join_params_size, false)) == 0) {
3648 wl_clr_drv_status(wl, AP_CREATING);
3649 wl_set_drv_status(wl, AP_CREATED);
3652 } else if (wl_get_drv_status(wl, AP_CREATED)) {
3654 /* find the WPSIE */
3655 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
3656 wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
3658 * Should be compared with saved ie before saving it
3660 wl_validate_wps_ie((char *) wps_ie, &pbc);
3661 memcpy(beacon_ie, wps_ie, wpsie_len);
3662 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3663 beacon_ie, wpsie_len);
3664 if (wl->ap_info->wps_ie &&
3665 memcmp(wl->ap_info->wps_ie, wps_ie, wpsie_len)) {
3666 WL_DBG((" WPS IE is changed\n"));
3667 kfree(wl->ap_info->wps_ie);
3668 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
3669 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3670 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3671 } else if (wl->ap_info->wps_ie == NULL) {
3672 WL_DBG((" WPS IE is added\n"));
3673 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
3674 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3675 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3677 /* find the RSN_IE */
3678 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3679 DOT11_MNG_RSN_ID)) != NULL) {
3680 WL_DBG((" WPA2 IE is found\n"));
3682 /* find the WPA_IE */
3683 if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail,
3684 info->tail_len)) != NULL) {
3685 WL_DBG((" WPA IE is found\n"));
3687 if ((wpa_ie != NULL || wpa2_ie != NULL)) {
3688 if (!wl->ap_info->security_mode) {
3689 /* change from open mode to security mode */
3691 if (wpa_ie != NULL) {
3692 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3693 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3696 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3697 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3700 } else if (wl->ap_info->wpa_ie) {
3701 /* change from WPA mode to WPA2 mode */
3702 if (wpa2_ie != NULL) {
3704 kfree(wl->ap_info->wpa_ie);
3705 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3706 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3708 wl->ap_info->wpa_ie = NULL;
3710 else if (memcmp(wl->ap_info->wpa_ie,
3711 wpa_ie, wpa_ie->length +
3712 WPA_RSN_IE_TAG_FIXED_LEN)) {
3713 kfree(wl->ap_info->wpa_ie);
3715 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3716 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3718 wl->ap_info->rsn_ie = NULL;
3721 /* change from WPA2 mode to WPA mode */
3722 if (wpa_ie != NULL) {
3724 kfree(wl->ap_info->rsn_ie);
3725 wl->ap_info->rsn_ie = NULL;
3726 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3727 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3729 } else if (memcmp(wl->ap_info->rsn_ie,
3730 wpa2_ie, wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN)) {
3732 kfree(wl->ap_info->rsn_ie);
3733 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3734 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3736 wl->ap_info->wpa_ie = NULL;
3740 wl->ap_info->security_mode = true;
3741 wl_cfgp2p_bss(dev, bssidx, 0);
3742 if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 ||
3743 wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
3746 wl_cfgp2p_bss(dev, bssidx, 1);
3750 WL_ERR(("No WPSIE in beacon \n"));
3756 #if defined(ANDROID_WIRELESS_PATCH)
3758 wl_cfg80211_drv_start(struct wiphy *wiphy, struct net_device *dev)
3760 /* struct wl_priv *wl = wiphy_to_wl(wiphy); */
3763 printk("Android driver start command\n");
3768 wl_cfg80211_drv_stop(struct wiphy *wiphy, struct net_device *dev)
3770 /* struct wl_priv *wl = wiphy_to_wl(wiphy); */
3773 printk("Android driver stop command\n");
3776 #endif /* defined(ANDROID_WIRELESS_PATCH) */
3778 static struct cfg80211_ops wl_cfg80211_ops = {
3779 .add_virtual_intf = wl_cfg80211_add_virtual_iface,
3780 .del_virtual_intf = wl_cfg80211_del_virtual_iface,
3781 .change_virtual_intf = wl_cfg80211_change_virtual_iface,
3782 .scan = wl_cfg80211_scan,
3783 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
3784 .join_ibss = wl_cfg80211_join_ibss,
3785 .leave_ibss = wl_cfg80211_leave_ibss,
3786 .get_station = wl_cfg80211_get_station,
3787 .set_tx_power = wl_cfg80211_set_tx_power,
3788 .get_tx_power = wl_cfg80211_get_tx_power,
3789 .add_key = wl_cfg80211_add_key,
3790 .del_key = wl_cfg80211_del_key,
3791 .get_key = wl_cfg80211_get_key,
3792 .set_default_key = wl_cfg80211_config_default_key,
3793 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
3794 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
3795 .connect = wl_cfg80211_connect,
3796 .disconnect = wl_cfg80211_disconnect,
3797 .suspend = wl_cfg80211_suspend,
3798 .resume = wl_cfg80211_resume,
3799 .set_pmksa = wl_cfg80211_set_pmksa,
3800 .del_pmksa = wl_cfg80211_del_pmksa,
3801 .flush_pmksa = wl_cfg80211_flush_pmksa,
3802 .remain_on_channel = wl_cfg80211_remain_on_channel,
3803 .cancel_remain_on_channel = wl_cfg80211_cancel_remain_on_channel,
3804 .mgmt_tx = wl_cfg80211_mgmt_tx,
3805 .mgmt_frame_register = wl_cfg80211_mgmt_frame_register,
3806 .change_bss = wl_cfg80211_change_bss,
3807 .set_channel = wl_cfg80211_set_channel,
3808 .set_beacon = wl_cfg80211_set_beacon,
3809 #if defined(ANDROID_WIRELESS_PATCH)
3810 .drv_start = wl_cfg80211_drv_start,
3811 .drv_stop = wl_cfg80211_drv_stop
3815 static s32 wl_mode_to_nl80211_iftype(s32 mode)
3821 return NL80211_IFTYPE_STATION;
3823 return NL80211_IFTYPE_ADHOC;
3825 return NL80211_IFTYPE_AP;
3827 return NL80211_IFTYPE_UNSPECIFIED;
3833 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
3836 struct wireless_dev *wdev;
3839 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
3840 if (unlikely(!wdev)) {
3841 WL_ERR(("Could not allocate wireless device\n"));
3842 return ERR_PTR(-ENOMEM);
3845 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
3846 if (unlikely(!wdev->wiphy)) {
3847 WL_ERR(("Couldn not allocate wiphy device\n"));
3851 set_wiphy_dev(wdev->wiphy, dev);
3852 wl = wiphy_to_wl(wdev->wiphy);
3853 wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
3854 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3855 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3856 wdev->wiphy->interface_modes =
3857 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC)
3858 | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
3860 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3861 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
3862 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3863 wdev->wiphy->cipher_suites = __wl_cipher_suites;
3864 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3865 wdev->wiphy->max_remain_on_channel_duration = 5000;
3866 wdev->wiphy->mgmt_stypes = wl_cfg80211_default_mgmt_stypes;
3867 #ifndef WL_POWERSAVE_DISABLED
3868 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
3870 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3871 #endif /* !WL_POWERSAVE_DISABLED */
3872 wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK |
3873 WIPHY_FLAG_4ADDR_AP |
3874 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)
3875 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS |
3877 WIPHY_FLAG_4ADDR_STATION;
3879 WL_DBG(("Registering custom regulatory)\n"));
3880 wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3881 wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
3882 /* Now we can register wiphy with cfg80211 module */
3883 err = wiphy_register(wdev->wiphy);
3884 if (unlikely(err < 0)) {
3885 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
3886 goto wiphy_register_out;
3891 wiphy_free(wdev->wiphy);
3896 return ERR_PTR(err);
3899 static void wl_free_wdev(struct wl_priv *wl)
3902 struct wireless_dev *wdev = wl_to_wdev(wl);
3904 if (unlikely(!wdev)) {
3905 WL_ERR(("wdev is invalid\n"));
3909 for (i = 0; i < VWDEV_CNT; i++) {
3910 if ((wl->vwdev[i] != NULL)) {
3911 kfree(wl->vwdev[i]);
3912 wl->vwdev[i] = NULL;
3915 wiphy_unregister(wdev->wiphy);
3916 wiphy_free(wdev->wiphy);
3918 wl_to_wdev(wl) = NULL;
3921 static s32 wl_inform_bss(struct wl_priv *wl)
3923 struct wl_scan_results *bss_list;
3924 struct wl_bss_info *bi = NULL; /* must be initialized */
3928 bss_list = wl->bss_list;
3930 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
3931 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
3932 bss_list->version));
3936 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
3937 bi = next_bss(bss_list, bi);
3938 for_each_bss(bss_list, bi, i) {
3939 err = wl_inform_single_bss(wl, bi);
3946 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
3948 struct wiphy *wiphy = wiphy_from_scan(wl);
3949 struct ieee80211_mgmt *mgmt;
3950 struct ieee80211_channel *channel;
3951 struct ieee80211_supported_band *band;
3952 struct wl_cfg80211_bss_info *notif_bss_info;
3953 struct wl_scan_req *sr = wl_to_sr(wl);
3954 struct beacon_proberesp *beacon_proberesp;
3960 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
3961 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
3964 notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt)
3965 - sizeof(u8) + WL_BSS_INFO_MAX, GFP_KERNEL);
3966 if (unlikely(!notif_bss_info)) {
3967 WL_ERR(("notif_bss_info alloc failed\n"));
3970 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
3971 notif_bss_info->channel =
3972 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
3974 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
3975 band = wiphy->bands[IEEE80211_BAND_2GHZ];
3977 band = wiphy->bands[IEEE80211_BAND_5GHZ];
3978 notif_bss_info->rssi = bi->RSSI;
3979 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
3980 mgmt_type = wl->active_scan ?
3981 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
3982 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
3983 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type);
3985 beacon_proberesp = wl->active_scan ?
3986 (struct beacon_proberesp *)&mgmt->u.probe_resp :
3987 (struct beacon_proberesp *)&mgmt->u.beacon;
3988 beacon_proberesp->timestamp = 0;
3989 beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
3990 beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
3993 * wl_add_ie is not necessary because it can only add duplicated
3994 * SSID, rate information to frame_buf
3997 * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
3998 * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
3999 * bi->rateset.rates);
4001 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
4002 wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
4003 offsetof(struct wl_cfg80211_bss_info, frame_buf));
4004 notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
4005 u.beacon.variable) + wl_get_ielen(wl);
4006 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4007 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
4009 freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
4011 channel = ieee80211_get_channel(wiphy, freq);
4013 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
4015 notif_bss_info->rssi, notif_bss_info->channel,
4016 mgmt->u.beacon.capab_info, &bi->BSSID));
4018 signal = notif_bss_info->rssi * 100;
4019 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
4021 (notif_bss_info->frame_len),
4022 signal, GFP_KERNEL))) {
4023 WL_ERR(("cfg80211_inform_bss_frame error\n"));
4024 kfree(notif_bss_info);
4027 kfree(notif_bss_info);
4032 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev)
4034 u32 event = ntoh32(e->event_type);
4035 u32 status = ntoh32(e->status);
4036 u16 flags = ntoh16(e->flags);
4038 WL_DBG(("event %d, status %d\n", event, status));
4039 if (event == WLC_E_SET_SSID) {
4040 if (status == WLC_E_STATUS_SUCCESS) {
4041 if (!wl_is_ibssmode(wl, ndev))
4044 } else if (event == WLC_E_LINK) {
4045 if (flags & WLC_EVENT_MSG_LINK)
4049 WL_DBG(("wl_is_linkup false\n"));
4053 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
4055 u32 event = ntoh32(e->event_type);
4056 u16 flags = ntoh16(e->flags);
4058 if (event == WLC_E_DEAUTH_IND ||
4059 event == WLC_E_DISASSOC_IND ||
4060 event == WLC_E_DISASSOC ||
4061 event == WLC_E_DEAUTH) {
4063 } else if (event == WLC_E_LINK) {
4064 if (!(flags & WLC_EVENT_MSG_LINK))
4071 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
4073 u32 event = ntoh32(e->event_type);
4074 u32 status = ntoh32(e->status);
4076 if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS)
4078 if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS)
4085 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
4086 const wl_event_msg_t *e, void *data)
4089 bool isfree = false;
4094 u32 event = ntoh32(e->event_type);
4095 u32 reason = ntoh32(e->reason);
4096 u32 len = ntoh32(e->datalen);
4099 u8 bsscfgidx = e->bsscfgidx;
4100 struct ieee80211_supported_band *band;
4101 struct ether_addr da;
4102 struct ether_addr bssid;
4103 struct wiphy *wiphy = wl_to_wiphy(wl);
4106 memset(body, 0, sizeof(body));
4107 WL_DBG(("Enter \n"));
4109 if (get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
4110 memcpy(body, data, len);
4111 wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
4112 &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
4113 wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
4115 case WLC_E_ASSOC_IND:
4118 case WLC_E_REASSOC_IND:
4119 fc = FC_REASSOC_REQ;
4121 case WLC_E_DISASSOC_IND:
4124 case WLC_E_DEAUTH_IND:
4134 if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
4137 channel = dtoh32(ci.hw_channel);
4138 if (channel <= CH_MAX_2G_CHANNEL)
4139 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4141 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4143 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4144 freq = ieee80211_channel_to_frequency(channel);
4146 freq = ieee80211_channel_to_frequency(channel, band->band);
4149 err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
4150 &mgmt_frame, &len, body);
4155 if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
4156 cfg80211_send_rx_assoc(ndev, mgmt_frame, len);
4157 } else if (event == WLC_E_DISASSOC_IND) {
4158 cfg80211_send_disassoc(ndev, mgmt_frame, len);
4159 } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
4160 cfg80211_send_deauth(ndev, mgmt_frame, len);
4164 WL_DBG(("wl_notify_connect_status : event %d status : %d \n",
4165 ntoh32(e->event_type), ntoh32(e->status)));
4166 if (wl_is_linkup(wl, e, ndev)) {
4168 if (wl_is_ibssmode(wl, ndev)) {
4169 printk("cfg80211_ibss_joined");
4170 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
4172 WL_DBG(("joined in IBSS network\n"));
4174 printk("wl_bss_connect_done succeeded");
4175 wl_bss_connect_done(wl, ndev, e, data, true);
4176 WL_DBG(("joined in BSS network \"%s\"\n",
4177 ((struct wlc_ssid *)
4178 wl_read_prof(wl, WL_PROF_SSID))->SSID));
4181 wl_update_prof(wl, e, &act, WL_PROF_ACT);
4182 } else if (wl_is_linkdown(wl, e)) {
4183 if (wl_get_drv_status(wl, CONNECTED)) {
4184 printk("link down, call cfg80211_disconnected ");
4186 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
4187 wl_clr_drv_status(wl, CONNECTED);
4189 wl_init_prof(wl->profile);
4191 } else if (wl_get_drv_status(wl, CONNECTING)) {
4192 printk("link down, during connecting");
4193 wl_bss_connect_done(wl, ndev, e, data, false);
4195 } else if (wl_is_nonetwork(wl, e)) {
4196 printk("connect failed e->status 0x%x", (int)ntoh32(e->status));
4197 if (wl_get_drv_status(wl, CONNECTING))
4198 wl_bss_connect_done(wl, ndev, e, data, false);
4200 printk("%s nothing\n", __FUNCTION__);
4211 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
4212 const wl_event_msg_t *e, void *data)
4216 u32 event = be32_to_cpu(e->event_type);
4217 u32 status = be32_to_cpu(e->status);
4219 WL_DBG(("Enter \n"));
4220 if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
4221 if (test_bit(WL_STATUS_CONNECTED, &wl->status))
4222 wl_bss_roaming_done(wl, ndev, e, data);
4224 wl_bss_connect_done(wl, ndev, e, data, true);
4226 wl_update_prof(wl, e, &act, WL_PROF_ACT);
4233 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
4235 struct wl_priv *wl = WL_PRIV_GET();
4238 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
4239 BUG_ON(unlikely(!buflen));
4241 return wldev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen, false);
4245 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
4248 struct wl_priv *wl = WL_PRIV_GET();
4252 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
4253 BUG_ON(unlikely(!len));
4254 err = wldev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
4255 WL_IOCTL_LEN_MAX, false);
4256 if (unlikely(err)) {
4257 WL_ERR(("error (%d)\n", err));
4260 memcpy(buf, wl->ioctl_buf, buf_len);
4265 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
4267 wl_assoc_info_t assoc_info;
4268 struct wl_connect_info *conn_info = wl_to_conn(wl);
4271 WL_DBG(("Enter \n"));
4272 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
4274 if (unlikely(err)) {
4275 WL_ERR(("could not get assoc info (%d)\n", err));
4278 memcpy(&assoc_info, wl->extra_buf, sizeof(wl_assoc_info_t));
4279 assoc_info.req_len = htod32(assoc_info.req_len);
4280 assoc_info.resp_len = htod32(assoc_info.resp_len);
4281 assoc_info.flags = htod32(assoc_info.flags);
4282 if (assoc_info.req_len) {
4283 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
4285 if (unlikely(err)) {
4286 WL_ERR(("could not get assoc req (%d)\n", err));
4289 conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req);
4290 if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
4291 conn_info->req_ie_len -= ETHER_ADDR_LEN;
4294 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
4296 conn_info->req_ie_len = 0;
4297 conn_info->req_ie = NULL;
4299 if (assoc_info.resp_len) {
4300 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
4302 if (unlikely(err)) {
4303 WL_ERR(("could not get assoc resp (%d)\n", err));
4306 conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
4307 conn_info->resp_ie =
4308 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
4310 conn_info->resp_ie_len = 0;
4311 conn_info->resp_ie = NULL;
4313 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
4314 conn_info->resp_ie_len));
4319 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
4320 size_t *join_params_size)
4322 chanspec_t chanspec = 0;
4325 join_params->params.chanspec_num = 1;
4326 join_params->params.chanspec_list[0] = ch;
4328 if (join_params->params.chanspec_list[0])
4329 chanspec |= WL_CHANSPEC_BAND_2G;
4331 chanspec |= WL_CHANSPEC_BAND_5G;
4333 chanspec |= WL_CHANSPEC_BW_20;
4334 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
4336 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
4337 join_params->params.chanspec_num * sizeof(chanspec_t);
4339 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
4340 join_params->params.chanspec_list[0] |= chanspec;
4341 join_params->params.chanspec_list[0] =
4342 htodchanspec(join_params->params.chanspec_list[0]);
4344 join_params->params.chanspec_num =
4345 htod32(join_params->params.chanspec_num);
4347 WL_DBG(("%s join_params->params.chanspec_list[0]= %X\n",
4348 __FUNCTION__, join_params->params.chanspec_list[0]));
4353 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev)
4355 struct cfg80211_bss *bss;
4356 struct wl_bss_info *bi;
4357 struct wlc_ssid *ssid;
4358 struct bcm_tlv *tim;
4359 u16 beacon_interval;
4364 struct wiphy *wiphy;
4365 wiphy = wl_to_wiphy(wl);
4367 if (wl_is_ibssmode(wl, ndev))
4370 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
4371 bss = cfg80211_get_bss(wiphy, NULL, (s8 *)&wl->bssid,
4372 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
4373 WLAN_CAPABILITY_ESS);
4376 if (unlikely(!bss)) {
4377 WL_DBG(("Could not find the AP\n"));
4378 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
4379 err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_BSS_INFO,
4380 wl->extra_buf, WL_EXTRA_BUF_MAX, false);
4381 if (unlikely(err)) {
4382 WL_ERR(("Could not get bss info %d\n", err));
4383 goto update_bss_info_out;
4385 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
4386 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
4388 goto update_bss_info_out;
4390 err = wl_inform_single_bss(wl, bi);
4392 goto update_bss_info_out;
4394 ie = ((u8 *)bi) + bi->ie_offset;
4395 ie_len = bi->ie_length;
4396 beacon_interval = cpu_to_le16(bi->beacon_period);
4398 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
4399 ie = bss->information_elements;
4400 ie_len = bss->len_information_elements;
4401 beacon_interval = bss->beacon_interval;
4402 cfg80211_put_bss(bss);
4405 tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
4407 dtim_period = tim->data[1];
4410 * active scan was done so we could not get dtim
4411 * information out of probe response.
4412 * so we speficially query dtim information to dongle.
4414 err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_DTIMPRD,
4415 &dtim_period, sizeof(dtim_period), false);
4416 if (unlikely(err)) {
4417 WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
4418 goto update_bss_info_out;
4422 wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
4423 wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
4425 update_bss_info_out:
4431 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
4432 const wl_event_msg_t *e, void *data)
4434 struct wl_connect_info *conn_info = wl_to_conn(wl);
4437 wl_get_assoc_ies(wl, ndev);
4438 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
4439 wl_update_bss_info(wl, ndev);
4440 cfg80211_roamed(ndev,
4441 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
4445 conn_info->req_ie, conn_info->req_ie_len,
4446 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4447 WL_DBG(("Report roaming result\n"));
4449 wl_set_drv_status(wl, CONNECTED);
4455 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
4456 const wl_event_msg_t *e, void *data, bool completed)
4458 struct wl_connect_info *conn_info = wl_to_conn(wl);
4461 WL_DBG((" enter\n"));
4462 wl_get_assoc_ies(wl, ndev);
4463 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
4464 wl_update_bss_info(wl, ndev);
4465 if (wl_get_drv_status(wl, CONNECTING)) {
4466 wl_clr_drv_status(wl, CONNECTING);
4467 cfg80211_connect_result(ndev,
4470 conn_info->req_ie_len,
4472 conn_info->resp_ie_len,
4473 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
4475 WL_DBG(("Report connect result - connection %s\n",
4476 completed ? "succeeded" : "failed"));
4479 wl_set_drv_status(wl, CONNECTED);
4481 if (wl->scan_request) {
4482 wl_cfg80211_scan_abort(wl, ndev);
4490 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
4491 const wl_event_msg_t *e, void *data)
4493 u16 flags = ntoh16(e->flags);
4494 enum nl80211_key_type key_type;
4497 if (flags & WLC_EVENT_MSG_GROUP)
4498 key_type = NL80211_KEYTYPE_GROUP;
4500 key_type = NL80211_KEYTYPE_PAIRWISE;
4502 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
4510 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
4511 const wl_event_msg_t *e, void *data)
4513 struct channel_info channel_inform;
4514 struct wl_scan_results *bss_list;
4515 u32 len = WL_SCAN_BUF_MAX;
4518 WL_DBG(("Enter \n"));
4519 if (wl->iscan_on && wl->iscan_kickstart)
4520 return wl_wakeup_iscan(wl_to_iscan(wl));
4522 if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
4523 wl_clr_drv_status(wl, SCANNING);
4524 WL_DBG(("Scan complete while device not scanning\n"));
4527 wl_clr_drv_status(wl, SCANNING);
4529 err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
4530 sizeof(channel_inform), false);
4531 if (unlikely(err)) {
4532 WL_ERR(("scan busy (%d)\n", err));
4535 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
4536 if (unlikely(channel_inform.scan_channel)) {
4538 WL_DBG(("channel_inform.scan_channel (%d)\n",
4539 channel_inform.scan_channel));
4541 wl->bss_list = wl->scan_results;
4542 bss_list = wl->bss_list;
4543 memset(bss_list, 0, len);
4544 bss_list->buflen = htod32(len);
4545 err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, false);
4546 if (unlikely(err)) {
4547 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
4551 bss_list->buflen = dtoh32(bss_list->buflen);
4552 bss_list->version = dtoh32(bss_list->version);
4553 bss_list->count = dtoh32(bss_list->count);
4555 err = wl_inform_bss(wl);
4560 if (wl->scan_request) {
4561 WL_DBG(("cfg80211_scan_done\n"));
4562 cfg80211_scan_done(wl->scan_request, false);
4563 wl->scan_request = NULL;
4569 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
4570 const struct ether_addr *sa, const struct ether_addr *bssid,
4571 u8 **pheader, u32 *body_len, u8 *pbody)
4573 struct dot11_management_header *hdr;
4577 u32 prebody_len = *body_len;
4580 /* capability , listen interval */
4581 totlen = DOT11_ASSOC_REQ_FIXED_LEN;
4582 *body_len += DOT11_ASSOC_REQ_FIXED_LEN;
4585 case FC_REASSOC_REQ:
4586 /* capability, listen inteval, ap address */
4587 totlen = DOT11_REASSOC_REQ_FIXED_LEN;
4588 *body_len += DOT11_REASSOC_REQ_FIXED_LEN;
4591 totlen += DOT11_MGMT_HDR_LEN + prebody_len;
4592 *pheader = kzalloc(totlen, GFP_KERNEL);
4593 if (*pheader == NULL) {
4594 WL_ERR(("memory alloc failed \n"));
4597 hdr = (struct dot11_management_header *) (*pheader);
4598 hdr->fc = htol16(fc);
4601 offset = (u8*)(hdr + 1) + (totlen - DOT11_MGMT_HDR_LEN - prebody_len);
4602 bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN);
4603 bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN);
4604 bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN);
4605 bcopy((const char*)pbody, offset, prebody_len);
4610 wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
4611 const wl_event_msg_t *e, void *data)
4613 struct ieee80211_supported_band *band;
4614 struct wiphy *wiphy = wl_to_wiphy(wl);
4615 struct ether_addr da;
4616 struct ether_addr bssid;
4617 bool isfree = false;
4620 wl_event_rx_frame_data_t *rxframe =
4621 (wl_event_rx_frame_data_t*)data;
4622 u32 event = ntoh32(e->event_type);
4624 u8 bsscfgidx = e->bsscfgidx;
4625 u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t);
4626 u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK) & 0x0f);
4627 if (channel <= CH_MAX_2G_CHANNEL)
4628 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4630 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4632 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4633 freq = ieee80211_channel_to_frequency(channel);
4635 freq = ieee80211_channel_to_frequency(channel, band->band);
4637 if (event == WLC_E_ACTION_FRAME_RX) {
4638 wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
4639 &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
4640 wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
4641 err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid,
4642 &mgmt_frame, &mgmt_frame_len,
4643 (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1));
4645 WL_ERR(("%s: Error in receiving action frame len %d channel %d freq %d\n",
4646 __func__, mgmt_frame_len, channel, freq));
4651 mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
4654 cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
4656 WL_DBG(("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__,
4657 mgmt_frame_len, ntoh32(e->datalen), channel, freq));
4665 static void wl_init_conf(struct wl_conf *conf)
4668 WL_DBG(("Enter \n"));
4669 for (i = 0; i <= VWDEV_CNT; i++) {
4670 conf->mode[i].type = -1;
4671 conf->mode[i].ndev = NULL;
4673 conf->frag_threshold = (u32)-1;
4674 conf->rts_threshold = (u32)-1;
4675 conf->retry_short = (u32)-1;
4676 conf->retry_long = (u32)-1;
4677 conf->tx_power = -1;
4680 static void wl_init_prof(struct wl_profile *prof)
4682 memset(prof, 0, sizeof(*prof));
4685 static void wl_init_event_handler(struct wl_priv *wl)
4687 memset(wl->evt_handler, 0, sizeof(wl->evt_handler));
4689 wl->evt_handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
4690 /* wl->evt_handler[WLC_E_JOIN] = wl_notify_connect_status; */
4691 wl->evt_handler[WLC_E_LINK] = wl_notify_connect_status;
4692 wl->evt_handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
4693 wl->evt_handler[WLC_E_DEAUTH] = wl_notify_connect_status;
4694 wl->evt_handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
4695 wl->evt_handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
4696 wl->evt_handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
4697 wl->evt_handler[WLC_E_ROAM] = wl_notify_roaming_status;
4698 wl->evt_handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
4699 wl->evt_handler[WLC_E_SET_SSID] = wl_notify_connect_status;
4700 wl->evt_handler[WLC_E_ACTION_FRAME_RX] = wl_notify_rx_mgmt_frame;
4701 wl->evt_handler[WLC_E_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
4702 wl->evt_handler[WLC_E_P2P_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
4703 wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete;
4704 wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
4705 wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
4709 static s32 wl_init_priv_mem(struct wl_priv *wl)
4711 WL_DBG(("Enter \n"));
4712 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
4713 if (unlikely(!wl->scan_results)) {
4714 WL_ERR(("Scan results alloc failed\n"));
4715 goto init_priv_mem_out;
4717 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
4718 if (unlikely(!wl->conf)) {
4719 WL_ERR(("wl_conf alloc failed\n"));
4720 goto init_priv_mem_out;
4722 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
4723 if (unlikely(!wl->profile)) {
4724 WL_ERR(("wl_profile alloc failed\n"));
4725 goto init_priv_mem_out;
4727 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4728 if (unlikely(!wl->bss_info)) {
4729 WL_ERR(("Bss information alloc failed\n"));
4730 goto init_priv_mem_out;
4733 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
4734 if (unlikely(!wl->scan_req_int)) {
4735 WL_ERR(("Scan req alloc failed\n"));
4736 goto init_priv_mem_out;
4738 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
4739 if (unlikely(!wl->ioctl_buf)) {
4740 WL_ERR(("Ioctl buf alloc failed\n"));
4741 goto init_priv_mem_out;
4743 wl->escan_ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
4744 if (unlikely(!wl->escan_ioctl_buf)) {
4745 WL_ERR(("Ioctl buf alloc failed\n"));
4746 goto init_priv_mem_out;
4748 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4749 if (unlikely(!wl->extra_buf)) {
4750 WL_ERR(("Extra buf alloc failed\n"));
4751 goto init_priv_mem_out;
4753 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
4754 if (unlikely(!wl->iscan)) {
4755 WL_ERR(("Iscan buf alloc failed\n"));
4756 goto init_priv_mem_out;
4758 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
4759 if (unlikely(!wl->fw)) {
4760 WL_ERR(("fw object alloc failed\n"));
4761 goto init_priv_mem_out;
4763 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
4764 if (unlikely(!wl->pmk_list)) {
4765 WL_ERR(("pmk list alloc failed\n"));
4766 goto init_priv_mem_out;
4772 wl_deinit_priv_mem(wl);
4777 static void wl_deinit_priv_mem(struct wl_priv *wl)
4779 kfree(wl->scan_results);
4780 wl->scan_results = NULL;
4781 kfree(wl->bss_info);
4782 wl->bss_info = NULL;
4787 kfree(wl->scan_req_int);
4788 wl->scan_req_int = NULL;
4789 kfree(wl->ioctl_buf);
4790 wl->ioctl_buf = NULL;
4791 kfree(wl->escan_ioctl_buf);
4792 wl->escan_ioctl_buf = NULL;
4793 kfree(wl->extra_buf);
4794 wl->extra_buf = NULL;
4799 kfree(wl->pmk_list);
4800 wl->pmk_list = NULL;
4802 kfree(wl->ap_info->wpa_ie);
4803 kfree(wl->ap_info->rsn_ie);
4804 kfree(wl->ap_info->wps_ie);
4810 static s32 wl_create_event_handler(struct wl_priv *wl)
4812 WL_DBG(("Enter \n"));
4813 sema_init(&wl->event_sync, 0);
4814 wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
4815 if (IS_ERR(wl->event_tsk)) {
4816 wl->event_tsk = NULL;
4817 WL_ERR(("failed to create event thread\n"));
4823 static void wl_destroy_event_handler(struct wl_priv *wl)
4825 if (wl->event_tsk) {
4826 send_sig(SIGTERM, wl->event_tsk, 1);
4827 kthread_stop(wl->event_tsk);
4828 wl->event_tsk = NULL;
4832 static void wl_term_iscan(struct wl_priv *wl)
4834 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
4836 if (wl->iscan_on && iscan->tsk) {
4837 iscan->state = WL_ISCAN_STATE_IDLE;
4838 WL_INFO(("SIGTERM\n"));
4839 send_sig(SIGTERM, iscan->tsk, 1);
4840 WL_DBG(("kthread_stop\n"));
4841 kthread_stop(iscan->tsk);
4846 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
4848 struct wl_priv *wl = iscan_to_wl(iscan);
4850 WL_DBG(("Enter \n"));
4851 if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
4852 wl_clr_drv_status(wl, SCANNING);
4853 WL_ERR(("Scan complete while device not scanning\n"));
4856 wl_clr_drv_status(wl, SCANNING);
4857 if (likely(wl->scan_request)) {
4858 cfg80211_scan_done(wl->scan_request, aborted);
4859 wl->scan_request = NULL;
4861 wl->iscan_kickstart = false;
4864 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
4866 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
4867 WL_DBG(("wake up iscan\n"));
4876 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
4877 struct wl_scan_results **bss_list)
4879 struct wl_iscan_results list;
4880 struct wl_scan_results *results;
4881 struct wl_iscan_results *list_buf;
4884 WL_DBG(("Enter \n"));
4885 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
4886 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
4887 results = &list_buf->results;
4888 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
4889 results->version = 0;
4892 memset(&list, 0, sizeof(list));
4893 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
4894 err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list,
4895 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
4897 if (unlikely(err)) {
4898 WL_ERR(("error (%d)\n", err));
4901 results->buflen = dtoh32(results->buflen);
4902 results->version = dtoh32(results->version);
4903 results->count = dtoh32(results->count);
4904 WL_DBG(("results->count = %d\n", results->count));
4905 WL_DBG(("results->buflen = %d\n", results->buflen));
4906 *status = dtoh32(list_buf->status);
4907 *bss_list = results;
4912 static s32 wl_iscan_done(struct wl_priv *wl)
4914 struct wl_iscan_ctrl *iscan = wl->iscan;
4917 iscan->state = WL_ISCAN_STATE_IDLE;
4920 wl_notify_iscan_complete(iscan, false);
4926 static s32 wl_iscan_pending(struct wl_priv *wl)
4928 struct wl_iscan_ctrl *iscan = wl->iscan;
4931 /* Reschedule the timer */
4932 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
4933 iscan->timer_on = 1;
4938 static s32 wl_iscan_inprogress(struct wl_priv *wl)
4940 struct wl_iscan_ctrl *iscan = wl->iscan;
4945 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
4947 /* Reschedule the timer */
4948 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
4949 iscan->timer_on = 1;
4954 static s32 wl_iscan_aborted(struct wl_priv *wl)
4956 struct wl_iscan_ctrl *iscan = wl->iscan;
4959 iscan->state = WL_ISCAN_STATE_IDLE;
4961 wl_notify_iscan_complete(iscan, true);
4967 static s32 wl_iscan_thread(void *data)
4969 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
4970 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
4971 struct wl_priv *wl = iscan_to_wl(iscan);
4975 sched_setscheduler(current, SCHED_FIFO, ¶m);
4976 allow_signal(SIGTERM);
4977 status = WL_SCAN_RESULTS_PARTIAL;
4978 while (likely(!down_interruptible(&iscan->sync))) {
4979 if (kthread_should_stop())
4981 if (iscan->timer_on) {
4982 del_timer_sync(&iscan->timer);
4983 iscan->timer_on = 0;
4986 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
4987 if (unlikely(err)) {
4988 status = WL_SCAN_RESULTS_ABORTED;
4989 WL_ERR(("Abort iscan\n"));
4992 iscan->iscan_handler[status] (wl);
4994 if (iscan->timer_on) {
4995 del_timer_sync(&iscan->timer);
4996 iscan->timer_on = 0;
4998 WL_DBG(("%s was terminated\n", __func__));
5003 static void wl_iscan_timer(unsigned long data)
5005 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
5008 iscan->timer_on = 0;
5009 WL_DBG(("timer expired\n"));
5010 wl_wakeup_iscan(iscan);
5014 static s32 wl_invoke_iscan(struct wl_priv *wl)
5016 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
5019 if (wl->iscan_on && !iscan->tsk) {
5020 iscan->state = WL_ISCAN_STATE_IDLE;
5021 sema_init(&iscan->sync, 0);
5022 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
5023 if (IS_ERR(iscan->tsk)) {
5024 WL_ERR(("Could not create iscan thread\n"));
5033 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan)
5035 memset(iscan->iscan_handler, 0, sizeof(iscan->iscan_handler));
5036 iscan->iscan_handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
5037 iscan->iscan_handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
5038 iscan->iscan_handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
5039 iscan->iscan_handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
5040 iscan->iscan_handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
5043 static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
5045 WL_DBG(("Enter \n"));
5046 if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
5047 wl_clr_drv_status(wl, SCANNING);
5048 WL_ERR(("Scan complete while device not scanning\n"));
5051 wl_clr_drv_status(wl, SCANNING);
5052 if (wl->p2p_supported && p2p_on(wl))
5053 wl_clr_p2p_status(wl, SCANNING);
5055 if (likely(wl->scan_request)) {
5056 cfg80211_scan_done(wl->scan_request, aborted);
5057 wl->scan_request = NULL;
5061 static s32 wl_escan_handler(struct wl_priv *wl,
5062 struct net_device *ndev,
5063 const wl_event_msg_t *e, void *data)
5066 s32 status = ntoh32(e->status);
5068 wl_escan_result_t *escan_result;
5069 wl_bss_info_t *bss = NULL;
5070 wl_scan_results_t *list;
5073 WL_DBG((" enter event type : %d, status : %d \n",
5074 ntoh32(e->event_type), ntoh32(e->status)));
5075 if (!wl->escan_on &&
5076 !wl_get_drv_status(wl, SCANNING)) {
5077 WL_ERR(("escan is not ready \n"));
5081 if (status == WLC_E_STATUS_PARTIAL) {
5082 WL_INFO(("WLC_E_STATUS_PARTIAL \n"));
5083 escan_result = (wl_escan_result_t *) data;
5084 if (!escan_result) {
5085 WL_ERR(("Invalid escan result (NULL pointer)\n"));
5088 if (dtoh16(escan_result->bss_count) != 1) {
5089 WL_ERR(("Invalid bss_count %d: ignoring\n", escan_result->bss_count));
5092 bi = escan_result->bss_info;
5094 WL_ERR(("Invalid escan bss info (NULL pointer)\n"));
5097 bi_length = dtoh32(bi->length);
5098 if (bi_length != (dtoh32(escan_result->buflen) - WL_ESCAN_RESULTS_FIXED_SIZE)) {
5099 WL_ERR(("Invalid bss_info length %d: ignoring\n", bi_length));
5102 list = (wl_scan_results_t *)wl->escan_info.escan_buf;
5103 if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
5104 WL_ERR(("Buffer is too small: ignoring\n"));
5107 #define WLC_BSS_RSSI_ON_CHANNEL 0x0002
5108 for (i = 0; i < list->count; i++) {
5109 bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
5112 if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
5113 CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
5114 bi->SSID_len == bss->SSID_len &&
5115 !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
5116 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
5117 (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
5118 /* preserve max RSSI if the measurements are
5119 * both on-channel or both off-channel
5121 bss->RSSI = MAX(bss->RSSI, bi->RSSI);
5122 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
5123 (bi->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
5124 /* preserve the on-channel rssi measurement
5125 * if the new measurement is off channel
5127 bss->RSSI = bi->RSSI;
5128 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
5134 memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length);
5135 list->version = dtoh32(bi->version);
5136 list->buflen += bi_length;
5140 else if (status == WLC_E_STATUS_SUCCESS) {
5141 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5142 if (likely(wl->scan_request)) {
5144 WL_INFO(("ESCAN COMPLETED\n"));
5145 wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
5147 wl_notify_escan_complete(wl, false);
5151 else if (status == WLC_E_STATUS_ABORT) {
5152 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5153 if (likely(wl->scan_request)) {
5155 WL_INFO(("ESCAN COMPLETED\n"));
5156 wl_notify_escan_complete(wl, true);
5164 static s32 wl_init_scan(struct wl_priv *wl)
5166 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
5170 iscan->dev = wl_to_prmry_ndev(wl);
5171 iscan->state = WL_ISCAN_STATE_IDLE;
5172 wl_init_iscan_handler(iscan);
5173 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
5174 init_timer(&iscan->timer);
5175 iscan->timer.data = (unsigned long) iscan;
5176 iscan->timer.function = wl_iscan_timer;
5177 sema_init(&iscan->sync, 0);
5178 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
5179 if (IS_ERR(iscan->tsk)) {
5180 WL_ERR(("Could not create iscan thread\n"));
5185 } else if (wl->escan_on) {
5186 wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler;
5187 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5193 static void wl_init_fw(struct wl_fw_ctrl *fw)
5198 static s32 wl_init_priv(struct wl_priv *wl)
5200 struct wiphy *wiphy = wl_to_wiphy(wl);
5204 wl->scan_request = NULL;
5205 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
5206 wl->iscan_on = false;
5207 wl->escan_on = true;
5208 wl->roam_on = false;
5209 wl->iscan_kickstart = false;
5210 wl->active_scan = true;
5211 wl->dongle_up = false;
5212 wl->rf_blocked = false;
5214 for (i = 0; i < VWDEV_CNT; i++)
5215 wl->vwdev[i] = NULL;
5217 init_waitqueue_head(&wl->dongle_event_wait);
5219 err = wl_init_priv_mem(wl);
5222 if (unlikely(wl_create_event_handler(wl)))
5224 wl_init_event_handler(wl);
5225 mutex_init(&wl->usr_sync);
5226 err = wl_init_scan(wl);
5230 wl_init_conf(wl->conf);
5231 wl_init_prof(wl->profile);
5237 static void wl_deinit_priv(struct wl_priv *wl)
5239 wl_destroy_event_handler(wl);
5240 wl->dongle_up = false; /* dongle down */
5244 wl_deinit_priv_mem(wl);
5247 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
5248 s32 wl_cfg80211_sysctl_export_devaddr(void *data)
5250 /* Export the p2p_dev_addr via sysctl interface
5251 * so that wpa_supplicant can access it
5253 dhd_pub_t *dhd = (dhd_pub_t *)data;
5254 struct wl_priv *wl = WL_PRIV_GET();
5256 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
5258 sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p->dev_addr.octet));
5259 sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p->int_addr.octet));
5263 #endif /* CONFIG_SYSCTL */
5265 s32 wl_cfg80211_attach_post(struct net_device *ndev)
5267 struct wl_priv * wl = NULL;
5270 if (unlikely(!ndev)) {
5271 WL_ERR(("ndev is invaild\n"));
5275 if (wl && !wl_get_drv_status(wl, READY)) {
5277 wl_cfgp2p_supported(wl, ndev)) {
5278 wl->wdev->wiphy->interface_modes |=
5279 (BIT(NL80211_IFTYPE_P2P_CLIENT)|
5280 BIT(NL80211_IFTYPE_P2P_GO));
5281 if ((err = wl_cfgp2p_init_priv(wl)) != 0)
5283 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
5284 wl_cfg80211_sysctl_export_devaddr(wl->pub);
5286 wl->p2p_supported = true;
5291 wl_set_drv_status(wl, READY);
5295 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
5297 struct wireless_dev *wdev;
5299 struct wl_iface *ci;
5303 if (unlikely(!ndev)) {
5304 WL_ERR(("ndev is invaild\n"));
5307 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
5308 if (unlikely(!wl_cfg80211_dev)) {
5309 WL_ERR(("wl_cfg80211_dev is invalid\n"));
5312 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
5313 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
5314 if (unlikely(IS_ERR(wdev)))
5317 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
5318 wl = wdev_to_wl(wdev);
5322 ci = (struct wl_iface *)wl_to_ci(wl);
5324 ndev->ieee80211_ptr = wdev;
5325 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
5326 wdev->netdev = ndev;
5328 err = wl_init_priv(wl);
5329 if (unlikely(err)) {
5330 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
5331 goto cfg80211_attach_out;
5334 err = wl_setup_rfkill(wl, TRUE);
5335 if (unlikely(err)) {
5336 WL_ERR(("Failed to setup rfkill %d\n", err));
5337 goto cfg80211_attach_out;
5340 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
5341 if (!(wl_sysctl_hdr = register_sysctl_table(wl_sysctl_table))) {
5342 WL_ERR(("%s: sysctl register failed!! \n", __func__));
5343 goto cfg80211_attach_out;
5346 wl_set_drvdata(wl_cfg80211_dev, ci);
5349 cfg80211_attach_out:
5350 err = wl_setup_rfkill(wl, FALSE);
5355 void wl_cfg80211_detach(void)
5362 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
5364 unregister_sysctl_table(wl_sysctl_hdr);
5366 wl_setup_rfkill(wl, FALSE);
5367 if (wl->p2p_supported)
5368 wl_cfgp2p_deinit_priv(wl);
5371 wl_set_drvdata(wl_cfg80211_dev, NULL);
5372 kfree(wl_cfg80211_dev);
5373 wl_cfg80211_dev = NULL;
5374 wl_clear_sdio_func();
5377 static void wl_wakeup_event(struct wl_priv *wl)
5379 up(&wl->event_sync);
5382 static s32 wl_event_handler(void *data)
5384 struct net_device *netdev;
5385 struct wl_priv *wl = (struct wl_priv *)data;
5386 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
5387 struct wl_event_q *e;
5389 sched_setscheduler(current, SCHED_FIFO, ¶m);
5390 allow_signal(SIGTERM);
5391 while (likely(!down_interruptible(&wl->event_sync))) {
5392 if (kthread_should_stop())
5394 e = wl_deq_event(wl);
5396 WL_ERR(("equeue empty..\n"));
5399 WL_DBG(("event type (%d), if idx: %d\n", e->etype, e->emsg.ifidx));
5400 netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx);
5402 netdev = wl_to_prmry_ndev(wl);
5403 if (wl->evt_handler[e->etype]) {
5404 wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata);
5406 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
5410 WL_DBG(("%s was terminated\n", __func__));
5415 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
5417 u32 event_type = ntoh32(e->event_type);
5418 struct wl_priv *wl = WL_PRIV_GET();
5420 #if (WL_DBG_LEVEL > 0)
5421 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
5422 wl_dbg_estr[event_type] : (s8 *) "Unknown";
5423 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
5424 #endif /* (WL_DBG_LEVEL > 0) */
5426 if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
5427 wl_wakeup_event(wl);
5430 static void wl_init_eq(struct wl_priv *wl)
5432 wl_init_eq_lock(wl);
5433 INIT_LIST_HEAD(&wl->eq_list);
5436 static void wl_flush_eq(struct wl_priv *wl)
5438 struct wl_event_q *e;
5441 while (!list_empty(&wl->eq_list)) {
5442 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
5443 list_del(&e->eq_list);
5450 * retrieve first queued event from head
5453 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
5455 struct wl_event_q *e = NULL;
5458 if (likely(!list_empty(&wl->eq_list))) {
5459 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
5460 list_del(&e->eq_list);
5468 * push event to tail of the queue
5472 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg,
5475 struct wl_event_q *e;
5482 data_len = ntoh32(msg->datalen);
5483 evtq_size = sizeof(struct wl_event_q) + data_len;
5484 e = kzalloc(evtq_size, GFP_ATOMIC);
5486 WL_ERR(("event alloc failed\n"));
5490 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
5492 memcpy(e->edata, data, data_len);
5494 list_add_tail(&e->eq_list, &wl->eq_list);
5500 static void wl_put_event(struct wl_event_q *e)
5505 void wl_cfg80211_set_sdio_func(void *func)
5507 cfg80211_sdio_func = (struct sdio_func *)func;
5510 static void wl_clear_sdio_func(void)
5512 cfg80211_sdio_func = NULL;
5515 struct sdio_func *wl_cfg80211_get_sdio_func(void)
5517 return cfg80211_sdio_func;
5520 static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype)
5526 case NL80211_IFTYPE_MONITOR:
5527 case NL80211_IFTYPE_WDS:
5528 WL_ERR(("type (%d) : currently we do not support this mode\n",
5532 case NL80211_IFTYPE_ADHOC:
5533 mode = WL_MODE_IBSS;
5535 case NL80211_IFTYPE_STATION:
5536 case NL80211_IFTYPE_P2P_CLIENT:
5540 case NL80211_IFTYPE_AP:
5541 case NL80211_IFTYPE_P2P_GO:
5547 WL_ERR(("invalid type (%d)\n", iftype));
5550 infra = htod32(infra);
5551 err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), false);
5552 if (unlikely(err)) {
5553 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
5557 set_mode_by_netdev(wl, ndev, mode);
5561 static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
5563 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5565 s8 eventmask[WL_EVENTING_MASK_LEN];
5568 /* Setup event_msgs */
5569 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5571 err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
5572 if (unlikely(err)) {
5573 WL_ERR(("Get event_msgs error (%d)\n", err));
5574 goto dongle_eventmsg_out;
5576 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
5578 setbit(eventmask, event);
5580 clrbit(eventmask, event);
5582 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5584 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5585 if (unlikely(err)) {
5586 WL_ERR(("Set event_msgs error (%d)\n", err));
5587 goto dongle_eventmsg_out;
5590 dongle_eventmsg_out:
5595 static s32 wl_dongle_eventmsg(struct net_device *ndev)
5597 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5599 s8 eventmask[WL_EVENTING_MASK_LEN];
5602 /* Setup event_msgs */
5603 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5605 err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
5606 if (unlikely(err)) {
5607 WL_ERR(("Get event_msgs error (%d)\n", err));
5608 goto dongle_eventmsg_out;
5610 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
5612 setbit(eventmask, WLC_E_SET_SSID);
5613 setbit(eventmask, WLC_E_PRUNE);
5614 setbit(eventmask, WLC_E_AUTH);
5615 setbit(eventmask, WLC_E_REASSOC);
5616 setbit(eventmask, WLC_E_REASSOC_IND);
5617 setbit(eventmask, WLC_E_DEAUTH_IND);
5618 setbit(eventmask, WLC_E_DEAUTH);
5619 setbit(eventmask, WLC_E_DISASSOC_IND);
5620 setbit(eventmask, WLC_E_DISASSOC);
5621 setbit(eventmask, WLC_E_JOIN);
5622 setbit(eventmask, WLC_E_ASSOC_IND);
5623 setbit(eventmask, WLC_E_PSK_SUP);
5624 setbit(eventmask, WLC_E_LINK);
5625 setbit(eventmask, WLC_E_NDIS_LINK);
5626 setbit(eventmask, WLC_E_MIC_ERROR);
5627 setbit(eventmask, WLC_E_PMKID_CACHE);
5628 setbit(eventmask, WLC_E_TXFAIL);
5629 setbit(eventmask, WLC_E_JOIN_START);
5630 setbit(eventmask, WLC_E_SCAN_COMPLETE);
5631 setbit(eventmask, WLC_E_ACTION_FRAME_RX);
5632 setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE);
5633 setbit(eventmask, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE);
5634 setbit(eventmask, WLC_E_P2P_PROBREQ_MSG);
5635 setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE);
5636 setbit(eventmask, WLC_E_ESCAN_RESULT);
5637 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5639 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5640 if (unlikely(err)) {
5641 WL_ERR(("Set event_msgs error (%d)\n", err));
5642 goto dongle_eventmsg_out;
5645 dongle_eventmsg_out:
5649 #ifndef EMBEDDED_PLATFORM
5650 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
5658 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
5662 err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), false);
5663 if (unlikely(err)) {
5664 WL_ERR(("WLC_UP error (%d)\n", err));
5669 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
5674 err = wldev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode), false);
5675 if (unlikely(err)) {
5676 WL_ERR(("WLC_SET_PM error (%d)\n", err));
5682 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
5684 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5688 /* Match Host and Dongle rx alignment */
5689 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
5691 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5692 if (unlikely(err)) {
5693 WL_ERR(("txglomalign error (%d)\n", err));
5694 goto dongle_glom_out;
5696 /* disable glom option per default */
5697 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
5698 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5699 if (unlikely(err)) {
5700 WL_ERR(("txglom error (%d)\n", err));
5701 goto dongle_glom_out;
5708 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
5710 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5714 /* Setup timeout if Beacons are lost and roam is off to report link down */
5716 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
5718 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5719 if (unlikely(err)) {
5720 WL_ERR(("bcn_timeout error (%d)\n", err));
5721 goto dongle_rom_out;
5724 /* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
5725 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
5726 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5727 if (unlikely(err)) {
5728 WL_ERR(("roam_off error (%d)\n", err));
5729 goto dongle_rom_out;
5736 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
5737 s32 scan_unassoc_time)
5741 err = wldev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
5742 sizeof(scan_assoc_time), false);
5744 if (err == -EOPNOTSUPP) {
5745 WL_INFO(("Scan assoc time is not supported\n"));
5747 WL_ERR(("Scan assoc time error (%d)\n", err));
5749 goto dongle_scantime_out;
5751 err = wldev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
5752 sizeof(scan_unassoc_time), false);
5754 if (err == -EOPNOTSUPP) {
5755 WL_INFO(("Scan unassoc time is not supported\n"));
5757 WL_ERR(("Scan unassoc time error (%d)\n", err));
5759 goto dongle_scantime_out;
5762 dongle_scantime_out:
5767 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
5769 /* Room for "event_msgs" + '\0' + bitvec */
5770 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5774 /* Set ARP offload */
5775 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
5776 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5778 if (err == -EOPNOTSUPP)
5779 WL_INFO(("arpoe is not supported\n"));
5781 WL_ERR(("arpoe error (%d)\n", err));
5783 goto dongle_offload_out;
5785 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
5786 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5788 if (err == -EOPNOTSUPP)
5789 WL_INFO(("arp_ol is not supported\n"));
5791 WL_ERR(("arp_ol error (%d)\n", err));
5793 goto dongle_offload_out;
5800 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
5803 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
5804 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
5807 src = src + 2; /* Skip past 0x */
5808 if (strlen(src) % 2 != 0) {
5809 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
5812 for (i = 0; *src != '\0'; i++) {
5814 strncpy(num, src, 2);
5816 dst[i] = (u8) simple_strtoul(num, NULL, 16);
5822 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
5824 /* Room for "event_msgs" + '\0' + bitvec */
5825 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5828 struct wl_pkt_filter pkt_filter;
5829 struct wl_pkt_filter *pkt_filterp;
5837 /* add a default packet filter pattern */
5838 str = "pkt_filter_add";
5839 str_len = strlen(str);
5840 strncpy(buf, str, str_len);
5841 buf[str_len] = '\0';
5842 buf_len = str_len + 1;
5844 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
5846 /* Parse packet filter id. */
5847 pkt_filter.id = htod32(100);
5849 /* Parse filter polarity. */
5850 pkt_filter.negate_match = htod32(0);
5852 /* Parse filter type. */
5853 pkt_filter.type = htod32(0);
5855 /* Parse pattern filter offset. */
5856 pkt_filter.u.pattern.offset = htod32(0);
5858 /* Parse pattern filter mask. */
5859 mask_size = htod32(wl_pattern_atoh("0xff",
5860 (char *)pkt_filterp->u.pattern.
5863 /* Parse pattern filter pattern. */
5864 pattern_size = htod32(wl_pattern_atoh("0x00",
5865 (char *)&pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
5867 if (mask_size != pattern_size) {
5868 WL_ERR(("Mask and pattern not the same size\n"));
5870 goto dongle_filter_out;
5873 pkt_filter.u.pattern.size_bytes = mask_size;
5874 buf_len += WL_PKT_FILTER_FIXED_LEN;
5875 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
5877 /* Keep-alive attributes are set in local
5878 * variable (keep_alive_pkt), and
5879 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
5880 * guarantee that the buffer is properly aligned.
5882 memcpy((char *)pkt_filterp, &pkt_filter,
5883 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
5885 err = wldev_ioctl(ndev, WLC_SET_VAR, buf, buf_len, false);
5887 if (err == -EOPNOTSUPP) {
5888 WL_INFO(("filter not supported\n"));
5890 WL_ERR(("filter (%d)\n", err));
5892 goto dongle_filter_out;
5895 /* set mode to allow pattern */
5896 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
5898 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5900 if (err == -EOPNOTSUPP) {
5901 WL_INFO(("filter_mode not supported\n"));
5903 WL_ERR(("filter_mode (%d)\n", err));
5905 goto dongle_filter_out;
5911 #endif /* !EMBEDDED_PLATFORM */
5913 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
5916 #define DHD_SDALIGN 32
5918 struct net_device *ndev;
5919 struct wireless_dev *wdev;
5923 if (wl->dongle_up) {
5924 WL_ERR(("Dongle is already up\n"));
5928 ndev = wl_to_prmry_ndev(wl);
5929 wdev = ndev->ieee80211_ptr;
5932 err = wl_dongle_eventmsg(ndev);
5933 if (unlikely(err)) {
5934 WL_ERR(("wl_dongle_eventmsg failed\n"));
5935 goto default_conf_out;
5937 #ifndef EMBEDDED_PLATFORM
5938 err = wl_dongle_up(ndev, 0);
5939 if (unlikely(err)) {
5940 WL_ERR(("wl_dongle_up failed\n"));
5941 goto default_conf_out;
5943 err = wl_dongle_country(ndev, 0);
5944 if (unlikely(err)) {
5945 WL_ERR(("wl_dongle_country failed\n"));
5946 goto default_conf_out;
5948 err = wl_dongle_power(ndev, PM_FAST);
5949 if (unlikely(err)) {
5950 WL_ERR(("wl_dongle_power failed\n"));
5951 goto default_conf_out;
5953 err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
5954 if (unlikely(err)) {
5955 WL_ERR(("wl_dongle_glom failed\n"));
5956 goto default_conf_out;
5958 err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
5959 if (unlikely(err)) {
5960 WL_ERR(("wl_dongle_roam failed\n"));
5961 goto default_conf_out;
5963 err = wl_dongle_eventmsg(ndev);
5964 if (unlikely(err)) {
5965 WL_ERR(("wl_dongle_eventmsg failed\n"));
5966 goto default_conf_out;
5969 wl_dongle_scantime(ndev, 40, 80);
5970 wl_dongle_offload(ndev, 1, 0xf);
5971 wl_dongle_filter(ndev, 1);
5972 #endif /* !EMBEDDED_PLATFORM */
5974 err = wl_dongle_mode(wl, ndev, wdev->iftype);
5975 if (unlikely(err && err != -EINPROGRESS)) {
5976 WL_ERR(("wl_dongle_mode failed\n"));
5977 goto default_conf_out;
5979 err = wl_dongle_probecap(wl);
5980 if (unlikely(err)) {
5981 WL_ERR(("wl_dongle_probecap failed\n"));
5982 goto default_conf_out;
5985 /* -EINPROGRESS: Call commit handler */
5991 wl->dongle_up = true;
5997 static s32 wl_update_wiphybands(struct wl_priv *wl)
5999 struct wiphy *wiphy;
6004 err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_PHYLIST, &phy_list,
6005 sizeof(phy_list), false);
6006 if (unlikely(err)) {
6007 WL_ERR(("error (%d)\n", err));
6011 phy = ((char *)&phy_list)[1];
6012 WL_DBG(("%c phy\n", phy));
6014 wiphy = wl_to_wiphy(wl);
6015 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
6016 } else if (phy == 'n') {
6017 wiphy = wl_to_wiphy(wl);
6018 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
6024 static s32 __wl_cfg80211_up(struct wl_priv *wl)
6029 wl_debugfs_add_netdev_params(wl);
6031 err = wl_config_dongle(wl, false);
6034 dhd_monitor_init(wl->pub);
6035 wl_invoke_iscan(wl);
6036 wl_set_drv_status(wl, READY);
6040 static s32 __wl_cfg80211_down(struct wl_priv *wl)
6045 /* Check if cfg80211 interface is already down */
6046 if (!wl_get_drv_status(wl, READY))
6047 return err; /* it is even not ready */
6049 wl_set_drv_status(wl, SCAN_ABORTING);
6052 if (wl->scan_request) {
6053 cfg80211_scan_done(wl->scan_request, true);
6054 wl->scan_request = NULL;
6056 wl_clr_drv_status(wl, READY);
6057 wl_clr_drv_status(wl, SCANNING);
6058 wl_clr_drv_status(wl, SCAN_ABORTING);
6059 wl_clr_drv_status(wl, CONNECTED);
6060 if (wl_get_drv_status(wl, AP_CREATED)) {
6061 wl_clr_drv_status(wl, AP_CREATED);
6062 wl_clr_drv_status(wl, AP_CREATING);
6063 wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype =
6064 NL80211_IFTYPE_STATION;
6066 wl->dongle_up = false;
6069 if (wl->p2p_supported)
6071 dhd_monitor_uninit();
6073 wl_debugfs_remove_netdev(wl);
6078 s32 wl_cfg80211_up(void)
6085 mutex_lock(&wl->usr_sync);
6086 wl_cfg80211_attach_post(wl_to_prmry_ndev(wl));
6087 err = __wl_cfg80211_up(wl);
6089 WL_ERR(("__wl_cfg80211_up failed\n"));
6090 mutex_unlock(&wl->usr_sync);
6095 s32 wl_cfg80211_down(void)
6102 mutex_lock(&wl->usr_sync);
6103 err = __wl_cfg80211_down(wl);
6104 mutex_unlock(&wl->usr_sync);
6108 static s32 wl_dongle_probecap(struct wl_priv *wl)
6112 err = wl_update_wiphybands(wl);
6119 static void *wl_read_prof(struct wl_priv *wl, s32 item)
6123 return &wl->profile->sec;
6125 return &wl->profile->active;
6127 return &wl->profile->bssid;
6129 return &wl->profile->ssid;
6131 WL_ERR(("invalid item (%d)\n", item));
6136 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
6140 struct wlc_ssid *ssid;
6144 ssid = (wlc_ssid_t *) data;
6145 memset(wl->profile->ssid.SSID, 0,
6146 sizeof(wl->profile->ssid.SSID));
6147 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
6148 wl->profile->ssid.SSID_len = ssid->SSID_len;
6152 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
6154 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
6157 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
6160 wl->profile->active = *(bool *)data;
6162 case WL_PROF_BEACONINT:
6163 wl->profile->beacon_interval = *(u16 *)data;
6165 case WL_PROF_DTIMPERIOD:
6166 wl->profile->dtim_period = *(u8 *)data;
6169 WL_ERR(("unsupported item (%d)\n", item));
6177 void wl_cfg80211_dbg_level(u32 level)
6180 * prohibit to change debug level
6181 * by insmod parameter.
6182 * eventually debug level will be configured
6183 * in compile time by using CONFIG_XXX
6185 /* wl_dbg_level = level; */
6188 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev)
6190 return get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS;
6193 static __used bool wl_is_ibssstarter(struct wl_priv *wl)
6195 return wl->ibss_starter;
6198 static void wl_rst_ie(struct wl_priv *wl)
6200 struct wl_ie *ie = wl_to_ie(wl);
6205 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
6207 struct wl_ie *ie = wl_to_ie(wl);
6210 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
6211 WL_ERR(("ei crosses buffer boundary\n"));
6214 ie->buf[ie->offset] = t;
6215 ie->buf[ie->offset + 1] = l;
6216 memcpy(&ie->buf[ie->offset + 2], v, l);
6217 ie->offset += l + 2;
6222 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
6224 struct wl_ie *ie = wl_to_ie(wl);
6227 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
6228 WL_ERR(("ei_stream crosses buffer boundary\n"));
6231 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
6232 ie->offset += ie_size;
6237 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
6239 struct wl_ie *ie = wl_to_ie(wl);
6242 if (unlikely(ie->offset > dst_size)) {
6243 WL_ERR(("dst_size is not enough\n"));
6246 memcpy(dst, &ie->buf[0], ie->offset);
6251 static u32 wl_get_ielen(struct wl_priv *wl)
6253 struct wl_ie *ie = wl_to_ie(wl);
6258 static void wl_link_up(struct wl_priv *wl)
6263 static void wl_link_down(struct wl_priv *wl)
6265 struct wl_connect_info *conn_info = wl_to_conn(wl);
6268 wl->link_up = false;
6269 kfree(conn_info->req_ie);
6270 conn_info->req_ie = NULL;
6271 conn_info->req_ie_len = 0;
6272 kfree(conn_info->resp_ie);
6273 conn_info->resp_ie = NULL;
6274 conn_info->resp_ie_len = 0;
6277 static void wl_lock_eq(struct wl_priv *wl)
6279 spin_lock_irq(&wl->eq_lock);
6282 static void wl_unlock_eq(struct wl_priv *wl)
6284 spin_unlock_irq(&wl->eq_lock);
6287 static void wl_init_eq_lock(struct wl_priv *wl)
6289 spin_lock_init(&wl->eq_lock);
6292 static void wl_delay(u32 ms)
6294 if (ms < 1000 / HZ) {
6302 static void wl_set_drvdata(struct wl_dev *dev, void *data)
6304 dev->driver_data = data;
6307 static void *wl_get_drvdata(struct wl_dev *dev)
6309 return dev->driver_data;
6312 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
6314 const struct firmware *fw_entry;
6319 fw_entry = wl->fw->fw_entry;
6321 if (fw_entry->size < wl->fw->ptr + size)
6322 size = fw_entry->size - wl->fw->ptr;
6324 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
6325 wl->fw->ptr += size;
6329 void wl_cfg80211_release_fw(void)
6334 release_firmware(wl->fw->fw_entry);
6338 void *wl_cfg80211_request_fw(s8 *file_name)
6341 const struct firmware *fw_entry = NULL;
6345 WL_DBG(("file name : \"%s\"\n", file_name));
6348 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
6349 err = request_firmware(&wl->fw->fw_entry, file_name,
6350 &wl_cfg80211_get_sdio_func()->dev);
6351 if (unlikely(err)) {
6352 WL_ERR(("Could not download fw (%d)\n", err));
6355 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
6356 fw_entry = wl->fw->fw_entry;
6358 WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
6361 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
6362 err = request_firmware(&wl->fw->fw_entry, file_name,
6363 &wl_cfg80211_get_sdio_func()->dev);
6364 if (unlikely(err)) {
6365 WL_ERR(("Could not download nvram (%d)\n", err));
6368 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
6369 fw_entry = wl->fw->fw_entry;
6371 WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
6375 WL_DBG(("Downloading already done. Nothing to do more\n"));
6380 if (unlikely(err)) {
6384 return (void *)fw_entry->data;
6387 s8 *wl_cfg80211_get_fwname(void)
6392 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
6393 return wl->fw->fw_name;
6396 s8 *wl_cfg80211_get_nvramname(void)
6401 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
6402 return wl->fw->nvram_name;
6405 s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
6409 struct ether_addr p2pif_addr;
6412 dhd_pub = (dhd_pub_t *)wl->pub;
6413 wl_cfgp2p_generate_bss_mac(&dhd_pub->mac, p2pdev_addr, &p2pif_addr);
6418 static __used void wl_dongle_poweron(struct wl_priv *wl)
6421 WL_DBG(("Enter \n"));
6422 dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
6424 #if defined(BCMLXSDMMC)
6425 sdioh_start(NULL, 0);
6427 #if defined(BCMLXSDMMC)
6428 sdioh_start(NULL, 1);
6430 wl_cfg80211_resume(wl_to_wiphy(wl));
6433 static __used void wl_dongle_poweroff(struct wl_priv *wl)
6437 WL_DBG(("Enter \n"));
6438 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
6439 wl_cfg80211_suspend(wl_to_wiphy(wl), NULL);
6441 wl_cfg80211_suspend(wl_to_wiphy(wl));
6444 #if defined(BCMLXSDMMC)
6447 /* clean up dtim_skip setting */
6448 dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
6450 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
6452 char buf[10+IFNAMSIZ];
6457 sprintf(buf, "netdev:%s", wl_to_prmry_ndev(wl)->name);
6458 wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
6460 fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
6461 (u16 *)&wl->profile->beacon_interval);
6467 fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
6468 (u8 *)&wl->profile->dtim_period);
6478 static void wl_debugfs_remove_netdev(struct wl_priv *wl)
6480 WL_DBG(("Enter \n"));
6483 static const struct rfkill_ops wl_rfkill_ops = {
6484 .set_block = wl_rfkill_set
6487 static int wl_rfkill_set(void *data, bool blocked)
6489 struct wl_priv *wl = (struct wl_priv *)data;
6491 WL_DBG(("Enter \n"));
6492 WL_DBG(("RF %s\n", blocked ? "blocked" : "unblocked"));
6497 wl->rf_blocked = blocked;
6502 static int wl_setup_rfkill(struct wl_priv *wl, bool setup)
6506 WL_DBG(("Enter \n"));
6510 wl->rfkill = rfkill_alloc("brcmfmac-wifi",
6511 &wl_cfg80211_get_sdio_func()->dev,
6512 RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl);
6519 err = rfkill_register(wl->rfkill);
6522 rfkill_destroy(wl->rfkill);
6529 rfkill_unregister(wl->rfkill);
6530 rfkill_destroy(wl->rfkill);