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
38 #include <linux/sysctl.h>
43 #include <bcmendian.h>
44 #include <proto/ethernet.h>
45 #include <proto/802.11.h>
46 #include <linux/if_arp.h>
47 #include <asm/uaccess.h>
49 #include <dngl_stats.h>
54 #include <proto/ethernet.h>
55 #include <dngl_stats.h>
58 #include <linux/kernel.h>
59 #include <linux/kthread.h>
60 #include <linux/netdevice.h>
61 #include <linux/sched.h>
62 #include <linux/etherdevice.h>
63 #include <linux/wireless.h>
64 #include <linux/ieee80211.h>
65 #include <linux/wait.h>
66 #include <net/cfg80211.h>
68 #include <net/rtnetlink.h>
69 #include <linux/mmc/sdio_func.h>
70 #include <linux/firmware.h>
74 #include <wldev_common.h>
75 #include <wl_cfg80211.h>
76 #include <wl_cfgp2p.h>
78 static struct sdio_func *cfg80211_sdio_func;
79 static struct wl_dev *wl_cfg80211_dev;
81 u32 wl_dbg_level = WL_DBG_ERR;
83 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
84 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
85 #define WL_TRACE(a) printk("%s ", __FUNCTION__); printk a
86 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
87 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
88 #define MAX_WAIT_TIME 3000
89 static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
92 #define MAC_STRING_LEN (sizeof(u8) * 17)
93 u8 wl_sysctl_macstring[2][MAC_STRING_LEN];
95 static ctl_table wl_sysctl_child[] = {
97 .procname = "p2p_dev_addr",
98 .data = &wl_sysctl_macstring[0],
99 .maxlen = MAC_STRING_LEN,
102 .proc_handler = proc_dostring,
105 .procname = "p2p_int_addr",
106 .data = &wl_sysctl_macstring[1],
107 .maxlen = MAC_STRING_LEN,
110 .proc_handler = proc_dostring,
114 static ctl_table wl_sysctl_table[] = {
120 .child = wl_sysctl_child,
121 .proc_handler = NULL,
125 static struct ctl_table_header *wl_sysctl_hdr;
126 #endif /* CONFIG_SYSCTL */
128 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
129 * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
130 * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165).
131 * With respect to these flags, wpa_supplicant doesn't start p2p operations on 5GHz channels.
132 * All the chnages in world regulatory domain are to be done here.
134 static const struct ieee80211_regdomain brcm_regdom = {
138 /* IEEE 802.11b/g, channels 1..11 */
139 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
140 /* IEEE 802.11b/g, channels 12..13. No HT40
143 REG_RULE(2467-10, 2472+10, 20, 6, 20,
144 NL80211_RRF_PASSIVE_SCAN |
145 NL80211_RRF_NO_IBSS),
146 /* IEEE 802.11 channel 14 - Only JP enables
147 * this and for 802.11b only
149 REG_RULE(2484-10, 2484+10, 20, 6, 20,
150 NL80211_RRF_PASSIVE_SCAN |
151 NL80211_RRF_NO_IBSS |
152 NL80211_RRF_NO_OFDM),
153 /* IEEE 802.11a, channel 36..48 */
154 REG_RULE(5180-10, 5240+10, 40, 6, 20, 0),
156 /* NB: 5260 MHz - 5700 MHz requies DFS */
158 /* IEEE 802.11a, channel 149..165 */
159 REG_RULE(5745-10, 5825+10, 40, 6, 20, 0), }
163 /* Data Element Definitions */
164 #define WPS_ID_CONFIG_METHODS 0x1008
165 #define WPS_ID_REQ_TYPE 0x103A
166 #define WPS_ID_DEVICE_NAME 0x1011
167 #define WPS_ID_VERSION 0x104A
168 #define WPS_ID_DEVICE_PWD_ID 0x1012
169 #define WPS_ID_REQ_DEV_TYPE 0x106A
170 #define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053
171 #define WPS_ID_PRIM_DEV_TYPE 0x1054
173 /* Device Password ID */
174 #define DEV_PW_DEFAULT 0x0000
175 #define DEV_PW_USER_SPECIFIED 0x0001,
176 #define DEV_PW_MACHINE_SPECIFIED 0x0002
177 #define DEV_PW_REKEY 0x0003
178 #define DEV_PW_PUSHBUTTON 0x0004
179 #define DEV_PW_REGISTRAR_SPECIFIED 0x0005
182 #define WPS_CONFIG_USBA 0x0001
183 #define WPS_CONFIG_ETHERNET 0x0002
184 #define WPS_CONFIG_LABEL 0x0004
185 #define WPS_CONFIG_DISPLAY 0x0008
186 #define WPS_CONFIG_EXT_NFC_TOKEN 0x0010
187 #define WPS_CONFIG_INT_NFC_TOKEN 0x0020
188 #define WPS_CONFIG_NFC_INTERFACE 0x0040
189 #define WPS_CONFIG_PUSHBUTTON 0x0080
190 #define WPS_CONFIG_KEYPAD 0x0100
191 #define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
192 #define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
193 #define WPS_CONFIG_VIRT_DISPLAY 0x2008
194 #define WPS_CONFIG_PHY_DISPLAY 0x4008
197 * cfg80211_ops api/callback list
199 static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
200 const struct ether_addr *sa, const struct ether_addr *bssid,
201 u8 **pheader, u32 *body_len, u8 *pbody);
202 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
203 struct cfg80211_scan_request *request,
204 struct cfg80211_ssid *this_ssid);
205 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
206 struct cfg80211_scan_request *request);
207 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
208 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
209 struct cfg80211_ibss_params *params);
210 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
211 struct net_device *dev);
212 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
213 struct net_device *dev, u8 *mac,
214 struct station_info *sinfo);
215 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
216 struct net_device *dev, bool enabled,
218 static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
219 struct net_device *dev,
221 const struct cfg80211_bitrate_mask *mask);
222 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
223 struct cfg80211_connect_params *sme);
224 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
226 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
227 enum nl80211_tx_power_setting type,
229 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
230 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
231 struct net_device *dev,
232 u8 key_idx, bool unicast, bool multicast);
233 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
234 u8 key_idx, bool pairwise, const u8 *mac_addr,
235 struct key_params *params);
236 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
237 u8 key_idx, bool pairwise, const u8 *mac_addr);
238 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
239 u8 key_idx, bool pairwise, const u8 *mac_addr,
240 void *cookie, void (*callback) (void *cookie,
241 struct key_params *params));
242 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
243 struct net_device *dev, u8 key_idx);
244 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
245 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
246 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
248 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
250 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
251 struct cfg80211_pmksa *pmksa);
252 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
253 struct cfg80211_pmksa *pmksa);
254 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
255 struct net_device *dev);
256 static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted);
258 * event & event Q handlers for cfg80211 interfaces
260 static s32 wl_create_event_handler(struct wl_priv *wl);
261 static void wl_destroy_event_handler(struct wl_priv *wl);
262 static s32 wl_event_handler(void *data);
263 static void wl_init_eq(struct wl_priv *wl);
264 static void wl_flush_eq(struct wl_priv *wl);
265 static void wl_lock_eq(struct wl_priv *wl);
266 static void wl_unlock_eq(struct wl_priv *wl);
267 static void wl_init_eq_lock(struct wl_priv *wl);
268 static void wl_init_event_handler(struct wl_priv *wl);
269 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
270 static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
271 const wl_event_msg_t *msg, void *data);
272 static void wl_put_event(struct wl_event_q *e);
273 static void wl_wakeup_event(struct wl_priv *wl);
274 static s32 wl_notify_connect_status(struct wl_priv *wl,
275 struct net_device *ndev,
276 const wl_event_msg_t *e, void *data);
277 static s32 wl_notify_roaming_status(struct wl_priv *wl,
278 struct net_device *ndev,
279 const wl_event_msg_t *e, void *data);
280 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
281 const wl_event_msg_t *e, void *data);
282 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
283 const wl_event_msg_t *e, void *data, bool completed);
284 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
285 const wl_event_msg_t *e, void *data);
286 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
287 const wl_event_msg_t *e, void *data);
289 * register/deregister sdio function
291 struct sdio_func *wl_cfg80211_get_sdio_func(void);
292 static void wl_clear_sdio_func(void);
297 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
299 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
301 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
302 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
306 * cfg80211 set_wiphy_params utilities
308 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
309 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
310 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
313 * wl profile utilities
315 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
316 void *data, s32 item);
317 static void *wl_read_prof(struct wl_priv *wl, s32 item);
318 static void wl_init_prof(struct wl_profile *prof);
321 * cfg80211 connect utilites
323 static s32 wl_set_wpa_version(struct net_device *dev,
324 struct cfg80211_connect_params *sme);
325 static s32 wl_set_auth_type(struct net_device *dev,
326 struct cfg80211_connect_params *sme);
327 static s32 wl_set_set_cipher(struct net_device *dev,
328 struct cfg80211_connect_params *sme);
329 static s32 wl_set_key_mgmt(struct net_device *dev,
330 struct cfg80211_connect_params *sme);
331 static s32 wl_set_set_sharedkey(struct net_device *dev,
332 struct cfg80211_connect_params *sme);
333 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev);
334 static void wl_ch_to_chanspec(int ch,
335 struct wl_join_params *join_params, size_t *join_params_size);
338 * information element utilities
340 static void wl_rst_ie(struct wl_priv *wl);
341 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
342 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
343 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
344 static u32 wl_get_ielen(struct wl_priv *wl);
346 static s32 wl_mode_to_nl80211_iftype(s32 mode);
348 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
350 static void wl_free_wdev(struct wl_priv *wl);
352 static s32 wl_inform_bss(struct wl_priv *wl);
353 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
354 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev);
356 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
357 u8 key_idx, const u8 *mac_addr,
358 struct key_params *params);
360 * key indianess swap utilities
362 static void swap_key_from_BE(struct wl_wsec_key *key);
363 static void swap_key_to_BE(struct wl_wsec_key *key);
366 * wl_priv memory init/deinit utilities
368 static s32 wl_init_priv_mem(struct wl_priv *wl);
369 static void wl_deinit_priv_mem(struct wl_priv *wl);
371 static void wl_delay(u32 ms);
374 * store/restore cfg80211 instance data
376 static void wl_set_drvdata(struct wl_dev *dev, void *data);
377 static void *wl_get_drvdata(struct wl_dev *dev);
380 * ibss mode utilities
382 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
383 static __used bool wl_is_ibssstarter(struct wl_priv *wl);
386 * dongle up/down , default configuration utilities
388 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
389 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
390 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
391 static void wl_link_up(struct wl_priv *wl);
392 static void wl_link_down(struct wl_priv *wl);
393 static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
394 static s32 __wl_cfg80211_up(struct wl_priv *wl);
395 static s32 __wl_cfg80211_down(struct wl_priv *wl);
396 static s32 wl_dongle_probecap(struct wl_priv *wl);
397 static void wl_init_conf(struct wl_conf *conf);
398 static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
399 static s32 wl_dongle_eventmsg(struct net_device *ndev);
402 * dongle configuration utilities
404 #ifndef EMBEDDED_PLATFORM
405 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
406 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
407 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
408 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
410 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
412 static s32 wl_dongle_eventmsg(struct net_device *ndev);
413 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
414 s32 scan_unassoc_time);
415 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
417 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
418 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
419 static s32 wl_update_wiphybands(struct wl_priv *wl);
420 #endif /* !EMBEDDED_PLATFORM */
421 static __used void wl_dongle_poweron(struct wl_priv *wl);
422 static __used void wl_dongle_poweroff(struct wl_priv *wl);
423 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
428 static void wl_iscan_timer(unsigned long data);
429 static void wl_term_iscan(struct wl_priv *wl);
430 static s32 wl_init_scan(struct wl_priv *wl);
431 static s32 wl_iscan_thread(void *data);
432 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
434 static s32 wl_do_iscan(struct wl_priv *wl);
435 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
436 static s32 wl_invoke_iscan(struct wl_priv *wl);
437 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
438 struct wl_scan_results **bss_list);
439 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
440 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan);
441 static s32 wl_iscan_done(struct wl_priv *wl);
442 static s32 wl_iscan_pending(struct wl_priv *wl);
443 static s32 wl_iscan_inprogress(struct wl_priv *wl);
444 static s32 wl_iscan_aborted(struct wl_priv *wl);
447 * fw/nvram downloading handler
449 static void wl_init_fw(struct wl_fw_ctrl *fw);
452 * find most significant bit set
454 static __used u32 wl_find_msb(u16 bit16);
457 * update pmklist to dongle
459 static __used s32 wl_update_pmklist(struct net_device *dev,
460 struct wl_pmk_list *pmk_list, s32 err);
465 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
466 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
471 static int wl_setup_rfkill(struct wl_priv *wl, bool setup);
472 static int wl_rfkill_set(void *data, bool blocked);
475 * Some external functions, TODO: move them to dhd_linux.h
477 int dhd_add_monitor(char *name, struct net_device **new_ndev);
478 int dhd_del_monitor(struct net_device *ndev);
479 int dhd_monitor_init(void *dhd_pub);
480 int dhd_monitor_uninit(void);
481 int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
483 #define WL_PRIV_GET() \
485 struct wl_iface *ci = NULL; \
486 if (unlikely(!(wl_cfg80211_dev && \
487 (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
488 WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
494 #define CHECK_SYS_UP() \
496 struct wl_priv *wl = WL_PRIV_GET(); \
497 if (unlikely(!wl_get_drv_status(wl, READY))) { \
498 WL_INFO(("device is not ready : status (%d)\n", \
505 #define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
506 (akm) == RSN_AKM_UNSPECIFIED || \
507 (akm) == RSN_AKM_PSK)
510 extern int dhd_wait_pend8021x(struct net_device *dev);
512 #if (WL_DBG_LEVEL > 0)
513 #define WL_DBG_ESTR_MAX 50
514 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
515 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
516 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
517 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
518 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
519 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
520 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
521 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
523 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
525 "RADIO", "PSM_WATCHDOG", "WLC_E_CCX_ASSOC_START", "WLC_E_CCX_ASSOC_ABORT",
527 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
528 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
529 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
530 "WLC_E_BTA_HCI_EVENT", "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE",
531 "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG",
532 "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND",
533 "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED",
534 "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT",
535 "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE",
536 "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP",
537 "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE"
539 #endif /* WL_DBG_LEVEL */
541 #define CHAN2G(_channel, _freq, _flags) { \
542 .band = IEEE80211_BAND_2GHZ, \
543 .center_freq = (_freq), \
544 .hw_value = (_channel), \
546 .max_antenna_gain = 0, \
550 #define CHAN5G(_channel, _flags) { \
551 .band = IEEE80211_BAND_5GHZ, \
552 .center_freq = 5000 + (5 * (_channel)), \
553 .hw_value = (_channel), \
555 .max_antenna_gain = 0, \
559 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
560 #define RATETAB_ENT(_rateid, _flags) \
562 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
563 .hw_value = (_rateid), \
567 static struct ieee80211_rate __wl_rates[] = {
568 RATETAB_ENT(WLC_RATE_1M, 0),
569 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
570 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
571 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
572 RATETAB_ENT(WLC_RATE_6M, 0),
573 RATETAB_ENT(WLC_RATE_9M, 0),
574 RATETAB_ENT(WLC_RATE_12M, 0),
575 RATETAB_ENT(WLC_RATE_18M, 0),
576 RATETAB_ENT(WLC_RATE_24M, 0),
577 RATETAB_ENT(WLC_RATE_36M, 0),
578 RATETAB_ENT(WLC_RATE_48M, 0),
579 RATETAB_ENT(WLC_RATE_54M, 0)
582 #define wl_a_rates (__wl_rates + 4)
583 #define wl_a_rates_size 8
584 #define wl_g_rates (__wl_rates + 0)
585 #define wl_g_rates_size 12
587 static struct ieee80211_channel __wl_2ghz_channels[] = {
604 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
605 CHAN5G(34, 0), CHAN5G(36, 0),
606 CHAN5G(38, 0), CHAN5G(40, 0),
607 CHAN5G(42, 0), CHAN5G(44, 0),
608 CHAN5G(46, 0), CHAN5G(48, 0),
609 CHAN5G(52, 0), CHAN5G(56, 0),
610 CHAN5G(60, 0), CHAN5G(64, 0),
611 CHAN5G(100, 0), CHAN5G(104, 0),
612 CHAN5G(108, 0), CHAN5G(112, 0),
613 CHAN5G(116, 0), CHAN5G(120, 0),
614 CHAN5G(124, 0), CHAN5G(128, 0),
615 CHAN5G(132, 0), CHAN5G(136, 0),
616 CHAN5G(140, 0), CHAN5G(149, 0),
617 CHAN5G(153, 0), CHAN5G(157, 0),
618 CHAN5G(161, 0), CHAN5G(165, 0),
619 CHAN5G(184, 0), CHAN5G(188, 0),
620 CHAN5G(192, 0), CHAN5G(196, 0),
621 CHAN5G(200, 0), CHAN5G(204, 0),
622 CHAN5G(208, 0), CHAN5G(212, 0),
626 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
627 CHAN5G(32, 0), CHAN5G(34, 0),
628 CHAN5G(36, 0), CHAN5G(38, 0),
629 CHAN5G(40, 0), CHAN5G(42, 0),
630 CHAN5G(44, 0), CHAN5G(46, 0),
631 CHAN5G(48, 0), CHAN5G(50, 0),
632 CHAN5G(52, 0), CHAN5G(54, 0),
633 CHAN5G(56, 0), CHAN5G(58, 0),
634 CHAN5G(60, 0), CHAN5G(62, 0),
635 CHAN5G(64, 0), CHAN5G(66, 0),
636 CHAN5G(68, 0), CHAN5G(70, 0),
637 CHAN5G(72, 0), CHAN5G(74, 0),
638 CHAN5G(76, 0), CHAN5G(78, 0),
639 CHAN5G(80, 0), CHAN5G(82, 0),
640 CHAN5G(84, 0), CHAN5G(86, 0),
641 CHAN5G(88, 0), CHAN5G(90, 0),
642 CHAN5G(92, 0), CHAN5G(94, 0),
643 CHAN5G(96, 0), CHAN5G(98, 0),
644 CHAN5G(100, 0), CHAN5G(102, 0),
645 CHAN5G(104, 0), CHAN5G(106, 0),
646 CHAN5G(108, 0), CHAN5G(110, 0),
647 CHAN5G(112, 0), CHAN5G(114, 0),
648 CHAN5G(116, 0), CHAN5G(118, 0),
649 CHAN5G(120, 0), CHAN5G(122, 0),
650 CHAN5G(124, 0), CHAN5G(126, 0),
651 CHAN5G(128, 0), CHAN5G(130, 0),
652 CHAN5G(132, 0), CHAN5G(134, 0),
653 CHAN5G(136, 0), CHAN5G(138, 0),
654 CHAN5G(140, 0), CHAN5G(142, 0),
655 CHAN5G(144, 0), CHAN5G(145, 0),
656 CHAN5G(146, 0), CHAN5G(147, 0),
657 CHAN5G(148, 0), CHAN5G(149, 0),
658 CHAN5G(150, 0), CHAN5G(151, 0),
659 CHAN5G(152, 0), CHAN5G(153, 0),
660 CHAN5G(154, 0), CHAN5G(155, 0),
661 CHAN5G(156, 0), CHAN5G(157, 0),
662 CHAN5G(158, 0), CHAN5G(159, 0),
663 CHAN5G(160, 0), CHAN5G(161, 0),
664 CHAN5G(162, 0), CHAN5G(163, 0),
665 CHAN5G(164, 0), CHAN5G(165, 0),
666 CHAN5G(166, 0), CHAN5G(168, 0),
667 CHAN5G(170, 0), CHAN5G(172, 0),
668 CHAN5G(174, 0), CHAN5G(176, 0),
669 CHAN5G(178, 0), CHAN5G(180, 0),
670 CHAN5G(182, 0), CHAN5G(184, 0),
671 CHAN5G(186, 0), CHAN5G(188, 0),
672 CHAN5G(190, 0), CHAN5G(192, 0),
673 CHAN5G(194, 0), CHAN5G(196, 0),
674 CHAN5G(198, 0), CHAN5G(200, 0),
675 CHAN5G(202, 0), CHAN5G(204, 0),
676 CHAN5G(206, 0), CHAN5G(208, 0),
677 CHAN5G(210, 0), CHAN5G(212, 0),
678 CHAN5G(214, 0), CHAN5G(216, 0),
679 CHAN5G(218, 0), CHAN5G(220, 0),
680 CHAN5G(222, 0), CHAN5G(224, 0),
681 CHAN5G(226, 0), CHAN5G(228, 0)
684 static struct ieee80211_supported_band __wl_band_2ghz = {
685 .band = IEEE80211_BAND_2GHZ,
686 .channels = __wl_2ghz_channels,
687 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
688 .bitrates = wl_g_rates,
689 .n_bitrates = wl_g_rates_size
692 static struct ieee80211_supported_band __wl_band_5ghz_a = {
693 .band = IEEE80211_BAND_5GHZ,
694 .channels = __wl_5ghz_a_channels,
695 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
696 .bitrates = wl_a_rates,
697 .n_bitrates = wl_a_rates_size
700 static struct ieee80211_supported_band __wl_band_5ghz_n = {
701 .band = IEEE80211_BAND_5GHZ,
702 .channels = __wl_5ghz_n_channels,
703 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
704 .bitrates = wl_a_rates,
705 .n_bitrates = wl_a_rates_size
708 static const u32 __wl_cipher_suites[] = {
709 WLAN_CIPHER_SUITE_WEP40,
710 WLAN_CIPHER_SUITE_WEP104,
711 WLAN_CIPHER_SUITE_TKIP,
712 WLAN_CIPHER_SUITE_CCMP,
713 WLAN_CIPHER_SUITE_AES_CMAC
716 /* There isn't a lot of sense in it, but you can transmit anything you like */
717 static const struct ieee80211_txrx_stypes
718 wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
719 [NL80211_IFTYPE_ADHOC] = {
721 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
723 [NL80211_IFTYPE_STATION] = {
725 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
726 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
728 [NL80211_IFTYPE_AP] = {
730 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
731 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
732 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
733 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
734 BIT(IEEE80211_STYPE_AUTH >> 4) |
735 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
736 BIT(IEEE80211_STYPE_ACTION >> 4)
738 [NL80211_IFTYPE_AP_VLAN] = {
741 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
742 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
743 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
744 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
745 BIT(IEEE80211_STYPE_AUTH >> 4) |
746 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
747 BIT(IEEE80211_STYPE_ACTION >> 4)
749 [NL80211_IFTYPE_P2P_CLIENT] = {
751 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
752 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
754 [NL80211_IFTYPE_P2P_GO] = {
756 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
757 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
758 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
759 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
760 BIT(IEEE80211_STYPE_AUTH >> 4) |
761 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
762 BIT(IEEE80211_STYPE_ACTION >> 4)
766 static void swap_key_from_BE(struct wl_wsec_key *key)
768 key->index = htod32(key->index);
769 key->len = htod32(key->len);
770 key->algo = htod32(key->algo);
771 key->flags = htod32(key->flags);
772 key->rxiv.hi = htod32(key->rxiv.hi);
773 key->rxiv.lo = htod16(key->rxiv.lo);
774 key->iv_initialized = htod32(key->iv_initialized);
777 static void swap_key_to_BE(struct wl_wsec_key *key)
779 key->index = dtoh32(key->index);
780 key->len = dtoh32(key->len);
781 key->algo = dtoh32(key->algo);
782 key->flags = dtoh32(key->flags);
783 key->rxiv.hi = dtoh32(key->rxiv.hi);
784 key->rxiv.lo = dtoh16(key->rxiv.lo);
785 key->iv_initialized = dtoh32(key->iv_initialized);
788 /* For debug: Dump the contents of the encoded wps ie buffe */
790 wl_validate_wps_ie(char *wps_ie, bool *pbc)
792 #define WPS_IE_FIXED_LEN 6
793 u16 len = (u16) wps_ie[TLV_LEN_OFF];
794 u8 *subel = wps_ie+ WPS_IE_FIXED_LEN;
798 u8 *valptr = (uint8*) &val;
800 WL_DBG(("wps_ie len=%d\n", len));
802 len -= 4; /* for the WPS IE's OUI, oui_type fields */
804 while (len >= 4) { /* must have attr id, attr len fields */
805 valptr[0] = *subel++;
806 valptr[1] = *subel++;
807 subelt_id = HTON16(val);
809 valptr[0] = *subel++;
810 valptr[1] = *subel++;
811 subelt_len = HTON16(val);
813 len -= 4; /* for the attr id, attr len fields */
814 len -= subelt_len; /* for the remaining fields in this attribute */
815 WL_DBG((" subel=%p, subelt_id=0x%x subelt_len=%u\n",
816 subel, subelt_id, subelt_len));
818 if (subelt_id == WPS_ID_VERSION) {
819 WL_DBG((" attr WPS_ID_VERSION: %u\n", *subel));
820 } else if (subelt_id == WPS_ID_REQ_TYPE) {
821 WL_DBG((" attr WPS_ID_REQ_TYPE: %u\n", *subel));
822 } else if (subelt_id == WPS_ID_CONFIG_METHODS) {
824 valptr[1] = *(subel + 1);
825 WL_DBG((" attr WPS_ID_CONFIG_METHODS: %x\n", HTON16(val)));
826 } else if (subelt_id == WPS_ID_DEVICE_NAME) {
828 memcpy(devname, subel, subelt_len);
829 devname[subelt_len] = '\0';
830 WL_DBG((" attr WPS_ID_DEVICE_NAME: %s (len %u)\n",
831 devname, subelt_len));
832 } else if (subelt_id == WPS_ID_DEVICE_PWD_ID) {
834 valptr[1] = *(subel + 1);
835 WL_DBG((" attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val)));
836 *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false;
837 } else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) {
839 valptr[1] = *(subel + 1);
840 WL_DBG((" attr WPS_ID_PRIM_DEV_TYPE: cat=%u \n", HTON16(val)));
841 valptr[0] = *(subel + 6);
842 valptr[1] = *(subel + 7);
843 WL_DBG((" attr WPS_ID_PRIM_DEV_TYPE: subcat=%u\n", HTON16(val)));
844 } else if (subelt_id == WPS_ID_REQ_DEV_TYPE) {
846 valptr[1] = *(subel + 1);
847 WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: cat=%u\n", HTON16(val)));
848 valptr[0] = *(subel + 6);
849 valptr[1] = *(subel + 7);
850 WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val)));
851 } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) {
853 valptr[1] = *(subel + 1);
854 WL_DBG((" attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS"
855 ": cat=%u\n", HTON16(val)));
857 WL_DBG((" unknown attr 0x%x\n", subelt_id));
864 static struct net_device* wl_cfg80211_add_monitor_if(char *name)
867 struct net_device* ndev = NULL;
869 ret = dhd_add_monitor(name, &ndev);
870 WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev));
874 static struct net_device *
875 wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
876 enum nl80211_iftype type, u32 *flags,
877 struct vif_params *params)
885 struct wl_priv *wl = WL_PRIV_GET();
886 struct net_device *_ndev;
887 dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
889 WL_DBG(("if name: %s, type: %d\n", name, type));
891 case NL80211_IFTYPE_ADHOC:
892 case NL80211_IFTYPE_AP_VLAN:
893 case NL80211_IFTYPE_WDS:
894 case NL80211_IFTYPE_MESH_POINT:
895 WL_ERR(("Unsupported interface type\n"));
898 case NL80211_IFTYPE_MONITOR:
899 return wl_cfg80211_add_monitor_if(name);
900 case NL80211_IFTYPE_P2P_CLIENT:
901 case NL80211_IFTYPE_STATION:
902 wlif_type = WL_P2P_IF_CLIENT;
905 case NL80211_IFTYPE_P2P_GO:
906 case NL80211_IFTYPE_AP:
907 wlif_type = WL_P2P_IF_GO;
911 WL_ERR(("Unsupported interface type\n"));
917 WL_ERR(("name is NULL\n"));
920 if (wl->p2p_supported && (wlif_type != -1)) {
921 if (wl_get_p2p_status(wl, IF_DELETING) == 1) {
922 /* wait till IF_DEL is complete
923 * release the lock for the unregister to proceed
926 WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n",
928 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
929 (wl_get_p2p_status(wl, IF_DELETING) == false),
930 msecs_to_jiffies(MAX_WAIT_TIME));
932 /* put back the rtnl_lock again */
935 WL_ERR(("IF DEL is Success\n"));
938 WL_ERR(("%s: timeount < 0, return -EAGAIN\n", __func__));
939 return ERR_PTR(-EAGAIN);
942 if (!p2p_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
944 wl_cfgp2p_set_firm_p2p(wl);
945 wl_cfgp2p_init_discovery(wl);
948 memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
949 strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
950 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
952 /* Temporary use channel 11, in case GO will be changed with set_channel API */
953 chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
955 /* For P2P mode, use P2P-specific driver features to create the
956 * bss: "wl p2p_ifadd"
958 wl_set_p2p_status(wl, IF_ADD);
959 err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
962 return ERR_PTR(-ENOMEM);
964 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
965 (wl_get_p2p_status(wl, IF_ADD) == false),
966 msecs_to_jiffies(MAX_WAIT_TIME));
967 if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
969 struct wireless_dev *vwdev;
970 vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
971 if (unlikely(!vwdev)) {
972 WL_ERR(("Could not allocate wireless device\n"));
973 return ERR_PTR(-ENOMEM);
975 vwdev->wiphy = wl->wdev->wiphy;
976 WL_INFO((" virtual interface(%s) is created \n", wl->p2p->vir_ifname));
977 index = alloc_idx_vwdev(wl);
978 wl->vwdev[index] = vwdev;
980 (wlif_type == WL_P2P_IF_CLIENT) ? NL80211_IFTYPE_STATION
982 _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
983 _ndev->ieee80211_ptr = vwdev;
984 SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
985 vwdev->netdev = _ndev;
986 wl_set_drv_status(wl, READY);
987 wl->p2p->vif_created = true;
988 set_mode_by_netdev(wl, _ndev, mode);
989 wl = wdev_to_wl(vwdev);
993 wl_clr_p2p_status(wl, IF_ADD);
994 WL_ERR((" virtual interface(%s) is not created \n", wl->p2p->vir_ifname));
995 memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
996 wl->p2p->vif_created = false;
999 return ERR_PTR(-ENODEV);
1004 wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
1006 struct ether_addr p2p_mac;
1007 struct wl_priv *wl = WL_PRIV_GET();
1010 if (dev && dev->type == ARPHRD_IEEE80211_RADIOTAP) {
1011 ret = dhd_del_monitor(dev);
1014 if (wl->p2p_supported) {
1015 memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
1016 if (wl->p2p->vif_created) {
1017 if (wl_get_drv_status(wl, SCANNING)) {
1018 wl_cfg80211_scan_abort(wl, dev);
1021 wl_cfgp2p_ifdel(wl, &p2p_mac);
1022 wl_set_p2p_status(wl, IF_DELETING);
1024 /* Wait for any pending scan req to get aborted from the sysioc context */
1025 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
1026 (wl->scan_request == false),
1027 msecs_to_jiffies(MAX_WAIT_TIME));
1029 if (timeout > 0 && (!wl->scan_request)) {
1030 WL_DBG(("IFDEL Operations Done"));
1032 WL_ERR(("IFDEL didn't complete properly"));
1041 wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
1042 enum nl80211_iftype type, u32 *flags,
1043 struct vif_params *params)
1052 struct wl_priv *wl = WL_PRIV_GET();
1053 WL_DBG(("Enter \n"));
1055 case NL80211_IFTYPE_MONITOR:
1056 case NL80211_IFTYPE_WDS:
1057 case NL80211_IFTYPE_MESH_POINT:
1059 WL_ERR(("type (%d) : currently we do not support this type\n",
1062 case NL80211_IFTYPE_ADHOC:
1063 mode = WL_MODE_IBSS;
1065 case NL80211_IFTYPE_STATION:
1066 case NL80211_IFTYPE_P2P_CLIENT:
1070 case NL80211_IFTYPE_AP:
1071 case NL80211_IFTYPE_AP_VLAN:
1072 case NL80211_IFTYPE_P2P_GO:
1082 set_mode_by_netdev(wl, ndev, mode);
1083 if (wl->p2p_supported && wl->p2p->vif_created) {
1084 WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
1086 chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
1087 wlif_type = ap ? WL_P2P_IF_GO : WL_P2P_IF_CLIENT;
1088 WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n",
1089 ndev->name, ap, infra, type));
1090 wl_set_p2p_status(wl, IF_CHANGING);
1091 wl_clr_p2p_status(wl, IF_CHANGED);
1092 err = wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
1093 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
1094 (wl_get_p2p_status(wl, IF_CHANGED) == true),
1095 msecs_to_jiffies(MAX_WAIT_TIME));
1096 set_mode_by_netdev(wl, ndev, mode);
1097 wl_clr_p2p_status(wl, IF_CHANGING);
1098 wl_clr_p2p_status(wl, IF_CHANGED);
1099 } else if (ndev == wl_to_prmry_ndev(wl) &&
1100 !wl_get_drv_status(wl, AP_CREATED)) {
1101 wl_set_drv_status(wl, AP_CREATING);
1103 !(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) {
1104 WL_ERR(("struct ap_saved_ie allocation failed\n"));
1108 WL_ERR(("Cannot change the interface for GO or SOFTAP\n"));
1113 ndev->ieee80211_ptr->iftype = type;
1118 wl_cfg80211_notify_ifadd(struct net_device *net)
1120 struct wl_priv *wl = WL_PRIV_GET();
1122 if (!net || !net->name) {
1123 WL_ERR(("net is NULL\n"));
1126 if (wl->p2p_supported) {
1127 WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
1128 "new name: %s\n", net->name, wl->p2p->vir_ifname));
1129 /* Assign the net device to CONNECT BSSCFG */
1130 strncpy(net->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
1131 wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
1132 wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) =
1133 P2PAPI_BSSCFG_CONNECTION;
1134 wl_clr_p2p_status(wl, IF_ADD);
1135 wake_up_interruptible(&wl->dongle_event_wait);
1141 wl_cfg80211_ifdel_ops(struct net_device *net)
1143 struct wl_priv *wl = WL_PRIV_GET();
1145 if (!net || !net->name) {
1146 WL_DBG(("net is NULL\n"));
1150 if ((wl->p2p->vif_created) && (wl->scan_request)) {
1152 /* Abort any pending scan requests */
1153 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
1155 WL_INFO(("ESCAN COMPLETED\n"));
1156 wl_notify_escan_complete(wl, true);
1160 /* Wake up any waiting thread */
1161 wake_up_interruptible(&wl->dongle_event_wait);
1167 wl_cfg80211_notify_ifdel(struct net_device *net)
1169 struct wl_priv *wl = WL_PRIV_GET();
1172 if (wl->p2p->vif_created) {
1175 WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
1176 net->name, wl->p2p->vir_ifname));
1178 memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
1179 index = wl_cfgp2p_find_idx(wl, net);
1180 wl_to_p2p_bss_ndev(wl, index) = NULL;
1181 wl_to_p2p_bss_bssidx(wl, index) = 0;
1182 wl->p2p->vif_created = false;
1183 set_mode_by_netdev(wl, net, -1);
1184 wl_cfgp2p_clear_management_ie(wl,
1186 index = get_idx_vwdev_by_netdev(wl, net);
1187 WL_DBG(("index : %d\n", index));
1189 free_vwdev_by_index(wl, index);
1193 wl_clr_p2p_status(wl, IF_DELETING);
1195 /* Wake up any waiting thread */
1196 wake_up_interruptible(&wl->dongle_event_wait);
1202 wl_cfg80211_is_progress_ifadd(void)
1204 s32 is_progress = 0;
1205 struct wl_priv *wl = WL_PRIV_GET();
1206 if (wl_get_p2p_status(wl, IF_ADD))
1212 wl_cfg80211_is_progress_ifchange(void)
1214 s32 is_progress = 0;
1215 struct wl_priv *wl = WL_PRIV_GET();
1216 if (wl_get_p2p_status(wl, IF_CHANGING))
1223 wl_cfg80211_notify_ifchange(void)
1225 struct wl_priv *wl = WL_PRIV_GET();
1226 if (wl_get_p2p_status(wl, IF_CHANGING)) {
1227 wl_set_p2p_status(wl, IF_CHANGED);
1228 wake_up_interruptible(&wl->dongle_event_wait);
1233 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
1235 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
1236 params->bss_type = DOT11_BSSTYPE_ANY;
1237 params->scan_type = 0;
1238 params->nprobes = -1;
1239 params->active_time = -1;
1240 params->passive_time = -1;
1241 params->home_time = -1;
1242 params->channel_num = 0;
1244 params->nprobes = htod32(params->nprobes);
1245 params->active_time = htod32(params->active_time);
1246 params->passive_time = htod32(params->passive_time);
1247 params->home_time = htod32(params->home_time);
1248 if (ssid && ssid->SSID_len)
1249 memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t));
1254 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
1257 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
1258 struct wl_iscan_params *params;
1261 if (ssid && ssid->SSID_len)
1262 params_size += sizeof(struct wlc_ssid);
1263 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
1264 if (unlikely(!params))
1266 memset(params, 0, params_size);
1267 BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
1269 wl_iscan_prep(¶ms->params, ssid);
1271 params->version = htod32(ISCAN_REQ_VERSION);
1272 params->action = htod16(action);
1273 params->scan_duration = htod16(0);
1275 /* params_size += offsetof(wl_iscan_params_t, params); */
1276 err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
1277 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
1278 if (unlikely(err)) {
1279 if (err == -EBUSY) {
1280 WL_INFO(("system busy : iscan canceled\n"));
1282 WL_ERR(("error (%d)\n", err));
1289 static s32 wl_do_iscan(struct wl_priv *wl)
1291 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
1292 struct net_device *ndev = wl_to_prmry_ndev(wl);
1293 struct wlc_ssid ssid;
1297 /* Broadcast scan by default */
1298 memset(&ssid, 0, sizeof(ssid));
1300 iscan->state = WL_ISCAN_STATE_SCANING;
1302 passive_scan = wl->active_scan ? 0 : 1;
1303 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1304 &passive_scan, sizeof(passive_scan), false);
1305 if (unlikely(err)) {
1306 WL_DBG(("error (%d)\n", err));
1309 wl->iscan_kickstart = true;
1310 wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
1311 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
1312 iscan->timer_on = 1;
1318 wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint16 action)
1321 s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
1322 wl_escan_params_t *params;
1323 struct cfg80211_scan_request *scan_request = wl->scan_request;
1325 s32 search_state = WL_P2P_DISC_ST_SCAN;
1327 u16 *default_chan_list = NULL;
1328 WL_DBG(("Enter \n"));
1331 if (!wl->p2p_supported || ((ndev == wl_to_prmry_ndev(wl)) &&
1333 /* LEGACY SCAN TRIGGER */
1334 WL_DBG(("LEGACY SCAN START\n"));
1335 if (ssid && ssid->SSID_len) {
1336 params_size += sizeof(wlc_ssid_t);
1338 params = (wl_escan_params_t *) kmalloc(params_size, GFP_KERNEL);
1343 memset(params, 0, params_size);
1344 memcpy(¶ms->params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1345 params->params.bss_type = DOT11_BSSTYPE_ANY;
1346 params->params.scan_type = 0;
1347 params->params.nprobes = htod32(-1);
1348 params->params.active_time = htod32(-1);
1349 params->params.passive_time = htod32(-1);
1350 params->params.home_time = htod32(-1);
1351 params->params.channel_num = 0;
1352 if (ssid && ssid->SSID_len) {
1353 memcpy(params->params.ssid.SSID, ssid->SSID, ssid->SSID_len);
1354 params->params.ssid.SSID_len = htod32(ssid->SSID_len);
1356 params->version = htod32(ESCAN_REQ_VERSION);
1357 params->action = htod16(action);
1358 params->sync_id = htod16(0x1234);
1359 wldev_iovar_setbuf(ndev, "escan", params, params_size,
1360 wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
1363 else if (p2p_on(wl) && p2p_scan(wl)) {
1364 /* P2P SCAN TRIGGER */
1365 if (scan_request && scan_request->n_channels) {
1366 num_chans = scan_request->n_channels;
1367 WL_INFO((" chann number : %d\n", num_chans));
1368 default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
1370 if (default_chan_list == NULL) {
1371 WL_ERR(("channel list allocation failed \n"));
1375 for (i = 0; i < num_chans; i++)
1377 default_chan_list[i] =
1378 ieee80211_frequency_to_channel(
1379 scan_request->channels[i]->center_freq);
1381 if (num_chans == 3 && (
1382 (default_chan_list[0] == SOCIAL_CHAN_1) &&
1383 (default_chan_list[1] == SOCIAL_CHAN_2) &&
1384 (default_chan_list[2] == SOCIAL_CHAN_3))) {
1385 /* SOCIAL CHANNELS 1, 6, 11 */
1386 search_state = WL_P2P_DISC_ST_SEARCH;
1387 WL_INFO(("P2P SEARCH PHASE START \n"));
1389 WL_INFO(("P2P SCAN STATE START \n"));
1393 err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list,
1394 search_state, action,
1395 wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
1396 kfree(default_chan_list);
1404 wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wlc_ssid_t *ssid)
1408 wl_scan_results_t *results;
1409 WL_DBG(("Enter \n"));
1411 wl->escan_info.wiphy = wiphy;
1412 wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
1413 passive_scan = wl->active_scan ? 0 : 1;
1414 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1415 &passive_scan, sizeof(passive_scan), false);
1416 if (unlikely(err)) {
1417 WL_DBG(("error (%d)\n", err));
1420 results = (wl_scan_results_t *) wl->escan_info.escan_buf;
1421 results->version = 0;
1423 results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
1425 wl_run_escan(wl, ndev, ssid, WL_SCAN_ACTION_START);
1430 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
1431 struct cfg80211_scan_request *request,
1432 struct cfg80211_ssid *this_ssid)
1434 struct wl_priv *wl = WL_PRIV_GET();
1435 struct cfg80211_ssid *ssids;
1436 struct wl_scan_req *sr = wl_to_sr(wl);
1437 wlc_ssid_t ssid_info;
1444 if (unlikely(wl_get_drv_status(wl, SCANNING))) {
1445 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
1448 if (unlikely(wl_get_drv_status(wl, SCAN_ABORTING))) {
1449 WL_ERR(("Scanning being aborted : status (%d)\n",
1454 WL_DBG(("wiphy (%p)\n", wiphy));
1458 if (request) { /* scan bss */
1459 ssids = request->ssids;
1460 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) {
1462 } else if (wl->escan_on) {
1464 if (ssids->ssid_len && IS_P2P_SSID(ssids->ssid)) {
1465 if (wl->p2p_supported) {
1466 /* p2p scan trigger */
1467 if (p2p_on(wl) == false) {
1468 /* p2p on at the first time */
1470 wl_cfgp2p_set_firm_p2p(wl);
1472 p2p_scan(wl) = true;
1476 /* legacy scan trigger
1477 * So, we have to disable p2p discovery if p2p discovery is on
1479 if (wl->p2p_supported) {
1480 p2p_scan(wl) = false;
1481 /* If Netdevice is not equals to primary and p2p is on
1482 * , we will do p2p scan using P2PAPI_BSSCFG_DEVICE.
1484 if (p2p_on(wl) && (ndev != wl_to_prmry_ndev(wl)))
1485 p2p_scan(wl) = true;
1487 if (p2p_scan(wl) == false) {
1488 if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
1489 err = wl_cfgp2p_discover_enable_search(wl,
1491 if (unlikely(err)) {
1500 } else { /* scan in ibss */
1501 /* we don't do iscan in ibss */
1504 wl->scan_request = request;
1505 wl_set_drv_status(wl, SCANNING);
1507 err = wl_do_iscan(wl);
1512 } else if (escan_req) {
1513 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
1514 ssids->ssid, ssids->ssid_len));
1516 memcpy(ssid_info.SSID, ssids->ssid, ssids->ssid_len);
1517 ssid_info.SSID_len = ssids->ssid_len;
1518 if (wl->p2p_supported) {
1519 if (p2p_on(wl) && p2p_scan(wl)) {
1521 err = wl_cfgp2p_enable_discovery(wl, ndev,
1522 request->ie, request->ie_len);
1524 if (unlikely(err)) {
1529 err = wl_do_escan(wl, wiphy, ndev, &ssid_info);
1537 memset(&sr->ssid, 0, sizeof(sr->ssid));
1539 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
1540 if (sr->ssid.SSID_len) {
1541 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
1542 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
1543 WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
1544 sr->ssid.SSID, sr->ssid.SSID_len));
1547 WL_DBG(("Broadcast scan\n"));
1549 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
1550 passive_scan = wl->active_scan ? 0 : 1;
1551 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1552 &passive_scan, sizeof(passive_scan), false);
1553 if (unlikely(err)) {
1554 WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
1557 err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
1558 sizeof(sr->ssid), false);
1560 if (err == -EBUSY) {
1561 WL_INFO(("system busy : scan for \"%s\" "
1562 "canceled\n", sr->ssid.SSID));
1564 WL_ERR(("WLC_SCAN error (%d)\n", err));
1573 wl_clr_drv_status(wl, SCANNING);
1574 wl->scan_request = NULL;
1579 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
1580 struct cfg80211_scan_request *request)
1584 WL_DBG(("Enter \n"));
1586 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
1587 if (unlikely(err)) {
1588 WL_ERR(("scan error (%d)\n", err));
1595 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
1597 s8 buf[WLC_IOCTL_SMLEN];
1602 len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
1603 BUG_ON(unlikely(!len));
1605 err = wldev_ioctl(dev, WLC_SET_VAR, buf, len, false);
1606 if (unlikely(err)) {
1607 WL_ERR(("error (%d)\n", err));
1614 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
1617 s8 buf[WLC_IOCTL_SMLEN];
1624 len = bcm_mkiovar(name, (char *)(&data_null), 0,
1625 (char *)(&var), sizeof(var.buf));
1626 BUG_ON(unlikely(!len));
1627 err = wldev_ioctl(dev, WLC_GET_VAR, &var, len, false);
1628 if (unlikely(err)) {
1629 WL_ERR(("error (%d)\n", err));
1631 *retval = dtoh32(var.val);
1636 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
1640 err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
1641 if (unlikely(err)) {
1642 WL_ERR(("Error (%d)\n", err));
1648 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
1652 err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
1653 if (unlikely(err)) {
1654 WL_ERR(("Error (%d)\n", err));
1660 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
1663 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
1665 retry = htod32(retry);
1666 err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), false);
1667 if (unlikely(err)) {
1668 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
1674 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1676 struct wl_priv *wl = wiphy_to_wl(wiphy);
1677 struct net_device *ndev = wl_to_prmry_ndev(wl);
1681 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1682 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
1683 wl->conf->rts_threshold = wiphy->rts_threshold;
1684 err = wl_set_rts(ndev, wl->conf->rts_threshold);
1688 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1689 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
1690 wl->conf->frag_threshold = wiphy->frag_threshold;
1691 err = wl_set_frag(ndev, wl->conf->frag_threshold);
1695 if (changed & WIPHY_PARAM_RETRY_LONG &&
1696 (wl->conf->retry_long != wiphy->retry_long)) {
1697 wl->conf->retry_long = wiphy->retry_long;
1698 err = wl_set_retry(ndev, wl->conf->retry_long, true);
1702 if (changed & WIPHY_PARAM_RETRY_SHORT &&
1703 (wl->conf->retry_short != wiphy->retry_short)) {
1704 wl->conf->retry_short = wiphy->retry_short;
1705 err = wl_set_retry(ndev, wl->conf->retry_short, false);
1715 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1716 struct cfg80211_ibss_params *params)
1718 struct wl_priv *wl = WL_PRIV_GET();
1719 struct cfg80211_bss *bss;
1720 struct ieee80211_channel *chan;
1721 struct wl_join_params join_params;
1722 struct cfg80211_ssid ssid;
1728 if (params->bssid) {
1729 WL_ERR(("Invalid bssid\n"));
1732 bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1734 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1735 ssid.ssid_len = params->ssid_len;
1738 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1744 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1745 /* to allow scan_inform to propagate to cfg80211 plane */
1748 /* wait 4 secons till scan done.... */
1749 schedule_timeout_interruptible(4 * HZ);
1751 bss = cfg80211_get_ibss(wiphy, NULL,
1752 params->ssid, params->ssid_len);
1755 wl->ibss_starter = false;
1756 WL_DBG(("Found IBSS\n"));
1758 wl->ibss_starter = true;
1760 chan = params->channel;
1762 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1764 * Join with specific BSSID and cached SSID
1765 * If SSID is zero join based on BSSID only
1767 memset(&join_params, 0, sizeof(join_params));
1768 memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1770 join_params.ssid.SSID_len = htod32(params->ssid_len);
1772 memcpy(&join_params.params.bssid, params->bssid,
1775 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1777 err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
1778 sizeof(join_params), false);
1779 if (unlikely(err)) {
1780 WL_ERR(("Error (%d)\n", err));
1786 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1788 struct wl_priv *wl = WL_PRIV_GET();
1798 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1800 struct wl_priv *wl = WL_PRIV_GET();
1801 struct wl_security *sec;
1804 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1806 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1807 val = WPA_AUTH_PSK; /* | WPA_AUTH_UNSPECIFIED; */
1808 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1809 val = WPA2_AUTH_PSK; /* | WPA2_AUTH_UNSPECIFIED ; */
1811 val = WPA_AUTH_DISABLED;
1813 if (is_wps_conn(sme))
1814 val = WPA_AUTH_DISABLED;
1816 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1817 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
1818 if (unlikely(err)) {
1819 WL_ERR(("set wpa_auth failed (%d)\n", err));
1822 sec = wl_read_prof(wl, WL_PROF_SEC);
1823 sec->wpa_versions = sme->crypto.wpa_versions;
1828 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1830 struct wl_priv *wl = WL_PRIV_GET();
1831 struct wl_security *sec;
1834 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1835 switch (sme->auth_type) {
1836 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1838 WL_DBG(("open system\n"));
1840 case NL80211_AUTHTYPE_SHARED_KEY:
1842 WL_DBG(("shared key\n"));
1844 case NL80211_AUTHTYPE_AUTOMATIC:
1846 WL_DBG(("automatic\n"));
1848 case NL80211_AUTHTYPE_NETWORK_EAP:
1849 WL_DBG(("network eap\n"));
1852 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1856 err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
1857 if (unlikely(err)) {
1858 WL_ERR(("set auth failed (%d)\n", err));
1861 sec = wl_read_prof(wl, WL_PROF_SEC);
1862 sec->auth_type = sme->auth_type;
1867 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1869 struct wl_priv *wl = WL_PRIV_GET();
1870 struct wl_security *sec;
1874 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1876 if (sme->crypto.n_ciphers_pairwise) {
1877 switch (sme->crypto.ciphers_pairwise[0]) {
1878 case WLAN_CIPHER_SUITE_WEP40:
1879 case WLAN_CIPHER_SUITE_WEP104:
1882 case WLAN_CIPHER_SUITE_TKIP:
1883 pval = TKIP_ENABLED;
1885 case WLAN_CIPHER_SUITE_CCMP:
1888 case WLAN_CIPHER_SUITE_AES_CMAC:
1892 WL_ERR(("invalid cipher pairwise (%d)\n",
1893 sme->crypto.ciphers_pairwise[0]));
1897 if (sme->crypto.cipher_group) {
1898 switch (sme->crypto.cipher_group) {
1899 case WLAN_CIPHER_SUITE_WEP40:
1900 case WLAN_CIPHER_SUITE_WEP104:
1903 case WLAN_CIPHER_SUITE_TKIP:
1904 gval = TKIP_ENABLED;
1906 case WLAN_CIPHER_SUITE_CCMP:
1909 case WLAN_CIPHER_SUITE_AES_CMAC:
1913 WL_ERR(("invalid cipher group (%d)\n",
1914 sme->crypto.cipher_group));
1919 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1921 if (is_wps_conn(sme)) {
1922 err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
1924 err = wldev_iovar_setint_bsscfg(dev, "wsec", pval | gval, bssidx);
1926 if (unlikely(err)) {
1927 WL_ERR(("error (%d)\n", err));
1931 sec = wl_read_prof(wl, WL_PROF_SEC);
1932 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1933 sec->cipher_group = sme->crypto.cipher_group;
1939 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1941 struct wl_priv *wl = WL_PRIV_GET();
1942 struct wl_security *sec;
1945 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1947 if (sme->crypto.n_akm_suites) {
1948 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1949 if (unlikely(err)) {
1950 WL_ERR(("could not get wpa_auth (%d)\n", err));
1953 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1954 switch (sme->crypto.akm_suites[0]) {
1955 case WLAN_AKM_SUITE_8021X:
1956 val = WPA_AUTH_UNSPECIFIED;
1958 case WLAN_AKM_SUITE_PSK:
1962 WL_ERR(("invalid cipher group (%d)\n",
1963 sme->crypto.cipher_group));
1966 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1967 switch (sme->crypto.akm_suites[0]) {
1968 case WLAN_AKM_SUITE_8021X:
1969 val = WPA2_AUTH_UNSPECIFIED;
1971 case WLAN_AKM_SUITE_PSK:
1972 val = WPA2_AUTH_PSK;
1975 WL_ERR(("invalid cipher group (%d)\n",
1976 sme->crypto.cipher_group));
1981 WL_DBG(("setting wpa_auth to %d\n", val));
1983 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
1984 if (unlikely(err)) {
1985 WL_ERR(("could not set wpa_auth (%d)\n", err));
1989 sec = wl_read_prof(wl, WL_PROF_SEC);
1990 sec->wpa_auth = sme->crypto.akm_suites[0];
1996 wl_set_set_sharedkey(struct net_device *dev,
1997 struct cfg80211_connect_params *sme)
1999 struct wl_priv *wl = WL_PRIV_GET();
2000 struct wl_security *sec;
2001 struct wl_wsec_key key;
2004 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2006 WL_DBG(("key len (%d)\n", sme->key_len));
2008 sec = wl_read_prof(wl, WL_PROF_SEC);
2009 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
2010 sec->wpa_versions, sec->cipher_pairwise));
2011 if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 |
2012 NL80211_WPA_VERSION_2)) &&
2013 (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
2014 WLAN_CIPHER_SUITE_WEP104))) {
2015 memset(&key, 0, sizeof(key));
2016 key.len = (u32) sme->key_len;
2017 key.index = (u32) sme->key_idx;
2018 if (unlikely(key.len > sizeof(key.data))) {
2019 WL_ERR(("Too long key length (%u)\n", key.len));
2022 memcpy(key.data, sme->key, key.len);
2023 key.flags = WL_PRIMARY_KEY;
2024 switch (sec->cipher_pairwise) {
2025 case WLAN_CIPHER_SUITE_WEP40:
2026 key.algo = CRYPTO_ALGO_WEP1;
2028 case WLAN_CIPHER_SUITE_WEP104:
2029 key.algo = CRYPTO_ALGO_WEP128;
2032 WL_ERR(("Invalid algorithm (%d)\n",
2033 sme->crypto.ciphers_pairwise[0]));
2036 /* Set the new key/index */
2037 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
2038 key.len, key.index, key.algo));
2039 WL_DBG(("key \"%s\"\n", key.data));
2040 swap_key_from_BE(&key);
2041 err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
2042 ioctlbuf, sizeof(ioctlbuf), bssidx);
2043 if (unlikely(err)) {
2044 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2047 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
2048 WL_DBG(("set auth_type to shared key\n"));
2049 val = 1; /* shared key */
2050 err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
2051 if (unlikely(err)) {
2052 WL_ERR(("set auth failed (%d)\n", err));
2062 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
2063 struct cfg80211_connect_params *sme)
2065 struct wl_priv *wl = WL_PRIV_GET();
2066 struct ieee80211_channel *chan = sme->channel;
2067 struct wl_join_params join_params;
2068 size_t join_params_size;
2075 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
2077 if (wl->scan_request) {
2078 wl_set_drv_status(wl, SCAN_ABORTING);
2079 cfg80211_scan_done(wl->scan_request, true);
2080 wl->scan_request = NULL;
2081 wl_clr_drv_status(wl, SCANNING);
2082 wl_clr_drv_status(wl, SCAN_ABORTING);
2085 if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
2086 /* we only allow to connect using virtual interface in case of P2P */
2087 if (p2p_on(wl) && is_wps_conn(sme)) {
2088 WL_DBG(("p2p index : %d\n", wl_cfgp2p_find_idx(wl, dev)));
2089 /* Have to apply WPS IE + P2P IE in assoc req frame */
2090 wl_cfgp2p_set_management_ie(wl, dev,
2091 wl_cfgp2p_find_idx(wl, dev), VNDR_IE_PRBREQ_FLAG,
2092 wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie,
2093 wl_to_p2p_bss_saved_ie(wl,
2094 P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
2095 wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
2096 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
2097 } else if (p2p_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
2098 /* This is the connect req after WPS is done [credentials exchanged]
2099 * currently identified with WPA_VERSION_2 .
2100 * Update the previously set IEs with
2101 * the newly received IEs from Supplicant. This will remove the WPS IE from
2104 wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
2105 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
2109 WL_INFO(("No P2PIE in beacon \n"));
2112 if (unlikely(!sme->ssid)) {
2113 WL_ERR(("Invalid ssid\n"));
2117 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
2118 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
2119 chan->center_freq));
2121 WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
2122 err = wl_set_wpa_version(dev, sme);
2126 err = wl_set_auth_type(dev, sme);
2130 err = wl_set_set_cipher(dev, sme);
2134 err = wl_set_key_mgmt(dev, sme);
2138 err = wl_set_set_sharedkey(dev, sme);
2142 wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
2144 * Join with specific BSSID and cached SSID
2145 * If SSID is zero join based on BSSID only
2147 memset(&join_params, 0, sizeof(join_params));
2148 join_params_size = sizeof(join_params.ssid);
2150 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
2151 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
2152 join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
2153 wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
2154 memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
2156 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
2157 WL_DBG(("join_param_size %d\n", join_params_size));
2159 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
2160 WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
2161 join_params.ssid.SSID_len));
2163 err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, false);
2164 if (unlikely(err)) {
2165 WL_ERR(("error (%d)\n", err));
2168 wl_set_drv_status(wl, CONNECTING);
2174 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
2177 struct wl_priv *wl = WL_PRIV_GET();
2182 WL_ERR(("Reason %d\n\n\n", reason_code));
2184 act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
2186 scbval.val = reason_code;
2187 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
2188 scbval.val = htod32(scbval.val);
2189 err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
2190 sizeof(scb_val_t), false);
2191 if (unlikely(err)) {
2192 WL_ERR(("error (%d)\n", err));
2201 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
2202 enum nl80211_tx_power_setting type, s32 dbm)
2205 struct wl_priv *wl = WL_PRIV_GET();
2206 struct net_device *ndev = wl_to_prmry_ndev(wl);
2213 case NL80211_TX_POWER_AUTOMATIC:
2215 case NL80211_TX_POWER_LIMITED:
2217 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
2221 case NL80211_TX_POWER_FIXED:
2223 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
2228 /* Make sure radio is off or on as far as software is concerned */
2229 disable = WL_RADIO_SW_DISABLE << 16;
2230 disable = htod32(disable);
2231 err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), false);
2232 if (unlikely(err)) {
2233 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
2240 txpwrmw = (u16) dbm;
2241 err = wl_dev_intvar_set(ndev, "qtxpower",
2242 (s32) (bcm_mw_to_qdbm(txpwrmw)));
2243 if (unlikely(err)) {
2244 WL_ERR(("qtxpower error (%d)\n", err));
2247 wl->conf->tx_power = dbm;
2252 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
2254 struct wl_priv *wl = WL_PRIV_GET();
2255 struct net_device *ndev = wl_to_prmry_ndev(wl);
2261 err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
2262 if (unlikely(err)) {
2263 WL_ERR(("error (%d)\n", err));
2266 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
2267 *dbm = (s32) bcm_qdbm_to_mw(result);
2273 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
2274 u8 key_idx, bool unicast, bool multicast)
2276 struct wl_priv *wl = WL_PRIV_GET();
2280 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2282 WL_DBG(("key index (%d)\n", key_idx));
2284 err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2285 if (unlikely(err)) {
2286 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
2289 if (wsec & WEP_ENABLED) {
2290 /* Just select a new current key */
2291 index = (u32) key_idx;
2292 index = htod32(index);
2293 err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
2294 sizeof(index), false);
2295 if (unlikely(err)) {
2296 WL_ERR(("error (%d)\n", err));
2303 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
2304 u8 key_idx, const u8 *mac_addr, struct key_params *params)
2306 struct wl_priv *wl = WL_PRIV_GET();
2307 struct wl_wsec_key key;
2309 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2310 s32 mode = get_mode_by_netdev(wl, dev);
2311 memset(&key, 0, sizeof(key));
2312 key.index = (u32) key_idx;
2314 if (!ETHER_ISMULTI(mac_addr))
2315 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
2316 key.len = (u32) params->key_len;
2318 /* check for key index change */
2321 swap_key_from_BE(&key);
2322 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2323 sizeof(ioctlbuf), bssidx);
2324 if (unlikely(err)) {
2325 WL_ERR(("key delete error (%d)\n", err));
2329 if (key.len > sizeof(key.data)) {
2330 WL_ERR(("Invalid key length (%d)\n", key.len));
2333 WL_DBG(("Setting the key index %d\n", key.index));
2334 memcpy(key.data, params->key, key.len);
2336 if ((mode == WL_MODE_BSS) &&
2337 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2339 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2340 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2341 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2344 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2345 if (params->seq && params->seq_len == 6) {
2348 ivptr = (u8 *) params->seq;
2349 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2350 (ivptr[3] << 8) | ivptr[2];
2351 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2352 key.iv_initialized = true;
2355 switch (params->cipher) {
2356 case WLAN_CIPHER_SUITE_WEP40:
2357 key.algo = CRYPTO_ALGO_WEP1;
2358 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2360 case WLAN_CIPHER_SUITE_WEP104:
2361 key.algo = CRYPTO_ALGO_WEP128;
2362 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2364 case WLAN_CIPHER_SUITE_TKIP:
2365 key.algo = CRYPTO_ALGO_TKIP;
2366 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2368 case WLAN_CIPHER_SUITE_AES_CMAC:
2369 key.algo = CRYPTO_ALGO_AES_CCM;
2370 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2372 case WLAN_CIPHER_SUITE_CCMP:
2373 key.algo = CRYPTO_ALGO_AES_CCM;
2374 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
2377 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
2380 swap_key_from_BE(&key);
2381 #ifdef CONFIG_WIRELESS_EXT
2382 dhd_wait_pend8021x(dev);
2384 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2385 sizeof(ioctlbuf), bssidx);
2386 if (unlikely(err)) {
2387 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2395 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
2396 u8 key_idx, bool pairwise, const u8 *mac_addr,
2397 struct key_params *params)
2399 struct wl_wsec_key key;
2405 struct wl_priv *wl = WL_PRIV_GET();
2406 s32 mode = get_mode_by_netdev(wl, dev);
2407 WL_DBG(("key index (%d)\n", key_idx));
2410 bssidx = wl_cfgp2p_find_idx(wl, dev);
2413 wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
2416 memset(&key, 0, sizeof(key));
2418 key.len = (u32) params->key_len;
2419 key.index = (u32) key_idx;
2421 if (unlikely(key.len > sizeof(key.data))) {
2422 WL_ERR(("Too long key length (%u)\n", key.len));
2425 memcpy(key.data, params->key, key.len);
2427 key.flags = WL_PRIMARY_KEY;
2428 switch (params->cipher) {
2429 case WLAN_CIPHER_SUITE_WEP40:
2430 key.algo = CRYPTO_ALGO_WEP1;
2432 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2434 case WLAN_CIPHER_SUITE_WEP104:
2435 key.algo = CRYPTO_ALGO_WEP128;
2437 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2439 case WLAN_CIPHER_SUITE_TKIP:
2440 key.algo = CRYPTO_ALGO_TKIP;
2442 /* wpa_supplicant switches the third and fourth quarters of the TKIP key */
2443 if (mode == WL_MODE_BSS) {
2444 bcopy(&key.data[24], keybuf, sizeof(keybuf));
2445 bcopy(&key.data[16], &key.data[24], sizeof(keybuf));
2446 bcopy(keybuf, &key.data[16], sizeof(keybuf));
2448 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2450 case WLAN_CIPHER_SUITE_AES_CMAC:
2451 key.algo = CRYPTO_ALGO_AES_CCM;
2453 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2455 case WLAN_CIPHER_SUITE_CCMP:
2456 key.algo = CRYPTO_ALGO_AES_CCM;
2458 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
2461 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
2465 /* Set the new key/index */
2466 swap_key_from_BE(&key);
2467 err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2468 sizeof(ioctlbuf), bssidx);
2469 if (unlikely(err)) {
2470 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2475 err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2476 if (unlikely(err)) {
2477 WL_ERR(("get wsec error (%d)\n", err));
2482 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
2483 if (unlikely(err)) {
2484 WL_ERR(("set wsec error (%d)\n", err));
2489 /* TODO: Removed in P2P, check later --lm */
2490 val = 1; /* assume shared key. otherwise 0 */
2492 err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), false);
2493 if (unlikely(err)) {
2494 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
2502 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
2503 u8 key_idx, bool pairwise, const u8 *mac_addr)
2505 struct wl_wsec_key key;
2506 struct wl_priv *wl = WL_PRIV_GET();
2508 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2510 WL_DBG(("Enter\n"));
2512 memset(&key, 0, sizeof(key));
2514 key.index = (u32) key_idx;
2515 key.flags = WL_PRIMARY_KEY;
2516 key.algo = CRYPTO_ALGO_OFF;
2518 WL_DBG(("key index (%d)\n", key_idx));
2519 /* Set the new key/index */
2520 swap_key_from_BE(&key);
2521 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2522 sizeof(ioctlbuf), bssidx);
2523 if (unlikely(err)) {
2524 if (err == -EINVAL) {
2525 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
2526 /* we ignore this key index in this case */
2527 WL_DBG(("invalid key index (%d)\n", key_idx));
2530 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2536 /* TODO: Removed in P2P twig, check later --lin */
2537 val = 0; /* assume open key. otherwise 1 */
2539 err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), false);
2540 if (unlikely(err)) {
2541 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
2549 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
2550 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2551 void (*callback) (void *cookie, struct key_params * params))
2553 struct key_params params;
2554 struct wl_wsec_key key;
2555 struct wl_priv *wl = WL_PRIV_GET();
2556 struct wl_security *sec;
2559 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2561 WL_DBG(("key index (%d)\n", key_idx));
2563 memset(&key, 0, sizeof(key));
2564 key.index = key_idx;
2565 swap_key_to_BE(&key);
2566 memset(¶ms, 0, sizeof(params));
2567 params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
2568 memcpy(params.key, key.data, params.key_len);
2570 wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2571 if (unlikely(err)) {
2572 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
2575 switch (wsec & ~SES_OW_ENABLED) {
2577 sec = wl_read_prof(wl, WL_PROF_SEC);
2578 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2579 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2580 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2581 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2582 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2583 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2587 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2588 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2591 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2592 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2595 WL_ERR(("Invalid algo (0x%x)\n", wsec));
2599 callback(cookie, ¶ms);
2604 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2605 struct net_device *dev, u8 key_idx)
2607 WL_INFO(("Not supported\n"));
2613 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
2614 u8 *mac, struct station_info *sinfo)
2616 struct wl_priv *wl = WL_PRIV_GET();
2624 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
2625 WL_ERR(("Wrong Mac address\n"));
2629 /* Report the current tx rate */
2630 err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
2632 WL_ERR(("Could not get rate (%d)\n", err));
2634 rate = dtoh32(rate);
2635 sinfo->filled |= STATION_INFO_TX_BITRATE;
2636 sinfo->txrate.legacy = rate * 5;
2637 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
2640 if (wl_get_drv_status(wl, CONNECTED)) {
2641 memset(&scb_val, 0, sizeof(scb_val));
2643 err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
2644 sizeof(scb_val_t), false);
2645 if (unlikely(err)) {
2646 WL_ERR(("Could not get rssi (%d)\n", err));
2649 rssi = dtoh32(scb_val.val);
2650 sinfo->filled |= STATION_INFO_SIGNAL;
2651 sinfo->signal = rssi;
2652 WL_DBG(("RSSI %d dBm\n", rssi));
2655 #if defined(ANDROID_WIRELESS_PATCH)
2656 err = wldev_ioctl(dev, WLC_GET_RATE, &sinfo->link_speed, sizeof(sinfo->link_speed), false);
2657 sinfo->link_speed = sinfo->link_speed / 2; /* Convert internal 500Kbps to Mpbs */
2659 sinfo->filled |= STATION_LINK_SPEED;
2661 WL_ERR(("WLC_GET_RATE failed\n"));
2668 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2669 bool enabled, s32 timeout)
2675 pm = enabled ? PM_FAST : PM_OFF;
2677 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
2678 err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), false);
2679 if (unlikely(err)) {
2681 WL_DBG(("net_device is not ready yet\n"));
2683 WL_ERR(("error (%d)\n", err));
2689 static __used u32 wl_find_msb(u16 bit16)
2693 if (bit16 & 0xff00) {
2717 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
2719 const struct cfg80211_bitrate_mask *mask)
2721 struct wl_rateset rateset;
2730 /* addr param is always NULL. ignore it */
2731 /* Get current rateset */
2732 err = wldev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
2733 sizeof(rateset), false);
2734 if (unlikely(err)) {
2735 WL_ERR(("could not get current rateset (%d)\n", err));
2739 rateset.count = dtoh32(rateset.count);
2741 legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
2743 legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
2745 val = wl_g_rates[legacy - 1].bitrate * 100000;
2747 if (val < rateset.count) {
2748 /* Select rate by rateset index */
2749 rate = rateset.rates[val] & 0x7f;
2751 /* Specified rate in bps */
2752 rate = val / 500000;
2755 WL_DBG(("rate %d mbps\n", (rate / 2)));
2759 * Set rate override,
2760 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2762 err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
2763 err_a = wl_dev_intvar_set(dev, "a_rate", rate);
2764 if (unlikely(err_bg && err_a)) {
2765 WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
2766 return err_bg | err_a;
2772 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
2774 struct wl_priv *wl = WL_PRIV_GET();
2777 if (unlikely(!wl_get_drv_status(wl, READY))) {
2778 WL_INFO(("device is not ready : status (%d)\n",
2783 wl_invoke_iscan(wl);
2788 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
2789 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2791 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
2794 struct wl_priv *wl = WL_PRIV_GET();
2797 if (unlikely(!wl_get_drv_status(wl, READY))) {
2798 WL_INFO(("device is not ready : status (%d)\n",
2803 wl_set_drv_status(wl, SCAN_ABORTING);
2805 if (wl->scan_request) {
2806 cfg80211_scan_done(wl->scan_request, true);
2807 wl->scan_request = NULL;
2809 wl_clr_drv_status(wl, SCANNING);
2810 wl_clr_drv_status(wl, SCAN_ABORTING);
2816 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2820 struct wl_priv *wl = WL_PRIV_GET();
2821 struct net_device *primary_dev = wl_to_prmry_ndev(wl);
2823 /* Firmware is supporting pmk list only for STA interface i.e. primary interface
2824 * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
2825 * Do we really need to support PMK cache in P2P in firmware?
2827 if (primary_dev != dev) {
2828 WL_ERR(("Not supporting Flushing pmklist on virtual"
2829 " interfaces than primary interface\n"));
2833 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2834 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2835 WL_DBG(("PMKID[%d]: %pM =\n", i,
2836 &pmk_list->pmkids.pmkid[i].BSSID));
2837 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2838 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2842 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2850 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2851 struct cfg80211_pmksa *pmksa)
2853 struct wl_priv *wl = WL_PRIV_GET();
2858 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2859 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2862 if (i < WL_NUM_PMKIDS_MAX) {
2863 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2865 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2867 if (i == wl->pmk_list->pmkids.npmkid)
2868 wl->pmk_list->pmkids.npmkid++;
2872 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2873 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2874 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2876 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2880 err = wl_update_pmklist(dev, wl->pmk_list, err);
2886 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2887 struct cfg80211_pmksa *pmksa)
2889 struct wl_priv *wl = WL_PRIV_GET();
2890 struct _pmkid_list pmkid;
2895 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2896 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2898 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2899 &pmkid.pmkid[0].BSSID));
2900 for (i = 0; i < WPA2_PMKID_LEN; i++) {
2901 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2904 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2906 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2910 if ((wl->pmk_list->pmkids.npmkid > 0) &&
2911 (i < wl->pmk_list->pmkids.npmkid)) {
2912 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2913 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2914 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2915 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2917 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2918 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2921 wl->pmk_list->pmkids.npmkid--;
2926 err = wl_update_pmklist(dev, wl->pmk_list, err);
2933 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2935 struct wl_priv *wl = WL_PRIV_GET();
2938 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2939 err = wl_update_pmklist(dev, wl->pmk_list, err);
2945 wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
2947 wl_scan_params_t *params;
2951 *out_params_size = 0;
2953 /* Our scan params only need space for 1 channel and 0 ssids */
2954 params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16);
2955 params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL);
2956 if (params == NULL) {
2957 WL_ERR(("%s: mem alloc failed (%d bytes)\n", __func__, params_size));
2960 memset(params, 0, params_size);
2961 params->nprobes = nprobes;
2963 num_chans = (channel == 0) ? 0 : 1;
2965 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
2966 params->bss_type = DOT11_BSSTYPE_ANY;
2967 params->scan_type = DOT11_SCANTYPE_ACTIVE;
2968 params->nprobes = htod32(1);
2969 params->active_time = htod32(-1);
2970 params->passive_time = htod32(-1);
2971 params->home_time = htod32(10);
2972 params->channel_list[0] = htodchanspec(channel);
2974 /* Our scan params have 1 channel and 0 ssids */
2975 params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
2976 (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
2978 *out_params_size = params_size; /* rtn size to the caller */
2982 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
2984 wl_scan_params_t *params;
2988 WL_DBG(("Enter\n"));
2990 /* Our scan params only need space for 1 channel and 0 ssids */
2991 params = wl_cfg80211_scan_alloc_params(-1, 0, ¶ms_size);
2992 if (params == NULL) {
2993 WL_ERR(("scan params allocation failed \n"));
2996 /* Do a scan abort to stop the driver's scan engine */
2997 err = wldev_ioctl(ndev, WLC_SCAN, params, params_size, false);
2999 WL_ERR(("scan abort failed \n"));
3005 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
3006 struct ieee80211_channel * channel,
3007 enum nl80211_channel_type channel_type,
3008 unsigned int duration, u64 *cookie)
3013 struct wl_priv *wl = WL_PRIV_GET();
3014 dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
3015 WL_DBG(("Enter, netdev_ifidx: %d \n", dev->ifindex));
3016 if (likely(wl_get_drv_status(wl, SCANNING))) {
3017 wl_cfg80211_scan_abort(wl, dev);
3020 target_channel = ieee80211_frequency_to_channel(channel->center_freq);
3021 memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel));
3022 wl->remain_on_chan_type = channel_type;
3023 wl->cache_cookie = *cookie;
3024 cfg80211_ready_on_channel(dev, *cookie, channel,
3025 channel_type, duration, GFP_KERNEL);
3027 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
3029 /* In case of p2p_listen command, supplicant send remain_on_channel
3030 * without turning on P2P
3033 err = wl_cfgp2p_enable_discovery(wl, dev, NULL, 0);
3035 if (unlikely(err)) {
3041 wl_cfgp2p_discover_listen(wl, target_channel, duration);
3049 wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
3053 WL_DBG((" enter ) netdev_ifidx: %d \n", dev->ifindex));
3058 wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
3059 struct ieee80211_channel *channel, bool offchan,
3060 enum nl80211_channel_type channel_type,
3061 bool channel_type_valid, unsigned int wait,
3062 const u8* buf, size_t len, u64 *cookie)
3064 wl_action_frame_t *action_frame;
3065 wl_af_params_t *af_params;
3066 wifi_p2p_ie_t *p2p_ie;
3067 wpa_ie_fixed_t *wps_ie;
3068 const struct ieee80211_mgmt *mgmt;
3069 struct wl_priv *wl = WL_PRIV_GET();
3070 dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
3077 WL_DBG(("Enter \n"));
3078 /* find bssidx based on ndev */
3079 bssidx = wl_cfgp2p_find_idx(wl, dev);
3080 /* cookie generation */
3081 *cookie = (unsigned long) buf;
3085 WL_ERR(("Can not find the bssidx for dev( %p )\n", dev));
3088 if (wl->p2p_supported && p2p_on(wl)) {
3089 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
3090 /* Suspend P2P discovery search-listen to prevent it from changing the
3093 if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) {
3094 WL_ERR(("Can not disable discovery mode\n"));
3099 mgmt = (const struct ieee80211_mgmt *) buf;
3100 fc = mgmt->frame_control;
3101 if (fc != IEEE80211_STYPE_ACTION) {
3102 if (fc == IEEE80211_STYPE_PROBE_RESP) {
3103 s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3104 s32 ie_len = len - ie_offset;
3105 if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)(buf + ie_offset), ie_len))
3107 /* Total length of P2P Information Element */
3108 p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
3109 /* Have to change p2p device address in dev_info attribute
3110 * because Supplicant use primary eth0 address
3112 #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3113 wl_cfg80211_change_ifaddr((u8 *)p2p_ie,
3114 &wl->p2p_dev_addr, P2P_SEID_DEV_INFO);
3117 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len))
3119 /* Order of Vendor IE is 1) WPS IE +
3120 * 2) P2P IE created by supplicant
3121 * So, it is ok to find start address of WPS IE
3122 * to save IEs to firmware
3124 wpsie_len = wps_ie->length + sizeof(wps_ie->length) +
3125 sizeof(wps_ie->tag);
3126 wl_cfgp2p_set_management_ie(wl, dev, bssidx,
3127 VNDR_IE_PRBRSP_FLAG,
3128 (u8 *)wps_ie, wpsie_len + p2pie_len);
3129 /* remove WLC_E_PROBREQ_MSG event to prevent HOSTAPD
3130 * from responding many probe request
3134 cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_KERNEL);
3137 /* Abort the dwell time of any previous off-channel action frame that may
3138 * be still in effect. Sending off-channel action frames relies on the
3139 * driver's scan engine. If a previous off-channel action frame tx is
3140 * still in progress (including the dwell time), then this new action
3141 * frame will not be sent out.
3143 wl_cfg80211_scan_abort(wl, dev);
3145 af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
3147 if (af_params == NULL)
3149 WL_ERR(("unable to allocate frame\n"));
3153 action_frame = &af_params->action_frame;
3155 /* Add the packet Id */
3156 action_frame->packetId = (u32) action_frame;
3157 WL_DBG(("action frame %d\n", action_frame->packetId));
3159 memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN);
3160 memcpy(&af_params->BSSID, &mgmt->bssid[0], ETHER_ADDR_LEN);
3162 /* Add the length exepted for 802.11 header */
3163 action_frame->len = len - DOT11_MGMT_HDR_LEN;
3164 WL_DBG(("action_frame->len: %d\n", action_frame->len));
3166 /* Add the channel */
3167 af_params->channel =
3168 ieee80211_frequency_to_channel(channel->center_freq);
3170 /* Add the dwell time
3171 * Dwell time to stay off-channel to wait for a response action frame
3172 * after transmitting an GO Negotiation action frame
3174 af_params->dwell_time = WL_DWELL_TIME;
3176 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
3178 if (wl->p2p->vif_created) {
3179 wifi_p2p_pub_act_frame_t *act_frm =
3180 (wifi_p2p_pub_act_frame_t *) (action_frame->data);
3182 * Have to change intented address from GO REQ or GO RSP and INVITE REQ
3183 * because wpa-supplicant use eth0 primary address
3185 if ((act_frm->subtype == P2P_PAF_GON_REQ)||
3186 (act_frm->subtype == P2P_PAF_GON_RSP)||
3187 (act_frm->subtype == P2P_PAF_GON_CONF)||
3188 (act_frm->subtype == P2P_PAF_INVITE_REQ)) {
3189 p2p_ie = wl_cfgp2p_find_p2pie(act_frm->elts,
3190 action_frame->len - P2P_PUB_AF_FIXED_LEN);
3191 #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3192 wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.int_addr,
3193 P2P_SEID_INTINTADDR);
3194 wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
3196 wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
3202 ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true;
3203 cfg80211_mgmt_tx_status(dev, *cookie, buf, len, ack, GFP_KERNEL);
3212 wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev,
3213 u16 frame_type, bool reg)
3216 WL_DBG(("%s: frame_type: %x, reg: %d\n", __func__, frame_type, reg));
3218 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3226 wl_cfg80211_change_bss(struct wiphy *wiphy,
3227 struct net_device *dev,
3228 struct bss_parameters *params)
3230 if (params->use_cts_prot >= 0) {
3233 if (params->use_short_preamble >= 0) {
3236 if (params->use_short_slot_time >= 0) {
3239 if (params->basic_rates) {
3242 if (params->ap_isolate >= 0) {
3245 if (params->ht_opmode >= 0) {
3252 wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
3253 struct ieee80211_channel *chan,
3254 enum nl80211_channel_type channel_type)
3259 channel = ieee80211_frequency_to_channel(chan->center_freq);
3260 WL_DBG(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
3261 dev->ifindex, channel_type, channel));
3262 wldev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel), false);
3268 wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
3272 u16 auth = 0; /* d11 open authentication */
3279 wpa_suite_mcast_t *mcast;
3280 wpa_suite_ucast_t *ucast;
3281 wpa_suite_auth_key_mgmt_t *mgmt;
3285 WL_DBG(("Enter \n"));
3287 /* check the mcast cipher */
3288 mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN];
3290 switch (tmp[DOT11_OUI_LEN]) {
3291 case WPA_CIPHER_NONE:
3294 case WPA_CIPHER_WEP_40:
3295 case WPA_CIPHER_WEP_104:
3298 case WPA_CIPHER_TKIP:
3299 gval = TKIP_ENABLED;
3301 case WPA_CIPHER_AES_CCM:
3305 WL_ERR(("No Security Info\n"));
3308 len -= WPA_SUITE_LEN;
3309 /* check the unicast cipher */
3310 ucast = (wpa_suite_ucast_t *)&mcast[1];
3311 count = ltoh16_ua(&ucast->count);
3312 tmp = ucast->list[0].oui;
3313 switch (tmp[DOT11_OUI_LEN]) {
3314 case WPA_CIPHER_NONE:
3317 case WPA_CIPHER_WEP_40:
3318 case WPA_CIPHER_WEP_104:
3321 case WPA_CIPHER_TKIP:
3322 pval = TKIP_ENABLED;
3324 case WPA_CIPHER_AES_CCM:
3328 WL_ERR(("No Security Info\n"));
3330 /* FOR WPS , set SEC_OW_ENABLED */
3331 wsec = (pval | gval | SES_OW_ENABLED);
3333 mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[1];
3334 count = ltoh16_ua(&mgmt->count);
3335 tmp = (u8 *)&mgmt->list[0];
3336 switch (tmp[DOT11_OUI_LEN]) {
3338 wpa_auth = WPA_AUTH_NONE;
3340 case RSN_AKM_UNSPECIFIED:
3341 wpa_auth = WPA2_AUTH_UNSPECIFIED;
3344 wpa_auth = WPA2_AUTH_PSK;
3347 WL_ERR(("No Key Mgmt Info\n"));
3350 err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
3352 WL_ERR(("auth error %d\n", err));
3356 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
3358 WL_ERR(("wsec error %d\n", err));
3361 /* set upper-layer auth */
3362 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
3364 WL_ERR(("wpa_auth error %d\n", err));
3372 wl_validate_wpaie(struct net_device *dev, wpa_ie_fixed_t *wpaie, s32 bssidx)
3374 wpa_suite_mcast_t *mcast;
3375 wpa_suite_ucast_t *ucast;
3376 wpa_suite_auth_key_mgmt_t *mgmt;
3377 u16 auth = 0; /* d11 open authentication */
3390 WL_DBG(("Enter \n"));
3391 len = wpaie->length; /* value length */
3392 len -= WPA_IE_TAG_FIXED_LEN;
3393 /* check for multicast cipher suite */
3394 if (len < WPA_SUITE_LEN) {
3395 WL_INFO(("no multicast cipher suite\n"));
3399 /* pick up multicast cipher */
3400 mcast = (wpa_suite_mcast_t *)&wpaie[1];
3401 len -= WPA_SUITE_LEN;
3402 if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) {
3403 if (IS_WPA_CIPHER(mcast->type)) {
3405 switch (mcast->type) {
3406 case WPA_CIPHER_NONE:
3409 case WPA_CIPHER_WEP_40:
3410 case WPA_CIPHER_WEP_104:
3413 case WPA_CIPHER_TKIP:
3416 case WPA_CIPHER_AES_CCM:
3420 WL_ERR(("No Security Info\n"));
3425 /* Check for unicast suite(s) */
3426 if (len < WPA_IE_SUITE_COUNT_LEN) {
3427 WL_INFO(("no unicast suite\n"));
3430 /* walk thru unicast cipher list and pick up what we recognize */
3431 ucast = (wpa_suite_ucast_t *)&mcast[1];
3432 count = ltoh16_ua(&ucast->count);
3433 len -= WPA_IE_SUITE_COUNT_LEN;
3434 for (i = 0; i < count && len >= WPA_SUITE_LEN;
3435 i++, len -= WPA_SUITE_LEN) {
3436 if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
3437 if (IS_WPA_CIPHER(ucast->list[i].type)) {
3439 switch (ucast->list[i].type) {
3440 case WPA_CIPHER_NONE:
3443 case WPA_CIPHER_WEP_40:
3444 case WPA_CIPHER_WEP_104:
3447 case WPA_CIPHER_TKIP:
3450 case WPA_CIPHER_AES_CCM:
3454 WL_ERR(("No Security Info\n"));
3460 len -= (count - i) * WPA_SUITE_LEN;
3461 /* Check for auth key management suite(s) */
3462 if (len < WPA_IE_SUITE_COUNT_LEN) {
3463 WL_INFO((" no auth key mgmt suite\n"));
3466 /* walk thru auth management suite list and pick up what we recognize */
3467 mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count];
3468 count = ltoh16_ua(&mgmt->count);
3469 len -= WPA_IE_SUITE_COUNT_LEN;
3470 for (i = 0; i < count && len >= WPA_SUITE_LEN;
3471 i++, len -= WPA_SUITE_LEN) {
3472 if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
3473 if (IS_WPA_AKM(mgmt->list[i].type)) {
3475 switch (mgmt->list[i].type) {
3477 tmp = WPA_AUTH_NONE;
3479 case RSN_AKM_UNSPECIFIED:
3480 tmp = WPA_AUTH_UNSPECIFIED;
3486 WL_ERR(("No Key Mgmt Info\n"));
3493 /* FOR WPS , set SEC_OW_ENABLED */
3494 wsec = (pval | gval | SES_OW_ENABLED);
3496 err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
3498 WL_ERR(("auth error %d\n", err));
3502 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
3504 WL_ERR(("wsec error %d\n", err));
3507 /* set upper-layer auth */
3508 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
3510 WL_ERR(("wpa_auth error %d\n", err));
3518 wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
3519 struct beacon_parameters *info)
3524 struct wl_priv *wl = WL_PRIV_GET();
3525 struct wl_join_params join_params;
3526 wpa_ie_fixed_t *wps_ie;
3527 wpa_ie_fixed_t *wpa_ie;
3529 wifi_p2p_ie_t *p2p_ie;
3530 bool is_bssup = false;
3531 bool update_bss = false;
3535 u8 beacon_ie[IE_MAX_LEN];
3537 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
3539 s32 join_params_size = 0;
3541 WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
3542 info->interval, info->dtim_period, info->head_len, info->tail_len));
3543 if (wl->p2p_supported && p2p_on(wl) &&
3544 (bssidx >= wl_to_p2p_bss_bssidx(wl,
3545 P2PAPI_BSSCFG_CONNECTION))) {
3546 memset(beacon_ie, 0, sizeof(beacon_ie));
3547 /* We don't need to set beacon for P2P_GO,
3548 * but need to parse ssid from beacon_parameters
3549 * because there is no way to set ssid
3551 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3553 if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
3554 info->head_len - ie_offset,
3555 DOT11_MNG_SSID_ID)) != NULL) {
3556 memcpy(wl->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len);
3557 wl->p2p->ssid.SSID_len = ssid_ie->len;
3558 WL_DBG(("SSID (%s) in Head \n", ssid_ie->data));
3561 WL_ERR(("No SSID in beacon \n"));
3564 /* find the WPSIE */
3565 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
3566 wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
3568 * Should be compared with saved ie before saving it
3570 wl_validate_wps_ie((char *) wps_ie, &pbc);
3571 memcpy(beacon_ie, wps_ie, wpsie_len);
3573 WL_ERR(("No WPSIE in beacon \n"));
3577 /* find the P2PIE */
3578 if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)info->tail, info->tail_len)) != NULL) {
3579 /* Total length of P2P Information Element */
3580 p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
3581 #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3582 /* Have to change device address in dev_id attribute because Supplicant
3583 * use primary eth0 address
3585 wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr, P2P_SEID_DEV_ID);
3587 memcpy(&beacon_ie[wpsie_len], p2p_ie, p2pie_len);
3590 WL_ERR(("No P2PIE in beacon \n"));
3592 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3593 beacon_ie, wpsie_len + p2pie_len);
3594 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_ASSOCRSP_FLAG,
3595 beacon_ie, wpsie_len + p2pie_len);
3597 /* find the RSN_IE */
3598 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3599 DOT11_MNG_RSN_ID)) != NULL) {
3600 WL_DBG((" WPA2 IE is found\n"));
3602 is_bssup = wl_cfgp2p_bss_isup(dev, bssidx);
3604 if (!is_bssup && (wpa2_ie != NULL)) {
3605 if ((err = wl_validate_wpa2ie(dev, wpa2_ie, bssidx)) < 0) {
3606 WL_ERR(("WPA2 IE parsing error"));
3609 err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
3611 WL_ERR(("SET INFRA error %d\n", err));
3614 err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p->ssid,
3615 sizeof(wl->p2p->ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
3617 WL_ERR(("GO SSID setting error %d\n", err));
3620 if ((err = wl_cfgp2p_bss(dev, bssidx, 1)) < 0) {
3621 WL_ERR(("GO Bring up error %d\n", err));
3625 } else if (wl_get_drv_status(wl, AP_CREATING)) {
3626 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3629 if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
3630 info->head_len - ie_offset,
3631 DOT11_MNG_SSID_ID)) != NULL) {
3632 memset(&ssid, 0, sizeof(wlc_ssid_t));
3633 memcpy(ssid.SSID, ssid_ie->data, ssid_ie->len);
3634 WL_DBG(("SSID is (%s) in Head \n", ssid.SSID));
3635 ssid.SSID_len = ssid_ie->len;
3636 wldev_iovar_setint(dev, "mpc", 0);
3637 wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), false);
3638 wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
3639 wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), false);
3640 /* find the RSN_IE */
3641 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3642 DOT11_MNG_RSN_ID)) != NULL) {
3643 WL_DBG((" WPA2 IE is found\n"));
3645 /* find the WPA_IE */
3646 if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail,
3647 info->tail_len)) != NULL) {
3648 WL_DBG((" WPA IE is found\n"));
3650 if ((wpa_ie != NULL || wpa2_ie != NULL)) {
3651 if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 ||
3652 wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
3653 wl->ap_info->security_mode = false;
3656 wl->ap_info->security_mode = true;
3657 kfree(wl->ap_info->rsn_ie);
3658 kfree(wl->ap_info->wpa_ie);
3659 kfree(wl->ap_info->wps_ie);
3660 if (wpa_ie != NULL) {
3662 wl->ap_info->rsn_ie = NULL;
3663 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3664 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3668 wl->ap_info->wpa_ie = NULL;
3669 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3670 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3674 wl->ap_info->security_mode = false;
3675 /* find the WPSIE */
3676 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail,
3677 info->tail_len)) != NULL) {
3678 wpsie_len = wps_ie->length +WPA_RSN_IE_TAG_FIXED_LEN;
3680 * Should be compared with saved ie before saving it
3682 wl_validate_wps_ie((char *) wps_ie, &pbc);
3683 memcpy(beacon_ie, wps_ie, wpsie_len);
3684 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3685 beacon_ie, wpsie_len);
3686 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
3687 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3688 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3690 WL_DBG(("No WPSIE in beacon \n"));
3692 wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), false);
3694 memset(&join_params, 0, sizeof(join_params));
3695 /* join parameters starts with ssid */
3696 join_params_size = sizeof(join_params.ssid);
3697 memcpy(join_params.ssid.SSID, ssid.SSID, ssid.SSID_len);
3698 join_params.ssid.SSID_len = htod32(ssid.SSID_len);
3700 if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
3701 join_params_size, false)) == 0) {
3702 wl_clr_drv_status(wl, AP_CREATING);
3703 wl_set_drv_status(wl, AP_CREATED);
3706 } else if (wl_get_drv_status(wl, AP_CREATED)) {
3708 /* find the WPSIE */
3709 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
3710 wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
3712 * Should be compared with saved ie before saving it
3714 wl_validate_wps_ie((char *) wps_ie, &pbc);
3715 memcpy(beacon_ie, wps_ie, wpsie_len);
3716 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3717 beacon_ie, wpsie_len);
3718 if (wl->ap_info->wps_ie &&
3719 memcmp(wl->ap_info->wps_ie, wps_ie, wpsie_len)) {
3720 WL_DBG((" WPS IE is changed\n"));
3721 kfree(wl->ap_info->wps_ie);
3722 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
3723 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3724 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3725 } else if (wl->ap_info->wps_ie == NULL) {
3726 WL_DBG((" WPS IE is added\n"));
3727 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
3728 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3729 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3731 /* find the RSN_IE */
3732 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3733 DOT11_MNG_RSN_ID)) != NULL) {
3734 WL_DBG((" WPA2 IE is found\n"));
3736 /* find the WPA_IE */
3737 if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail,
3738 info->tail_len)) != NULL) {
3739 WL_DBG((" WPA IE is found\n"));
3741 if ((wpa_ie != NULL || wpa2_ie != NULL)) {
3742 if (!wl->ap_info->security_mode) {
3743 /* change from open mode to security mode */
3745 if (wpa_ie != NULL) {
3746 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3747 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3750 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3751 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3754 } else if (wl->ap_info->wpa_ie) {
3755 /* change from WPA mode to WPA2 mode */
3756 if (wpa2_ie != NULL) {
3758 kfree(wl->ap_info->wpa_ie);
3759 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3760 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3762 wl->ap_info->wpa_ie = NULL;
3764 else if (memcmp(wl->ap_info->wpa_ie,
3765 wpa_ie, wpa_ie->length +
3766 WPA_RSN_IE_TAG_FIXED_LEN)) {
3767 kfree(wl->ap_info->wpa_ie);
3769 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3770 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3772 wl->ap_info->rsn_ie = NULL;
3775 /* change from WPA2 mode to WPA mode */
3776 if (wpa_ie != NULL) {
3778 kfree(wl->ap_info->rsn_ie);
3779 wl->ap_info->rsn_ie = NULL;
3780 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3781 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3783 } else if (memcmp(wl->ap_info->rsn_ie,
3784 wpa2_ie, wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN)) {
3786 kfree(wl->ap_info->rsn_ie);
3787 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3788 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3790 wl->ap_info->wpa_ie = NULL;
3794 wl->ap_info->security_mode = true;
3795 wl_cfgp2p_bss(dev, bssidx, 0);
3796 if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 ||
3797 wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
3800 wl_cfgp2p_bss(dev, bssidx, 1);
3804 WL_ERR(("No WPSIE in beacon \n"));
3810 #if defined(ANDROID_WIRELESS_PATCH)
3812 wl_cfg80211_drv_start(struct wiphy *wiphy, struct net_device *dev)
3814 /* struct wl_priv *wl = wiphy_to_wl(wiphy); */
3817 printk("Android driver start command\n");
3822 wl_cfg80211_drv_stop(struct wiphy *wiphy, struct net_device *dev)
3824 /* struct wl_priv *wl = wiphy_to_wl(wiphy); */
3827 printk("Android driver stop command\n");
3830 #endif /* defined(ANDROID_WIRELESS_PATCH) */
3832 static struct cfg80211_ops wl_cfg80211_ops = {
3833 .add_virtual_intf = wl_cfg80211_add_virtual_iface,
3834 .del_virtual_intf = wl_cfg80211_del_virtual_iface,
3835 .change_virtual_intf = wl_cfg80211_change_virtual_iface,
3836 .scan = wl_cfg80211_scan,
3837 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
3838 .join_ibss = wl_cfg80211_join_ibss,
3839 .leave_ibss = wl_cfg80211_leave_ibss,
3840 .get_station = wl_cfg80211_get_station,
3841 .set_tx_power = wl_cfg80211_set_tx_power,
3842 .get_tx_power = wl_cfg80211_get_tx_power,
3843 .add_key = wl_cfg80211_add_key,
3844 .del_key = wl_cfg80211_del_key,
3845 .get_key = wl_cfg80211_get_key,
3846 .set_default_key = wl_cfg80211_config_default_key,
3847 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
3848 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
3849 .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
3850 .connect = wl_cfg80211_connect,
3851 .disconnect = wl_cfg80211_disconnect,
3852 .suspend = wl_cfg80211_suspend,
3853 .resume = wl_cfg80211_resume,
3854 .set_pmksa = wl_cfg80211_set_pmksa,
3855 .del_pmksa = wl_cfg80211_del_pmksa,
3856 .flush_pmksa = wl_cfg80211_flush_pmksa,
3857 .remain_on_channel = wl_cfg80211_remain_on_channel,
3858 .cancel_remain_on_channel = wl_cfg80211_cancel_remain_on_channel,
3859 .mgmt_tx = wl_cfg80211_mgmt_tx,
3860 .mgmt_frame_register = wl_cfg80211_mgmt_frame_register,
3861 .change_bss = wl_cfg80211_change_bss,
3862 .set_channel = wl_cfg80211_set_channel,
3863 .set_beacon = wl_cfg80211_set_beacon,
3864 #if defined(ANDROID_WIRELESS_PATCH)
3865 .drv_start = wl_cfg80211_drv_start,
3866 .drv_stop = wl_cfg80211_drv_stop
3870 static s32 wl_mode_to_nl80211_iftype(s32 mode)
3876 return NL80211_IFTYPE_STATION;
3878 return NL80211_IFTYPE_ADHOC;
3880 return NL80211_IFTYPE_AP;
3882 return NL80211_IFTYPE_UNSPECIFIED;
3888 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
3891 struct wireless_dev *wdev;
3894 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
3895 if (unlikely(!wdev)) {
3896 WL_ERR(("Could not allocate wireless device\n"));
3897 return ERR_PTR(-ENOMEM);
3900 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
3901 if (unlikely(!wdev->wiphy)) {
3902 WL_ERR(("Couldn not allocate wiphy device\n"));
3906 set_wiphy_dev(wdev->wiphy, dev);
3907 wl = wiphy_to_wl(wdev->wiphy);
3908 wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
3909 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3910 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3911 wdev->wiphy->interface_modes =
3912 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC)
3913 | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
3915 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3916 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
3917 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3918 wdev->wiphy->cipher_suites = __wl_cipher_suites;
3919 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3920 wdev->wiphy->max_remain_on_channel_duration = 5000;
3921 wdev->wiphy->mgmt_stypes = wl_cfg80211_default_mgmt_stypes;
3922 #ifndef WL_POWERSAVE_DISABLED
3923 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
3925 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3926 #endif /* !WL_POWERSAVE_DISABLED */
3927 wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK |
3928 WIPHY_FLAG_4ADDR_AP |
3929 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)
3930 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS |
3932 WIPHY_FLAG_4ADDR_STATION;
3934 WL_DBG(("Registering custom regulatory)\n"));
3935 wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3936 wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
3937 /* Now we can register wiphy with cfg80211 module */
3938 err = wiphy_register(wdev->wiphy);
3939 if (unlikely(err < 0)) {
3940 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
3941 goto wiphy_register_out;
3946 wiphy_free(wdev->wiphy);
3951 return ERR_PTR(err);
3954 static void wl_free_wdev(struct wl_priv *wl)
3957 struct wireless_dev *wdev = wl_to_wdev(wl);
3959 if (unlikely(!wdev)) {
3960 WL_ERR(("wdev is invalid\n"));
3964 for (i = 0; i < VWDEV_CNT; i++) {
3965 if ((wl->vwdev[i] != NULL)) {
3966 kfree(wl->vwdev[i]);
3967 wl->vwdev[i] = NULL;
3970 wiphy_unregister(wdev->wiphy);
3971 wiphy_free(wdev->wiphy);
3973 wl_to_wdev(wl) = NULL;
3976 static s32 wl_inform_bss(struct wl_priv *wl)
3978 struct wl_scan_results *bss_list;
3979 struct wl_bss_info *bi = NULL; /* must be initialized */
3983 bss_list = wl->bss_list;
3985 if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
3986 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
3987 bss_list->version));
3991 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
3992 bi = next_bss(bss_list, bi);
3993 for_each_bss(bss_list, bi, i) {
3994 err = wl_inform_single_bss(wl, bi);
4001 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
4003 struct wiphy *wiphy = wiphy_from_scan(wl);
4004 struct ieee80211_mgmt *mgmt;
4005 struct ieee80211_channel *channel;
4006 struct ieee80211_supported_band *band;
4007 struct wl_cfg80211_bss_info *notif_bss_info;
4008 struct wl_scan_req *sr = wl_to_sr(wl);
4009 struct beacon_proberesp *beacon_proberesp;
4015 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
4016 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
4019 notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt)
4020 - sizeof(u8) + WL_BSS_INFO_MAX, GFP_KERNEL);
4021 if (unlikely(!notif_bss_info)) {
4022 WL_ERR(("notif_bss_info alloc failed\n"));
4025 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
4026 notif_bss_info->channel =
4027 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
4029 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
4030 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4032 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4033 notif_bss_info->rssi = bi->RSSI;
4034 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
4035 mgmt_type = wl->active_scan ?
4036 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
4037 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
4038 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type);
4040 beacon_proberesp = wl->active_scan ?
4041 (struct beacon_proberesp *)&mgmt->u.probe_resp :
4042 (struct beacon_proberesp *)&mgmt->u.beacon;
4043 beacon_proberesp->timestamp = 0;
4044 beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
4045 beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
4048 * wl_add_ie is not necessary because it can only add duplicated
4049 * SSID, rate information to frame_buf
4052 * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
4053 * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
4054 * bi->rateset.rates);
4056 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
4057 wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
4058 offsetof(struct wl_cfg80211_bss_info, frame_buf));
4059 notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
4060 u.beacon.variable) + wl_get_ielen(wl);
4061 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4062 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
4064 freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
4066 channel = ieee80211_get_channel(wiphy, freq);
4068 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
4070 notif_bss_info->rssi, notif_bss_info->channel,
4071 mgmt->u.beacon.capab_info, &bi->BSSID));
4073 signal = notif_bss_info->rssi * 100;
4074 if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
4076 (notif_bss_info->frame_len),
4077 signal, GFP_KERNEL))) {
4078 WL_ERR(("cfg80211_inform_bss_frame error\n"));
4079 kfree(notif_bss_info);
4082 kfree(notif_bss_info);
4087 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev)
4089 u32 event = ntoh32(e->event_type);
4090 uint32 status = ntoh32(e->status);
4092 WL_DBG(("event %d, status %d\n", event, status));
4093 if (event == WLC_E_SET_SSID) {
4094 if (status == WLC_E_STATUS_SUCCESS) {
4095 if (!wl_is_ibssmode(wl, ndev))
4100 WL_DBG(("wl_is_linkup false\n"));
4104 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
4106 u32 event = ntoh32(e->event_type);
4107 u16 flags = ntoh16(e->flags);
4109 if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
4111 } else if (event == WLC_E_LINK) {
4112 if (!(flags & WLC_EVENT_MSG_LINK))
4119 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
4121 u32 event = ntoh32(e->event_type);
4122 u32 status = ntoh32(e->status);
4124 if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS)
4126 if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS)
4133 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
4134 const wl_event_msg_t *e, void *data)
4137 bool isfree = false;
4142 u32 event = ntoh32(e->event_type);
4143 u32 reason = ntoh32(e->reason);
4144 u32 len = ntoh32(e->datalen);
4147 u8 bsscfgidx = e->bsscfgidx;
4148 struct ieee80211_supported_band *band;
4149 struct ether_addr da;
4150 struct ether_addr bssid;
4151 struct wiphy *wiphy = wl_to_wiphy(wl);
4154 memset(body, 0, sizeof(body));
4155 WL_DBG(("Enter \n"));
4157 if (get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
4158 memcpy(body, data, len);
4159 wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
4160 &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
4161 wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
4163 case WLC_E_ASSOC_IND:
4166 case WLC_E_REASSOC_IND:
4167 fc = FC_REASSOC_REQ;
4169 case WLC_E_DISASSOC_IND:
4172 case WLC_E_DEAUTH_IND:
4182 if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
4185 channel = dtoh32(ci.hw_channel);
4186 if (channel <= CH_MAX_2G_CHANNEL)
4187 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4189 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4191 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4192 freq = ieee80211_channel_to_frequency(channel);
4194 freq = ieee80211_channel_to_frequency(channel, band->band);
4197 err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
4198 &mgmt_frame, &len, body);
4203 if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
4204 cfg80211_send_rx_assoc(ndev, mgmt_frame, len);
4205 } else if (event == WLC_E_DISASSOC_IND) {
4206 cfg80211_send_disassoc(ndev, mgmt_frame, len);
4207 } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
4208 cfg80211_send_deauth(ndev, mgmt_frame, len);
4212 WL_DBG(("wl_notify_connect_status : event %d status : %d \n",
4213 ntoh32(e->event_type), ntoh32(e->status)));
4214 if (wl_is_linkup(wl, e, ndev)) {
4216 if (wl_is_ibssmode(wl, ndev)) {
4217 printk("cfg80211_ibss_joined");
4218 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
4220 WL_DBG(("joined in IBSS network\n"));
4222 printk("wl_bss_connect_done succeeded");
4223 wl_bss_connect_done(wl, ndev, e, data, true);
4224 WL_DBG(("joined in BSS network \"%s\"\n",
4225 ((struct wlc_ssid *)
4226 wl_read_prof(wl, WL_PROF_SSID))->SSID));
4229 wl_update_prof(wl, e, &act, WL_PROF_ACT);
4230 } else if (wl_is_linkdown(wl, e)) {
4231 if (wl_get_drv_status(wl, CONNECTED)) {
4232 printk("link down, call cfg80211_disconnected ");
4233 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
4234 wl_clr_drv_status(wl, CONNECTED);
4236 wl_init_prof(wl->profile);
4238 } else if (wl_is_nonetwork(wl, e)) {
4239 printk("connect failed e->status 0x%x", (int)ntoh32(e->status));
4240 if (wl_get_drv_status(wl, CONNECTING))
4241 wl_bss_connect_done(wl, ndev, e, data, false);
4243 printk("%s nothing\n", __FUNCTION__);
4254 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
4255 const wl_event_msg_t *e, void *data)
4260 WL_DBG(("Enter \n"));
4261 wl_bss_roaming_done(wl, ndev, e, data);
4263 wl_update_prof(wl, e, &act, WL_PROF_ACT);
4269 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
4271 struct wl_priv *wl = WL_PRIV_GET();
4274 buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
4275 BUG_ON(unlikely(!buflen));
4277 return wldev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen, false);
4281 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
4284 struct wl_priv *wl = WL_PRIV_GET();
4288 len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
4289 BUG_ON(unlikely(!len));
4290 err = wldev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
4291 WL_IOCTL_LEN_MAX, false);
4292 if (unlikely(err)) {
4293 WL_ERR(("error (%d)\n", err));
4296 memcpy(buf, wl->ioctl_buf, buf_len);
4301 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
4303 wl_assoc_info_t assoc_info;
4304 struct wl_connect_info *conn_info = wl_to_conn(wl);
4307 WL_DBG(("Enter \n"));
4308 err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
4310 if (unlikely(err)) {
4311 WL_ERR(("could not get assoc info (%d)\n", err));
4314 memcpy(&assoc_info, wl->extra_buf, sizeof(wl_assoc_info_t));
4315 assoc_info.req_len = htod32(assoc_info.req_len);
4316 assoc_info.resp_len = htod32(assoc_info.resp_len);
4317 assoc_info.flags = htod32(assoc_info.flags);
4318 if (assoc_info.req_len) {
4319 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
4321 if (unlikely(err)) {
4322 WL_ERR(("could not get assoc req (%d)\n", err));
4325 conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req);
4326 if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
4327 conn_info->req_ie_len -= ETHER_ADDR_LEN;
4330 kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
4332 conn_info->req_ie_len = 0;
4333 conn_info->req_ie = NULL;
4335 if (assoc_info.resp_len) {
4336 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
4338 if (unlikely(err)) {
4339 WL_ERR(("could not get assoc resp (%d)\n", err));
4342 conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
4343 conn_info->resp_ie =
4344 kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
4346 conn_info->resp_ie_len = 0;
4347 conn_info->resp_ie = NULL;
4349 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
4350 conn_info->resp_ie_len));
4355 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
4356 size_t *join_params_size)
4358 chanspec_t chanspec = 0;
4361 join_params->params.chanspec_num = 1;
4362 join_params->params.chanspec_list[0] = ch;
4364 if (join_params->params.chanspec_list[0])
4365 chanspec |= WL_CHANSPEC_BAND_2G;
4367 chanspec |= WL_CHANSPEC_BAND_5G;
4369 chanspec |= WL_CHANSPEC_BW_20;
4370 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
4372 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
4373 join_params->params.chanspec_num * sizeof(chanspec_t);
4375 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
4376 join_params->params.chanspec_list[0] |= chanspec;
4377 join_params->params.chanspec_list[0] =
4378 htodchanspec(join_params->params.chanspec_list[0]);
4380 join_params->params.chanspec_num =
4381 htod32(join_params->params.chanspec_num);
4383 WL_DBG(("%s join_params->params.chanspec_list[0]= %X\n",
4384 __FUNCTION__, join_params->params.chanspec_list[0]));
4389 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev)
4391 struct cfg80211_bss *bss;
4392 struct wl_bss_info *bi;
4393 struct wlc_ssid *ssid;
4394 struct bcm_tlv *tim;
4395 u16 beacon_interval;
4400 struct wiphy *wiphy;
4401 wiphy = wl_to_wiphy(wl);
4403 if (wl_is_ibssmode(wl, ndev))
4406 ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
4407 bss = cfg80211_get_bss(wiphy, NULL, (s8 *)&wl->bssid,
4408 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
4409 WLAN_CAPABILITY_ESS);
4412 if (unlikely(!bss)) {
4413 WL_DBG(("Could not find the AP\n"));
4414 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
4415 err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_BSS_INFO,
4416 wl->extra_buf, WL_EXTRA_BUF_MAX, false);
4417 if (unlikely(err)) {
4418 WL_ERR(("Could not get bss info %d\n", err));
4419 goto update_bss_info_out;
4421 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
4422 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
4424 goto update_bss_info_out;
4426 err = wl_inform_single_bss(wl, bi);
4428 goto update_bss_info_out;
4430 ie = ((u8 *)bi) + bi->ie_offset;
4431 ie_len = bi->ie_length;
4432 beacon_interval = cpu_to_le16(bi->beacon_period);
4434 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
4435 ie = bss->information_elements;
4436 ie_len = bss->len_information_elements;
4437 beacon_interval = bss->beacon_interval;
4438 cfg80211_put_bss(bss);
4441 tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
4443 dtim_period = tim->data[1];
4446 * active scan was done so we could not get dtim
4447 * information out of probe response.
4448 * so we speficially query dtim information to dongle.
4450 err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_DTIMPRD,
4451 &dtim_period, sizeof(dtim_period), false);
4452 if (unlikely(err)) {
4453 WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
4454 goto update_bss_info_out;
4458 wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
4459 wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
4461 update_bss_info_out:
4467 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
4468 const wl_event_msg_t *e, void *data)
4470 struct wl_connect_info *conn_info = wl_to_conn(wl);
4473 wl_get_assoc_ies(wl, ndev);
4474 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
4475 wl_update_bss_info(wl, ndev);
4476 cfg80211_roamed(ndev,
4477 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
4481 conn_info->req_ie, conn_info->req_ie_len,
4482 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4483 WL_DBG(("Report roaming result\n"));
4485 wl_set_drv_status(wl, CONNECTED);
4491 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
4492 const wl_event_msg_t *e, void *data, bool completed)
4494 struct wl_connect_info *conn_info = wl_to_conn(wl);
4497 WL_DBG((" enter\n"));
4498 wl_get_assoc_ies(wl, ndev);
4499 memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
4500 wl_update_bss_info(wl, ndev);
4501 if (wl_get_drv_status(wl, CONNECTING)) {
4502 wl_clr_drv_status(wl, CONNECTING);
4503 cfg80211_connect_result(ndev,
4506 conn_info->req_ie_len,
4508 conn_info->resp_ie_len,
4509 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
4511 WL_DBG(("Report connect result - connection %s\n",
4512 completed ? "succeeded" : "failed"));
4514 wl_clr_drv_status(wl, CONNECTING);
4515 cfg80211_roamed(ndev,
4516 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
4520 conn_info->req_ie, conn_info->req_ie_len,
4521 conn_info->resp_ie, conn_info->resp_ie_len,
4523 WL_DBG(("Report roaming result\n"));
4526 wl_set_drv_status(wl, CONNECTED);
4528 if (wl->scan_request) {
4529 wl_set_drv_status(wl, SCAN_ABORTING);
4530 cfg80211_scan_done(wl->scan_request, true);
4531 wl->scan_request = NULL;
4532 wl_clr_drv_status(wl, SCANNING);
4533 wl_clr_drv_status(wl, SCAN_ABORTING);
4541 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
4542 const wl_event_msg_t *e, void *data)
4544 u16 flags = ntoh16(e->flags);
4545 enum nl80211_key_type key_type;
4548 if (flags & WLC_EVENT_MSG_GROUP)
4549 key_type = NL80211_KEYTYPE_GROUP;
4551 key_type = NL80211_KEYTYPE_PAIRWISE;
4553 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
4561 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
4562 const wl_event_msg_t *e, void *data)
4564 struct channel_info channel_inform;
4565 struct wl_scan_results *bss_list;
4566 u32 len = WL_SCAN_BUF_MAX;
4569 WL_DBG(("Enter \n"));
4570 if (wl->iscan_on && wl->iscan_kickstart)
4571 return wl_wakeup_iscan(wl_to_iscan(wl));
4573 if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
4574 wl_clr_drv_status(wl, SCANNING);
4575 WL_DBG(("Scan complete while device not scanning\n"));
4578 wl_clr_drv_status(wl, SCANNING);
4580 err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
4581 sizeof(channel_inform), false);
4582 if (unlikely(err)) {
4583 WL_ERR(("scan busy (%d)\n", err));
4586 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
4587 if (unlikely(channel_inform.scan_channel)) {
4589 WL_DBG(("channel_inform.scan_channel (%d)\n",
4590 channel_inform.scan_channel));
4592 wl->bss_list = wl->scan_results;
4593 bss_list = wl->bss_list;
4594 memset(bss_list, 0, len);
4595 bss_list->buflen = htod32(len);
4596 err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, false);
4597 if (unlikely(err)) {
4598 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
4602 bss_list->buflen = dtoh32(bss_list->buflen);
4603 bss_list->version = dtoh32(bss_list->version);
4604 bss_list->count = dtoh32(bss_list->count);
4606 err = wl_inform_bss(wl);
4611 if (wl->scan_request) {
4612 WL_DBG(("cfg80211_scan_done\n"));
4613 cfg80211_scan_done(wl->scan_request, false);
4614 wl->scan_request = NULL;
4620 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
4621 const struct ether_addr *sa, const struct ether_addr *bssid,
4622 u8 **pheader, u32 *body_len, u8 *pbody)
4624 struct dot11_management_header *hdr;
4628 u32 prebody_len = *body_len;
4631 /* capability , listen interval */
4632 totlen = DOT11_ASSOC_REQ_FIXED_LEN;
4633 *body_len += DOT11_ASSOC_REQ_FIXED_LEN;
4636 case FC_REASSOC_REQ:
4637 /* capability, listen inteval, ap address */
4638 totlen = DOT11_REASSOC_REQ_FIXED_LEN;
4639 *body_len += DOT11_REASSOC_REQ_FIXED_LEN;
4642 totlen += DOT11_MGMT_HDR_LEN + prebody_len;
4643 *pheader = kzalloc(totlen, GFP_KERNEL);
4644 if (*pheader == NULL) {
4645 WL_ERR(("memory alloc failed \n"));
4648 hdr = (struct dot11_management_header *) (*pheader);
4649 hdr->fc = htol16(fc);
4652 offset = (u8*)(hdr + 1) + (totlen - DOT11_MGMT_HDR_LEN - prebody_len);
4653 bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN);
4654 bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN);
4655 bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN);
4656 bcopy((const char*)pbody, offset, prebody_len);
4661 wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
4662 const wl_event_msg_t *e, void *data)
4664 struct ieee80211_supported_band *band;
4665 struct wiphy *wiphy = wl_to_wiphy(wl);
4666 struct ether_addr da;
4667 struct ether_addr bssid;
4668 bool isfree = false;
4671 wl_event_rx_frame_data_t *rxframe =
4672 (wl_event_rx_frame_data_t*)data;
4673 u32 event = ntoh32(e->event_type);
4675 u8 bsscfgidx = e->bsscfgidx;
4676 u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t);
4677 u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK) & 0x0f);
4678 if (channel <= CH_MAX_2G_CHANNEL)
4679 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4681 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4683 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4684 freq = ieee80211_channel_to_frequency(channel);
4686 freq = ieee80211_channel_to_frequency(channel, band->band);
4688 if (event == WLC_E_ACTION_FRAME_RX) {
4689 wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
4690 &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
4691 wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
4692 err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid,
4693 &mgmt_frame, &mgmt_frame_len,
4694 (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1));
4696 WL_ERR(("%s: Error in receiving action frame len %d channel %d freq %d\n",
4697 __func__, mgmt_frame_len, channel, freq));
4702 mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
4705 cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
4707 WL_DBG(("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__,
4708 mgmt_frame_len, ntoh32(e->datalen), channel, freq));
4716 static void wl_init_conf(struct wl_conf *conf)
4719 WL_DBG(("Enter \n"));
4720 for (i = 0; i <= VWDEV_CNT; i++) {
4721 conf->mode[i].type = -1;
4722 conf->mode[i].ndev = NULL;
4724 conf->frag_threshold = (u32)-1;
4725 conf->rts_threshold = (u32)-1;
4726 conf->retry_short = (u32)-1;
4727 conf->retry_long = (u32)-1;
4728 conf->tx_power = -1;
4731 static void wl_init_prof(struct wl_profile *prof)
4733 memset(prof, 0, sizeof(*prof));
4736 static void wl_init_event_handler(struct wl_priv *wl)
4738 memset(wl->evt_handler, 0, sizeof(wl->evt_handler));
4740 wl->evt_handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
4741 /* wl->evt_handler[WLC_E_JOIN] = wl_notify_connect_status; */
4742 wl->evt_handler[WLC_E_LINK] = wl_notify_connect_status;
4743 wl->evt_handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
4744 wl->evt_handler[WLC_E_DEAUTH] = wl_notify_connect_status;
4745 wl->evt_handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
4746 wl->evt_handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
4747 wl->evt_handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
4748 wl->evt_handler[WLC_E_ROAM] = wl_notify_roaming_status;
4749 wl->evt_handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
4750 wl->evt_handler[WLC_E_SET_SSID] = wl_notify_connect_status;
4751 wl->evt_handler[WLC_E_ACTION_FRAME_RX] = wl_notify_rx_mgmt_frame;
4752 wl->evt_handler[WLC_E_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
4753 wl->evt_handler[WLC_E_P2P_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
4754 wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete;
4755 wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
4756 wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
4760 static s32 wl_init_priv_mem(struct wl_priv *wl)
4762 WL_DBG(("Enter \n"));
4763 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
4764 if (unlikely(!wl->scan_results)) {
4765 WL_ERR(("Scan results alloc failed\n"));
4766 goto init_priv_mem_out;
4768 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
4769 if (unlikely(!wl->conf)) {
4770 WL_ERR(("wl_conf alloc failed\n"));
4771 goto init_priv_mem_out;
4773 wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
4774 if (unlikely(!wl->profile)) {
4775 WL_ERR(("wl_profile alloc failed\n"));
4776 goto init_priv_mem_out;
4778 wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4779 if (unlikely(!wl->bss_info)) {
4780 WL_ERR(("Bss information alloc failed\n"));
4781 goto init_priv_mem_out;
4784 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
4785 if (unlikely(!wl->scan_req_int)) {
4786 WL_ERR(("Scan req alloc failed\n"));
4787 goto init_priv_mem_out;
4789 wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
4790 if (unlikely(!wl->ioctl_buf)) {
4791 WL_ERR(("Ioctl buf alloc failed\n"));
4792 goto init_priv_mem_out;
4794 wl->escan_ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
4795 if (unlikely(!wl->escan_ioctl_buf)) {
4796 WL_ERR(("Ioctl buf alloc failed\n"));
4797 goto init_priv_mem_out;
4799 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4800 if (unlikely(!wl->extra_buf)) {
4801 WL_ERR(("Extra buf alloc failed\n"));
4802 goto init_priv_mem_out;
4804 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
4805 if (unlikely(!wl->iscan)) {
4806 WL_ERR(("Iscan buf alloc failed\n"));
4807 goto init_priv_mem_out;
4809 wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
4810 if (unlikely(!wl->fw)) {
4811 WL_ERR(("fw object alloc failed\n"));
4812 goto init_priv_mem_out;
4814 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
4815 if (unlikely(!wl->pmk_list)) {
4816 WL_ERR(("pmk list alloc failed\n"));
4817 goto init_priv_mem_out;
4823 wl_deinit_priv_mem(wl);
4828 static void wl_deinit_priv_mem(struct wl_priv *wl)
4830 kfree(wl->scan_results);
4831 wl->scan_results = NULL;
4832 kfree(wl->bss_info);
4833 wl->bss_info = NULL;
4838 kfree(wl->scan_req_int);
4839 wl->scan_req_int = NULL;
4840 kfree(wl->ioctl_buf);
4841 wl->ioctl_buf = NULL;
4842 kfree(wl->escan_ioctl_buf);
4843 wl->escan_ioctl_buf = NULL;
4844 kfree(wl->extra_buf);
4845 wl->extra_buf = NULL;
4850 kfree(wl->pmk_list);
4851 wl->pmk_list = NULL;
4853 kfree(wl->ap_info->wpa_ie);
4854 kfree(wl->ap_info->rsn_ie);
4855 kfree(wl->ap_info->wps_ie);
4861 static s32 wl_create_event_handler(struct wl_priv *wl)
4863 WL_DBG(("Enter \n"));
4864 sema_init(&wl->event_sync, 0);
4865 wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
4866 if (IS_ERR(wl->event_tsk)) {
4867 wl->event_tsk = NULL;
4868 WL_ERR(("failed to create event thread\n"));
4874 static void wl_destroy_event_handler(struct wl_priv *wl)
4876 if (wl->event_tsk) {
4877 send_sig(SIGTERM, wl->event_tsk, 1);
4878 kthread_stop(wl->event_tsk);
4879 wl->event_tsk = NULL;
4883 static void wl_term_iscan(struct wl_priv *wl)
4885 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
4887 if (wl->iscan_on && iscan->tsk) {
4888 iscan->state = WL_ISCAN_STATE_IDLE;
4889 WL_INFO(("SIGTERM\n"));
4890 send_sig(SIGTERM, iscan->tsk, 1);
4891 WL_DBG(("kthread_stop\n"));
4892 kthread_stop(iscan->tsk);
4897 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
4899 struct wl_priv *wl = iscan_to_wl(iscan);
4901 WL_DBG(("Enter \n"));
4902 if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
4903 wl_clr_drv_status(wl, SCANNING);
4904 WL_ERR(("Scan complete while device not scanning\n"));
4907 wl_clr_drv_status(wl, SCANNING);
4908 if (likely(wl->scan_request)) {
4909 cfg80211_scan_done(wl->scan_request, aborted);
4910 wl->scan_request = NULL;
4912 wl->iscan_kickstart = false;
4915 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
4917 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
4918 WL_DBG(("wake up iscan\n"));
4927 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
4928 struct wl_scan_results **bss_list)
4930 struct wl_iscan_results list;
4931 struct wl_scan_results *results;
4932 struct wl_iscan_results *list_buf;
4935 WL_DBG(("Enter \n"));
4936 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
4937 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
4938 results = &list_buf->results;
4939 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
4940 results->version = 0;
4943 memset(&list, 0, sizeof(list));
4944 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
4945 err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list,
4946 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
4948 if (unlikely(err)) {
4949 WL_ERR(("error (%d)\n", err));
4952 results->buflen = dtoh32(results->buflen);
4953 results->version = dtoh32(results->version);
4954 results->count = dtoh32(results->count);
4955 WL_DBG(("results->count = %d\n", results->count));
4956 WL_DBG(("results->buflen = %d\n", results->buflen));
4957 *status = dtoh32(list_buf->status);
4958 *bss_list = results;
4963 static s32 wl_iscan_done(struct wl_priv *wl)
4965 struct wl_iscan_ctrl *iscan = wl->iscan;
4968 iscan->state = WL_ISCAN_STATE_IDLE;
4971 wl_notify_iscan_complete(iscan, false);
4977 static s32 wl_iscan_pending(struct wl_priv *wl)
4979 struct wl_iscan_ctrl *iscan = wl->iscan;
4982 /* Reschedule the timer */
4983 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
4984 iscan->timer_on = 1;
4989 static s32 wl_iscan_inprogress(struct wl_priv *wl)
4991 struct wl_iscan_ctrl *iscan = wl->iscan;
4996 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
4998 /* Reschedule the timer */
4999 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
5000 iscan->timer_on = 1;
5005 static s32 wl_iscan_aborted(struct wl_priv *wl)
5007 struct wl_iscan_ctrl *iscan = wl->iscan;
5010 iscan->state = WL_ISCAN_STATE_IDLE;
5012 wl_notify_iscan_complete(iscan, true);
5018 static s32 wl_iscan_thread(void *data)
5020 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
5021 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
5022 struct wl_priv *wl = iscan_to_wl(iscan);
5026 sched_setscheduler(current, SCHED_FIFO, ¶m);
5027 allow_signal(SIGTERM);
5028 status = WL_SCAN_RESULTS_PARTIAL;
5029 while (likely(!down_interruptible(&iscan->sync))) {
5030 if (kthread_should_stop())
5032 if (iscan->timer_on) {
5033 del_timer_sync(&iscan->timer);
5034 iscan->timer_on = 0;
5037 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
5038 if (unlikely(err)) {
5039 status = WL_SCAN_RESULTS_ABORTED;
5040 WL_ERR(("Abort iscan\n"));
5043 iscan->iscan_handler[status] (wl);
5045 if (iscan->timer_on) {
5046 del_timer_sync(&iscan->timer);
5047 iscan->timer_on = 0;
5049 WL_DBG(("%s was terminated\n", __func__));
5054 static void wl_iscan_timer(unsigned long data)
5056 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
5059 iscan->timer_on = 0;
5060 WL_DBG(("timer expired\n"));
5061 wl_wakeup_iscan(iscan);
5065 static s32 wl_invoke_iscan(struct wl_priv *wl)
5067 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
5070 if (wl->iscan_on && !iscan->tsk) {
5071 iscan->state = WL_ISCAN_STATE_IDLE;
5072 sema_init(&iscan->sync, 0);
5073 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
5074 if (IS_ERR(iscan->tsk)) {
5075 WL_ERR(("Could not create iscan thread\n"));
5084 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan)
5086 memset(iscan->iscan_handler, 0, sizeof(iscan->iscan_handler));
5087 iscan->iscan_handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
5088 iscan->iscan_handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
5089 iscan->iscan_handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
5090 iscan->iscan_handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
5091 iscan->iscan_handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
5094 static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
5096 WL_DBG(("Enter \n"));
5097 if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
5098 wl_clr_drv_status(wl, SCANNING);
5099 WL_ERR(("Scan complete while device not scanning\n"));
5102 wl_clr_drv_status(wl, SCANNING);
5103 if (wl->p2p_supported && p2p_on(wl))
5104 wl_clr_p2p_status(wl, SCANNING);
5106 if (likely(wl->scan_request)) {
5107 cfg80211_scan_done(wl->scan_request, aborted);
5108 wl->scan_request = NULL;
5112 static s32 wl_escan_handler(struct wl_priv *wl,
5113 struct net_device *ndev,
5114 const wl_event_msg_t *e, void *data)
5117 s32 status = ntoh32(e->status);
5119 wl_escan_result_t *escan_result;
5120 wl_bss_info_t *bss = NULL;
5121 wl_scan_results_t *list;
5124 WL_DBG((" enter event type : %d, status : %d \n",
5125 ntoh32(e->event_type), ntoh32(e->status)));
5126 if (!wl->escan_on &&
5127 !wl_get_drv_status(wl, SCANNING)) {
5128 WL_ERR(("escan is not ready \n"));
5132 if (status == WLC_E_STATUS_PARTIAL) {
5133 WL_INFO(("WLC_E_STATUS_PARTIAL \n"));
5134 escan_result = (wl_escan_result_t *) data;
5135 if (!escan_result) {
5136 WL_ERR(("Invalid escan result (NULL pointer)\n"));
5139 if (dtoh16(escan_result->bss_count) != 1) {
5140 WL_ERR(("Invalid bss_count %d: ignoring\n", escan_result->bss_count));
5143 bi = escan_result->bss_info;
5145 WL_ERR(("Invalid escan bss info (NULL pointer)\n"));
5148 bi_length = dtoh32(bi->length);
5149 if (bi_length != (dtoh32(escan_result->buflen) - WL_ESCAN_RESULTS_FIXED_SIZE)) {
5150 WL_ERR(("Invalid bss_info length %d: ignoring\n", bi_length));
5153 list = (wl_scan_results_t *)wl->escan_info.escan_buf;
5154 if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
5155 WL_ERR(("Buffer is too small: ignoring\n"));
5158 #define WLC_BSS_RSSI_ON_CHANNEL 0x0002
5159 for (i = 0; i < list->count; i++) {
5160 bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
5163 if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
5164 CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
5165 bi->SSID_len == bss->SSID_len &&
5166 !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
5167 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
5168 (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
5169 /* preserve max RSSI if the measurements are
5170 * both on-channel or both off-channel
5172 bss->RSSI = MAX(bss->RSSI, bi->RSSI);
5173 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
5174 (bi->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
5175 /* preserve the on-channel rssi measurement
5176 * if the new measurement is off channel
5178 bss->RSSI = bi->RSSI;
5179 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
5185 memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length);
5186 list->version = dtoh32(bi->version);
5187 list->buflen += bi_length;
5191 else if (status == WLC_E_STATUS_SUCCESS) {
5192 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5193 if (likely(wl->scan_request)) {
5195 WL_INFO(("ESCAN COMPLETED\n"));
5196 wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
5198 wl_notify_escan_complete(wl, false);
5202 else if (status == WLC_E_STATUS_ABORT) {
5203 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5204 if (likely(wl->scan_request)) {
5206 WL_INFO(("ESCAN COMPLETED\n"));
5207 wl_notify_escan_complete(wl, true);
5215 static s32 wl_init_scan(struct wl_priv *wl)
5217 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
5221 iscan->dev = wl_to_prmry_ndev(wl);
5222 iscan->state = WL_ISCAN_STATE_IDLE;
5223 wl_init_iscan_handler(iscan);
5224 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
5225 init_timer(&iscan->timer);
5226 iscan->timer.data = (unsigned long) iscan;
5227 iscan->timer.function = wl_iscan_timer;
5228 sema_init(&iscan->sync, 0);
5229 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
5230 if (IS_ERR(iscan->tsk)) {
5231 WL_ERR(("Could not create iscan thread\n"));
5236 } else if (wl->escan_on) {
5237 wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler;
5238 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5244 static void wl_init_fw(struct wl_fw_ctrl *fw)
5249 static s32 wl_init_priv(struct wl_priv *wl)
5251 struct wiphy *wiphy = wl_to_wiphy(wl);
5255 wl->scan_request = NULL;
5256 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
5257 wl->iscan_on = false;
5258 wl->escan_on = true;
5259 wl->roam_on = false;
5260 wl->iscan_kickstart = false;
5261 wl->active_scan = true;
5262 wl->dongle_up = false;
5263 wl->rf_blocked = false;
5265 for (i = 0; i < VWDEV_CNT; i++)
5266 wl->vwdev[i] = NULL;
5268 init_waitqueue_head(&wl->dongle_event_wait);
5270 err = wl_init_priv_mem(wl);
5273 if (unlikely(wl_create_event_handler(wl)))
5275 wl_init_event_handler(wl);
5276 mutex_init(&wl->usr_sync);
5277 err = wl_init_scan(wl);
5281 wl_init_conf(wl->conf);
5282 wl_init_prof(wl->profile);
5288 static void wl_deinit_priv(struct wl_priv *wl)
5290 wl_destroy_event_handler(wl);
5291 wl->dongle_up = false; /* dongle down */
5295 wl_deinit_priv_mem(wl);
5298 #ifdef CONFIG_SYSCTL
5299 s32 wl_cfg80211_sysctl_export_devaddr(void *data)
5301 /* Export the p2p_dev_addr via sysctl interface
5302 * so that wpa_supplicant can access it
5304 dhd_pub_t *dhd = (dhd_pub_t *)data;
5305 struct wl_priv *wl = WL_PRIV_GET();
5307 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
5309 sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p->dev_addr.octet));
5310 sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p->int_addr.octet));
5314 #endif /* CONFIG_SYSCTL */
5316 s32 wl_cfg80211_attach_post(struct net_device *ndev)
5318 struct wl_priv * wl = NULL;
5321 if (unlikely(!ndev)) {
5322 WL_ERR(("ndev is invaild\n"));
5326 if (wl && !wl_get_drv_status(wl, READY)) {
5328 wl_cfgp2p_supported(wl, ndev)) {
5329 wl->wdev->wiphy->interface_modes |=
5330 (BIT(NL80211_IFTYPE_P2P_CLIENT)|
5331 BIT(NL80211_IFTYPE_P2P_GO));
5332 if ((err = wl_cfgp2p_init_priv(wl)) != 0)
5334 #ifdef CONFIG_SYSCTL
5335 wl_cfg80211_sysctl_export_devaddr(wl->pub);
5337 wl->p2p_supported = true;
5342 wl_set_drv_status(wl, READY);
5346 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
5348 struct wireless_dev *wdev;
5350 struct wl_iface *ci;
5354 if (unlikely(!ndev)) {
5355 WL_ERR(("ndev is invaild\n"));
5358 wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
5359 if (unlikely(!wl_cfg80211_dev)) {
5360 WL_ERR(("wl_cfg80211_dev is invalid\n"));
5363 WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
5364 wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
5365 if (unlikely(IS_ERR(wdev)))
5368 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
5369 wl = wdev_to_wl(wdev);
5373 ci = (struct wl_iface *)wl_to_ci(wl);
5375 ndev->ieee80211_ptr = wdev;
5376 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
5377 wdev->netdev = ndev;
5379 err = wl_init_priv(wl);
5380 if (unlikely(err)) {
5381 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
5382 goto cfg80211_attach_out;
5385 err = wl_setup_rfkill(wl, TRUE);
5386 if (unlikely(err)) {
5387 WL_ERR(("Failed to setup rfkill %d\n", err));
5388 goto cfg80211_attach_out;
5391 #ifdef CONFIG_SYSCTL
5392 if (!(wl_sysctl_hdr = register_sysctl_table(wl_sysctl_table))) {
5393 WL_ERR(("%s: sysctl register failed!! \n", __func__));
5394 goto cfg80211_attach_out;
5397 wl_set_drvdata(wl_cfg80211_dev, ci);
5400 cfg80211_attach_out:
5401 err = wl_setup_rfkill(wl, FALSE);
5406 void wl_cfg80211_detach(void)
5414 #ifdef CONFIG_SYSCTL
5416 unregister_sysctl_table(wl_sysctl_hdr);
5418 wl_setup_rfkill(wl, FALSE);
5419 if (wl->p2p_supported)
5420 wl_cfgp2p_deinit_priv(wl);
5423 wl_set_drvdata(wl_cfg80211_dev, NULL);
5424 kfree(wl_cfg80211_dev);
5425 wl_cfg80211_dev = NULL;
5426 wl_clear_sdio_func();
5429 static void wl_wakeup_event(struct wl_priv *wl)
5431 up(&wl->event_sync);
5434 static s32 wl_event_handler(void *data)
5436 struct net_device *netdev;
5437 struct wl_priv *wl = (struct wl_priv *)data;
5438 struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
5439 struct wl_event_q *e;
5441 sched_setscheduler(current, SCHED_FIFO, ¶m);
5442 allow_signal(SIGTERM);
5443 while (likely(!down_interruptible(&wl->event_sync))) {
5444 if (kthread_should_stop())
5446 e = wl_deq_event(wl);
5448 WL_ERR(("equeue empty..\n"));
5451 WL_DBG(("event type (%d), if idx: %d\n", e->etype, e->emsg.ifidx));
5452 netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx);
5454 netdev = wl_to_prmry_ndev(wl);
5455 if (wl->evt_handler[e->etype]) {
5456 wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata);
5458 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
5462 WL_DBG(("%s was terminated\n", __func__));
5467 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
5469 u32 event_type = ntoh32(e->event_type);
5470 struct wl_priv *wl = WL_PRIV_GET();
5472 #if (WL_DBG_LEVEL > 0)
5473 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
5474 wl_dbg_estr[event_type] : (s8 *) "Unknown";
5475 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
5476 #endif /* (WL_DBG_LEVEL > 0) */
5478 if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
5479 wl_wakeup_event(wl);
5482 static void wl_init_eq(struct wl_priv *wl)
5484 wl_init_eq_lock(wl);
5485 INIT_LIST_HEAD(&wl->eq_list);
5488 static void wl_flush_eq(struct wl_priv *wl)
5490 struct wl_event_q *e;
5493 while (!list_empty(&wl->eq_list)) {
5494 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
5495 list_del(&e->eq_list);
5502 * retrieve first queued event from head
5505 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
5507 struct wl_event_q *e = NULL;
5510 if (likely(!list_empty(&wl->eq_list))) {
5511 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
5512 list_del(&e->eq_list);
5520 * push event to tail of the queue
5524 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg,
5527 struct wl_event_q *e;
5534 data_len = ntoh32(msg->datalen);
5535 evtq_size = sizeof(struct wl_event_q) + data_len;
5536 e = kzalloc(evtq_size, GFP_ATOMIC);
5538 WL_ERR(("event alloc failed\n"));
5542 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
5544 memcpy(e->edata, data, data_len);
5546 list_add_tail(&e->eq_list, &wl->eq_list);
5552 static void wl_put_event(struct wl_event_q *e)
5557 void wl_cfg80211_set_sdio_func(void *func)
5559 cfg80211_sdio_func = (struct sdio_func *)func;
5562 static void wl_clear_sdio_func(void)
5564 cfg80211_sdio_func = NULL;
5567 struct sdio_func *wl_cfg80211_get_sdio_func(void)
5569 return cfg80211_sdio_func;
5572 static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype)
5578 case NL80211_IFTYPE_MONITOR:
5579 case NL80211_IFTYPE_WDS:
5580 WL_ERR(("type (%d) : currently we do not support this mode\n",
5584 case NL80211_IFTYPE_ADHOC:
5585 mode = WL_MODE_IBSS;
5587 case NL80211_IFTYPE_STATION:
5588 case NL80211_IFTYPE_P2P_CLIENT:
5592 case NL80211_IFTYPE_AP:
5593 case NL80211_IFTYPE_P2P_GO:
5599 WL_ERR(("invalid type (%d)\n", iftype));
5602 infra = htod32(infra);
5603 err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), false);
5604 if (unlikely(err)) {
5605 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
5609 set_mode_by_netdev(wl, ndev, mode);
5613 static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
5615 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5617 s8 eventmask[WL_EVENTING_MASK_LEN];
5620 /* Setup event_msgs */
5621 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5623 err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
5624 if (unlikely(err)) {
5625 WL_ERR(("Get event_msgs error (%d)\n", err));
5626 goto dongle_eventmsg_out;
5628 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
5630 setbit(eventmask, event);
5632 clrbit(eventmask, event);
5634 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5636 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5637 if (unlikely(err)) {
5638 WL_ERR(("Set event_msgs error (%d)\n", err));
5639 goto dongle_eventmsg_out;
5642 dongle_eventmsg_out:
5647 static s32 wl_dongle_eventmsg(struct net_device *ndev)
5649 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5651 s8 eventmask[WL_EVENTING_MASK_LEN];
5654 /* Setup event_msgs */
5655 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5657 err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
5658 if (unlikely(err)) {
5659 WL_ERR(("Get event_msgs error (%d)\n", err));
5660 goto dongle_eventmsg_out;
5662 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
5664 setbit(eventmask, WLC_E_SET_SSID);
5665 setbit(eventmask, WLC_E_PRUNE);
5666 setbit(eventmask, WLC_E_AUTH);
5667 setbit(eventmask, WLC_E_REASSOC);
5668 setbit(eventmask, WLC_E_REASSOC_IND);
5669 setbit(eventmask, WLC_E_DEAUTH_IND);
5670 setbit(eventmask, WLC_E_DEAUTH);
5671 setbit(eventmask, WLC_E_DISASSOC_IND);
5672 setbit(eventmask, WLC_E_DISASSOC);
5673 setbit(eventmask, WLC_E_JOIN);
5674 setbit(eventmask, WLC_E_ASSOC_IND);
5675 setbit(eventmask, WLC_E_PSK_SUP);
5676 setbit(eventmask, WLC_E_LINK);
5677 setbit(eventmask, WLC_E_NDIS_LINK);
5678 setbit(eventmask, WLC_E_MIC_ERROR);
5679 setbit(eventmask, WLC_E_PMKID_CACHE);
5680 setbit(eventmask, WLC_E_TXFAIL);
5681 setbit(eventmask, WLC_E_JOIN_START);
5682 setbit(eventmask, WLC_E_SCAN_COMPLETE);
5683 setbit(eventmask, WLC_E_ACTION_FRAME_RX);
5684 setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE);
5685 setbit(eventmask, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE);
5686 setbit(eventmask, WLC_E_P2P_PROBREQ_MSG);
5687 setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE);
5688 setbit(eventmask, WLC_E_ESCAN_RESULT);
5689 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5691 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5692 if (unlikely(err)) {
5693 WL_ERR(("Set event_msgs error (%d)\n", err));
5694 goto dongle_eventmsg_out;
5697 dongle_eventmsg_out:
5701 #ifndef EMBEDDED_PLATFORM
5702 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
5710 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
5714 err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), false);
5715 if (unlikely(err)) {
5716 WL_ERR(("WLC_UP error (%d)\n", err));
5721 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
5726 err = wldev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode), false);
5727 if (unlikely(err)) {
5728 WL_ERR(("WLC_SET_PM error (%d)\n", err));
5734 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
5736 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5740 /* Match Host and Dongle rx alignment */
5741 bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
5743 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5744 if (unlikely(err)) {
5745 WL_ERR(("txglomalign error (%d)\n", err));
5746 goto dongle_glom_out;
5748 /* disable glom option per default */
5749 bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
5750 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5751 if (unlikely(err)) {
5752 WL_ERR(("txglom error (%d)\n", err));
5753 goto dongle_glom_out;
5760 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
5762 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5766 /* Setup timeout if Beacons are lost and roam is off to report link down */
5768 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
5770 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5771 if (unlikely(err)) {
5772 WL_ERR(("bcn_timeout error (%d)\n", err));
5773 goto dongle_rom_out;
5776 /* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
5777 bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
5778 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5779 if (unlikely(err)) {
5780 WL_ERR(("roam_off error (%d)\n", err));
5781 goto dongle_rom_out;
5788 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
5789 s32 scan_unassoc_time)
5793 err = wldev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
5794 sizeof(scan_assoc_time), false);
5796 if (err == -EOPNOTSUPP) {
5797 WL_INFO(("Scan assoc time is not supported\n"));
5799 WL_ERR(("Scan assoc time error (%d)\n", err));
5801 goto dongle_scantime_out;
5803 err = wldev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
5804 sizeof(scan_unassoc_time), false);
5806 if (err == -EOPNOTSUPP) {
5807 WL_INFO(("Scan unassoc time is not supported\n"));
5809 WL_ERR(("Scan unassoc time error (%d)\n", err));
5811 goto dongle_scantime_out;
5814 dongle_scantime_out:
5819 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
5821 /* Room for "event_msgs" + '\0' + bitvec */
5822 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5826 /* Set ARP offload */
5827 bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
5828 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5830 if (err == -EOPNOTSUPP)
5831 WL_INFO(("arpoe is not supported\n"));
5833 WL_ERR(("arpoe error (%d)\n", err));
5835 goto dongle_offload_out;
5837 bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
5838 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5840 if (err == -EOPNOTSUPP)
5841 WL_INFO(("arp_ol is not supported\n"));
5843 WL_ERR(("arp_ol error (%d)\n", err));
5845 goto dongle_offload_out;
5852 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
5855 if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
5856 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
5859 src = src + 2; /* Skip past 0x */
5860 if (strlen(src) % 2 != 0) {
5861 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
5864 for (i = 0; *src != '\0'; i++) {
5866 strncpy(num, src, 2);
5868 dst[i] = (u8) simple_strtoul(num, NULL, 16);
5874 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
5876 /* Room for "event_msgs" + '\0' + bitvec */
5877 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5880 struct wl_pkt_filter pkt_filter;
5881 struct wl_pkt_filter *pkt_filterp;
5889 /* add a default packet filter pattern */
5890 str = "pkt_filter_add";
5891 str_len = strlen(str);
5892 strncpy(buf, str, str_len);
5893 buf[str_len] = '\0';
5894 buf_len = str_len + 1;
5896 pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
5898 /* Parse packet filter id. */
5899 pkt_filter.id = htod32(100);
5901 /* Parse filter polarity. */
5902 pkt_filter.negate_match = htod32(0);
5904 /* Parse filter type. */
5905 pkt_filter.type = htod32(0);
5907 /* Parse pattern filter offset. */
5908 pkt_filter.u.pattern.offset = htod32(0);
5910 /* Parse pattern filter mask. */
5911 mask_size = htod32(wl_pattern_atoh("0xff",
5912 (char *)pkt_filterp->u.pattern.
5915 /* Parse pattern filter pattern. */
5916 pattern_size = htod32(wl_pattern_atoh("0x00",
5917 (char *)&pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
5919 if (mask_size != pattern_size) {
5920 WL_ERR(("Mask and pattern not the same size\n"));
5922 goto dongle_filter_out;
5925 pkt_filter.u.pattern.size_bytes = mask_size;
5926 buf_len += WL_PKT_FILTER_FIXED_LEN;
5927 buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
5929 /* Keep-alive attributes are set in local
5930 * variable (keep_alive_pkt), and
5931 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
5932 * guarantee that the buffer is properly aligned.
5934 memcpy((char *)pkt_filterp, &pkt_filter,
5935 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
5937 err = wldev_ioctl(ndev, WLC_SET_VAR, buf, buf_len, false);
5939 if (err == -EOPNOTSUPP) {
5940 WL_INFO(("filter not supported\n"));
5942 WL_ERR(("filter (%d)\n", err));
5944 goto dongle_filter_out;
5947 /* set mode to allow pattern */
5948 bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
5950 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5952 if (err == -EOPNOTSUPP) {
5953 WL_INFO(("filter_mode not supported\n"));
5955 WL_ERR(("filter_mode (%d)\n", err));
5957 goto dongle_filter_out;
5963 #endif /* !EMBEDDED_PLATFORM */
5965 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
5968 #define DHD_SDALIGN 32
5970 struct net_device *ndev;
5971 struct wireless_dev *wdev;
5975 if (wl->dongle_up) {
5976 WL_ERR(("Dongle is already up\n"));
5980 ndev = wl_to_prmry_ndev(wl);
5981 wdev = ndev->ieee80211_ptr;
5984 err = wl_dongle_eventmsg(ndev);
5985 if (unlikely(err)) {
5986 WL_ERR(("wl_dongle_eventmsg failed\n"));
5987 goto default_conf_out;
5989 #ifndef EMBEDDED_PLATFORM
5990 err = wl_dongle_up(ndev, 0);
5991 if (unlikely(err)) {
5992 WL_ERR(("wl_dongle_up failed\n"));
5993 goto default_conf_out;
5995 err = wl_dongle_country(ndev, 0);
5996 if (unlikely(err)) {
5997 WL_ERR(("wl_dongle_country failed\n"));
5998 goto default_conf_out;
6000 err = wl_dongle_power(ndev, PM_FAST);
6001 if (unlikely(err)) {
6002 WL_ERR(("wl_dongle_power failed\n"));
6003 goto default_conf_out;
6005 err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
6006 if (unlikely(err)) {
6007 WL_ERR(("wl_dongle_glom failed\n"));
6008 goto default_conf_out;
6010 err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
6011 if (unlikely(err)) {
6012 WL_ERR(("wl_dongle_roam failed\n"));
6013 goto default_conf_out;
6015 err = wl_dongle_eventmsg(ndev);
6016 if (unlikely(err)) {
6017 WL_ERR(("wl_dongle_eventmsg failed\n"));
6018 goto default_conf_out;
6021 wl_dongle_scantime(ndev, 40, 80);
6022 wl_dongle_offload(ndev, 1, 0xf);
6023 wl_dongle_filter(ndev, 1);
6024 #endif /* !EMBEDDED_PLATFORM */
6026 err = wl_dongle_mode(wl, ndev, wdev->iftype);
6027 if (unlikely(err && err != -EINPROGRESS)) {
6028 WL_ERR(("wl_dongle_mode failed\n"));
6029 goto default_conf_out;
6031 err = wl_dongle_probecap(wl);
6032 if (unlikely(err)) {
6033 WL_ERR(("wl_dongle_probecap failed\n"));
6034 goto default_conf_out;
6037 /* -EINPROGRESS: Call commit handler */
6043 wl->dongle_up = true;
6049 static s32 wl_update_wiphybands(struct wl_priv *wl)
6051 struct wiphy *wiphy;
6056 err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_PHYLIST, &phy_list,
6057 sizeof(phy_list), false);
6058 if (unlikely(err)) {
6059 WL_ERR(("error (%d)\n", err));
6063 phy = ((char *)&phy_list)[1];
6064 WL_DBG(("%c phy\n", phy));
6066 wiphy = wl_to_wiphy(wl);
6067 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
6068 } else if (phy == 'n') {
6069 wiphy = wl_to_wiphy(wl);
6070 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
6076 static s32 __wl_cfg80211_up(struct wl_priv *wl)
6081 wl_debugfs_add_netdev_params(wl);
6083 err = wl_config_dongle(wl, false);
6086 dhd_monitor_init(wl->pub);
6087 wl_invoke_iscan(wl);
6088 wl_set_drv_status(wl, READY);
6092 static s32 __wl_cfg80211_down(struct wl_priv *wl)
6097 /* Check if cfg80211 interface is already down */
6098 if (!wl_get_drv_status(wl, READY))
6099 return err; /* it is even not ready */
6101 wl_set_drv_status(wl, SCAN_ABORTING);
6104 if (wl->scan_request) {
6105 cfg80211_scan_done(wl->scan_request, true);
6106 wl->scan_request = NULL;
6108 wl_clr_drv_status(wl, READY);
6109 wl_clr_drv_status(wl, SCANNING);
6110 wl_clr_drv_status(wl, SCAN_ABORTING);
6111 wl_clr_drv_status(wl, CONNECTED);
6112 if (wl_get_drv_status(wl, AP_CREATED)) {
6113 wl_clr_drv_status(wl, AP_CREATED);
6114 wl_clr_drv_status(wl, AP_CREATING);
6115 wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype =
6116 NL80211_IFTYPE_STATION;
6118 wl->dongle_up = false;
6121 if (wl->p2p_supported)
6123 dhd_monitor_uninit();
6125 wl_debugfs_remove_netdev(wl);
6130 s32 wl_cfg80211_up(void)
6137 mutex_lock(&wl->usr_sync);
6138 wl_cfg80211_attach_post(wl_to_prmry_ndev(wl));
6139 err = __wl_cfg80211_up(wl);
6141 WL_ERR(("__wl_cfg80211_up failed\n"));
6142 mutex_unlock(&wl->usr_sync);
6147 s32 wl_cfg80211_down(void)
6154 mutex_lock(&wl->usr_sync);
6155 err = __wl_cfg80211_down(wl);
6156 mutex_unlock(&wl->usr_sync);
6160 static s32 wl_dongle_probecap(struct wl_priv *wl)
6164 err = wl_update_wiphybands(wl);
6171 static void *wl_read_prof(struct wl_priv *wl, s32 item)
6175 return &wl->profile->sec;
6177 return &wl->profile->active;
6179 return &wl->profile->bssid;
6181 return &wl->profile->ssid;
6183 WL_ERR(("invalid item (%d)\n", item));
6188 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
6192 struct wlc_ssid *ssid;
6196 ssid = (wlc_ssid_t *) data;
6197 memset(wl->profile->ssid.SSID, 0,
6198 sizeof(wl->profile->ssid.SSID));
6199 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
6200 wl->profile->ssid.SSID_len = ssid->SSID_len;
6204 memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
6206 memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
6209 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
6212 wl->profile->active = *(bool *)data;
6214 case WL_PROF_BEACONINT:
6215 wl->profile->beacon_interval = *(u16 *)data;
6217 case WL_PROF_DTIMPERIOD:
6218 wl->profile->dtim_period = *(u8 *)data;
6221 WL_ERR(("unsupported item (%d)\n", item));
6229 void wl_cfg80211_dbg_level(u32 level)
6232 * prohibit to change debug level
6233 * by insmod parameter.
6234 * eventually debug level will be configured
6235 * in compile time by using CONFIG_XXX
6237 /* wl_dbg_level = level; */
6240 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev)
6242 return get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS;
6245 static __used bool wl_is_ibssstarter(struct wl_priv *wl)
6247 return wl->ibss_starter;
6250 static void wl_rst_ie(struct wl_priv *wl)
6252 struct wl_ie *ie = wl_to_ie(wl);
6257 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
6259 struct wl_ie *ie = wl_to_ie(wl);
6262 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
6263 WL_ERR(("ei crosses buffer boundary\n"));
6266 ie->buf[ie->offset] = t;
6267 ie->buf[ie->offset + 1] = l;
6268 memcpy(&ie->buf[ie->offset + 2], v, l);
6269 ie->offset += l + 2;
6274 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
6276 struct wl_ie *ie = wl_to_ie(wl);
6279 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
6280 WL_ERR(("ei_stream crosses buffer boundary\n"));
6283 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
6284 ie->offset += ie_size;
6289 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
6291 struct wl_ie *ie = wl_to_ie(wl);
6294 if (unlikely(ie->offset > dst_size)) {
6295 WL_ERR(("dst_size is not enough\n"));
6298 memcpy(dst, &ie->buf[0], ie->offset);
6303 static u32 wl_get_ielen(struct wl_priv *wl)
6305 struct wl_ie *ie = wl_to_ie(wl);
6310 static void wl_link_up(struct wl_priv *wl)
6315 static void wl_link_down(struct wl_priv *wl)
6317 struct wl_connect_info *conn_info = wl_to_conn(wl);
6320 wl->link_up = false;
6321 kfree(conn_info->req_ie);
6322 conn_info->req_ie = NULL;
6323 conn_info->req_ie_len = 0;
6324 kfree(conn_info->resp_ie);
6325 conn_info->resp_ie = NULL;
6326 conn_info->resp_ie_len = 0;
6329 static void wl_lock_eq(struct wl_priv *wl)
6331 spin_lock_irq(&wl->eq_lock);
6334 static void wl_unlock_eq(struct wl_priv *wl)
6336 spin_unlock_irq(&wl->eq_lock);
6339 static void wl_init_eq_lock(struct wl_priv *wl)
6341 spin_lock_init(&wl->eq_lock);
6344 static void wl_delay(u32 ms)
6346 if (ms < 1000 / HZ) {
6354 static void wl_set_drvdata(struct wl_dev *dev, void *data)
6356 dev->driver_data = data;
6359 static void *wl_get_drvdata(struct wl_dev *dev)
6361 return dev->driver_data;
6364 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
6366 const struct firmware *fw_entry;
6371 fw_entry = wl->fw->fw_entry;
6373 if (fw_entry->size < wl->fw->ptr + size)
6374 size = fw_entry->size - wl->fw->ptr;
6376 memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
6377 wl->fw->ptr += size;
6381 void wl_cfg80211_release_fw(void)
6386 release_firmware(wl->fw->fw_entry);
6390 void *wl_cfg80211_request_fw(s8 *file_name)
6393 const struct firmware *fw_entry = NULL;
6397 WL_DBG(("file name : \"%s\"\n", file_name));
6400 if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
6401 err = request_firmware(&wl->fw->fw_entry, file_name,
6402 &wl_cfg80211_get_sdio_func()->dev);
6403 if (unlikely(err)) {
6404 WL_ERR(("Could not download fw (%d)\n", err));
6407 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
6408 fw_entry = wl->fw->fw_entry;
6410 WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
6413 } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
6414 err = request_firmware(&wl->fw->fw_entry, file_name,
6415 &wl_cfg80211_get_sdio_func()->dev);
6416 if (unlikely(err)) {
6417 WL_ERR(("Could not download nvram (%d)\n", err));
6420 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
6421 fw_entry = wl->fw->fw_entry;
6423 WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
6427 WL_DBG(("Downloading already done. Nothing to do more\n"));
6432 if (unlikely(err)) {
6436 return (void *)fw_entry->data;
6439 s8 *wl_cfg80211_get_fwname(void)
6444 strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
6445 return wl->fw->fw_name;
6448 s8 *wl_cfg80211_get_nvramname(void)
6453 strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
6454 return wl->fw->nvram_name;
6457 s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
6461 struct ether_addr p2pif_addr;
6464 dhd_pub = (dhd_pub_t *)wl->pub;
6465 wl_cfgp2p_generate_bss_mac(&dhd_pub->mac, p2pdev_addr, &p2pif_addr);
6470 static __used void wl_dongle_poweron(struct wl_priv *wl)
6473 WL_DBG(("Enter \n"));
6474 dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
6476 #if defined(BCMLXSDMMC)
6477 sdioh_start(NULL, 0);
6479 #if defined(BCMLXSDMMC)
6480 sdioh_start(NULL, 1);
6482 wl_cfg80211_resume(wl_to_wiphy(wl));
6485 static __used void wl_dongle_poweroff(struct wl_priv *wl)
6489 WL_DBG(("Enter \n"));
6490 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
6491 wl_cfg80211_suspend(wl_to_wiphy(wl), NULL);
6493 wl_cfg80211_suspend(wl_to_wiphy(wl));
6496 #if defined(BCMLXSDMMC)
6499 /* clean up dtim_skip setting */
6500 dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
6502 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
6504 char buf[10+IFNAMSIZ];
6509 sprintf(buf, "netdev:%s", wl_to_prmry_ndev(wl)->name);
6510 wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
6512 fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
6513 (u16 *)&wl->profile->beacon_interval);
6519 fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
6520 (u8 *)&wl->profile->dtim_period);
6530 static void wl_debugfs_remove_netdev(struct wl_priv *wl)
6532 WL_DBG(("Enter \n"));
6535 static const struct rfkill_ops wl_rfkill_ops = {
6536 .set_block = wl_rfkill_set
6539 static int wl_rfkill_set(void *data, bool blocked)
6541 struct wl_priv *wl = (struct wl_priv *)data;
6543 WL_DBG(("Enter \n"));
6544 WL_DBG(("RF %s\n", blocked ? "blocked" : "unblocked"));
6549 wl->rf_blocked = blocked;
6554 static int wl_setup_rfkill(struct wl_priv *wl, bool setup)
6558 WL_DBG(("Enter \n"));
6562 wl->rfkill = rfkill_alloc("brcmfmac-wifi",
6563 &wl_cfg80211_get_sdio_func()->dev,
6564 RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl);
6571 err = rfkill_register(wl->rfkill);
6574 rfkill_destroy(wl->rfkill);
6581 rfkill_unregister(wl->rfkill);
6582 rfkill_destroy(wl->rfkill);