OSDN Git Service

366ce2224ab61b50cdca929f3016c7ff6c7680ac
[android-x86/kernel.git] / drivers / net / wireless / bcmdhd / wl_cfg80211.c
1 /*
2  * Linux cfg80211 driver
3  *
4  * Copyright (C) 1999-2011, Broadcom Corporation
5  * 
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:
11  * 
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.
19  * 
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.
23  *
24  * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $
25  */
26
27 #include <typedefs.h>
28 #include <linuxver.h>
29 #include <osl.h>
30 #include <linux/kernel.h>
31
32 /*
33  * sys proc file will be REMOVED in next release
34  */
35 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
36 #include <linux/sysctl.h>
37 #endif
38
39 #include <bcmutils.h>
40 #include <bcmwifi.h>
41 #include <bcmendian.h>
42 #include <proto/ethernet.h>
43 #include <proto/802.11.h>
44 #include <linux/if_arp.h>
45 #include <asm/uaccess.h>
46
47 #include <dngl_stats.h>
48 #include <dhd.h>
49 #include <dhdioctl.h>
50 #include <wlioctl.h>
51
52 #include <proto/ethernet.h>
53 #include <dngl_stats.h>
54 #include <dhd.h>
55
56 #include <linux/kernel.h>
57 #include <linux/kthread.h>
58 #include <linux/netdevice.h>
59 #include <linux/sched.h>
60 #include <linux/etherdevice.h>
61 #include <linux/wireless.h>
62 #include <linux/ieee80211.h>
63 #include <linux/wait.h>
64 #include <net/cfg80211.h>
65
66 #include <net/rtnetlink.h>
67 #include <linux/mmc/sdio_func.h>
68 #include <linux/firmware.h>
69 #include <bcmsdbus.h>
70
71 #include <wlioctl.h>
72 #include <wldev_common.h>
73 #include <wl_cfg80211.h>
74 #include <wl_cfgp2p.h>
75
76 static struct sdio_func *cfg80211_sdio_func;
77 static struct wl_dev *wl_cfg80211_dev;
78
79 u32 wl_dbg_level = WL_DBG_ERR;
80
81 #define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4-218-248-5.bin"
82 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4-218-248-5.txt"
83 #define WL_TRACE(a) printk("%s ", __FUNCTION__); printk a
84 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
85 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
86 #define MAX_WAIT_TIME 3000
87 static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
88
89 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
90 #define MAC_STRING_LEN (sizeof(u8) * 17)
91 u8 wl_sysctl_macstring[2][MAC_STRING_LEN];
92
93 static ctl_table wl_sysctl_child[] = {
94         {
95         .procname = "p2p_dev_addr",
96         .data = &wl_sysctl_macstring[0],
97         .maxlen = MAC_STRING_LEN,
98         .mode =  0444,
99         .child = NULL,
100         .proc_handler = proc_dostring,
101         },
102         {
103         .procname = "p2p_int_addr",
104         .data = &wl_sysctl_macstring[1],
105         .maxlen = MAC_STRING_LEN,
106         .mode =  0444,
107         .child = NULL,
108         .proc_handler = proc_dostring,
109         },
110         {0}
111 };
112 static ctl_table wl_sysctl_table[] = {
113         {
114         .procname = "wifi",
115         .data = NULL,
116         .maxlen = 0,
117         .mode =  0555,
118         .child = wl_sysctl_child,
119         .proc_handler = NULL,
120         },
121         {0}
122 };
123 static struct ctl_table_header *wl_sysctl_hdr;
124 #endif /* CONFIG_SYSCTL */
125
126 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
127  * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
128  * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165).
129  * With respect to these flags, wpa_supplicant doesn't start p2p operations on 5GHz channels.
130  * All the chnages in world regulatory domain are to be done here.
131  */
132 static const struct ieee80211_regdomain brcm_regdom = {
133         .n_reg_rules = 5,
134         .alpha2 =  "99",
135         .reg_rules = {
136                 /* IEEE 802.11b/g, channels 1..11 */
137                 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
138                 /* IEEE 802.11b/g, channels 12..13. No HT40
139                  * channel fits here.
140                  */
141                 REG_RULE(2467-10, 2472+10, 20, 6, 20,
142                 NL80211_RRF_PASSIVE_SCAN |
143                 NL80211_RRF_NO_IBSS),
144                 /* IEEE 802.11 channel 14 - Only JP enables
145                  * this and for 802.11b only
146                  */
147                 REG_RULE(2484-10, 2484+10, 20, 6, 20,
148                 NL80211_RRF_PASSIVE_SCAN |
149                 NL80211_RRF_NO_IBSS |
150                 NL80211_RRF_NO_OFDM),
151                 /* IEEE 802.11a, channel 36..48 */
152                 REG_RULE(5180-10, 5240+10, 40, 6, 20, 0),
153
154                 /* NB: 5260 MHz - 5700 MHz requies DFS */
155
156                 /* IEEE 802.11a, channel 149..165 */
157                 REG_RULE(5745-10, 5825+10, 40, 6, 20, 0), }
158 };
159
160
161 /* Data Element Definitions */
162 #define WPS_ID_CONFIG_METHODS     0x1008
163 #define WPS_ID_REQ_TYPE           0x103A
164 #define WPS_ID_DEVICE_NAME        0x1011
165 #define WPS_ID_VERSION            0x104A
166 #define WPS_ID_DEVICE_PWD_ID      0x1012
167 #define WPS_ID_REQ_DEV_TYPE       0x106A
168 #define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053
169 #define WPS_ID_PRIM_DEV_TYPE      0x1054
170
171 /* Device Password ID */
172 #define DEV_PW_DEFAULT 0x0000
173 #define DEV_PW_USER_SPECIFIED 0x0001,
174 #define DEV_PW_MACHINE_SPECIFIED 0x0002
175 #define DEV_PW_REKEY 0x0003
176 #define DEV_PW_PUSHBUTTON 0x0004
177 #define DEV_PW_REGISTRAR_SPECIFIED 0x0005
178
179 /* Config Methods */
180 #define WPS_CONFIG_USBA 0x0001
181 #define WPS_CONFIG_ETHERNET 0x0002
182 #define WPS_CONFIG_LABEL 0x0004
183 #define WPS_CONFIG_DISPLAY 0x0008
184 #define WPS_CONFIG_EXT_NFC_TOKEN 0x0010
185 #define WPS_CONFIG_INT_NFC_TOKEN 0x0020
186 #define WPS_CONFIG_NFC_INTERFACE 0x0040
187 #define WPS_CONFIG_PUSHBUTTON 0x0080
188 #define WPS_CONFIG_KEYPAD 0x0100
189 #define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
190 #define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
191 #define WPS_CONFIG_VIRT_DISPLAY 0x2008
192 #define WPS_CONFIG_PHY_DISPLAY 0x4008
193
194 /*
195  * cfg80211_ops api/callback list
196  */
197 static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
198         const struct ether_addr *sa, const struct ether_addr *bssid,
199         u8 **pheader, u32 *body_len, u8 *pbody);
200 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
201         struct cfg80211_scan_request *request,
202         struct cfg80211_ssid *this_ssid);
203 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
204         struct cfg80211_scan_request *request);
205 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
206 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
207         struct cfg80211_ibss_params *params);
208 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
209         struct net_device *dev);
210 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
211         struct net_device *dev, u8 *mac,
212         struct station_info *sinfo);
213 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
214         struct net_device *dev, bool enabled,
215         s32 timeout);
216 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
217         struct cfg80211_connect_params *sme);
218 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
219         u16 reason_code);
220 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
221         enum nl80211_tx_power_setting type,
222         s32 dbm);
223 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
224 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
225         struct net_device *dev,
226         u8 key_idx, bool unicast, bool multicast);
227 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
228         u8 key_idx, bool pairwise, const u8 *mac_addr,
229         struct key_params *params);
230 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
231         u8 key_idx, bool pairwise, const u8 *mac_addr);
232 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
233         u8 key_idx, bool pairwise, const u8 *mac_addr,
234         void *cookie, void (*callback) (void *cookie,
235         struct key_params *params));
236 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
237         struct net_device *dev, u8 key_idx);
238 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
239 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
240 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
241 #else
242 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
243 #endif
244 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
245         struct cfg80211_pmksa *pmksa);
246 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
247         struct cfg80211_pmksa *pmksa);
248 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
249         struct net_device *dev);
250 static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted);
251 /*
252  * event & event Q handlers for cfg80211 interfaces
253  */
254 static s32 wl_create_event_handler(struct wl_priv *wl);
255 static void wl_destroy_event_handler(struct wl_priv *wl);
256 static s32 wl_event_handler(void *data);
257 static void wl_init_eq(struct wl_priv *wl);
258 static void wl_flush_eq(struct wl_priv *wl);
259 static void wl_lock_eq(struct wl_priv *wl);
260 static void wl_unlock_eq(struct wl_priv *wl);
261 static void wl_init_eq_lock(struct wl_priv *wl);
262 static void wl_init_event_handler(struct wl_priv *wl);
263 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
264 static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
265         const wl_event_msg_t *msg, void *data);
266 static void wl_put_event(struct wl_event_q *e);
267 static void wl_wakeup_event(struct wl_priv *wl);
268 static s32 wl_notify_connect_status(struct wl_priv *wl,
269         struct net_device *ndev,
270         const wl_event_msg_t *e, void *data);
271 static s32 wl_notify_roaming_status(struct wl_priv *wl,
272         struct net_device *ndev,
273         const wl_event_msg_t *e, void *data);
274 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
275         const wl_event_msg_t *e, void *data);
276 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
277         const wl_event_msg_t *e, void *data, bool completed);
278 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
279         const wl_event_msg_t *e, void *data);
280 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
281         const wl_event_msg_t *e, void *data);
282 /*
283  * register/deregister sdio function
284  */
285 struct sdio_func *wl_cfg80211_get_sdio_func(void);
286 static void wl_clear_sdio_func(void);
287
288 /*
289  * ioctl utilites
290  */
291 static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
292         s32 buf_len);
293 static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name,
294         s8 *buf, s32 len);
295 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val);
296 static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name,
297         s32 *retval);
298
299 /*
300  * cfg80211 set_wiphy_params utilities
301  */
302 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
303 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
304 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
305
306 /*
307  * wl profile utilities
308  */
309 static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e,
310         void *data, s32 item);
311 static void *wl_read_prof(struct wl_priv *wl, s32 item);
312 static void wl_init_prof(struct wl_profile *prof);
313
314 /*
315  * cfg80211 connect utilites
316  */
317 static s32 wl_set_wpa_version(struct net_device *dev,
318         struct cfg80211_connect_params *sme);
319 static s32 wl_set_auth_type(struct net_device *dev,
320         struct cfg80211_connect_params *sme);
321 static s32 wl_set_set_cipher(struct net_device *dev,
322         struct cfg80211_connect_params *sme);
323 static s32 wl_set_key_mgmt(struct net_device *dev,
324         struct cfg80211_connect_params *sme);
325 static s32 wl_set_set_sharedkey(struct net_device *dev,
326         struct cfg80211_connect_params *sme);
327 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev);
328 static void wl_ch_to_chanspec(int ch,
329         struct wl_join_params *join_params, size_t *join_params_size);
330
331 /*
332  * information element utilities
333  */
334 static void wl_rst_ie(struct wl_priv *wl);
335 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
336 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
337 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
338 static u32 wl_get_ielen(struct wl_priv *wl);
339
340 static s32 wl_mode_to_nl80211_iftype(s32 mode);
341
342 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
343         struct device *dev);
344 static void wl_free_wdev(struct wl_priv *wl);
345
346 static s32 wl_inform_bss(struct wl_priv *wl);
347 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
348 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev);
349
350 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
351         u8 key_idx, const u8 *mac_addr,
352         struct key_params *params);
353 /*
354  * key indianess swap utilities
355  */
356 static void swap_key_from_BE(struct wl_wsec_key *key);
357 static void swap_key_to_BE(struct wl_wsec_key *key);
358
359 /*
360  * wl_priv memory init/deinit utilities
361  */
362 static s32 wl_init_priv_mem(struct wl_priv *wl);
363 static void wl_deinit_priv_mem(struct wl_priv *wl);
364
365 static void wl_delay(u32 ms);
366
367 /*
368  * store/restore cfg80211 instance data
369  */
370 static void wl_set_drvdata(struct wl_dev *dev, void *data);
371 static void *wl_get_drvdata(struct wl_dev *dev);
372
373 /*
374  * ibss mode utilities
375  */
376 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
377 static __used bool wl_is_ibssstarter(struct wl_priv *wl);
378
379 /*
380  * dongle up/down , default configuration utilities
381  */
382 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
383 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
384 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
385 static void wl_link_up(struct wl_priv *wl);
386 static void wl_link_down(struct wl_priv *wl);
387 static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
388 static s32 __wl_cfg80211_up(struct wl_priv *wl);
389 static s32 __wl_cfg80211_down(struct wl_priv *wl);
390 static s32 wl_dongle_probecap(struct wl_priv *wl);
391 static void wl_init_conf(struct wl_conf *conf);
392 static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
393 static s32 wl_dongle_eventmsg(struct net_device *ndev);
394
395 /*
396  * dongle configuration utilities
397  */
398 #ifndef EMBEDDED_PLATFORM
399 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode);
400 static s32 wl_dongle_up(struct net_device *ndev, u32 up);
401 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
402 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
403         u32 dongle_align);
404 static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
405         u32 bcn_timeout);
406 static s32 wl_dongle_eventmsg(struct net_device *ndev);
407 static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
408         s32 scan_unassoc_time);
409 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
410         s32 arp_ol);
411 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
412 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
413 static s32 wl_update_wiphybands(struct wl_priv *wl);
414 #endif                          /* !EMBEDDED_PLATFORM */
415 static __used void wl_dongle_poweron(struct wl_priv *wl);
416 static __used void wl_dongle_poweroff(struct wl_priv *wl);
417 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
418
419 /*
420  * iscan handler
421  */
422 static void wl_iscan_timer(unsigned long data);
423 static void wl_term_iscan(struct wl_priv *wl);
424 static s32 wl_init_scan(struct wl_priv *wl);
425 static s32 wl_iscan_thread(void *data);
426 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
427         u16 action);
428 static s32 wl_do_iscan(struct wl_priv *wl);
429 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
430 static s32 wl_invoke_iscan(struct wl_priv *wl);
431 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
432         struct wl_scan_results **bss_list);
433 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
434 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan);
435 static s32 wl_iscan_done(struct wl_priv *wl);
436 static s32 wl_iscan_pending(struct wl_priv *wl);
437 static s32 wl_iscan_inprogress(struct wl_priv *wl);
438 static s32 wl_iscan_aborted(struct wl_priv *wl);
439
440 /*
441  * fw/nvram downloading handler
442  */
443 static void wl_init_fw(struct wl_fw_ctrl *fw);
444
445 /*
446  * find most significant bit set
447  */
448 static __used u32 wl_find_msb(u16 bit16);
449
450 /*
451  * update pmklist to dongle
452  */
453 static __used s32 wl_update_pmklist(struct net_device *dev,
454         struct wl_pmk_list *pmk_list, s32 err);
455
456 /*
457  * debufs support
458  */
459 static int wl_debugfs_add_netdev_params(struct wl_priv *wl);
460 static void wl_debugfs_remove_netdev(struct wl_priv *wl);
461
462 /*
463  * rfkill support
464  */
465 static int wl_setup_rfkill(struct wl_priv *wl, bool setup);
466 static int wl_rfkill_set(void *data, bool blocked);
467
468 /*
469  * Some external functions, TODO: move them to dhd_linux.h
470  */
471 int dhd_add_monitor(char *name, struct net_device **new_ndev);
472 int dhd_del_monitor(struct net_device *ndev);
473 int dhd_monitor_init(void *dhd_pub);
474 int dhd_monitor_uninit(void);
475 int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
476
477 #define WL_PRIV_GET()                                                   \
478         ({                                                              \
479         struct wl_iface *ci = NULL;                                     \
480         if (unlikely(!(wl_cfg80211_dev &&                               \
481                 (ci = wl_get_drvdata(wl_cfg80211_dev))))) {             \
482                 WL_ERR(("wl_cfg80211_dev is unavailable\n"));           \
483                 BUG();                                                  \
484         }                                                               \
485         ci_to_wl(ci);                                                   \
486 })
487
488 #define CHECK_SYS_UP()                                                  \
489 do {                                                                    \
490         struct wl_priv *wl = WL_PRIV_GET();                     \
491         if (unlikely(!wl_get_drv_status(wl, READY))) {  \
492                 WL_INFO(("device is not ready : status (%d)\n",         \
493                         (int)wl->status));                              \
494                 return -EIO;                                            \
495         }                                                               \
496 } while (0)
497
498
499 #define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
500                                  (akm) == RSN_AKM_UNSPECIFIED || \
501                                  (akm) == RSN_AKM_PSK)
502
503
504 extern int dhd_wait_pend8021x(struct net_device *dev);
505
506 #if (WL_DBG_LEVEL > 0)
507 #define WL_DBG_ESTR_MAX 50
508 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
509         "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
510         "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
511         "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
512         "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
513         "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
514         "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
515         "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
516         "PFN_NET_LOST",
517         "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
518         "IBSS_ASSOC",
519         "RADIO", "PSM_WATCHDOG", "WLC_E_CCX_ASSOC_START", "WLC_E_CCX_ASSOC_ABORT",
520         "PROBREQ_MSG",
521         "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
522         "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
523         "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
524         "WLC_E_BTA_HCI_EVENT", "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE",
525         "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG",
526         "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND",
527         "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED",
528         "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT",
529         "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE",
530         "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP",
531         "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE"
532 };
533 #endif                          /* WL_DBG_LEVEL */
534
535 #define CHAN2G(_channel, _freq, _flags) {                       \
536         .band                   = IEEE80211_BAND_2GHZ,          \
537         .center_freq            = (_freq),                      \
538         .hw_value               = (_channel),                   \
539         .flags                  = (_flags),                     \
540         .max_antenna_gain       = 0,                            \
541         .max_power              = 30,                           \
542 }
543
544 #define CHAN5G(_channel, _flags) {                              \
545         .band                   = IEEE80211_BAND_5GHZ,          \
546         .center_freq            = 5000 + (5 * (_channel)),      \
547         .hw_value               = (_channel),                   \
548         .flags                  = (_flags),                     \
549         .max_antenna_gain       = 0,                            \
550         .max_power              = 30,                           \
551 }
552
553 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
554 #define RATETAB_ENT(_rateid, _flags) \
555         {                                                               \
556                 .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
557                 .hw_value       = (_rateid),                        \
558                 .flags    = (_flags),                        \
559         }
560
561 static struct ieee80211_rate __wl_rates[] = {
562         RATETAB_ENT(WLC_RATE_1M, 0),
563         RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
564         RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
565         RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
566         RATETAB_ENT(WLC_RATE_6M, 0),
567         RATETAB_ENT(WLC_RATE_9M, 0),
568         RATETAB_ENT(WLC_RATE_12M, 0),
569         RATETAB_ENT(WLC_RATE_18M, 0),
570         RATETAB_ENT(WLC_RATE_24M, 0),
571         RATETAB_ENT(WLC_RATE_36M, 0),
572         RATETAB_ENT(WLC_RATE_48M, 0),
573         RATETAB_ENT(WLC_RATE_54M, 0)
574 };
575
576 #define wl_a_rates              (__wl_rates + 4)
577 #define wl_a_rates_size 8
578 #define wl_g_rates              (__wl_rates + 0)
579 #define wl_g_rates_size 12
580
581 static struct ieee80211_channel __wl_2ghz_channels[] = {
582         CHAN2G(1, 2412, 0),
583         CHAN2G(2, 2417, 0),
584         CHAN2G(3, 2422, 0),
585         CHAN2G(4, 2427, 0),
586         CHAN2G(5, 2432, 0),
587         CHAN2G(6, 2437, 0),
588         CHAN2G(7, 2442, 0),
589         CHAN2G(8, 2447, 0),
590         CHAN2G(9, 2452, 0),
591         CHAN2G(10, 2457, 0),
592         CHAN2G(11, 2462, 0),
593         CHAN2G(12, 2467, 0),
594         CHAN2G(13, 2472, 0),
595         CHAN2G(14, 2484, 0)
596 };
597
598 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
599         CHAN5G(34, 0), CHAN5G(36, 0),
600         CHAN5G(38, 0), CHAN5G(40, 0),
601         CHAN5G(42, 0), CHAN5G(44, 0),
602         CHAN5G(46, 0), CHAN5G(48, 0),
603         CHAN5G(52, 0), CHAN5G(56, 0),
604         CHAN5G(60, 0), CHAN5G(64, 0),
605         CHAN5G(100, 0), CHAN5G(104, 0),
606         CHAN5G(108, 0), CHAN5G(112, 0),
607         CHAN5G(116, 0), CHAN5G(120, 0),
608         CHAN5G(124, 0), CHAN5G(128, 0),
609         CHAN5G(132, 0), CHAN5G(136, 0),
610         CHAN5G(140, 0), CHAN5G(149, 0),
611         CHAN5G(153, 0), CHAN5G(157, 0),
612         CHAN5G(161, 0), CHAN5G(165, 0),
613         CHAN5G(184, 0), CHAN5G(188, 0),
614         CHAN5G(192, 0), CHAN5G(196, 0),
615         CHAN5G(200, 0), CHAN5G(204, 0),
616         CHAN5G(208, 0), CHAN5G(212, 0),
617         CHAN5G(216, 0)
618 };
619
620 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
621         CHAN5G(32, 0), CHAN5G(34, 0),
622         CHAN5G(36, 0), CHAN5G(38, 0),
623         CHAN5G(40, 0), CHAN5G(42, 0),
624         CHAN5G(44, 0), CHAN5G(46, 0),
625         CHAN5G(48, 0), CHAN5G(50, 0),
626         CHAN5G(52, 0), CHAN5G(54, 0),
627         CHAN5G(56, 0), CHAN5G(58, 0),
628         CHAN5G(60, 0), CHAN5G(62, 0),
629         CHAN5G(64, 0), CHAN5G(66, 0),
630         CHAN5G(68, 0), CHAN5G(70, 0),
631         CHAN5G(72, 0), CHAN5G(74, 0),
632         CHAN5G(76, 0), CHAN5G(78, 0),
633         CHAN5G(80, 0), CHAN5G(82, 0),
634         CHAN5G(84, 0), CHAN5G(86, 0),
635         CHAN5G(88, 0), CHAN5G(90, 0),
636         CHAN5G(92, 0), CHAN5G(94, 0),
637         CHAN5G(96, 0), CHAN5G(98, 0),
638         CHAN5G(100, 0), CHAN5G(102, 0),
639         CHAN5G(104, 0), CHAN5G(106, 0),
640         CHAN5G(108, 0), CHAN5G(110, 0),
641         CHAN5G(112, 0), CHAN5G(114, 0),
642         CHAN5G(116, 0), CHAN5G(118, 0),
643         CHAN5G(120, 0), CHAN5G(122, 0),
644         CHAN5G(124, 0), CHAN5G(126, 0),
645         CHAN5G(128, 0), CHAN5G(130, 0),
646         CHAN5G(132, 0), CHAN5G(134, 0),
647         CHAN5G(136, 0), CHAN5G(138, 0),
648         CHAN5G(140, 0), CHAN5G(142, 0),
649         CHAN5G(144, 0), CHAN5G(145, 0),
650         CHAN5G(146, 0), CHAN5G(147, 0),
651         CHAN5G(148, 0), CHAN5G(149, 0),
652         CHAN5G(150, 0), CHAN5G(151, 0),
653         CHAN5G(152, 0), CHAN5G(153, 0),
654         CHAN5G(154, 0), CHAN5G(155, 0),
655         CHAN5G(156, 0), CHAN5G(157, 0),
656         CHAN5G(158, 0), CHAN5G(159, 0),
657         CHAN5G(160, 0), CHAN5G(161, 0),
658         CHAN5G(162, 0), CHAN5G(163, 0),
659         CHAN5G(164, 0), CHAN5G(165, 0),
660         CHAN5G(166, 0), CHAN5G(168, 0),
661         CHAN5G(170, 0), CHAN5G(172, 0),
662         CHAN5G(174, 0), CHAN5G(176, 0),
663         CHAN5G(178, 0), CHAN5G(180, 0),
664         CHAN5G(182, 0), CHAN5G(184, 0),
665         CHAN5G(186, 0), CHAN5G(188, 0),
666         CHAN5G(190, 0), CHAN5G(192, 0),
667         CHAN5G(194, 0), CHAN5G(196, 0),
668         CHAN5G(198, 0), CHAN5G(200, 0),
669         CHAN5G(202, 0), CHAN5G(204, 0),
670         CHAN5G(206, 0), CHAN5G(208, 0),
671         CHAN5G(210, 0), CHAN5G(212, 0),
672         CHAN5G(214, 0), CHAN5G(216, 0),
673         CHAN5G(218, 0), CHAN5G(220, 0),
674         CHAN5G(222, 0), CHAN5G(224, 0),
675         CHAN5G(226, 0), CHAN5G(228, 0)
676 };
677
678 static struct ieee80211_supported_band __wl_band_2ghz = {
679         .band = IEEE80211_BAND_2GHZ,
680         .channels = __wl_2ghz_channels,
681         .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
682         .bitrates = wl_g_rates,
683         .n_bitrates = wl_g_rates_size
684 };
685
686 static struct ieee80211_supported_band __wl_band_5ghz_a = {
687         .band = IEEE80211_BAND_5GHZ,
688         .channels = __wl_5ghz_a_channels,
689         .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
690         .bitrates = wl_a_rates,
691         .n_bitrates = wl_a_rates_size
692 };
693
694 static struct ieee80211_supported_band __wl_band_5ghz_n = {
695         .band = IEEE80211_BAND_5GHZ,
696         .channels = __wl_5ghz_n_channels,
697         .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
698         .bitrates = wl_a_rates,
699         .n_bitrates = wl_a_rates_size
700 };
701
702 static const u32 __wl_cipher_suites[] = {
703         WLAN_CIPHER_SUITE_WEP40,
704         WLAN_CIPHER_SUITE_WEP104,
705         WLAN_CIPHER_SUITE_TKIP,
706         WLAN_CIPHER_SUITE_CCMP,
707         WLAN_CIPHER_SUITE_AES_CMAC
708 };
709
710 /* There isn't a lot of sense in it, but you can transmit anything you like */
711 static const struct ieee80211_txrx_stypes
712 wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
713         [NL80211_IFTYPE_ADHOC] = {
714                 .tx = 0xffff,
715                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
716         },
717         [NL80211_IFTYPE_STATION] = {
718                 .tx = 0xffff,
719                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
720                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
721         },
722         [NL80211_IFTYPE_AP] = {
723                 .tx = 0xffff,
724                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
725                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
726                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
727                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
728                 BIT(IEEE80211_STYPE_AUTH >> 4) |
729                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
730                 BIT(IEEE80211_STYPE_ACTION >> 4)
731         },
732         [NL80211_IFTYPE_AP_VLAN] = {
733                 /* copy AP */
734                 .tx = 0xffff,
735                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
736                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
737                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
738                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
739                 BIT(IEEE80211_STYPE_AUTH >> 4) |
740                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
741                 BIT(IEEE80211_STYPE_ACTION >> 4)
742         },
743         [NL80211_IFTYPE_P2P_CLIENT] = {
744                 .tx = 0xffff,
745                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
746                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
747         },
748         [NL80211_IFTYPE_P2P_GO] = {
749                 .tx = 0xffff,
750                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
751                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
752                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
753                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
754                 BIT(IEEE80211_STYPE_AUTH >> 4) |
755                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
756                 BIT(IEEE80211_STYPE_ACTION >> 4)
757         }
758 };
759
760 static void swap_key_from_BE(struct wl_wsec_key *key)
761 {
762         key->index = htod32(key->index);
763         key->len = htod32(key->len);
764         key->algo = htod32(key->algo);
765         key->flags = htod32(key->flags);
766         key->rxiv.hi = htod32(key->rxiv.hi);
767         key->rxiv.lo = htod16(key->rxiv.lo);
768         key->iv_initialized = htod32(key->iv_initialized);
769 }
770
771 static void swap_key_to_BE(struct wl_wsec_key *key)
772 {
773         key->index = dtoh32(key->index);
774         key->len = dtoh32(key->len);
775         key->algo = dtoh32(key->algo);
776         key->flags = dtoh32(key->flags);
777         key->rxiv.hi = dtoh32(key->rxiv.hi);
778         key->rxiv.lo = dtoh16(key->rxiv.lo);
779         key->iv_initialized = dtoh32(key->iv_initialized);
780 }
781
782 /* For debug: Dump the contents of the encoded wps ie buffe */
783 static void
784 wl_validate_wps_ie(char *wps_ie, bool *pbc)
785 {
786         #define WPS_IE_FIXED_LEN 6
787         u16 len = (u16) wps_ie[TLV_LEN_OFF];
788         u8 *subel = wps_ie+  WPS_IE_FIXED_LEN;
789         u16 subelt_id;
790         u16 subelt_len;
791         u16 val;
792         u8 *valptr = (uint8*) &val;
793
794         WL_DBG(("wps_ie len=%d\n", len));
795
796         len -= 4;       /* for the WPS IE's OUI, oui_type fields */
797
798         while (len >= 4) {              /* must have attr id, attr len fields */
799                 valptr[0] = *subel++;
800                 valptr[1] = *subel++;
801                 subelt_id = HTON16(val);
802
803                 valptr[0] = *subel++;
804                 valptr[1] = *subel++;
805                 subelt_len = HTON16(val);
806
807                 len -= 4;                       /* for the attr id, attr len fields */
808                 len -= subelt_len;      /* for the remaining fields in this attribute */
809                 WL_DBG((" subel=%p, subelt_id=0x%x subelt_len=%u\n",
810                         subel, subelt_id, subelt_len));
811
812                 if (subelt_id == WPS_ID_VERSION) {
813                         WL_DBG(("  attr WPS_ID_VERSION: %u\n", *subel));
814                 } else if (subelt_id == WPS_ID_REQ_TYPE) {
815                         WL_DBG(("  attr WPS_ID_REQ_TYPE: %u\n", *subel));
816                 } else if (subelt_id == WPS_ID_CONFIG_METHODS) {
817                         valptr[0] = *subel;
818                         valptr[1] = *(subel + 1);
819                         WL_DBG(("  attr WPS_ID_CONFIG_METHODS: %x\n", HTON16(val)));
820                 } else if (subelt_id == WPS_ID_DEVICE_NAME) {
821                         char devname[100];
822                         memcpy(devname, subel, subelt_len);
823                         devname[subelt_len] = '\0';
824                         WL_DBG(("  attr WPS_ID_DEVICE_NAME: %s (len %u)\n",
825                                 devname, subelt_len));
826                 } else if (subelt_id == WPS_ID_DEVICE_PWD_ID) {
827                         valptr[0] = *subel;
828                         valptr[1] = *(subel + 1);
829                         WL_DBG(("  attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val)));
830                         *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false;
831                 } else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) {
832                         valptr[0] = *subel;
833                         valptr[1] = *(subel + 1);
834                         WL_DBG(("  attr WPS_ID_PRIM_DEV_TYPE: cat=%u \n", HTON16(val)));
835                         valptr[0] = *(subel + 6);
836                         valptr[1] = *(subel + 7);
837                         WL_DBG(("  attr WPS_ID_PRIM_DEV_TYPE: subcat=%u\n", HTON16(val)));
838                 } else if (subelt_id == WPS_ID_REQ_DEV_TYPE) {
839                         valptr[0] = *subel;
840                         valptr[1] = *(subel + 1);
841                         WL_DBG(("  attr WPS_ID_REQ_DEV_TYPE: cat=%u\n", HTON16(val)));
842                         valptr[0] = *(subel + 6);
843                         valptr[1] = *(subel + 7);
844                         WL_DBG(("  attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val)));
845                 } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) {
846                         valptr[0] = *subel;
847                         valptr[1] = *(subel + 1);
848                         WL_DBG(("  attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS"
849                                 ": cat=%u\n", HTON16(val)));
850                 } else {
851                         WL_DBG(("  unknown attr 0x%x\n", subelt_id));
852                 }
853
854                 subel += subelt_len;
855         }
856 }
857
858 static struct net_device* wl_cfg80211_add_monitor_if(char *name)
859 {
860         int ret = 0;
861         struct net_device* ndev = NULL;
862
863         ret = dhd_add_monitor(name, &ndev);
864         WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev));
865         return ndev;
866 }
867
868 static struct net_device *
869 wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
870         enum nl80211_iftype type, u32 *flags,
871         struct vif_params *params)
872 {
873         s32 err;
874         s32 timeout = -1;
875         s32 wlif_type = -1;
876         s32 index = 0;
877         s32 mode = 0;
878         chanspec_t chspec;
879         struct wl_priv *wl = WL_PRIV_GET();
880         struct net_device *_ndev;
881         dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
882         int (*net_attach)(dhd_pub_t *dhdp, int ifidx);
883
884         WL_DBG(("if name: %s, type: %d\n", name, type));
885         switch (type) {
886         case NL80211_IFTYPE_ADHOC:
887         case NL80211_IFTYPE_AP_VLAN:
888         case NL80211_IFTYPE_WDS:
889         case NL80211_IFTYPE_MESH_POINT:
890                 WL_ERR(("Unsupported interface type\n"));
891                 mode = WL_MODE_IBSS;
892                 return NULL;
893         case NL80211_IFTYPE_MONITOR:
894                 return wl_cfg80211_add_monitor_if(name);
895         case NL80211_IFTYPE_P2P_CLIENT:
896         case NL80211_IFTYPE_STATION:
897                 wlif_type = WL_P2P_IF_CLIENT;
898                 mode = WL_MODE_BSS;
899                 break;
900         case NL80211_IFTYPE_P2P_GO:
901         case NL80211_IFTYPE_AP:
902                 wlif_type = WL_P2P_IF_GO;
903                 mode = WL_MODE_AP;
904                 break;
905         default:
906                 WL_ERR(("Unsupported interface type\n"));
907                 return NULL;
908                 break;
909         }
910
911         if (!name) {
912                 WL_ERR(("name is NULL\n"));
913                 return NULL;
914         }
915         if (wl->p2p_supported && (wlif_type != -1)) {
916                 if (wl_get_p2p_status(wl, IF_DELETING) == 1) {
917                         /* wait till IF_DEL is complete
918                          * release the lock for the unregister to proceed
919                          */
920                         rtnl_unlock();
921                         WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n",
922                                 __func__));
923                         timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
924                                 (wl_get_p2p_status(wl, IF_DELETING) == false),
925                                 msecs_to_jiffies(MAX_WAIT_TIME));
926
927                         /* put back the rtnl_lock again */
928                         rtnl_lock();
929                         if (timeout > 0) {
930                                 WL_ERR(("IF DEL is Success\n"));
931
932                         } else {
933                                 WL_ERR(("%s: timeount < 0, return -EAGAIN\n", __func__));
934                                 return ERR_PTR(-EAGAIN);
935                         }
936                 }
937                 if (!p2p_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
938                         p2p_on(wl) = true;
939                         wl_cfgp2p_set_firm_p2p(wl);
940                         wl_cfgp2p_init_discovery(wl);
941                 }
942
943                 memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
944                 strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
945                 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
946
947                 /* Temporary use channel 11, in case GO will be changed with set_channel API  */
948                 chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
949
950                 /* For P2P mode, use P2P-specific driver features to create the
951                  * bss: "wl p2p_ifadd"
952                  */
953                 wl_set_p2p_status(wl, IF_ADD);
954                 err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
955
956                 if (unlikely(err))
957                         return ERR_PTR(-ENOMEM);
958
959                 timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
960                         (wl_get_p2p_status(wl, IF_ADD) == false),
961                         msecs_to_jiffies(MAX_WAIT_TIME));
962                 if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
963
964                         struct wireless_dev *vwdev;
965                         vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
966                         if (unlikely(!vwdev)) {
967                                 WL_ERR(("Could not allocate wireless device\n"));
968                                 return ERR_PTR(-ENOMEM);
969                         }
970                         vwdev->wiphy = wl->wdev->wiphy;
971                         WL_INFO((" virtual interface(%s) is created \n", wl->p2p->vir_ifname));
972                         index = alloc_idx_vwdev(wl);
973                         wl->vwdev[index] = vwdev;
974                         vwdev->iftype =
975                                 (wlif_type == WL_P2P_IF_CLIENT) ? NL80211_IFTYPE_STATION
976                                 : NL80211_IFTYPE_AP;
977                         _ndev =  wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
978                         _ndev->ieee80211_ptr = vwdev;
979                         SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
980                         vwdev->netdev = _ndev;
981                         wl_set_drv_status(wl, READY);
982                         wl->p2p->vif_created = true;
983                         set_mode_by_netdev(wl, _ndev, mode);
984                         wl = wdev_to_wl(vwdev);
985                         net_attach =  wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
986                         rtnl_unlock();
987                         if (net_attach && !net_attach(dhd, _ndev->ifindex))
988                                 WL_DBG((" virtual interface(%s) is "
989                                         "created\n", wl->p2p->vir_ifname));
990                         else {
991                                 rtnl_lock();
992                                 goto fail;
993                         }
994                         rtnl_lock();
995                         return _ndev;
996
997                 } else {
998                         wl_clr_p2p_status(wl, IF_ADD);
999                         WL_ERR((" virtual interface(%s) is not created \n", wl->p2p->vir_ifname));
1000                         memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
1001                         wl->p2p->vif_created = false;
1002                 }
1003         }
1004 fail:
1005         return ERR_PTR(-ENODEV);
1006 }
1007
1008
1009 static s32
1010 wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
1011 {
1012         struct ether_addr p2p_mac;
1013         struct wl_priv *wl = WL_PRIV_GET();
1014         s32 timeout = -1;
1015         s32 ret = 0;
1016
1017         if (wl->p2p_supported) {
1018                 memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
1019                 if (wl->p2p->vif_created) {
1020                         if (wl_get_drv_status(wl, SCANNING)) {
1021                                 wl_cfg80211_scan_abort(wl, dev);
1022                         }
1023
1024                         wl_cfgp2p_ifdel(wl, &p2p_mac);
1025                         wl_set_p2p_status(wl, IF_DELETING);
1026
1027                         /* Wait for any pending scan req to get aborted from the sysioc context */
1028                         timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
1029                                 (wl->scan_request == false),
1030                                 msecs_to_jiffies(MAX_WAIT_TIME));
1031
1032                         if (timeout > 0 && (!wl->scan_request)) {
1033                                 WL_DBG(("IFDEL Operations Done"));
1034                         } else {
1035                                 WL_ERR(("IFDEL didn't complete properly"));
1036                         }
1037                         ret = dhd_del_monitor(dev);
1038                 }
1039         }
1040         return ret;
1041 }
1042
1043 static s32
1044 wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
1045         enum nl80211_iftype type, u32 *flags,
1046         struct vif_params *params)
1047 {
1048         s32 ap = 0;
1049         s32 infra = 0;
1050         s32 err = BCME_OK;
1051         s32 timeout = -1;
1052         s32 wlif_type;
1053         s32 mode = 0;
1054         chanspec_t chspec;
1055         struct wl_priv *wl = WL_PRIV_GET();
1056         WL_DBG(("Enter \n"));
1057         switch (type) {
1058         case NL80211_IFTYPE_MONITOR:
1059         case NL80211_IFTYPE_WDS:
1060         case NL80211_IFTYPE_MESH_POINT:
1061                 ap = 1;
1062                 WL_ERR(("type (%d) : currently we do not support this type\n",
1063                         type));
1064                 break;
1065         case NL80211_IFTYPE_ADHOC:
1066                 mode = WL_MODE_IBSS;
1067                 break;
1068         case NL80211_IFTYPE_STATION:
1069         case NL80211_IFTYPE_P2P_CLIENT:
1070                 mode = WL_MODE_BSS;
1071                 infra = 1;
1072                 break;
1073         case NL80211_IFTYPE_AP:
1074         case NL80211_IFTYPE_AP_VLAN:
1075         case NL80211_IFTYPE_P2P_GO:
1076                 mode = WL_MODE_AP;
1077                 ap = 1;
1078                 break;
1079         default:
1080                 return -EINVAL;
1081         }
1082
1083
1084         if (ap) {
1085                 set_mode_by_netdev(wl, ndev, mode);
1086                 if (wl->p2p_supported && wl->p2p->vif_created) {
1087                         WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
1088                         p2p_on(wl)));
1089                         chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
1090                         wlif_type = ap ? WL_P2P_IF_GO : WL_P2P_IF_CLIENT;
1091                         WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n",
1092                                 ndev->name, ap, infra, type));
1093                         wl_set_p2p_status(wl, IF_CHANGING);
1094                         wl_clr_p2p_status(wl, IF_CHANGED);
1095                         err = wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
1096                         timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
1097                                 (wl_get_p2p_status(wl, IF_CHANGED) == true),
1098                                 msecs_to_jiffies(MAX_WAIT_TIME));
1099                         set_mode_by_netdev(wl, ndev, mode);
1100                         wl_clr_p2p_status(wl, IF_CHANGING);
1101                         wl_clr_p2p_status(wl, IF_CHANGED);
1102                 } else if (ndev == wl_to_prmry_ndev(wl) &&
1103                         !wl_get_drv_status(wl, AP_CREATED)) {
1104                         wl_set_drv_status(wl, AP_CREATING);
1105                         if (!wl->ap_info &&
1106                                 !(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) {
1107                                 WL_ERR(("struct ap_saved_ie allocation failed\n"));
1108                                 return -ENOMEM;
1109                         }
1110                 } else {
1111                         WL_ERR(("Cannot change the interface for GO or SOFTAP\n"));
1112                         return -EINVAL;
1113                 }
1114         }
1115
1116         ndev->ieee80211_ptr->iftype = type;
1117         return 0;
1118 }
1119
1120 s32
1121 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx,
1122 int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
1123 {
1124         struct wl_priv *wl = WL_PRIV_GET();
1125         s32 ret = BCME_OK;
1126         if (!net) {
1127                 WL_ERR(("net is NULL\n"));
1128                 return 0;
1129         }
1130         if (wl->p2p_supported) {
1131                 WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
1132                         "new name: %s\n", net->name, wl->p2p->vir_ifname));
1133                 /* Assign the net device to CONNECT BSSCFG */
1134                 strncpy(net->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
1135                 wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
1136                 wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) =
1137                         P2PAPI_BSSCFG_CONNECTION;
1138                 wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach;
1139                 wl_clr_p2p_status(wl, IF_ADD);
1140                 net->ifindex = idx;
1141                 wake_up_interruptible(&wl->dongle_event_wait);
1142         }
1143         return ret;
1144 }
1145
1146 s32
1147 wl_cfg80211_ifdel_ops(struct net_device *net)
1148 {
1149         struct wl_priv *wl = WL_PRIV_GET();
1150
1151         if (!net || !net->name) {
1152                 WL_DBG(("net is NULL\n"));
1153                 return 0;
1154         }
1155
1156         if ((wl->p2p->vif_created) && (wl->scan_request)) {
1157
1158                 /* Abort any pending scan requests */
1159                 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
1160                 rtnl_lock();
1161                 WL_INFO(("ESCAN COMPLETED\n"));
1162                 wl_notify_escan_complete(wl, true);
1163                 rtnl_unlock();
1164         }
1165
1166         /* Wake up any waiting thread */
1167         wake_up_interruptible(&wl->dongle_event_wait);
1168
1169         return 0;
1170 }
1171
1172 s32
1173 wl_cfg80211_notify_ifdel(struct net_device *net)
1174 {
1175         struct wl_priv *wl = WL_PRIV_GET();
1176
1177
1178         if (wl->p2p->vif_created) {
1179                 s32 index = 0;
1180
1181                 WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
1182                         net->name, wl->p2p->vir_ifname));
1183
1184                 memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
1185                 index = wl_cfgp2p_find_idx(wl, net);
1186                 wl_to_p2p_bss_ndev(wl, index) = NULL;
1187                 wl_to_p2p_bss_bssidx(wl, index) = 0;
1188                 wl->p2p->vif_created = false;
1189                 set_mode_by_netdev(wl, net, -1);
1190                 wl_cfgp2p_clear_management_ie(wl,
1191                         index);
1192                 index = get_idx_vwdev_by_netdev(wl, net);
1193                 WL_DBG(("index : %d\n", index));
1194                 if (index >= 0) {
1195                                 free_vwdev_by_index(wl, index);
1196                 }
1197         }
1198
1199         wl_clr_p2p_status(wl, IF_DELETING);
1200
1201         /* Wake up any waiting thread */
1202         wake_up_interruptible(&wl->dongle_event_wait);
1203
1204         return 0;
1205 }
1206
1207 s32
1208 wl_cfg80211_is_progress_ifadd(void)
1209 {
1210         s32 is_progress = 0;
1211         struct wl_priv *wl = WL_PRIV_GET();
1212         if (wl_get_p2p_status(wl, IF_ADD))
1213                 is_progress = 1;
1214         return is_progress;
1215 }
1216
1217 s32
1218 wl_cfg80211_is_progress_ifchange(void)
1219 {
1220         s32 is_progress = 0;
1221         struct wl_priv *wl = WL_PRIV_GET();
1222         if (wl_get_p2p_status(wl, IF_CHANGING))
1223                 is_progress = 1;
1224         return is_progress;
1225 }
1226
1227
1228 s32
1229 wl_cfg80211_notify_ifchange(void)
1230 {
1231         struct wl_priv *wl = WL_PRIV_GET();
1232         if (wl_get_p2p_status(wl, IF_CHANGING)) {
1233                 wl_set_p2p_status(wl, IF_CHANGED);
1234                 wake_up_interruptible(&wl->dongle_event_wait);
1235         }
1236         return 0;
1237 }
1238
1239 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
1240 {
1241         memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
1242         params->bss_type = DOT11_BSSTYPE_ANY;
1243         params->scan_type = 0;
1244         params->nprobes = -1;
1245         params->active_time = -1;
1246         params->passive_time = -1;
1247         params->home_time = -1;
1248         params->channel_num = 0;
1249
1250         params->nprobes = htod32(params->nprobes);
1251         params->active_time = htod32(params->active_time);
1252         params->passive_time = htod32(params->passive_time);
1253         params->home_time = htod32(params->home_time);
1254         if (ssid && ssid->SSID_len)
1255                 memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
1256
1257 }
1258
1259 static s32
1260 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
1261 {
1262         s32 params_size =
1263                 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
1264         struct wl_iscan_params *params;
1265         s32 err = 0;
1266
1267         if (ssid && ssid->SSID_len)
1268                 params_size += sizeof(struct wlc_ssid);
1269         params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
1270         if (unlikely(!params))
1271                 return -ENOMEM;
1272         memset(params, 0, params_size);
1273         BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
1274
1275         wl_iscan_prep(&params->params, ssid);
1276
1277         params->version = htod32(ISCAN_REQ_VERSION);
1278         params->action = htod16(action);
1279         params->scan_duration = htod16(0);
1280
1281         /* params_size += offsetof(wl_iscan_params_t, params); */
1282         err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
1283                 iscan->ioctl_buf, WLC_IOCTL_SMLEN);
1284         if (unlikely(err)) {
1285                 if (err == -EBUSY) {
1286                 WL_INFO(("system busy : iscan canceled\n"));
1287                 } else {
1288                         WL_ERR(("error (%d)\n", err));
1289                 }
1290         }
1291         kfree(params);
1292         return err;
1293 }
1294
1295 static s32 wl_do_iscan(struct wl_priv *wl)
1296 {
1297         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
1298         struct net_device *ndev = wl_to_prmry_ndev(wl);
1299         struct wlc_ssid ssid;
1300         s32 passive_scan;
1301         s32 err = 0;
1302
1303         /* Broadcast scan by default */
1304         memset(&ssid, 0, sizeof(ssid));
1305
1306         iscan->state = WL_ISCAN_STATE_SCANING;
1307
1308         passive_scan = wl->active_scan ? 0 : 1;
1309         err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1310                 &passive_scan, sizeof(passive_scan), false);
1311         if (unlikely(err)) {
1312                 WL_DBG(("error (%d)\n", err));
1313                 return err;
1314         }
1315         wl->iscan_kickstart = true;
1316         wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
1317         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
1318         iscan->timer_on = 1;
1319
1320         return err;
1321 }
1322
1323 static s32
1324 wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint16 action)
1325 {
1326         s32 err = BCME_OK;
1327         s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
1328         wl_escan_params_t *params;
1329         struct cfg80211_scan_request *scan_request = wl->scan_request;
1330         u32 num_chans = 0;
1331         s32 search_state = WL_P2P_DISC_ST_SCAN;
1332         u32 i;
1333         u16 *default_chan_list = NULL;
1334         WL_DBG(("Enter \n"));
1335
1336
1337         if (!wl->p2p_supported || ((ndev == wl_to_prmry_ndev(wl)) &&
1338                 !p2p_scan(wl))) {
1339                 /* LEGACY SCAN TRIGGER */
1340                 WL_DBG(("LEGACY SCAN START\n"));
1341                 if (ssid && ssid->SSID_len) {
1342                         params_size += sizeof(wlc_ssid_t);
1343                 }
1344                 params = (wl_escan_params_t *) kmalloc(params_size, GFP_KERNEL);
1345
1346                 if (params == NULL)
1347                         return -ENOMEM;
1348
1349                 memset(params, 0, params_size);
1350                 memcpy(&params->params.bssid, &ether_bcast, ETHER_ADDR_LEN);
1351                 params->params.bss_type = DOT11_BSSTYPE_ANY;
1352                 params->params.scan_type = 0;
1353                 params->params.nprobes = htod32(-1);
1354                 params->params.active_time = htod32(-1);
1355                 params->params.passive_time = htod32(-1);
1356                 params->params.home_time = htod32(-1);
1357                 params->params.channel_num = 0;
1358                 if (ssid && ssid->SSID_len) {
1359                         memcpy(params->params.ssid.SSID, ssid->SSID, ssid->SSID_len);
1360                         params->params.ssid.SSID_len = htod32(ssid->SSID_len);
1361                 }
1362                 params->version = htod32(ESCAN_REQ_VERSION);
1363                 params->action =  htod16(action);
1364                 params->sync_id = htod16(0x1234);
1365                 wldev_iovar_setbuf(ndev, "escan", params, params_size,
1366                         wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
1367                 kfree(params);
1368         }
1369         else if (p2p_on(wl) && p2p_scan(wl)) {
1370                 /* P2P SCAN TRIGGER */
1371                 if (scan_request && scan_request->n_channels) {
1372                         num_chans = scan_request->n_channels;
1373                         WL_INFO((" chann number : %d\n", num_chans));
1374                         default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
1375                                 GFP_KERNEL);
1376                         if (default_chan_list == NULL) {
1377                                 WL_ERR(("channel list allocation failed \n"));
1378                                 err = -ENOMEM;
1379                                 goto exit;
1380                         }
1381                         for (i = 0; i < num_chans; i++)
1382                         {
1383                                 default_chan_list[i] =
1384                                 ieee80211_frequency_to_channel(
1385                                         scan_request->channels[i]->center_freq);
1386                         }
1387                         if (num_chans == 3 && (
1388                                                 (default_chan_list[0] == SOCIAL_CHAN_1) &&
1389                                                 (default_chan_list[1] == SOCIAL_CHAN_2) &&
1390                                                 (default_chan_list[2] == SOCIAL_CHAN_3))) {
1391                                 /* SOCIAL CHANNELS 1, 6, 11 */
1392                                 search_state = WL_P2P_DISC_ST_SEARCH;
1393                                 WL_INFO(("P2P SEARCH PHASE START \n"));
1394                         } else {
1395                                 WL_INFO(("P2P SCAN STATE START \n"));
1396                         }
1397
1398                 }
1399                 err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list,
1400                         search_state, action,
1401                         wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
1402                 kfree(default_chan_list);
1403         }
1404 exit:
1405         return err;
1406 }
1407
1408
1409 static s32
1410 wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wlc_ssid_t *ssid)
1411 {
1412         s32 err = BCME_OK;
1413         s32 passive_scan;
1414         wl_scan_results_t *results;
1415         WL_DBG(("Enter \n"));
1416
1417         wl->escan_info.wiphy = wiphy;
1418         wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
1419         passive_scan = wl->active_scan ? 0 : 1;
1420         err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1421                 &passive_scan, sizeof(passive_scan), false);
1422         if (unlikely(err)) {
1423                 WL_DBG(("error (%d)\n", err));
1424                 return err;
1425         }
1426         results = (wl_scan_results_t *) wl->escan_info.escan_buf;
1427         results->version = 0;
1428         results->count = 0;
1429         results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
1430
1431         wl_run_escan(wl, ndev, ssid, WL_SCAN_ACTION_START);
1432         return err;
1433 }
1434
1435 static s32
1436 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
1437         struct cfg80211_scan_request *request,
1438         struct cfg80211_ssid *this_ssid)
1439 {
1440         struct wl_priv *wl = WL_PRIV_GET();
1441         struct cfg80211_ssid *ssids;
1442         struct wl_scan_req *sr = wl_to_sr(wl);
1443         wlc_ssid_t ssid_info;
1444         s32 passive_scan;
1445         bool iscan_req;
1446         bool escan_req;
1447         bool spec_scan;
1448         s32 err = 0;
1449
1450         if (unlikely(wl_get_drv_status(wl, SCANNING))) {
1451                 WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
1452                 return -EAGAIN;
1453         }
1454         if (unlikely(wl_get_drv_status(wl, SCAN_ABORTING))) {
1455                 WL_ERR(("Scanning being aborted : status (%d)\n",
1456                         (int)wl->status));
1457                 return -EAGAIN;
1458         }
1459
1460         WL_DBG(("wiphy (%p)\n", wiphy));
1461
1462         iscan_req = false;
1463         spec_scan = false;
1464         if (request) {          /* scan bss */
1465                 ssids = request->ssids;
1466                 if (wl->iscan_on && (!ssids || !ssids->ssid_len)) {
1467                         iscan_req = true;
1468                 } else if (wl->escan_on) {
1469                         escan_req = true;
1470                         if (ssids->ssid_len && IS_P2P_SSID(ssids->ssid)) {
1471                                 if (wl->p2p_supported) {
1472                                         /* p2p scan trigger */
1473                                         if (p2p_on(wl) == false) {
1474                                                 /* p2p on at the first time */
1475                                                 p2p_on(wl) = true;
1476                                                 wl_cfgp2p_set_firm_p2p(wl);
1477                                         }
1478                                         p2p_scan(wl) = true;
1479                                 }
1480
1481                         } else {
1482                                 /* legacy scan trigger
1483                                  * So, we have to disable p2p discovery if p2p discovery is on
1484                                  */
1485                                 if (wl->p2p_supported) {
1486                                         p2p_scan(wl) = false;
1487                                         /* If Netdevice is not equals to primary and p2p is on
1488                                         *  , we will do p2p scan using P2PAPI_BSSCFG_DEVICE.
1489                                         */
1490                                         if (p2p_on(wl) && (ndev != wl_to_prmry_ndev(wl)))
1491                                                 p2p_scan(wl) = true;
1492
1493                                         if (p2p_scan(wl) == false) {
1494                                                 if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
1495                                                         err = wl_cfgp2p_discover_enable_search(wl,
1496                                                         false);
1497                                                         if (unlikely(err)) {
1498                                                                 goto scan_out;
1499                                                         }
1500
1501                                                 }
1502                                         }
1503                                 }
1504                         }
1505                 }
1506         } else {                /* scan in ibss */
1507                 /* we don't do iscan in ibss */
1508                 ssids = this_ssid;
1509         }
1510         wl->scan_request = request;
1511         wl_set_drv_status(wl, SCANNING);
1512         if (iscan_req) {
1513                 err = wl_do_iscan(wl);
1514                 if (likely(!err))
1515                         return err;
1516                 else
1517                         goto scan_out;
1518         } else if (escan_req) {
1519                 WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
1520                         ssids->ssid, ssids->ssid_len));
1521
1522                 memcpy(ssid_info.SSID, ssids->ssid, ssids->ssid_len);
1523                 ssid_info.SSID_len = ssids->ssid_len;
1524                 if (wl->p2p_supported) {
1525                         if (p2p_on(wl) && p2p_scan(wl)) {
1526
1527                                 err = wl_cfgp2p_enable_discovery(wl, ndev,
1528                                 request->ie, request->ie_len);
1529
1530                                 if (unlikely(err)) {
1531                                         goto scan_out;
1532                                 }
1533                         }
1534                 }
1535                 err = wl_do_escan(wl, wiphy, ndev, &ssid_info);
1536                 if (likely(!err))
1537                         return err;
1538                 else
1539                         goto scan_out;
1540
1541
1542         } else {
1543                 memset(&sr->ssid, 0, sizeof(sr->ssid));
1544                 sr->ssid.SSID_len =
1545                         min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
1546                 if (sr->ssid.SSID_len) {
1547                         memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
1548                         sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
1549                         WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
1550                                 sr->ssid.SSID, sr->ssid.SSID_len));
1551                         spec_scan = true;
1552                 } else {
1553                         WL_DBG(("Broadcast scan\n"));
1554                 }
1555                 WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
1556                 passive_scan = wl->active_scan ? 0 : 1;
1557                 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1558                         &passive_scan, sizeof(passive_scan), false);
1559                 if (unlikely(err)) {
1560                         WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
1561                         goto scan_out;
1562                 }
1563                 err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
1564                         sizeof(sr->ssid), false);
1565                 if (err) {
1566                         if (err == -EBUSY) {
1567                                 WL_INFO(("system busy : scan for \"%s\" "
1568                                         "canceled\n", sr->ssid.SSID));
1569                         } else {
1570                                 WL_ERR(("WLC_SCAN error (%d)\n", err));
1571                         }
1572                         goto scan_out;
1573                 }
1574         }
1575
1576         return 0;
1577
1578 scan_out:
1579         wl_clr_drv_status(wl, SCANNING);
1580         wl->scan_request = NULL;
1581         return err;
1582 }
1583
1584 static s32
1585 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
1586         struct cfg80211_scan_request *request)
1587 {
1588         s32 err = 0;
1589
1590         WL_DBG(("Enter \n"));
1591         CHECK_SYS_UP();
1592         err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
1593         if (unlikely(err)) {
1594                 WL_ERR(("scan error (%d)\n", err));
1595                 return err;
1596         }
1597
1598         return err;
1599 }
1600
1601 static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val)
1602 {
1603         s8 buf[WLC_IOCTL_SMLEN];
1604         u32 len;
1605         s32 err = 0;
1606
1607         val = htod32(val);
1608         len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
1609         BUG_ON(unlikely(!len));
1610
1611         err = wldev_ioctl(dev, WLC_SET_VAR, buf, len, false);
1612         if (unlikely(err)) {
1613                 WL_ERR(("error (%d)\n", err));
1614         }
1615
1616         return err;
1617 }
1618
1619 static s32
1620 wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval)
1621 {
1622         union {
1623                 s8 buf[WLC_IOCTL_SMLEN];
1624                 s32 val;
1625         } var;
1626         u32 len;
1627         u32 data_null;
1628         s32 err = 0;
1629
1630         len = bcm_mkiovar(name, (char *)(&data_null), 0,
1631                 (char *)(&var), sizeof(var.buf));
1632         BUG_ON(unlikely(!len));
1633         err = wldev_ioctl(dev, WLC_GET_VAR, &var, len, false);
1634         if (unlikely(err)) {
1635                 WL_ERR(("error (%d)\n", err));
1636         }
1637         *retval = dtoh32(var.val);
1638
1639         return err;
1640 }
1641
1642 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
1643 {
1644         s32 err = 0;
1645
1646         err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
1647         if (unlikely(err)) {
1648                 WL_ERR(("Error (%d)\n", err));
1649                 return err;
1650         }
1651         return err;
1652 }
1653
1654 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
1655 {
1656         s32 err = 0;
1657
1658         err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
1659         if (unlikely(err)) {
1660                 WL_ERR(("Error (%d)\n", err));
1661                 return err;
1662         }
1663         return err;
1664 }
1665
1666 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
1667 {
1668         s32 err = 0;
1669         u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
1670
1671         retry = htod32(retry);
1672         err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), false);
1673         if (unlikely(err)) {
1674                 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
1675                 return err;
1676         }
1677         return err;
1678 }
1679
1680 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1681 {
1682         struct wl_priv *wl = wiphy_to_wl(wiphy);
1683         struct net_device *ndev = wl_to_prmry_ndev(wl);
1684         s32 err = 0;
1685
1686         CHECK_SYS_UP();
1687         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1688                 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
1689                 wl->conf->rts_threshold = wiphy->rts_threshold;
1690                 err = wl_set_rts(ndev, wl->conf->rts_threshold);
1691                 if (!err)
1692                         return err;
1693         }
1694         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1695                 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
1696                 wl->conf->frag_threshold = wiphy->frag_threshold;
1697                 err = wl_set_frag(ndev, wl->conf->frag_threshold);
1698                 if (!err)
1699                         return err;
1700         }
1701         if (changed & WIPHY_PARAM_RETRY_LONG &&
1702                 (wl->conf->retry_long != wiphy->retry_long)) {
1703                 wl->conf->retry_long = wiphy->retry_long;
1704                 err = wl_set_retry(ndev, wl->conf->retry_long, true);
1705                 if (!err)
1706                         return err;
1707         }
1708         if (changed & WIPHY_PARAM_RETRY_SHORT &&
1709                 (wl->conf->retry_short != wiphy->retry_short)) {
1710                 wl->conf->retry_short = wiphy->retry_short;
1711                 err = wl_set_retry(ndev, wl->conf->retry_short, false);
1712                 if (!err) {
1713                         return err;
1714                 }
1715         }
1716
1717         return err;
1718 }
1719
1720 static s32
1721 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1722         struct cfg80211_ibss_params *params)
1723 {
1724         struct wl_priv *wl = WL_PRIV_GET();
1725         struct cfg80211_bss *bss;
1726         struct ieee80211_channel *chan;
1727         struct wl_join_params join_params;
1728         struct cfg80211_ssid ssid;
1729         s32 scan_retry = 0;
1730         s32 err = 0;
1731
1732         WL_TRACE(("In\n"));
1733         CHECK_SYS_UP();
1734         if (params->bssid) {
1735                 WL_ERR(("Invalid bssid\n"));
1736                 return -EOPNOTSUPP;
1737         }
1738         bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
1739         if (!bss) {
1740                 memcpy(ssid.ssid, params->ssid, params->ssid_len);
1741                 ssid.ssid_len = params->ssid_len;
1742                 do {
1743                         if (unlikely
1744                                 (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
1745                                  -EBUSY)) {
1746                                 wl_delay(150);
1747                         } else {
1748                                 break;
1749                         }
1750                 } while (++scan_retry < WL_SCAN_RETRY_MAX);
1751                 /* to allow scan_inform to propagate to cfg80211 plane */
1752                 rtnl_unlock();
1753
1754                 /* wait 4 secons till scan done.... */
1755                 schedule_timeout_interruptible(4 * HZ);
1756                 rtnl_lock();
1757                 bss = cfg80211_get_ibss(wiphy, NULL,
1758                         params->ssid, params->ssid_len);
1759         }
1760         if (bss) {
1761                 wl->ibss_starter = false;
1762                 WL_DBG(("Found IBSS\n"));
1763         } else {
1764                 wl->ibss_starter = true;
1765         }
1766         chan = params->channel;
1767         if (chan)
1768                 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
1769         /*
1770          * Join with specific BSSID and cached SSID
1771          * If SSID is zero join based on BSSID only
1772          */
1773         memset(&join_params, 0, sizeof(join_params));
1774         memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
1775                 params->ssid_len);
1776         join_params.ssid.SSID_len = htod32(params->ssid_len);
1777         if (params->bssid)
1778                 memcpy(&join_params.params.bssid, params->bssid,
1779                         ETHER_ADDR_LEN);
1780         else
1781                 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
1782
1783         err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
1784                 sizeof(join_params), false);
1785         if (unlikely(err)) {
1786                 WL_ERR(("Error (%d)\n", err));
1787                 return err;
1788         }
1789         return err;
1790 }
1791
1792 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1793 {
1794         struct wl_priv *wl = WL_PRIV_GET();
1795         s32 err = 0;
1796
1797         CHECK_SYS_UP();
1798         wl_link_down(wl);
1799
1800         return err;
1801 }
1802
1803 static s32
1804 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
1805 {
1806         struct wl_priv *wl = WL_PRIV_GET();
1807         struct wl_security *sec;
1808         s32 val = 0;
1809         s32 err = 0;
1810         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1811
1812         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1813                 val = WPA_AUTH_PSK; /* | WPA_AUTH_UNSPECIFIED; */
1814         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1815                 val = WPA2_AUTH_PSK; /* | WPA2_AUTH_UNSPECIFIED ; */
1816         else
1817                 val = WPA_AUTH_DISABLED;
1818
1819         if (is_wps_conn(sme))
1820                 val = WPA_AUTH_DISABLED;
1821
1822         WL_DBG(("setting wpa_auth to 0x%0x\n", val));
1823         err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
1824         if (unlikely(err)) {
1825                 WL_ERR(("set wpa_auth failed (%d)\n", err));
1826                 return err;
1827         }
1828         sec = wl_read_prof(wl, WL_PROF_SEC);
1829         sec->wpa_versions = sme->crypto.wpa_versions;
1830         return err;
1831 }
1832
1833 static s32
1834 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
1835 {
1836         struct wl_priv *wl = WL_PRIV_GET();
1837         struct wl_security *sec;
1838         s32 val = 0;
1839         s32 err = 0;
1840         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1841         switch (sme->auth_type) {
1842         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1843                 val = 0;
1844                 WL_DBG(("open system\n"));
1845                 break;
1846         case NL80211_AUTHTYPE_SHARED_KEY:
1847                 val = 1;
1848                 WL_DBG(("shared key\n"));
1849                 break;
1850         case NL80211_AUTHTYPE_AUTOMATIC:
1851                 val = 2;
1852                 WL_DBG(("automatic\n"));
1853                 break;
1854         case NL80211_AUTHTYPE_NETWORK_EAP:
1855                 WL_DBG(("network eap\n"));
1856         default:
1857                 val = 2;
1858                 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
1859                 break;
1860         }
1861
1862         err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
1863         if (unlikely(err)) {
1864                 WL_ERR(("set auth failed (%d)\n", err));
1865                 return err;
1866         }
1867         sec = wl_read_prof(wl, WL_PROF_SEC);
1868         sec->auth_type = sme->auth_type;
1869         return err;
1870 }
1871
1872 static s32
1873 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
1874 {
1875         struct wl_priv *wl = WL_PRIV_GET();
1876         struct wl_security *sec;
1877         s32 pval = 0;
1878         s32 gval = 0;
1879         s32 err = 0;
1880         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1881
1882         if (sme->crypto.n_ciphers_pairwise) {
1883                 switch (sme->crypto.ciphers_pairwise[0]) {
1884                 case WLAN_CIPHER_SUITE_WEP40:
1885                 case WLAN_CIPHER_SUITE_WEP104:
1886                         pval = WEP_ENABLED;
1887                         break;
1888                 case WLAN_CIPHER_SUITE_TKIP:
1889                         pval = TKIP_ENABLED;
1890                         break;
1891                 case WLAN_CIPHER_SUITE_CCMP:
1892                         pval = AES_ENABLED;
1893                         break;
1894                 case WLAN_CIPHER_SUITE_AES_CMAC:
1895                         pval = AES_ENABLED;
1896                         break;
1897                 default:
1898                         WL_ERR(("invalid cipher pairwise (%d)\n",
1899                                 sme->crypto.ciphers_pairwise[0]));
1900                         return -EINVAL;
1901                 }
1902         }
1903         if (sme->crypto.cipher_group) {
1904                 switch (sme->crypto.cipher_group) {
1905                 case WLAN_CIPHER_SUITE_WEP40:
1906                 case WLAN_CIPHER_SUITE_WEP104:
1907                         gval = WEP_ENABLED;
1908                         break;
1909                 case WLAN_CIPHER_SUITE_TKIP:
1910                         gval = TKIP_ENABLED;
1911                         break;
1912                 case WLAN_CIPHER_SUITE_CCMP:
1913                         gval = AES_ENABLED;
1914                         break;
1915                 case WLAN_CIPHER_SUITE_AES_CMAC:
1916                         gval = AES_ENABLED;
1917                         break;
1918                 default:
1919                         WL_ERR(("invalid cipher group (%d)\n",
1920                                 sme->crypto.cipher_group));
1921                         return -EINVAL;
1922                 }
1923         }
1924
1925         WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
1926
1927         if (is_wps_conn(sme)) {
1928                 err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
1929         } else {
1930                 err = wldev_iovar_setint_bsscfg(dev, "wsec", pval | gval, bssidx);
1931         }
1932         if (unlikely(err)) {
1933                 WL_ERR(("error (%d)\n", err));
1934                 return err;
1935         }
1936
1937         sec = wl_read_prof(wl, WL_PROF_SEC);
1938         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1939         sec->cipher_group = sme->crypto.cipher_group;
1940
1941         return err;
1942 }
1943
1944 static s32
1945 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
1946 {
1947         struct wl_priv *wl = WL_PRIV_GET();
1948         struct wl_security *sec;
1949         s32 val = 0;
1950         s32 err = 0;
1951         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
1952
1953         if (sme->crypto.n_akm_suites) {
1954                 err = wl_dev_intvar_get(dev, "wpa_auth", &val);
1955                 if (unlikely(err)) {
1956                         WL_ERR(("could not get wpa_auth (%d)\n", err));
1957                         return err;
1958                 }
1959                 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1960                         switch (sme->crypto.akm_suites[0]) {
1961                         case WLAN_AKM_SUITE_8021X:
1962                                 val = WPA_AUTH_UNSPECIFIED;
1963                                 break;
1964                         case WLAN_AKM_SUITE_PSK:
1965                                 val = WPA_AUTH_PSK;
1966                                 break;
1967                         default:
1968                                 WL_ERR(("invalid cipher group (%d)\n",
1969                                         sme->crypto.cipher_group));
1970                                 return -EINVAL;
1971                         }
1972                 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1973                         switch (sme->crypto.akm_suites[0]) {
1974                         case WLAN_AKM_SUITE_8021X:
1975                                 val = WPA2_AUTH_UNSPECIFIED;
1976                                 break;
1977                         case WLAN_AKM_SUITE_PSK:
1978                                 val = WPA2_AUTH_PSK;
1979                                 break;
1980                         default:
1981                                 WL_ERR(("invalid cipher group (%d)\n",
1982                                         sme->crypto.cipher_group));
1983                                 return -EINVAL;
1984                         }
1985                 }
1986
1987                 WL_DBG(("setting wpa_auth to %d\n", val));
1988
1989                 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
1990                 if (unlikely(err)) {
1991                         WL_ERR(("could not set wpa_auth (%d)\n", err));
1992                         return err;
1993                 }
1994         }
1995         sec = wl_read_prof(wl, WL_PROF_SEC);
1996         sec->wpa_auth = sme->crypto.akm_suites[0];
1997
1998         return err;
1999 }
2000
2001 static s32
2002 wl_set_set_sharedkey(struct net_device *dev,
2003         struct cfg80211_connect_params *sme)
2004 {
2005         struct wl_priv *wl = WL_PRIV_GET();
2006         struct wl_security *sec;
2007         struct wl_wsec_key key;
2008         s32 val;
2009         s32 err = 0;
2010         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2011
2012         WL_DBG(("key len (%d)\n", sme->key_len));
2013         if (sme->key_len) {
2014                 sec = wl_read_prof(wl, WL_PROF_SEC);
2015                 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
2016                         sec->wpa_versions, sec->cipher_pairwise));
2017                 if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 |
2018                         NL80211_WPA_VERSION_2)) &&
2019                         (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
2020                         WLAN_CIPHER_SUITE_WEP104))) {
2021                         memset(&key, 0, sizeof(key));
2022                         key.len = (u32) sme->key_len;
2023                         key.index = (u32) sme->key_idx;
2024                         if (unlikely(key.len > sizeof(key.data))) {
2025                                 WL_ERR(("Too long key length (%u)\n", key.len));
2026                                 return -EINVAL;
2027                         }
2028                         memcpy(key.data, sme->key, key.len);
2029                         key.flags = WL_PRIMARY_KEY;
2030                         switch (sec->cipher_pairwise) {
2031                         case WLAN_CIPHER_SUITE_WEP40:
2032                                 key.algo = CRYPTO_ALGO_WEP1;
2033                                 break;
2034                         case WLAN_CIPHER_SUITE_WEP104:
2035                                 key.algo = CRYPTO_ALGO_WEP128;
2036                                 break;
2037                         default:
2038                                 WL_ERR(("Invalid algorithm (%d)\n",
2039                                         sme->crypto.ciphers_pairwise[0]));
2040                                 return -EINVAL;
2041                         }
2042                         /* Set the new key/index */
2043                         WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
2044                                 key.len, key.index, key.algo));
2045                         WL_DBG(("key \"%s\"\n", key.data));
2046                         swap_key_from_BE(&key);
2047                         err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
2048                                 ioctlbuf, sizeof(ioctlbuf), bssidx);
2049                         if (unlikely(err)) {
2050                                 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2051                                 return err;
2052                         }
2053                         if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
2054                                 WL_DBG(("set auth_type to shared key\n"));
2055                                 val = 1;        /* shared key */
2056                                 err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
2057                                 if (unlikely(err)) {
2058                                         WL_ERR(("set auth failed (%d)\n", err));
2059                                         return err;
2060                                 }
2061                         }
2062                 }
2063         }
2064         return err;
2065 }
2066
2067 static s32
2068 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
2069         struct cfg80211_connect_params *sme)
2070 {
2071         struct wl_priv *wl = WL_PRIV_GET();
2072         struct ieee80211_channel *chan = sme->channel;
2073         struct wl_join_params join_params;
2074         size_t join_params_size;
2075         s32 err = 0;
2076
2077         WL_DBG(("In\n"));
2078         CHECK_SYS_UP();
2079
2080         /*
2081          * Cancel ongoing scan to sync up with sme state machine of cfg80211.
2082          */
2083         if (wl->scan_request) {
2084                 wl_cfg80211_scan_abort(wl, dev);
2085         }
2086
2087         if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
2088                 /* we only allow to connect using virtual interface in case of P2P */
2089                 if (p2p_on(wl) && is_wps_conn(sme)) {
2090                         WL_DBG(("p2p index : %d\n", wl_cfgp2p_find_idx(wl, dev)));
2091                         /* Have to apply WPS IE + P2P IE in assoc req frame */
2092                         wl_cfgp2p_set_management_ie(wl, dev,
2093                                 wl_cfgp2p_find_idx(wl, dev), VNDR_IE_PRBREQ_FLAG,
2094                                 wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie,
2095                                 wl_to_p2p_bss_saved_ie(wl,
2096                                 P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
2097                         wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
2098                                 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
2099                 } else if (p2p_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
2100                         /* This is the connect req after WPS is done [credentials exchanged] 
2101                          * currently identified with WPA_VERSION_2 .
2102                          * Update the previously set IEs with
2103                          * the newly received IEs from Supplicant. This will remove the WPS IE from
2104                          * the Assoc Req.
2105                          */
2106                         wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
2107                                 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
2108                 }
2109
2110         } else {
2111                 WL_INFO(("No P2PIE in beacon \n"));
2112         }
2113
2114         if (unlikely(!sme->ssid)) {
2115                 WL_ERR(("Invalid ssid\n"));
2116                 return -EOPNOTSUPP;
2117         }
2118         if (chan) {
2119                 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
2120                 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
2121                         chan->center_freq));
2122         }
2123         WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
2124         err = wl_set_wpa_version(dev, sme);
2125         if (unlikely(err))
2126                 return err;
2127
2128         err = wl_set_auth_type(dev, sme);
2129         if (unlikely(err))
2130                 return err;
2131
2132         err = wl_set_set_cipher(dev, sme);
2133         if (unlikely(err))
2134                 return err;
2135
2136         err = wl_set_key_mgmt(dev, sme);
2137         if (unlikely(err))
2138                 return err;
2139
2140         err = wl_set_set_sharedkey(dev, sme);
2141         if (unlikely(err))
2142                 return err;
2143
2144         wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
2145         /*
2146          *  Join with specific BSSID and cached SSID
2147          *  If SSID is zero join based on BSSID only
2148          */
2149         memset(&join_params, 0, sizeof(join_params));
2150         join_params_size = sizeof(join_params.ssid);
2151
2152         join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
2153         memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
2154         join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
2155         wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
2156         memcpy(&join_params.params.bssid, &ether_bcast, ETHER_ADDR_LEN);
2157
2158         wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
2159         WL_DBG(("join_param_size %d\n", join_params_size));
2160
2161         if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
2162                 WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
2163                         join_params.ssid.SSID_len));
2164         }
2165         err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, false);
2166         if (unlikely(err)) {
2167                 WL_ERR(("error (%d)\n", err));
2168                 return err;
2169         }
2170         wl_set_drv_status(wl, CONNECTING);
2171
2172         return err;
2173 }
2174
2175 static s32
2176 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
2177         u16 reason_code)
2178 {
2179         struct wl_priv *wl = WL_PRIV_GET();
2180         scb_val_t scbval;
2181         bool act = false;
2182         s32 err = 0;
2183
2184         WL_ERR(("Reason %d\n\n\n", reason_code));
2185         CHECK_SYS_UP();
2186         act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
2187         if (likely(act)) {
2188                 scbval.val = reason_code;
2189                 memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
2190                 scbval.val = htod32(scbval.val);
2191                 err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
2192                         sizeof(scb_val_t), false);
2193                 if (unlikely(err)) {
2194                         WL_ERR(("error (%d)\n", err));
2195                         return err;
2196                 }
2197         }
2198
2199         return err;
2200 }
2201
2202 static s32
2203 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
2204         enum nl80211_tx_power_setting type, s32 dbm)
2205 {
2206
2207         struct wl_priv *wl = WL_PRIV_GET();
2208         struct net_device *ndev = wl_to_prmry_ndev(wl);
2209         u16 txpwrmw;
2210         s32 err = 0;
2211         s32 disable = 0;
2212
2213         CHECK_SYS_UP();
2214         switch (type) {
2215         case NL80211_TX_POWER_AUTOMATIC:
2216                 break;
2217         case NL80211_TX_POWER_LIMITED:
2218                 if (dbm < 0) {
2219                         WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
2220                         return -EINVAL;
2221                 }
2222                 break;
2223         case NL80211_TX_POWER_FIXED:
2224                 if (dbm < 0) {
2225                         WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
2226                         return -EINVAL;
2227                 }
2228                 break;
2229         }
2230         /* Make sure radio is off or on as far as software is concerned */
2231         disable = WL_RADIO_SW_DISABLE << 16;
2232         disable = htod32(disable);
2233         err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), false);
2234         if (unlikely(err)) {
2235                 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
2236                 return err;
2237         }
2238
2239         if (dbm > 0xffff)
2240                 txpwrmw = 0xffff;
2241         else
2242                 txpwrmw = (u16) dbm;
2243         err = wl_dev_intvar_set(ndev, "qtxpower",
2244                 (s32) (bcm_mw_to_qdbm(txpwrmw)));
2245         if (unlikely(err)) {
2246                 WL_ERR(("qtxpower error (%d)\n", err));
2247                 return err;
2248         }
2249         wl->conf->tx_power = dbm;
2250
2251         return err;
2252 }
2253
2254 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
2255 {
2256         struct wl_priv *wl = WL_PRIV_GET();
2257         struct net_device *ndev = wl_to_prmry_ndev(wl);
2258         s32 txpwrdbm;
2259         u8 result;
2260         s32 err = 0;
2261
2262         CHECK_SYS_UP();
2263         err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
2264         if (unlikely(err)) {
2265                 WL_ERR(("error (%d)\n", err));
2266                 return err;
2267         }
2268         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
2269         *dbm = (s32) bcm_qdbm_to_mw(result);
2270
2271         return err;
2272 }
2273
2274 static s32
2275 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
2276         u8 key_idx, bool unicast, bool multicast)
2277 {
2278         struct wl_priv *wl = WL_PRIV_GET();
2279         u32 index;
2280         s32 wsec;
2281         s32 err = 0;
2282         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2283
2284         WL_DBG(("key index (%d)\n", key_idx));
2285         CHECK_SYS_UP();
2286         err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2287         if (unlikely(err)) {
2288                 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
2289                 return err;
2290         }
2291         if (wsec & WEP_ENABLED) {
2292                 /* Just select a new current key */
2293                 index = (u32) key_idx;
2294                 index = htod32(index);
2295                 err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
2296                         sizeof(index), false);
2297                 if (unlikely(err)) {
2298                         WL_ERR(("error (%d)\n", err));
2299                 }
2300         }
2301         return err;
2302 }
2303
2304 static s32
2305 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
2306         u8 key_idx, const u8 *mac_addr, struct key_params *params)
2307 {
2308         struct wl_priv *wl = WL_PRIV_GET();
2309         struct wl_wsec_key key;
2310         s32 err = 0;
2311         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2312         s32 mode = get_mode_by_netdev(wl, dev);
2313         memset(&key, 0, sizeof(key));
2314         key.index = (u32) key_idx;
2315
2316         if (!ETHER_ISMULTI(mac_addr))
2317                 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
2318         key.len = (u32) params->key_len;
2319
2320         /* check for key index change */
2321         if (key.len == 0) {
2322                 /* key delete */
2323                 swap_key_from_BE(&key);
2324                 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2325                         sizeof(ioctlbuf), bssidx);
2326                 if (unlikely(err)) {
2327                         WL_ERR(("key delete error (%d)\n", err));
2328                         return err;
2329                 }
2330         } else {
2331                 if (key.len > sizeof(key.data)) {
2332                         WL_ERR(("Invalid key length (%d)\n", key.len));
2333                         return -EINVAL;
2334                 }
2335                 WL_DBG(("Setting the key index %d\n", key.index));
2336                 memcpy(key.data, params->key, key.len);
2337
2338                 if ((mode == WL_MODE_BSS) &&
2339                         (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2340                         u8 keybuf[8];
2341                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
2342                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2343                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
2344                 }
2345
2346                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2347                 if (params->seq && params->seq_len == 6) {
2348                         /* rx iv */
2349                         u8 *ivptr;
2350                         ivptr = (u8 *) params->seq;
2351                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2352                                 (ivptr[3] << 8) | ivptr[2];
2353                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2354                         key.iv_initialized = true;
2355                 }
2356
2357                 switch (params->cipher) {
2358                 case WLAN_CIPHER_SUITE_WEP40:
2359                         key.algo = CRYPTO_ALGO_WEP1;
2360                         WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2361                         break;
2362                 case WLAN_CIPHER_SUITE_WEP104:
2363                         key.algo = CRYPTO_ALGO_WEP128;
2364                         WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2365                         break;
2366                 case WLAN_CIPHER_SUITE_TKIP:
2367                         key.algo = CRYPTO_ALGO_TKIP;
2368                         WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2369                         break;
2370                 case WLAN_CIPHER_SUITE_AES_CMAC:
2371                         key.algo = CRYPTO_ALGO_AES_CCM;
2372                         WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2373                         break;
2374                 case WLAN_CIPHER_SUITE_CCMP:
2375                         key.algo = CRYPTO_ALGO_AES_CCM;
2376                         WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
2377                         break;
2378                 default:
2379                         WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
2380                         return -EINVAL;
2381                 }
2382                 swap_key_from_BE(&key);
2383 #ifdef CONFIG_WIRELESS_EXT
2384                 dhd_wait_pend8021x(dev);
2385 #endif
2386                 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2387                         sizeof(ioctlbuf), bssidx);
2388                 if (unlikely(err)) {
2389                         WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2390                         return err;
2391                 }
2392         }
2393         return err;
2394 }
2395
2396 static s32
2397 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
2398         u8 key_idx, bool pairwise, const u8 *mac_addr,
2399         struct key_params *params)
2400 {
2401         struct wl_wsec_key key;
2402         s32 val = 0;
2403         s32 wsec = 0;
2404         s32 err = 0;
2405         u8 keybuf[8];
2406         s32 bssidx = 0;
2407         struct wl_priv *wl = WL_PRIV_GET();
2408         s32 mode = get_mode_by_netdev(wl, dev);
2409         WL_DBG(("key index (%d)\n", key_idx));
2410         CHECK_SYS_UP();
2411
2412         bssidx = wl_cfgp2p_find_idx(wl, dev);
2413
2414         if (mac_addr) {
2415                 wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
2416                 goto exit;
2417         }
2418         memset(&key, 0, sizeof(key));
2419
2420         key.len = (u32) params->key_len;
2421         key.index = (u32) key_idx;
2422
2423         if (unlikely(key.len > sizeof(key.data))) {
2424                 WL_ERR(("Too long key length (%u)\n", key.len));
2425                 return -EINVAL;
2426         }
2427         memcpy(key.data, params->key, key.len);
2428
2429         key.flags = WL_PRIMARY_KEY;
2430         switch (params->cipher) {
2431         case WLAN_CIPHER_SUITE_WEP40:
2432                 key.algo = CRYPTO_ALGO_WEP1;
2433                 val = WEP_ENABLED;
2434                 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2435                 break;
2436         case WLAN_CIPHER_SUITE_WEP104:
2437                 key.algo = CRYPTO_ALGO_WEP128;
2438                 val = WEP_ENABLED;
2439                 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2440                 break;
2441         case WLAN_CIPHER_SUITE_TKIP:
2442                 key.algo = CRYPTO_ALGO_TKIP;
2443                 val = TKIP_ENABLED;
2444                 /* wpa_supplicant switches the third and fourth quarters of the TKIP key */
2445                 if (mode == WL_MODE_BSS) {
2446                         bcopy(&key.data[24], keybuf, sizeof(keybuf));
2447                         bcopy(&key.data[16], &key.data[24], sizeof(keybuf));
2448                         bcopy(keybuf, &key.data[16], sizeof(keybuf));
2449                 }
2450                 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2451                 break;
2452         case WLAN_CIPHER_SUITE_AES_CMAC:
2453                 key.algo = CRYPTO_ALGO_AES_CCM;
2454                 val = AES_ENABLED;
2455                 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2456                 break;
2457         case WLAN_CIPHER_SUITE_CCMP:
2458                 key.algo = CRYPTO_ALGO_AES_CCM;
2459                 val = AES_ENABLED;
2460                 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
2461                 break;
2462         default:
2463                 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
2464                 return -EINVAL;
2465         }
2466
2467         /* Set the new key/index */
2468         swap_key_from_BE(&key);
2469         err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2470                 sizeof(ioctlbuf), bssidx);
2471         if (unlikely(err)) {
2472                 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2473                 return err;
2474         }
2475
2476 exit:
2477         err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2478         if (unlikely(err)) {
2479                 WL_ERR(("get wsec error (%d)\n", err));
2480                 return err;
2481         }
2482
2483         wsec |= val;
2484         err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
2485         if (unlikely(err)) {
2486                 WL_ERR(("set wsec error (%d)\n", err));
2487                 return err;
2488         }
2489
2490 #ifdef NOT_YET
2491         /* TODO: Removed in P2P, check later --lm */
2492         val = 1;                /* assume shared key. otherwise 0 */
2493         val = htod32(val);
2494         err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), false);
2495         if (unlikely(err)) {
2496                 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
2497                 return err;
2498         }
2499 #endif
2500         return err;
2501 }
2502
2503 static s32
2504 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
2505         u8 key_idx, bool pairwise, const u8 *mac_addr)
2506 {
2507         struct wl_wsec_key key;
2508         struct wl_priv *wl = WL_PRIV_GET();
2509         s32 err = 0;
2510         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2511
2512         WL_DBG(("Enter\n"));
2513         CHECK_SYS_UP();
2514         memset(&key, 0, sizeof(key));
2515
2516         key.index = (u32) key_idx;
2517         key.flags = WL_PRIMARY_KEY;
2518         key.algo = CRYPTO_ALGO_OFF;
2519
2520         WL_DBG(("key index (%d)\n", key_idx));
2521         /* Set the new key/index */
2522         swap_key_from_BE(&key);
2523         wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), ioctlbuf,
2524                 sizeof(ioctlbuf), bssidx);
2525         if (unlikely(err)) {
2526                 if (err == -EINVAL) {
2527                         if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
2528                                 /* we ignore this key index in this case */
2529                                 WL_DBG(("invalid key index (%d)\n", key_idx));
2530                         }
2531                 } else {
2532                         WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2533                 }
2534                 return err;
2535         }
2536
2537 #ifdef NOT_YET
2538         /* TODO: Removed in P2P twig, check later --lin */
2539         val = 0;                /* assume open key. otherwise 1 */
2540         val = htod32(val);
2541         err = wldev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val), false);
2542         if (unlikely(err)) {
2543                 WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
2544                 return err;
2545         }
2546 #endif
2547         return err;
2548 }
2549
2550 static s32
2551 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
2552         u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2553         void (*callback) (void *cookie, struct key_params * params))
2554 {
2555         struct key_params params;
2556         struct wl_wsec_key key;
2557         struct wl_priv *wl = WL_PRIV_GET();
2558         struct wl_security *sec;
2559         s32 wsec;
2560         s32 err = 0;
2561         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2562
2563         WL_DBG(("key index (%d)\n", key_idx));
2564         CHECK_SYS_UP();
2565         memset(&key, 0, sizeof(key));
2566         key.index = key_idx;
2567         swap_key_to_BE(&key);
2568         memset(&params, 0, sizeof(params));
2569         params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
2570         memcpy(params.key, key.data, params.key_len);
2571
2572         wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2573         if (unlikely(err)) {
2574                 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
2575                 return err;
2576         }
2577         switch (wsec & ~SES_OW_ENABLED) {
2578                 case WEP_ENABLED:
2579                         sec = wl_read_prof(wl, WL_PROF_SEC);
2580                         if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2581                                 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2582                                 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2583                         } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2584                                 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2585                                 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2586                         }
2587                         break;
2588                 case TKIP_ENABLED:
2589                         params.cipher = WLAN_CIPHER_SUITE_TKIP;
2590                         WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2591                         break;
2592                 case AES_ENABLED:
2593                         params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2594                         WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2595                         break;
2596                 default:
2597                         WL_ERR(("Invalid algo (0x%x)\n", wsec));
2598                         return -EINVAL;
2599         }
2600
2601         callback(cookie, &params);
2602         return err;
2603 }
2604
2605 static s32
2606 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2607         struct net_device *dev, u8 key_idx)
2608 {
2609         WL_INFO(("Not supported\n"));
2610         CHECK_SYS_UP();
2611         return -EOPNOTSUPP;
2612 }
2613
2614 static s32
2615 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
2616         u8 *mac, struct station_info *sinfo)
2617 {
2618         struct wl_priv *wl = WL_PRIV_GET();
2619         scb_val_t scb_val;
2620         int rssi;
2621         s32 rate;
2622         s32 err = 0;
2623
2624         CHECK_SYS_UP();
2625         if (unlikely
2626                 (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
2627                 WL_ERR(("Wrong Mac address\n"));
2628                 return -ENOENT;
2629         }
2630
2631         /* Report the current tx rate */
2632         err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
2633         if (err) {
2634                 WL_ERR(("Could not get rate (%d)\n", err));
2635         } else {
2636                 rate = dtoh32(rate);
2637                 sinfo->filled |= STATION_INFO_TX_BITRATE;
2638                 sinfo->txrate.legacy = rate * 5;
2639                 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
2640         }
2641
2642         if (wl_get_drv_status(wl, CONNECTED)) {
2643                 memset(&scb_val, 0, sizeof(scb_val));
2644                 scb_val.val = 0;
2645                 err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
2646                         sizeof(scb_val_t), false);
2647                 if (unlikely(err)) {
2648                         WL_ERR(("Could not get rssi (%d)\n", err));
2649                         return err;
2650                 }
2651                 rssi = dtoh32(scb_val.val);
2652                 sinfo->filled |= STATION_INFO_SIGNAL;
2653                 sinfo->signal = rssi;
2654                 WL_DBG(("RSSI %d dBm\n", rssi));
2655         }
2656
2657 #if defined(ANDROID_WIRELESS_PATCH)
2658         err = wldev_ioctl(dev, WLC_GET_RATE, &sinfo->link_speed, sizeof(sinfo->link_speed), false);
2659         sinfo->link_speed = sinfo->link_speed / 2; /* Convert internal 500Kbps to Mpbs */
2660         if (!err)
2661                 sinfo->filled |= STATION_LINK_SPEED;
2662         else
2663                 WL_ERR(("WLC_GET_RATE failed\n"));
2664 #endif
2665
2666         return err;
2667 }
2668
2669 static s32
2670 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2671         bool enabled, s32 timeout)
2672 {
2673         s32 pm;
2674         s32 err = 0;
2675
2676         CHECK_SYS_UP();
2677         pm = enabled ? PM_FAST : PM_OFF;
2678         pm = htod32(pm);
2679         WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
2680         err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), false);
2681         if (unlikely(err)) {
2682                 if (err == -ENODEV)
2683                         WL_DBG(("net_device is not ready yet\n"));
2684                 else
2685                         WL_ERR(("error (%d)\n", err));
2686                 return err;
2687         }
2688         return err;
2689 }
2690
2691 static __used u32 wl_find_msb(u16 bit16)
2692 {
2693         u32 ret = 0;
2694
2695         if (bit16 & 0xff00) {
2696                 ret += 8;
2697                 bit16 >>= 8;
2698         }
2699
2700         if (bit16 & 0xf0) {
2701                 ret += 4;
2702                 bit16 >>= 4;
2703         }
2704
2705         if (bit16 & 0xc) {
2706                 ret += 2;
2707                 bit16 >>= 2;
2708         }
2709
2710         if (bit16 & 2)
2711                 ret += bit16 & 2;
2712         else if (bit16)
2713                 ret += bit16;
2714
2715         return ret;
2716 }
2717
2718 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
2719 {
2720         struct wl_priv *wl = WL_PRIV_GET();
2721         s32 err = 0;
2722
2723         if (unlikely(!wl_get_drv_status(wl, READY))) {
2724                 WL_INFO(("device is not ready : status (%d)\n",
2725                         (int)wl->status));
2726                 return 0;
2727         }
2728
2729         wl_invoke_iscan(wl);
2730
2731         return err;
2732 }
2733
2734 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
2735 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
2736 #else
2737 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
2738 #endif
2739 {
2740         struct wl_priv *wl = WL_PRIV_GET();
2741         s32 err = 0;
2742
2743         if (unlikely(!wl_get_drv_status(wl, READY))) {
2744                 WL_INFO(("device is not ready : status (%d)\n",
2745                         (int)wl->status));
2746                 return 0;
2747         }
2748
2749         wl_set_drv_status(wl, SCAN_ABORTING);
2750         wl_term_iscan(wl);
2751         if (wl->scan_request) {
2752                 cfg80211_scan_done(wl->scan_request, true);
2753                 wl->scan_request = NULL;
2754         }
2755         wl_clr_drv_status(wl, SCANNING);
2756         wl_clr_drv_status(wl, SCAN_ABORTING);
2757
2758         return err;
2759 }
2760
2761 static __used s32
2762 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
2763         s32 err)
2764 {
2765         int i, j;
2766         struct wl_priv *wl = WL_PRIV_GET();
2767         struct net_device *primary_dev = wl_to_prmry_ndev(wl);
2768
2769         /* Firmware is supporting pmk list only for STA interface i.e. primary interface
2770           * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
2771           * Do we really need to support PMK cache in P2P in firmware?
2772         */
2773         if (primary_dev != dev) {
2774                 WL_ERR(("Not supporting Flushing pmklist on virtual"
2775                         " interfaces than primary interface\n"));
2776                 return err;
2777         }
2778
2779         WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
2780         for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2781                 WL_DBG(("PMKID[%d]: %pM =\n", i,
2782                         &pmk_list->pmkids.pmkid[i].BSSID));
2783                 for (j = 0; j < WPA2_PMKID_LEN; j++) {
2784                         WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
2785                 }
2786         }
2787         if (likely(!err)) {
2788                 err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2789                         sizeof(*pmk_list));
2790         }
2791
2792         return err;
2793 }
2794
2795 static s32
2796 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2797         struct cfg80211_pmksa *pmksa)
2798 {
2799         struct wl_priv *wl = WL_PRIV_GET();
2800         s32 err = 0;
2801         int i;
2802
2803         CHECK_SYS_UP();
2804         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2805                 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2806                         ETHER_ADDR_LEN))
2807                         break;
2808         if (i < WL_NUM_PMKIDS_MAX) {
2809                 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
2810                         ETHER_ADDR_LEN);
2811                 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
2812                         WPA2_PMKID_LEN);
2813                 if (i == wl->pmk_list->pmkids.npmkid)
2814                         wl->pmk_list->pmkids.npmkid++;
2815         } else {
2816                 err = -EINVAL;
2817         }
2818         WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2819                 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
2820         for (i = 0; i < WPA2_PMKID_LEN; i++) {
2821                 WL_DBG(("%02x\n",
2822                         wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
2823                         PMKID[i]));
2824         }
2825
2826         err = wl_update_pmklist(dev, wl->pmk_list, err);
2827
2828         return err;
2829 }
2830
2831 static s32
2832 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2833         struct cfg80211_pmksa *pmksa)
2834 {
2835         struct wl_priv *wl = WL_PRIV_GET();
2836         struct _pmkid_list pmkid;
2837         s32 err = 0;
2838         int i;
2839
2840         CHECK_SYS_UP();
2841         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
2842         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
2843
2844         WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2845                 &pmkid.pmkid[0].BSSID));
2846         for (i = 0; i < WPA2_PMKID_LEN; i++) {
2847                 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
2848         }
2849
2850         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
2851                 if (!memcmp
2852                     (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
2853                      ETHER_ADDR_LEN))
2854                         break;
2855
2856         if ((wl->pmk_list->pmkids.npmkid > 0) &&
2857                 (i < wl->pmk_list->pmkids.npmkid)) {
2858                 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
2859                 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
2860                         memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
2861                                 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
2862                                 ETHER_ADDR_LEN);
2863                         memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
2864                                 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
2865                                 WPA2_PMKID_LEN);
2866                 }
2867                 wl->pmk_list->pmkids.npmkid--;
2868         } else {
2869                 err = -EINVAL;
2870         }
2871
2872         err = wl_update_pmklist(dev, wl->pmk_list, err);
2873
2874         return err;
2875
2876 }
2877
2878 static s32
2879 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2880 {
2881         struct wl_priv *wl = WL_PRIV_GET();
2882         s32 err = 0;
2883         CHECK_SYS_UP();
2884         memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
2885         err = wl_update_pmklist(dev, wl->pmk_list, err);
2886         return err;
2887
2888 }
2889
2890 wl_scan_params_t *
2891 wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
2892 {
2893         wl_scan_params_t *params;
2894         int params_size;
2895         int num_chans;
2896
2897         *out_params_size = 0;
2898
2899         /* Our scan params only need space for 1 channel and 0 ssids */
2900         params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16);
2901         params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL);
2902         if (params == NULL) {
2903                 WL_ERR(("%s: mem alloc failed (%d bytes)\n", __func__, params_size));
2904                 return params;
2905         }
2906         memset(params, 0, params_size);
2907         params->nprobes = nprobes;
2908
2909         num_chans = (channel == 0) ? 0 : 1;
2910
2911         memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
2912         params->bss_type = DOT11_BSSTYPE_ANY;
2913         params->scan_type = DOT11_SCANTYPE_ACTIVE;
2914         params->nprobes = htod32(1);
2915         params->active_time = htod32(-1);
2916         params->passive_time = htod32(-1);
2917         params->home_time = htod32(10);
2918         params->channel_list[0] = htodchanspec(channel);
2919
2920         /* Our scan params have 1 channel and 0 ssids */
2921         params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
2922         (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
2923
2924         *out_params_size = params_size; /* rtn size to the caller */
2925         return params;
2926 }
2927 s32
2928 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
2929 {
2930         wl_scan_params_t *params;
2931         s32 params_size;
2932         s32 err = BCME_OK;
2933
2934         WL_DBG(("Enter\n"));
2935
2936         /* Our scan params only need space for 1 channel and 0 ssids */
2937         params = wl_cfg80211_scan_alloc_params(-1, 0, &params_size);
2938         if (params == NULL) {
2939                 WL_ERR(("scan params allocation failed \n"));
2940                 err = -ENOMEM;
2941         }
2942         /* Do a scan abort to stop the driver's scan engine */
2943         err = wldev_ioctl(ndev, WLC_SCAN, params, params_size, false);
2944         if (err < 0) {
2945                 WL_ERR(("scan abort  failed \n"));
2946         }
2947
2948         return err;
2949 }
2950 static s32
2951 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
2952         struct ieee80211_channel * channel,
2953         enum nl80211_channel_type channel_type,
2954         unsigned int duration, u64 *cookie)
2955 {
2956         s32 target_channel;
2957
2958         s32 err = BCME_OK;
2959         struct wl_priv *wl = WL_PRIV_GET();
2960         dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
2961         WL_DBG(("Enter, netdev_ifidx: %d \n", dev->ifindex));
2962         if (likely(wl_get_drv_status(wl, SCANNING))) {
2963                 wl_cfg80211_scan_abort(wl, dev);
2964         }
2965
2966         target_channel = ieee80211_frequency_to_channel(channel->center_freq);
2967         memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel));
2968         wl->remain_on_chan_type = channel_type;
2969         wl->cache_cookie = *cookie;
2970         cfg80211_ready_on_channel(dev, *cookie, channel,
2971                 channel_type, duration, GFP_KERNEL);
2972         if (!p2p_on(wl)) {
2973                 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
2974
2975                 /* In case of p2p_listen command, supplicant send remain_on_channel
2976                  * without turning on P2P
2977                  */
2978
2979                 err = wl_cfgp2p_enable_discovery(wl, dev, NULL, 0);
2980
2981                 if (unlikely(err)) {
2982                         goto exit;
2983                 }
2984                 p2p_on(wl) = true;
2985         }
2986         if (p2p_on(wl))
2987                 wl_cfgp2p_discover_listen(wl, target_channel, duration);
2988
2989
2990 exit:
2991         return err;
2992 }
2993
2994 static s32
2995 wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
2996         u64 cookie)
2997 {
2998         s32 err = 0;
2999         WL_DBG((" enter ) netdev_ifidx: %d \n", dev->ifindex));
3000         return err;
3001 }
3002
3003 static s32
3004 wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
3005         struct ieee80211_channel *channel, bool offchan,
3006         enum nl80211_channel_type channel_type,
3007         bool channel_type_valid, unsigned int wait,
3008         const u8* buf, size_t len, u64 *cookie)
3009 {
3010         wl_action_frame_t *action_frame;
3011         wl_af_params_t *af_params;
3012         wifi_p2p_ie_t *p2p_ie;
3013         wpa_ie_fixed_t *wps_ie;
3014         const struct ieee80211_mgmt *mgmt;
3015         struct wl_priv *wl = WL_PRIV_GET();
3016         dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
3017         s32 err = BCME_OK;
3018         s32 bssidx = 0;
3019         u32 p2pie_len = 0;
3020         u32 wpsie_len = 0;
3021         u16 fc;
3022         bool ack = false;
3023         WL_DBG(("Enter \n"));
3024         /* find bssidx based on ndev */
3025         bssidx = wl_cfgp2p_find_idx(wl, dev);
3026         /* cookie generation */
3027         *cookie = (unsigned long) buf;
3028
3029         if (bssidx == -1) {
3030
3031                 WL_ERR(("Can not find the bssidx for dev( %p )\n", dev));
3032                 return -ENODEV;
3033         }
3034         if (wl->p2p_supported && p2p_on(wl)) {
3035                 wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
3036                 /* Suspend P2P discovery search-listen to prevent it from changing the
3037                  * channel.
3038                  */
3039                 if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) {
3040                         WL_ERR(("Can not disable discovery mode\n"));
3041                         return -EFAULT;
3042                 }
3043         }
3044
3045         mgmt = (const struct ieee80211_mgmt *) buf;
3046         fc = mgmt->frame_control;
3047         if (fc != IEEE80211_STYPE_ACTION) {
3048                 if (fc == IEEE80211_STYPE_PROBE_RESP) {
3049                         s32 ie_offset =  DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3050                         s32 ie_len = len - ie_offset;
3051                         if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)(buf + ie_offset), ie_len))
3052                                 != NULL) {
3053                                 /* Total length of P2P Information Element */
3054                                 p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
3055                                 /* Have to change p2p device address in dev_info attribute
3056                                  * because Supplicant use primary eth0 address
3057                                  */
3058                         #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3059                                 wl_cfg80211_change_ifaddr((u8 *)p2p_ie,
3060                                         &wl->p2p_dev_addr, P2P_SEID_DEV_INFO);
3061                         #endif
3062                         }
3063                         if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len))
3064                                 != NULL) {
3065                                 /* Order of Vendor IE is 1) WPS IE +
3066                                  * 2) P2P IE created by supplicant
3067                                  *  So, it is ok to find start address of WPS IE
3068                                  *  to save IEs to firmware
3069                                  */
3070                                 wpsie_len = wps_ie->length + sizeof(wps_ie->length) +
3071                                         sizeof(wps_ie->tag);
3072                                 wl_cfgp2p_set_management_ie(wl, dev, bssidx,
3073                                         VNDR_IE_PRBRSP_FLAG,
3074                                         (u8 *)wps_ie, wpsie_len + p2pie_len);
3075                                 /* remove WLC_E_PROBREQ_MSG event to prevent HOSTAPD
3076                                  * from responding many probe request
3077                                  */
3078                         }
3079                 }
3080                 cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_KERNEL);
3081                 goto exit;
3082         } else {
3083             /* Abort the dwell time of any previous off-channel action frame that may
3084              * be still in effect.  Sending off-channel action frames relies on the
3085              * driver's scan engine.  If a previous off-channel action frame tx is
3086              * still in progress (including the dwell time), then this new action
3087              * frame will not be sent out.
3088              */
3089                 wl_cfg80211_scan_abort(wl, dev);
3090         }
3091         af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
3092
3093         if (af_params == NULL)
3094         {
3095                 WL_ERR(("unable to allocate frame\n"));
3096                 return -ENOMEM;
3097         }
3098
3099         action_frame = &af_params->action_frame;
3100
3101         /* Add the packet Id */
3102         action_frame->packetId = (u32) action_frame;
3103         WL_DBG(("action frame %d\n", action_frame->packetId));
3104         /* Add BSSID */
3105         memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN);
3106         memcpy(&af_params->BSSID, &mgmt->bssid[0], ETHER_ADDR_LEN);
3107
3108         /* Add the length exepted for 802.11 header  */
3109         action_frame->len = len - DOT11_MGMT_HDR_LEN;
3110         WL_DBG(("action_frame->len: %d\n", action_frame->len));
3111
3112         /* Add the channel */
3113         af_params->channel =
3114                 ieee80211_frequency_to_channel(channel->center_freq);
3115
3116         /* Add the dwell time
3117          * Dwell time to stay off-channel to wait for a response action frame
3118          * after transmitting an GO Negotiation action frame
3119          */
3120         af_params->dwell_time = WL_DWELL_TIME;
3121
3122         memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
3123
3124         if (wl->p2p->vif_created) {
3125                 wifi_p2p_pub_act_frame_t *act_frm =
3126                         (wifi_p2p_pub_act_frame_t *) (action_frame->data);
3127                 /*
3128                  *  Have to change intented address from GO REQ or GO RSP and INVITE REQ
3129                  *  because wpa-supplicant use eth0 primary address
3130                  */
3131                 if ((act_frm->subtype == P2P_PAF_GON_REQ)||
3132                   (act_frm->subtype == P2P_PAF_GON_RSP)||
3133                   (act_frm->subtype == P2P_PAF_GON_CONF)||
3134                   (act_frm->subtype == P2P_PAF_INVITE_REQ)) {
3135                         p2p_ie = wl_cfgp2p_find_p2pie(act_frm->elts,
3136                                 action_frame->len - P2P_PUB_AF_FIXED_LEN);
3137                 #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3138                         wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.int_addr,
3139                                 P2P_SEID_INTINTADDR);
3140                         wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
3141                                 P2P_SEID_DEV_INFO);
3142                         wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
3143                                 P2P_SEID_GROUP_ID);
3144                 #endif
3145                 }
3146         }
3147
3148         ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true;
3149         cfg80211_mgmt_tx_status(dev, *cookie, buf, len, ack, GFP_KERNEL);
3150
3151         kfree(af_params);
3152 exit:
3153         return err;
3154 }
3155
3156
3157 static void
3158 wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev,
3159         u16 frame_type, bool reg)
3160 {
3161
3162         WL_DBG(("%s: frame_type: %x, reg: %d\n", __func__, frame_type, reg));
3163
3164         if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3165                 return;
3166
3167         return;
3168 }
3169
3170
3171 static s32
3172 wl_cfg80211_change_bss(struct wiphy *wiphy,
3173         struct net_device *dev,
3174         struct bss_parameters *params)
3175 {
3176         if (params->use_cts_prot >= 0) {
3177         }
3178
3179         if (params->use_short_preamble >= 0) {
3180         }
3181
3182         if (params->use_short_slot_time >= 0) {
3183         }
3184
3185         if (params->basic_rates) {
3186         }
3187
3188         if (params->ap_isolate >= 0) {
3189         }
3190
3191         if (params->ht_opmode >= 0) {
3192         }
3193
3194         return 0;
3195 }
3196
3197 static s32
3198 wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
3199         struct ieee80211_channel *chan,
3200         enum nl80211_channel_type channel_type)
3201 {
3202         s32 channel;
3203         s32 err = BCME_OK;
3204
3205         channel = ieee80211_frequency_to_channel(chan->center_freq);
3206         WL_DBG(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
3207                 dev->ifindex, channel_type, channel));
3208         wldev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel), false);
3209
3210         return err;
3211 }
3212
3213 static s32
3214 wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
3215 {
3216         s32 len = 0;
3217         s32 err = BCME_OK;
3218         u16 auth = 0; /* d11 open authentication */
3219         u16 count;
3220         u32 wsec;
3221         u32 pval = 0;
3222         u32 gval = 0;
3223         u32 wpa_auth = 0;
3224         u8* tmp;
3225         wpa_suite_mcast_t *mcast;
3226         wpa_suite_ucast_t *ucast;
3227         wpa_suite_auth_key_mgmt_t *mgmt;
3228         if (wpa2ie == NULL)
3229                 goto exit;
3230
3231         WL_DBG(("Enter \n"));
3232         len =  wpa2ie->len;
3233         /* check the mcast cipher */
3234         mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN];
3235         tmp = mcast->oui;
3236         switch (tmp[DOT11_OUI_LEN]) {
3237                 case WPA_CIPHER_NONE:
3238                         gval = 0;
3239                         break;
3240                 case WPA_CIPHER_WEP_40:
3241                 case WPA_CIPHER_WEP_104:
3242                         gval = WEP_ENABLED;
3243                         break;
3244                 case WPA_CIPHER_TKIP:
3245                         gval = TKIP_ENABLED;
3246                         break;
3247                 case WPA_CIPHER_AES_CCM:
3248                         gval = AES_ENABLED;
3249                         break;
3250                 default:
3251                         WL_ERR(("No Security Info\n"));
3252                         break;
3253         }
3254         len -= WPA_SUITE_LEN;
3255         /* check the unicast cipher */
3256         ucast = (wpa_suite_ucast_t *)&mcast[1];
3257         count = ltoh16_ua(&ucast->count);
3258         tmp = ucast->list[0].oui;
3259         switch (tmp[DOT11_OUI_LEN]) {
3260                 case WPA_CIPHER_NONE:
3261                         pval = 0;
3262                         break;
3263                 case WPA_CIPHER_WEP_40:
3264                 case WPA_CIPHER_WEP_104:
3265                         pval = WEP_ENABLED;
3266                         break;
3267                 case WPA_CIPHER_TKIP:
3268                         pval = TKIP_ENABLED;
3269                         break;
3270                 case WPA_CIPHER_AES_CCM:
3271                         pval = AES_ENABLED;
3272                         break;
3273                 default:
3274                         WL_ERR(("No Security Info\n"));
3275         }
3276         /* FOR WPS , set SEC_OW_ENABLED */
3277         wsec = (pval | gval | SES_OW_ENABLED);
3278         /* check the AKM */
3279         mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[1];
3280         count = ltoh16_ua(&mgmt->count);
3281         tmp = (u8 *)&mgmt->list[0];
3282         switch (tmp[DOT11_OUI_LEN]) {
3283                 case RSN_AKM_NONE:
3284                         wpa_auth = WPA_AUTH_NONE;
3285                         break;
3286                 case RSN_AKM_UNSPECIFIED:
3287                         wpa_auth = WPA2_AUTH_UNSPECIFIED;
3288                         break;
3289                 case RSN_AKM_PSK:
3290                         wpa_auth = WPA2_AUTH_PSK;
3291                         break;
3292                 default:
3293                         WL_ERR(("No Key Mgmt Info\n"));
3294         }
3295         /* set auth */
3296         err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
3297         if (err < 0) {
3298                 WL_ERR(("auth error %d\n", err));
3299                 return BCME_ERROR;
3300         }
3301         /* set wsec */
3302         err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
3303         if (err < 0) {
3304                 WL_ERR(("wsec error %d\n", err));
3305                 return BCME_ERROR;
3306         }
3307         /* set upper-layer auth */
3308         err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
3309         if (err < 0) {
3310                 WL_ERR(("wpa_auth error %d\n", err));
3311                 return BCME_ERROR;
3312         }
3313 exit:
3314         return 0;
3315 }
3316
3317 static s32
3318 wl_validate_wpaie(struct net_device *dev, wpa_ie_fixed_t *wpaie, s32 bssidx)
3319 {
3320         wpa_suite_mcast_t *mcast;
3321         wpa_suite_ucast_t *ucast;
3322         wpa_suite_auth_key_mgmt_t *mgmt;
3323         u16 auth = 0; /* d11 open authentication */
3324         u16 count;
3325         s32 err = BCME_OK;
3326         s32 len = 0;
3327         u32 i;
3328         u32 wsec;
3329         u32 pval = 0;
3330         u32 gval = 0;
3331         u32 wpa_auth = 0;
3332         u32 tmp = 0;
3333
3334         if (wpaie == NULL)
3335                 goto exit;
3336         WL_DBG(("Enter \n"));
3337         len = wpaie->length;    /* value length */
3338         len -= WPA_IE_TAG_FIXED_LEN;
3339         /* check for multicast cipher suite */
3340         if (len < WPA_SUITE_LEN) {
3341                 WL_INFO(("no multicast cipher suite\n"));
3342                 goto exit;
3343         }
3344
3345         /* pick up multicast cipher */
3346         mcast = (wpa_suite_mcast_t *)&wpaie[1];
3347         len -= WPA_SUITE_LEN;
3348         if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) {
3349                 if (IS_WPA_CIPHER(mcast->type)) {
3350                         tmp = 0;
3351                         switch (mcast->type) {
3352                                 case WPA_CIPHER_NONE:
3353                                         tmp = 0;
3354                                         break;
3355                                 case WPA_CIPHER_WEP_40:
3356                                 case WPA_CIPHER_WEP_104:
3357                                         tmp = WEP_ENABLED;
3358                                         break;
3359                                 case WPA_CIPHER_TKIP:
3360                                         tmp = TKIP_ENABLED;
3361                                         break;
3362                                 case WPA_CIPHER_AES_CCM:
3363                                         tmp = AES_ENABLED;
3364                                         break;
3365                                 default:
3366                                         WL_ERR(("No Security Info\n"));
3367                         }
3368                         gval |= tmp;
3369                 }
3370         }
3371         /* Check for unicast suite(s) */
3372         if (len < WPA_IE_SUITE_COUNT_LEN) {
3373                 WL_INFO(("no unicast suite\n"));
3374                 goto exit;
3375         }
3376         /* walk thru unicast cipher list and pick up what we recognize */
3377         ucast = (wpa_suite_ucast_t *)&mcast[1];
3378         count = ltoh16_ua(&ucast->count);
3379         len -= WPA_IE_SUITE_COUNT_LEN;
3380         for (i = 0; i < count && len >= WPA_SUITE_LEN;
3381                 i++, len -= WPA_SUITE_LEN) {
3382                 if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
3383                         if (IS_WPA_CIPHER(ucast->list[i].type)) {
3384                                 tmp = 0;
3385                                 switch (ucast->list[i].type) {
3386                                         case WPA_CIPHER_NONE:
3387                                                 tmp = 0;
3388                                                 break;
3389                                         case WPA_CIPHER_WEP_40:
3390                                         case WPA_CIPHER_WEP_104:
3391                                                 tmp = WEP_ENABLED;
3392                                                 break;
3393                                         case WPA_CIPHER_TKIP:
3394                                                 tmp = TKIP_ENABLED;
3395                                                 break;
3396                                         case WPA_CIPHER_AES_CCM:
3397                                                 tmp = AES_ENABLED;
3398                                                 break;
3399                                         default:
3400                                                 WL_ERR(("No Security Info\n"));
3401                                 }
3402                                 pval |= tmp;
3403                         }
3404                 }
3405         }
3406         len -= (count - i) * WPA_SUITE_LEN;
3407         /* Check for auth key management suite(s) */
3408         if (len < WPA_IE_SUITE_COUNT_LEN) {
3409                 WL_INFO((" no auth key mgmt suite\n"));
3410                 goto exit;
3411         }
3412         /* walk thru auth management suite list and pick up what we recognize */
3413         mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count];
3414         count = ltoh16_ua(&mgmt->count);
3415         len -= WPA_IE_SUITE_COUNT_LEN;
3416         for (i = 0; i < count && len >= WPA_SUITE_LEN;
3417                 i++, len -= WPA_SUITE_LEN) {
3418                 if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
3419                         if (IS_WPA_AKM(mgmt->list[i].type)) {
3420                                 tmp = 0;
3421                                 switch (mgmt->list[i].type) {
3422                                         case RSN_AKM_NONE:
3423                                                 tmp = WPA_AUTH_NONE;
3424                                                 break;
3425                                         case RSN_AKM_UNSPECIFIED:
3426                                                 tmp = WPA_AUTH_UNSPECIFIED;
3427                                                 break;
3428                                         case RSN_AKM_PSK:
3429                                                 tmp = WPA_AUTH_PSK;
3430                                                 break;
3431                                         default:
3432                                                 WL_ERR(("No Key Mgmt Info\n"));
3433                                 }
3434                                 wpa_auth |= tmp;
3435                         }
3436                 }
3437
3438         }
3439         /* FOR WPS , set SEC_OW_ENABLED */
3440         wsec = (pval | gval | SES_OW_ENABLED);
3441         /* set auth */
3442         err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
3443         if (err < 0) {
3444                 WL_ERR(("auth error %d\n", err));
3445                 return BCME_ERROR;
3446         }
3447         /* set wsec */
3448         err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
3449         if (err < 0) {
3450                 WL_ERR(("wsec error %d\n", err));
3451                 return BCME_ERROR;
3452         }
3453         /* set upper-layer auth */
3454         err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
3455         if (err < 0) {
3456                 WL_ERR(("wpa_auth error %d\n", err));
3457                 return BCME_ERROR;
3458         }
3459 exit:
3460         return 0;
3461 }
3462
3463 static s32
3464 wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
3465         struct beacon_parameters *info)
3466 {
3467         s32 err = BCME_OK;
3468         bcm_tlv_t *ssid_ie;
3469         wlc_ssid_t ssid;
3470         struct wl_priv *wl = WL_PRIV_GET();
3471         struct wl_join_params join_params;
3472         wpa_ie_fixed_t *wps_ie;
3473         wpa_ie_fixed_t *wpa_ie;
3474         bcm_tlv_t *wpa2_ie;
3475         wifi_p2p_ie_t *p2p_ie;
3476         bool is_bssup = false;
3477         bool update_bss = false;
3478         bool pbc = false;
3479         u16 wpsie_len = 0;
3480         u16 p2pie_len = 0;
3481         u8 beacon_ie[IE_MAX_LEN];
3482         s32 ie_offset = 0;
3483         s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
3484         s32 infra = 1;
3485         s32 join_params_size = 0;
3486         s32 ap = 0;
3487         WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
3488                 info->interval, info->dtim_period, info->head_len, info->tail_len));
3489         if (wl->p2p_supported && p2p_on(wl) &&
3490                 (bssidx >= wl_to_p2p_bss_bssidx(wl,
3491                 P2PAPI_BSSCFG_CONNECTION))) {
3492                 memset(beacon_ie, 0, sizeof(beacon_ie));
3493                 /* We don't need to set beacon for P2P_GO,
3494                  * but need to parse ssid from beacon_parameters
3495                  * because there is no way to set ssid
3496                  */
3497                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3498                 /* find the SSID */
3499                 if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
3500                         info->head_len - ie_offset,
3501                         DOT11_MNG_SSID_ID)) != NULL) {
3502                         memcpy(wl->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len);
3503                         wl->p2p->ssid.SSID_len = ssid_ie->len;
3504                         WL_DBG(("SSID (%s) in Head \n", ssid_ie->data));
3505
3506                 } else {
3507                         WL_ERR(("No SSID in beacon \n"));
3508                 }
3509
3510                 /* find the WPSIE */
3511                 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
3512                         wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
3513                         /*
3514                          * Should be compared with saved ie before saving it
3515                          */
3516                         wl_validate_wps_ie((char *) wps_ie, &pbc);
3517                         memcpy(beacon_ie, wps_ie, wpsie_len);
3518                 } else {
3519                         WL_ERR(("No WPSIE in beacon \n"));
3520                 }
3521
3522
3523                 /* find the P2PIE */
3524                 if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)info->tail, info->tail_len)) != NULL) {
3525                         /* Total length of P2P Information Element */
3526                         p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
3527                 #ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
3528                         /* Have to change device address in dev_id attribute because Supplicant
3529                          * use primary eth0 address
3530                          */
3531                         wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr, P2P_SEID_DEV_ID);
3532                 #endif
3533                         memcpy(&beacon_ie[wpsie_len], p2p_ie, p2pie_len);
3534
3535                 } else {
3536                         WL_ERR(("No P2PIE in beacon \n"));
3537                 }
3538                 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3539                         beacon_ie, wpsie_len + p2pie_len);
3540                 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_ASSOCRSP_FLAG,
3541                         beacon_ie, wpsie_len + p2pie_len);
3542
3543                 /* find the RSN_IE */
3544                 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3545                         DOT11_MNG_RSN_ID)) != NULL) {
3546                         WL_DBG((" WPA2 IE is found\n"));
3547                 }
3548                 is_bssup = wl_cfgp2p_bss_isup(dev, bssidx);
3549
3550                 if (!is_bssup && (wpa2_ie != NULL)) {
3551                         if ((err = wl_validate_wpa2ie(dev, wpa2_ie, bssidx)) < 0) {
3552                                         WL_ERR(("WPA2 IE parsing error"));
3553                                         return BCME_ERROR;
3554                         }
3555                         err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
3556                         if (err < 0) {
3557                                 WL_ERR(("SET INFRA error %d\n", err));
3558                                 return err;
3559                         }
3560                         err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p->ssid,
3561                                 sizeof(wl->p2p->ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
3562                         if (err < 0) {
3563                                 WL_ERR(("GO SSID setting error %d\n", err));
3564                                 return err;
3565                         }
3566                         if ((err = wl_cfgp2p_bss(dev, bssidx, 1)) < 0) {
3567                                 WL_ERR(("GO Bring up error %d\n", err));
3568                                 return err;
3569                         }
3570                 }
3571         } else if (wl_get_drv_status(wl, AP_CREATING)) {
3572                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3573                 ap = 1;
3574                 /* find the SSID */
3575                 if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
3576                         info->head_len - ie_offset,
3577                         DOT11_MNG_SSID_ID)) != NULL) {
3578                         memset(&ssid, 0, sizeof(wlc_ssid_t));
3579                         memcpy(ssid.SSID, ssid_ie->data, ssid_ie->len);
3580                         WL_DBG(("SSID is (%s) in Head \n", ssid.SSID));
3581                         ssid.SSID_len = ssid_ie->len;
3582                         wldev_iovar_setint(dev, "mpc", 0);
3583                         wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), false);
3584                         wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
3585                         wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), false);
3586                         /* find the RSN_IE */
3587                         if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3588                                 DOT11_MNG_RSN_ID)) != NULL) {
3589                                 WL_DBG((" WPA2 IE is found\n"));
3590                         }
3591                         /* find the WPA_IE */
3592                         if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail,
3593                         info->tail_len)) != NULL) {
3594                                 WL_DBG((" WPA IE is found\n"));
3595                         }
3596                         if ((wpa_ie != NULL || wpa2_ie != NULL)) {
3597                                 if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx)  < 0 ||
3598                                         wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
3599                                         wl->ap_info->security_mode = false;
3600                                         return BCME_ERROR;
3601                                 }
3602                                 wl->ap_info->security_mode = true;
3603                                 kfree(wl->ap_info->rsn_ie);
3604                                 kfree(wl->ap_info->wpa_ie);
3605                                 kfree(wl->ap_info->wps_ie);
3606                                 if (wpa_ie != NULL) {
3607                                         /* WPAIE */
3608                                         wl->ap_info->rsn_ie = NULL;
3609                                         wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3610                                                 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3611                                                 GFP_KERNEL);
3612                                 } else {
3613                                         /* RSNIE */
3614                                         wl->ap_info->wpa_ie = NULL;
3615                                         wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3616                                                 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3617                                                 GFP_KERNEL);
3618                                 }
3619                         } else
3620                                 wl->ap_info->security_mode = false;
3621                         /* find the WPSIE */
3622                         if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail,
3623                                 info->tail_len)) != NULL) {
3624                                 wpsie_len = wps_ie->length +WPA_RSN_IE_TAG_FIXED_LEN;
3625                                 /*
3626                                 * Should be compared with saved ie before saving it
3627                                 */
3628                                 wl_validate_wps_ie((char *) wps_ie, &pbc);
3629                                 memcpy(beacon_ie, wps_ie, wpsie_len);
3630                                 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3631                                 beacon_ie, wpsie_len);
3632                                 wl->ap_info->wps_ie = kmemdup(wps_ie,   wpsie_len, GFP_KERNEL);
3633                                 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3634                                 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3635                         } else {
3636                                 WL_DBG(("No WPSIE in beacon \n"));
3637                         }
3638                         wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), false);
3639
3640                         memset(&join_params, 0, sizeof(join_params));
3641                         /* join parameters starts with ssid */
3642                         join_params_size = sizeof(join_params.ssid);
3643                         memcpy(join_params.ssid.SSID, ssid.SSID, ssid.SSID_len);
3644                         join_params.ssid.SSID_len = htod32(ssid.SSID_len);
3645                         /* create softap */
3646                         if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
3647                                 join_params_size, false)) == 0) {
3648                                 wl_clr_drv_status(wl, AP_CREATING);
3649                                 wl_set_drv_status(wl, AP_CREATED);
3650                         }
3651                 }
3652         } else if (wl_get_drv_status(wl, AP_CREATED)) {
3653                 ap = 1;
3654                 /* find the WPSIE */
3655                 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
3656                         wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
3657                         /*
3658                          * Should be compared with saved ie before saving it
3659                          */
3660                         wl_validate_wps_ie((char *) wps_ie, &pbc);
3661                         memcpy(beacon_ie, wps_ie, wpsie_len);
3662                         wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
3663                         beacon_ie, wpsie_len);
3664                         if (wl->ap_info->wps_ie &&
3665                                 memcmp(wl->ap_info->wps_ie, wps_ie, wpsie_len)) {
3666                                 WL_DBG((" WPS IE is changed\n"));
3667                                 kfree(wl->ap_info->wps_ie);
3668                                 wl->ap_info->wps_ie = kmemdup(wps_ie,   wpsie_len, GFP_KERNEL);
3669                                 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3670                                 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3671                         } else if (wl->ap_info->wps_ie == NULL) {
3672                                 WL_DBG((" WPS IE is added\n"));
3673                                 wl->ap_info->wps_ie = kmemdup(wps_ie,   wpsie_len, GFP_KERNEL);
3674                                 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
3675                                 wl_dongle_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
3676                         }
3677                         /* find the RSN_IE */
3678                         if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
3679                                 DOT11_MNG_RSN_ID)) != NULL) {
3680                                 WL_DBG((" WPA2 IE is found\n"));
3681                         }
3682                         /* find the WPA_IE */
3683                         if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail,
3684                                 info->tail_len)) != NULL) {
3685                                 WL_DBG((" WPA IE is found\n"));
3686                         }
3687                         if ((wpa_ie != NULL || wpa2_ie != NULL)) {
3688                                 if (!wl->ap_info->security_mode) {
3689                                         /* change from open mode to security mode */
3690                                         update_bss = true;
3691                                         if (wpa_ie != NULL) {
3692                                                 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3693                                                 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3694                                                 GFP_KERNEL);
3695                                         } else {
3696                                                 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3697                                                 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3698                                                 GFP_KERNEL);
3699                                         }
3700                                 } else if (wl->ap_info->wpa_ie) {
3701                                         /* change from WPA mode to WPA2 mode */
3702                                         if (wpa2_ie != NULL) {
3703                                                 update_bss = true;
3704                                                 kfree(wl->ap_info->wpa_ie);
3705                                                 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3706                                                 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3707                                                 GFP_KERNEL);
3708                                                 wl->ap_info->wpa_ie = NULL;
3709                                         }
3710                                         else if (memcmp(wl->ap_info->wpa_ie,
3711                                                 wpa_ie, wpa_ie->length +
3712                                                 WPA_RSN_IE_TAG_FIXED_LEN)) {
3713                                                 kfree(wl->ap_info->wpa_ie);
3714                                                 update_bss = true;
3715                                                 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3716                                                 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3717                                                 GFP_KERNEL);
3718                                                 wl->ap_info->rsn_ie = NULL;
3719                                         }
3720                                 } else {
3721                                         /* change from WPA2 mode to WPA mode */
3722                                         if (wpa_ie != NULL) {
3723                                                 update_bss = true;
3724                                                 kfree(wl->ap_info->rsn_ie);
3725                                                 wl->ap_info->rsn_ie = NULL;
3726                                                 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
3727                                                 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
3728                                                 GFP_KERNEL);
3729                                         } else if (memcmp(wl->ap_info->rsn_ie,
3730                                                 wpa2_ie, wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN)) {
3731                                                 update_bss = true;
3732                                                 kfree(wl->ap_info->rsn_ie);
3733                                                 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
3734                                                 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
3735                                                 GFP_KERNEL);
3736                                                 wl->ap_info->wpa_ie = NULL;
3737                                         }
3738                                 }
3739                                 if (update_bss) {
3740                                         wl->ap_info->security_mode = true;
3741                                         wl_cfgp2p_bss(dev, bssidx, 0);
3742                                         if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx)  < 0 ||
3743                                                 wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
3744                                                 return BCME_ERROR;
3745                                         }
3746                                         wl_cfgp2p_bss(dev, bssidx, 1);
3747                                 }
3748                         }
3749                 } else {
3750                         WL_ERR(("No WPSIE in beacon \n"));
3751                 }
3752         }
3753         return 0;
3754 }
3755
3756 #if defined(ANDROID_WIRELESS_PATCH)
3757 static s32
3758 wl_cfg80211_drv_start(struct wiphy *wiphy, struct net_device *dev)
3759 {
3760         /* struct wl_priv *wl = wiphy_to_wl(wiphy); */
3761         s32 err = 0;
3762
3763         printk("Android driver start command\n");
3764         return err;
3765 }
3766
3767 static s32
3768 wl_cfg80211_drv_stop(struct wiphy *wiphy, struct net_device *dev)
3769 {
3770         /* struct wl_priv *wl = wiphy_to_wl(wiphy); */
3771         s32 err = 0;
3772
3773         printk("Android driver stop command\n");
3774         return err;
3775 }
3776 #endif /* defined(ANDROID_WIRELESS_PATCH) */
3777
3778 static struct cfg80211_ops wl_cfg80211_ops = {
3779         .add_virtual_intf = wl_cfg80211_add_virtual_iface,
3780         .del_virtual_intf = wl_cfg80211_del_virtual_iface,
3781         .change_virtual_intf = wl_cfg80211_change_virtual_iface,
3782         .scan = wl_cfg80211_scan,
3783         .set_wiphy_params = wl_cfg80211_set_wiphy_params,
3784         .join_ibss = wl_cfg80211_join_ibss,
3785         .leave_ibss = wl_cfg80211_leave_ibss,
3786         .get_station = wl_cfg80211_get_station,
3787         .set_tx_power = wl_cfg80211_set_tx_power,
3788         .get_tx_power = wl_cfg80211_get_tx_power,
3789         .add_key = wl_cfg80211_add_key,
3790         .del_key = wl_cfg80211_del_key,
3791         .get_key = wl_cfg80211_get_key,
3792         .set_default_key = wl_cfg80211_config_default_key,
3793         .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
3794         .set_power_mgmt = wl_cfg80211_set_power_mgmt,
3795         .connect = wl_cfg80211_connect,
3796         .disconnect = wl_cfg80211_disconnect,
3797         .suspend = wl_cfg80211_suspend,
3798         .resume = wl_cfg80211_resume,
3799         .set_pmksa = wl_cfg80211_set_pmksa,
3800         .del_pmksa = wl_cfg80211_del_pmksa,
3801         .flush_pmksa = wl_cfg80211_flush_pmksa,
3802         .remain_on_channel = wl_cfg80211_remain_on_channel,
3803         .cancel_remain_on_channel = wl_cfg80211_cancel_remain_on_channel,
3804         .mgmt_tx = wl_cfg80211_mgmt_tx,
3805         .mgmt_frame_register = wl_cfg80211_mgmt_frame_register,
3806         .change_bss = wl_cfg80211_change_bss,
3807         .set_channel = wl_cfg80211_set_channel,
3808         .set_beacon = wl_cfg80211_set_beacon,
3809 #if defined(ANDROID_WIRELESS_PATCH)
3810         .drv_start = wl_cfg80211_drv_start,
3811         .drv_stop = wl_cfg80211_drv_stop
3812 #endif
3813 };
3814
3815 static s32 wl_mode_to_nl80211_iftype(s32 mode)
3816 {
3817         s32 err = 0;
3818
3819         switch (mode) {
3820         case WL_MODE_BSS:
3821                 return NL80211_IFTYPE_STATION;
3822         case WL_MODE_IBSS:
3823                 return NL80211_IFTYPE_ADHOC;
3824         case WL_MODE_AP:
3825                 return NL80211_IFTYPE_AP;
3826         default:
3827                 return NL80211_IFTYPE_UNSPECIFIED;
3828         }
3829
3830         return err;
3831 }
3832
3833 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
3834         struct device *dev)
3835 {
3836         struct wireless_dev *wdev;
3837         s32 err = 0;
3838         struct wl_priv *wl;
3839         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
3840         if (unlikely(!wdev)) {
3841                 WL_ERR(("Could not allocate wireless device\n"));
3842                 return ERR_PTR(-ENOMEM);
3843         }
3844         wdev->wiphy =
3845             wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
3846         if (unlikely(!wdev->wiphy)) {
3847                 WL_ERR(("Couldn not allocate wiphy device\n"));
3848                 err = -ENOMEM;
3849                 goto wiphy_new_out;
3850         }
3851         set_wiphy_dev(wdev->wiphy, dev);
3852         wl = wiphy_to_wl(wdev->wiphy);
3853         wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
3854         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3855         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3856         wdev->wiphy->interface_modes =
3857             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC)
3858             | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
3859
3860         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3861         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
3862         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3863         wdev->wiphy->cipher_suites = __wl_cipher_suites;
3864         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3865         wdev->wiphy->max_remain_on_channel_duration = 5000;
3866         wdev->wiphy->mgmt_stypes = wl_cfg80211_default_mgmt_stypes;
3867 #ifndef WL_POWERSAVE_DISABLED
3868         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
3869 #else
3870         wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3871 #endif                          /* !WL_POWERSAVE_DISABLED */
3872         wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK |
3873                 WIPHY_FLAG_4ADDR_AP |
3874 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)
3875                 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS |
3876 #endif
3877                 WIPHY_FLAG_4ADDR_STATION;
3878
3879         WL_DBG(("Registering custom regulatory)\n"));
3880         wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
3881         wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
3882         /* Now we can register wiphy with cfg80211 module */
3883         err = wiphy_register(wdev->wiphy);
3884         if (unlikely(err < 0)) {
3885                 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
3886                 goto wiphy_register_out;
3887         }
3888         return wdev;
3889
3890 wiphy_register_out:
3891         wiphy_free(wdev->wiphy);
3892
3893 wiphy_new_out:
3894         kfree(wdev);
3895
3896         return ERR_PTR(err);
3897 }
3898
3899 static void wl_free_wdev(struct wl_priv *wl)
3900 {
3901         int i;
3902         struct wireless_dev *wdev = wl_to_wdev(wl);
3903
3904         if (unlikely(!wdev)) {
3905                 WL_ERR(("wdev is invalid\n"));
3906                 return;
3907         }
3908
3909         for (i = 0; i < VWDEV_CNT; i++) {
3910                 if ((wl->vwdev[i] != NULL)) {
3911                         kfree(wl->vwdev[i]);
3912                         wl->vwdev[i] = NULL;
3913                 }
3914         }
3915         wiphy_unregister(wdev->wiphy);
3916         wiphy_free(wdev->wiphy);
3917         kfree(wdev);
3918         wl_to_wdev(wl) = NULL;
3919 }
3920
3921 static s32 wl_inform_bss(struct wl_priv *wl)
3922 {
3923         struct wl_scan_results *bss_list;
3924         struct wl_bss_info *bi = NULL;  /* must be initialized */
3925         s32 err = 0;
3926         s32 i;
3927
3928         bss_list = wl->bss_list;
3929 #if 0
3930         if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
3931                 WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
3932                         bss_list->version));
3933                 return -EOPNOTSUPP;
3934         }
3935 #endif
3936         WL_DBG(("scanned AP count (%d)\n", bss_list->count));
3937         bi = next_bss(bss_list, bi);
3938         for_each_bss(bss_list, bi, i) {
3939                 err = wl_inform_single_bss(wl, bi);
3940                 if (unlikely(err))
3941                         break;
3942         }
3943         return err;
3944 }
3945
3946 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
3947 {
3948         struct wiphy *wiphy = wiphy_from_scan(wl);
3949         struct ieee80211_mgmt *mgmt;
3950         struct ieee80211_channel *channel;
3951         struct ieee80211_supported_band *band;
3952         struct wl_cfg80211_bss_info *notif_bss_info;
3953         struct wl_scan_req *sr = wl_to_sr(wl);
3954         struct beacon_proberesp *beacon_proberesp;
3955         s32 mgmt_type;
3956         u32 signal;
3957         u32 freq;
3958         s32 err = 0;
3959
3960         if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
3961                 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
3962                 return err;
3963         }
3964         notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt)
3965                 - sizeof(u8) + WL_BSS_INFO_MAX, GFP_KERNEL);
3966         if (unlikely(!notif_bss_info)) {
3967                 WL_ERR(("notif_bss_info alloc failed\n"));
3968                 return -ENOMEM;
3969         }
3970         mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
3971         notif_bss_info->channel =
3972                 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
3973
3974         if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
3975                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
3976         else
3977                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
3978         notif_bss_info->rssi = bi->RSSI;
3979         memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
3980         mgmt_type = wl->active_scan ?
3981                 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
3982         if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
3983             mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type);
3984         }
3985         beacon_proberesp = wl->active_scan ?
3986                 (struct beacon_proberesp *)&mgmt->u.probe_resp :
3987                 (struct beacon_proberesp *)&mgmt->u.beacon;
3988         beacon_proberesp->timestamp = 0;
3989         beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
3990         beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
3991         wl_rst_ie(wl);
3992         /*
3993         * wl_add_ie is not necessary because it can only add duplicated
3994         * SSID, rate information to frame_buf
3995         */
3996         /*
3997         * wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
3998         * wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
3999         * bi->rateset.rates);
4000         */
4001         wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
4002         wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
4003                 offsetof(struct wl_cfg80211_bss_info, frame_buf));
4004         notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
4005                 u.beacon.variable) + wl_get_ielen(wl);
4006 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4007         freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
4008 #else
4009         freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
4010 #endif
4011         channel = ieee80211_get_channel(wiphy, freq);
4012
4013         WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
4014                 bi->SSID,
4015                 notif_bss_info->rssi, notif_bss_info->channel,
4016                 mgmt->u.beacon.capab_info, &bi->BSSID));
4017
4018         signal = notif_bss_info->rssi * 100;
4019         if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
4020                 le16_to_cpu
4021                 (notif_bss_info->frame_len),
4022                 signal, GFP_KERNEL))) {
4023                 WL_ERR(("cfg80211_inform_bss_frame error\n"));
4024                 kfree(notif_bss_info);
4025                 return -EINVAL;
4026         }
4027         kfree(notif_bss_info);
4028
4029         return err;
4030 }
4031
4032 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev)
4033 {
4034         u32 event = ntoh32(e->event_type);
4035         u32 status =  ntoh32(e->status);
4036         u16 flags = ntoh16(e->flags);
4037
4038         WL_DBG(("event %d, status %d\n", event, status));
4039         if (event == WLC_E_SET_SSID) {
4040                 if (status == WLC_E_STATUS_SUCCESS) {
4041                         if (!wl_is_ibssmode(wl, ndev))
4042                                 return true;
4043                 }
4044         } else if (event == WLC_E_LINK) {
4045                 if (flags & WLC_EVENT_MSG_LINK)
4046                         return true;
4047         }
4048
4049         WL_DBG(("wl_is_linkup false\n"));
4050         return false;
4051 }
4052
4053 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
4054 {
4055         u32 event = ntoh32(e->event_type);
4056         u16 flags = ntoh16(e->flags);
4057
4058         if (event == WLC_E_DEAUTH_IND ||
4059         event == WLC_E_DISASSOC_IND ||
4060         event == WLC_E_DISASSOC ||
4061         event == WLC_E_DEAUTH) {
4062                 return true;
4063         } else if (event == WLC_E_LINK) {
4064                 if (!(flags & WLC_EVENT_MSG_LINK))
4065                         return true;
4066         }
4067
4068         return false;
4069 }
4070
4071 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
4072 {
4073         u32 event = ntoh32(e->event_type);
4074         u32 status = ntoh32(e->status);
4075
4076         if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS)
4077                 return true;
4078         if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS)
4079                 return true;
4080
4081         return false;
4082 }
4083
4084 static s32
4085 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
4086         const wl_event_msg_t *e, void *data)
4087 {
4088         bool act;
4089         bool isfree = false;
4090         s32 err = 0;
4091         s32 freq;
4092         s32 channel;
4093         u8 body[200];
4094         u32 event = ntoh32(e->event_type);
4095         u32 reason = ntoh32(e->reason);
4096         u32 len = ntoh32(e->datalen);
4097         u16 fc = 0;
4098         u8 *mgmt_frame;
4099         u8 bsscfgidx = e->bsscfgidx;
4100         struct ieee80211_supported_band *band;
4101         struct ether_addr da;
4102         struct ether_addr bssid;
4103         struct wiphy *wiphy = wl_to_wiphy(wl);
4104         channel_info_t ci;
4105
4106         memset(body, 0, sizeof(body));
4107         WL_DBG(("Enter \n"));
4108
4109         if (get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
4110                 memcpy(body, data, len);
4111                 wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
4112                 &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
4113                 wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
4114                 switch (event) {
4115                         case WLC_E_ASSOC_IND:
4116                                 fc = FC_ASSOC_REQ;
4117                                 break;
4118                         case WLC_E_REASSOC_IND:
4119                                 fc = FC_REASSOC_REQ;
4120                                 break;
4121                         case WLC_E_DISASSOC_IND:
4122                                 fc = FC_DISASSOC;
4123                                 break;
4124                         case WLC_E_DEAUTH_IND:
4125                                 fc = FC_DEAUTH;
4126                                 break;
4127                         case WLC_E_DEAUTH:
4128                                 fc = FC_DEAUTH;
4129                                 break;
4130                         default:
4131                                 fc = 0;
4132                                 goto exit;
4133                 }
4134                 if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
4135                         return err;
4136
4137                 channel = dtoh32(ci.hw_channel);
4138                 if (channel <= CH_MAX_2G_CHANNEL)
4139                         band = wiphy->bands[IEEE80211_BAND_2GHZ];
4140                 else
4141                         band = wiphy->bands[IEEE80211_BAND_5GHZ];
4142
4143 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4144                 freq = ieee80211_channel_to_frequency(channel);
4145 #else
4146                 freq = ieee80211_channel_to_frequency(channel, band->band);
4147 #endif
4148
4149                 err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
4150                 &mgmt_frame, &len, body);
4151                 if (err < 0)
4152                                 goto exit;
4153                 isfree = true;
4154
4155                 if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
4156                         cfg80211_send_rx_assoc(ndev, mgmt_frame, len);
4157                 } else if (event == WLC_E_DISASSOC_IND) {
4158                         cfg80211_send_disassoc(ndev, mgmt_frame, len);
4159                 } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
4160                         cfg80211_send_deauth(ndev, mgmt_frame, len);
4161                 }
4162
4163         } else {
4164                 WL_DBG(("wl_notify_connect_status : event %d status : %d \n",
4165                         ntoh32(e->event_type), ntoh32(e->status)));
4166                 if (wl_is_linkup(wl, e, ndev)) {
4167                         wl_link_up(wl);
4168                         if (wl_is_ibssmode(wl, ndev)) {
4169                                 printk("cfg80211_ibss_joined");
4170                                 cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
4171                                         GFP_KERNEL);
4172                                 WL_DBG(("joined in IBSS network\n"));
4173                         } else {
4174                                 printk("wl_bss_connect_done succeeded");
4175                                 wl_bss_connect_done(wl, ndev, e, data, true);
4176                                 WL_DBG(("joined in BSS network \"%s\"\n",
4177                                         ((struct wlc_ssid *)
4178                                          wl_read_prof(wl, WL_PROF_SSID))->SSID));
4179                         }
4180                         act = true;
4181                         wl_update_prof(wl, e, &act, WL_PROF_ACT);
4182                 } else if (wl_is_linkdown(wl, e)) {
4183                         if (wl_get_drv_status(wl, CONNECTED)) {
4184                                 printk("link down, call cfg80211_disconnected ");
4185                                 rtnl_lock();
4186                                 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
4187                                 wl_clr_drv_status(wl, CONNECTED);
4188                                 wl_link_down(wl);
4189                                 wl_init_prof(wl->profile);
4190                                 rtnl_unlock();
4191                         } else if (wl_get_drv_status(wl, CONNECTING)) {
4192                                 printk("link down, during connecting");
4193                                 wl_bss_connect_done(wl, ndev, e, data, false);
4194                         }
4195                 } else if (wl_is_nonetwork(wl, e)) {
4196                         printk("connect failed e->status 0x%x", (int)ntoh32(e->status));
4197                         if (wl_get_drv_status(wl, CONNECTING))
4198                                 wl_bss_connect_done(wl, ndev, e, data, false);
4199                 } else {
4200                         printk("%s nothing\n", __FUNCTION__);
4201                 }
4202                 printk("\n");
4203         }
4204 exit:
4205         if (isfree)
4206                 kfree(mgmt_frame);
4207         return err;
4208 }
4209
4210 static s32
4211 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
4212         const wl_event_msg_t *e, void *data)
4213 {
4214         bool act;
4215         s32 err = 0;
4216         u32 event = be32_to_cpu(e->event_type);
4217         u32 status = be32_to_cpu(e->status);
4218
4219         WL_DBG(("Enter \n"));
4220         if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
4221                 if (test_bit(WL_STATUS_CONNECTED, &wl->status))
4222                         wl_bss_roaming_done(wl, ndev, e, data);
4223                 else
4224                         wl_bss_connect_done(wl, ndev, e, data, true);
4225                 act = true;
4226                 wl_update_prof(wl, e, &act, WL_PROF_ACT);
4227         }
4228
4229         return err;
4230 }
4231
4232 static __used s32
4233 wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
4234 {
4235         struct wl_priv *wl = WL_PRIV_GET();
4236         u32 buflen;
4237
4238         buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
4239         BUG_ON(unlikely(!buflen));
4240
4241         return wldev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen, false);
4242 }
4243
4244 static s32
4245 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
4246         s32 buf_len)
4247 {
4248         struct wl_priv *wl = WL_PRIV_GET();
4249         u32 len;
4250         s32 err = 0;
4251
4252         len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
4253         BUG_ON(unlikely(!len));
4254         err = wldev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
4255                 WL_IOCTL_LEN_MAX, false);
4256         if (unlikely(err)) {
4257                 WL_ERR(("error (%d)\n", err));
4258                 return err;
4259         }
4260         memcpy(buf, wl->ioctl_buf, buf_len);
4261
4262         return err;
4263 }
4264
4265 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
4266 {
4267         wl_assoc_info_t assoc_info;
4268         struct wl_connect_info *conn_info = wl_to_conn(wl);
4269         s32 err = 0;
4270
4271         WL_DBG(("Enter \n"));
4272         err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
4273                 WL_ASSOC_INFO_MAX);
4274         if (unlikely(err)) {
4275                 WL_ERR(("could not get assoc info (%d)\n", err));
4276                 return err;
4277         }
4278         memcpy(&assoc_info, wl->extra_buf, sizeof(wl_assoc_info_t));
4279         assoc_info.req_len = htod32(assoc_info.req_len);
4280         assoc_info.resp_len = htod32(assoc_info.resp_len);
4281         assoc_info.flags = htod32(assoc_info.flags);
4282         if (assoc_info.req_len) {
4283                 err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
4284                         WL_ASSOC_INFO_MAX);
4285                 if (unlikely(err)) {
4286                         WL_ERR(("could not get assoc req (%d)\n", err));
4287                         return err;
4288                 }
4289                 conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req);
4290                 if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
4291                         conn_info->req_ie_len -= ETHER_ADDR_LEN;
4292                 }
4293                 conn_info->req_ie =
4294                     kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
4295         } else {
4296                 conn_info->req_ie_len = 0;
4297                 conn_info->req_ie = NULL;
4298         }
4299         if (assoc_info.resp_len) {
4300                 err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
4301                         WL_ASSOC_INFO_MAX);
4302                 if (unlikely(err)) {
4303                         WL_ERR(("could not get assoc resp (%d)\n", err));
4304                         return err;
4305                 }
4306                 conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
4307                 conn_info->resp_ie =
4308                     kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
4309         } else {
4310                 conn_info->resp_ie_len = 0;
4311                 conn_info->resp_ie = NULL;
4312         }
4313         WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
4314                 conn_info->resp_ie_len));
4315
4316         return err;
4317 }
4318
4319 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
4320         size_t *join_params_size)
4321 {
4322         chanspec_t chanspec = 0;
4323
4324         if (ch != 0) {
4325                 join_params->params.chanspec_num = 1;
4326                 join_params->params.chanspec_list[0] = ch;
4327
4328                 if (join_params->params.chanspec_list[0])
4329                         chanspec |= WL_CHANSPEC_BAND_2G;
4330                 else
4331                         chanspec |= WL_CHANSPEC_BAND_5G;
4332
4333                 chanspec |= WL_CHANSPEC_BW_20;
4334                 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
4335
4336                 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
4337                         join_params->params.chanspec_num * sizeof(chanspec_t);
4338
4339                 join_params->params.chanspec_list[0]  &= WL_CHANSPEC_CHAN_MASK;
4340                 join_params->params.chanspec_list[0] |= chanspec;
4341                 join_params->params.chanspec_list[0] =
4342                         htodchanspec(join_params->params.chanspec_list[0]);
4343
4344                 join_params->params.chanspec_num =
4345                         htod32(join_params->params.chanspec_num);
4346
4347                 WL_DBG(("%s  join_params->params.chanspec_list[0]= %X\n",
4348                         __FUNCTION__, join_params->params.chanspec_list[0]));
4349
4350         }
4351 }
4352
4353 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev)
4354 {
4355         struct cfg80211_bss *bss;
4356         struct wl_bss_info *bi;
4357         struct wlc_ssid *ssid;
4358         struct bcm_tlv *tim;
4359         u16 beacon_interval;
4360         u8 dtim_period;
4361         size_t ie_len;
4362         u8 *ie;
4363         s32 err = 0;
4364         struct wiphy *wiphy;
4365         wiphy = wl_to_wiphy(wl);
4366
4367         if (wl_is_ibssmode(wl, ndev))
4368                 return err;
4369
4370         ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
4371         bss = cfg80211_get_bss(wiphy, NULL, (s8 *)&wl->bssid,
4372                 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
4373                 WLAN_CAPABILITY_ESS);
4374
4375         rtnl_lock();
4376         if (unlikely(!bss)) {
4377                 WL_DBG(("Could not find the AP\n"));
4378                 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
4379                 err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_BSS_INFO,
4380                         wl->extra_buf, WL_EXTRA_BUF_MAX, false);
4381                 if (unlikely(err)) {
4382                         WL_ERR(("Could not get bss info %d\n", err));
4383                         goto update_bss_info_out;
4384                 }
4385                 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
4386                 if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
4387                         err = -EIO;
4388                         goto update_bss_info_out;
4389                 }
4390                 err = wl_inform_single_bss(wl, bi);
4391                 if (unlikely(err))
4392                         goto update_bss_info_out;
4393
4394                 ie = ((u8 *)bi) + bi->ie_offset;
4395                 ie_len = bi->ie_length;
4396                 beacon_interval = cpu_to_le16(bi->beacon_period);
4397         } else {
4398                 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
4399                 ie = bss->information_elements;
4400                 ie_len = bss->len_information_elements;
4401                 beacon_interval = bss->beacon_interval;
4402                 cfg80211_put_bss(bss);
4403         }
4404
4405         tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
4406         if (tim) {
4407                 dtim_period = tim->data[1];
4408         } else {
4409                 /*
4410                 * active scan was done so we could not get dtim
4411                 * information out of probe response.
4412                 * so we speficially query dtim information to dongle.
4413                 */
4414                 err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_DTIMPRD,
4415                         &dtim_period, sizeof(dtim_period), false);
4416                 if (unlikely(err)) {
4417                         WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
4418                         goto update_bss_info_out;
4419                 }
4420         }
4421
4422         wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
4423         wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
4424
4425 update_bss_info_out:
4426         rtnl_unlock();
4427         return err;
4428 }
4429
4430 static s32
4431 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
4432         const wl_event_msg_t *e, void *data)
4433 {
4434         struct wl_connect_info *conn_info = wl_to_conn(wl);
4435         s32 err = 0;
4436
4437         wl_get_assoc_ies(wl, ndev);
4438         memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
4439         wl_update_bss_info(wl, ndev);
4440         cfg80211_roamed(ndev,
4441 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
4442                 NULL,
4443 #endif
4444                 (u8 *)&wl->bssid,
4445                 conn_info->req_ie, conn_info->req_ie_len,
4446                 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4447         WL_DBG(("Report roaming result\n"));
4448
4449         wl_set_drv_status(wl, CONNECTED);
4450
4451         return err;
4452 }
4453
4454 static s32
4455 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
4456         const wl_event_msg_t *e, void *data, bool completed)
4457 {
4458         struct wl_connect_info *conn_info = wl_to_conn(wl);
4459         s32 err = 0;
4460
4461         WL_DBG((" enter\n"));
4462         wl_get_assoc_ies(wl, ndev);
4463         memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
4464         wl_update_bss_info(wl, ndev);
4465         if (wl_get_drv_status(wl, CONNECTING)) {
4466                 wl_clr_drv_status(wl, CONNECTING);
4467                 cfg80211_connect_result(ndev,
4468                         (u8 *)&wl->bssid,
4469                         conn_info->req_ie,
4470                         conn_info->req_ie_len,
4471                         conn_info->resp_ie,
4472                         conn_info->resp_ie_len,
4473                         completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
4474                         GFP_KERNEL);
4475                 WL_DBG(("Report connect result - connection %s\n",
4476                         completed ? "succeeded" : "failed"));
4477         }
4478         if (completed)
4479                 wl_set_drv_status(wl, CONNECTED);
4480         else {
4481                 if (wl->scan_request) {
4482                         wl_cfg80211_scan_abort(wl, ndev);
4483                 }
4484         }
4485
4486         return err;
4487 }
4488
4489 static s32
4490 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
4491         const wl_event_msg_t *e, void *data)
4492 {
4493         u16 flags = ntoh16(e->flags);
4494         enum nl80211_key_type key_type;
4495
4496         rtnl_lock();
4497         if (flags & WLC_EVENT_MSG_GROUP)
4498                 key_type = NL80211_KEYTYPE_GROUP;
4499         else
4500                 key_type = NL80211_KEYTYPE_PAIRWISE;
4501
4502         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
4503                 NULL, GFP_KERNEL);
4504         rtnl_unlock();
4505
4506         return 0;
4507 }
4508
4509 static s32
4510 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
4511         const wl_event_msg_t *e, void *data)
4512 {
4513         struct channel_info channel_inform;
4514         struct wl_scan_results *bss_list;
4515         u32 len = WL_SCAN_BUF_MAX;
4516         s32 err = 0;
4517
4518         WL_DBG(("Enter \n"));
4519         if (wl->iscan_on && wl->iscan_kickstart)
4520                 return wl_wakeup_iscan(wl_to_iscan(wl));
4521
4522         if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
4523                 wl_clr_drv_status(wl, SCANNING);
4524                 WL_DBG(("Scan complete while device not scanning\n"));
4525                 return -EINVAL;
4526         }
4527         wl_clr_drv_status(wl, SCANNING);
4528         rtnl_lock();
4529         err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
4530                 sizeof(channel_inform), false);
4531         if (unlikely(err)) {
4532                 WL_ERR(("scan busy (%d)\n", err));
4533                 goto scan_done_out;
4534         }
4535         channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
4536         if (unlikely(channel_inform.scan_channel)) {
4537
4538                 WL_DBG(("channel_inform.scan_channel (%d)\n",
4539                         channel_inform.scan_channel));
4540         }
4541         wl->bss_list = wl->scan_results;
4542         bss_list = wl->bss_list;
4543         memset(bss_list, 0, len);
4544         bss_list->buflen = htod32(len);
4545         err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, false);
4546         if (unlikely(err)) {
4547                 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
4548                 err = -EINVAL;
4549                 goto scan_done_out;
4550         }
4551         bss_list->buflen = dtoh32(bss_list->buflen);
4552         bss_list->version = dtoh32(bss_list->version);
4553         bss_list->count = dtoh32(bss_list->count);
4554
4555         err = wl_inform_bss(wl);
4556         if (err)
4557                 goto scan_done_out;
4558
4559 scan_done_out:
4560         if (wl->scan_request) {
4561                 WL_DBG(("cfg80211_scan_done\n"));
4562                 cfg80211_scan_done(wl->scan_request, false);
4563                 wl->scan_request = NULL;
4564         }
4565         rtnl_unlock();
4566         return err;
4567 }
4568 static s32
4569 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
4570         const struct ether_addr *sa, const struct ether_addr *bssid,
4571         u8 **pheader, u32 *body_len, u8 *pbody)
4572 {
4573         struct dot11_management_header *hdr;
4574         u32 totlen = 0;
4575         s32 err = 0;
4576         u8 *offset;
4577         u32 prebody_len = *body_len;
4578         switch (fc) {
4579                 case FC_ASSOC_REQ:
4580                         /* capability , listen interval */
4581                         totlen = DOT11_ASSOC_REQ_FIXED_LEN;
4582                         *body_len += DOT11_ASSOC_REQ_FIXED_LEN;
4583                         break;
4584
4585                 case FC_REASSOC_REQ:
4586                         /* capability, listen inteval, ap address */
4587                         totlen = DOT11_REASSOC_REQ_FIXED_LEN;
4588                         *body_len += DOT11_REASSOC_REQ_FIXED_LEN;
4589                         break;
4590         }
4591         totlen += DOT11_MGMT_HDR_LEN + prebody_len;
4592         *pheader = kzalloc(totlen, GFP_KERNEL);
4593         if (*pheader == NULL) {
4594                 WL_ERR(("memory alloc failed \n"));
4595                 return -ENOMEM;
4596         }
4597         hdr = (struct dot11_management_header *) (*pheader);
4598         hdr->fc = htol16(fc);
4599         hdr->durid = 0;
4600         hdr->seq = 0;
4601         offset = (u8*)(hdr + 1) + (totlen - DOT11_MGMT_HDR_LEN - prebody_len);
4602         bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN);
4603         bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN);
4604         bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN);
4605         bcopy((const char*)pbody, offset, prebody_len);
4606         *body_len = totlen;
4607         return err;
4608 }
4609 static s32
4610 wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
4611         const wl_event_msg_t *e, void *data)
4612 {
4613         struct ieee80211_supported_band *band;
4614         struct wiphy *wiphy = wl_to_wiphy(wl);
4615         struct ether_addr da;
4616         struct ether_addr bssid;
4617         bool isfree = false;
4618         s32 err = 0;
4619         s32 freq;
4620         wl_event_rx_frame_data_t *rxframe =
4621                 (wl_event_rx_frame_data_t*)data;
4622         u32 event = ntoh32(e->event_type);
4623         u8 *mgmt_frame;
4624         u8 bsscfgidx = e->bsscfgidx;
4625         u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t);
4626         u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK) & 0x0f);
4627         if (channel <= CH_MAX_2G_CHANNEL)
4628                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4629         else
4630                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4631
4632 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4633         freq = ieee80211_channel_to_frequency(channel);
4634 #else
4635         freq = ieee80211_channel_to_frequency(channel, band->band);
4636 #endif
4637         if (event == WLC_E_ACTION_FRAME_RX) {
4638                 wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
4639                 &da, sizeof(struct ether_addr), ioctlbuf, sizeof(ioctlbuf), bsscfgidx);
4640                 wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
4641                 err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid,
4642                         &mgmt_frame, &mgmt_frame_len,
4643                         (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1));
4644                 if (err < 0) {
4645                         WL_ERR(("%s: Error in receiving action frame len %d channel %d freq %d\n",
4646                                 __func__, mgmt_frame_len, channel, freq));
4647                         goto exit;
4648                 }
4649                 isfree = true;
4650         } else {
4651                 mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
4652         }
4653
4654         cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
4655
4656         WL_DBG(("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__,
4657                 mgmt_frame_len, ntoh32(e->datalen), channel, freq));
4658
4659         if (isfree)
4660                 kfree(mgmt_frame);
4661 exit:
4662         return 0;
4663 }
4664
4665 static void wl_init_conf(struct wl_conf *conf)
4666 {
4667         s32 i = 0;
4668         WL_DBG(("Enter \n"));
4669         for (i = 0; i <= VWDEV_CNT; i++) {
4670                 conf->mode[i].type = -1;
4671                 conf->mode[i].ndev = NULL;
4672         }
4673         conf->frag_threshold = (u32)-1;
4674         conf->rts_threshold = (u32)-1;
4675         conf->retry_short = (u32)-1;
4676         conf->retry_long = (u32)-1;
4677         conf->tx_power = -1;
4678 }
4679
4680 static void wl_init_prof(struct wl_profile *prof)
4681 {
4682         memset(prof, 0, sizeof(*prof));
4683 }
4684
4685 static void wl_init_event_handler(struct wl_priv *wl)
4686 {
4687         memset(wl->evt_handler, 0, sizeof(wl->evt_handler));
4688
4689         wl->evt_handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
4690         /* wl->evt_handler[WLC_E_JOIN] = wl_notify_connect_status; */
4691         wl->evt_handler[WLC_E_LINK] = wl_notify_connect_status;
4692         wl->evt_handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
4693         wl->evt_handler[WLC_E_DEAUTH] = wl_notify_connect_status;
4694         wl->evt_handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
4695         wl->evt_handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
4696         wl->evt_handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
4697         wl->evt_handler[WLC_E_ROAM] = wl_notify_roaming_status;
4698         wl->evt_handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
4699         wl->evt_handler[WLC_E_SET_SSID] = wl_notify_connect_status;
4700         wl->evt_handler[WLC_E_ACTION_FRAME_RX] = wl_notify_rx_mgmt_frame;
4701         wl->evt_handler[WLC_E_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
4702         wl->evt_handler[WLC_E_P2P_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
4703         wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete;
4704         wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
4705         wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
4706
4707 }
4708
4709 static s32 wl_init_priv_mem(struct wl_priv *wl)
4710 {
4711         WL_DBG(("Enter \n"));
4712         wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
4713         if (unlikely(!wl->scan_results)) {
4714                 WL_ERR(("Scan results alloc failed\n"));
4715                 goto init_priv_mem_out;
4716         }
4717         wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
4718         if (unlikely(!wl->conf)) {
4719                 WL_ERR(("wl_conf alloc failed\n"));
4720                 goto init_priv_mem_out;
4721         }
4722         wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
4723         if (unlikely(!wl->profile)) {
4724                 WL_ERR(("wl_profile alloc failed\n"));
4725                 goto init_priv_mem_out;
4726         }
4727         wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4728         if (unlikely(!wl->bss_info)) {
4729                 WL_ERR(("Bss information alloc failed\n"));
4730                 goto init_priv_mem_out;
4731         }
4732         wl->scan_req_int =
4733             (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
4734         if (unlikely(!wl->scan_req_int)) {
4735                 WL_ERR(("Scan req alloc failed\n"));
4736                 goto init_priv_mem_out;
4737         }
4738         wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
4739         if (unlikely(!wl->ioctl_buf)) {
4740                 WL_ERR(("Ioctl buf alloc failed\n"));
4741                 goto init_priv_mem_out;
4742         }
4743         wl->escan_ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
4744         if (unlikely(!wl->escan_ioctl_buf)) {
4745                 WL_ERR(("Ioctl buf alloc failed\n"));
4746                 goto init_priv_mem_out;
4747         }
4748         wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4749         if (unlikely(!wl->extra_buf)) {
4750                 WL_ERR(("Extra buf alloc failed\n"));
4751                 goto init_priv_mem_out;
4752         }
4753         wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
4754         if (unlikely(!wl->iscan)) {
4755                 WL_ERR(("Iscan buf alloc failed\n"));
4756                 goto init_priv_mem_out;
4757         }
4758         wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
4759         if (unlikely(!wl->fw)) {
4760                 WL_ERR(("fw object alloc failed\n"));
4761                 goto init_priv_mem_out;
4762         }
4763         wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
4764         if (unlikely(!wl->pmk_list)) {
4765                 WL_ERR(("pmk list alloc failed\n"));
4766                 goto init_priv_mem_out;
4767         }
4768
4769         return 0;
4770
4771 init_priv_mem_out:
4772         wl_deinit_priv_mem(wl);
4773
4774         return -ENOMEM;
4775 }
4776
4777 static void wl_deinit_priv_mem(struct wl_priv *wl)
4778 {
4779         kfree(wl->scan_results);
4780         wl->scan_results = NULL;
4781         kfree(wl->bss_info);
4782         wl->bss_info = NULL;
4783         kfree(wl->conf);
4784         wl->conf = NULL;
4785         kfree(wl->profile);
4786         wl->profile = NULL;
4787         kfree(wl->scan_req_int);
4788         wl->scan_req_int = NULL;
4789         kfree(wl->ioctl_buf);
4790         wl->ioctl_buf = NULL;
4791         kfree(wl->escan_ioctl_buf);
4792         wl->escan_ioctl_buf = NULL;
4793         kfree(wl->extra_buf);
4794         wl->extra_buf = NULL;
4795         kfree(wl->iscan);
4796         wl->iscan = NULL;
4797         kfree(wl->fw);
4798         wl->fw = NULL;
4799         kfree(wl->pmk_list);
4800         wl->pmk_list = NULL;
4801         if (wl->ap_info) {
4802                 kfree(wl->ap_info->wpa_ie);
4803                 kfree(wl->ap_info->rsn_ie);
4804                 kfree(wl->ap_info->wps_ie);
4805                 kfree(wl->ap_info);
4806                 wl->ap_info = NULL;
4807         }
4808 }
4809
4810 static s32 wl_create_event_handler(struct wl_priv *wl)
4811 {
4812         WL_DBG(("Enter \n"));
4813         sema_init(&wl->event_sync, 0);
4814         wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
4815         if (IS_ERR(wl->event_tsk)) {
4816                 wl->event_tsk = NULL;
4817                 WL_ERR(("failed to create event thread\n"));
4818                 return -ENOMEM;
4819         }
4820         return 0;
4821 }
4822
4823 static void wl_destroy_event_handler(struct wl_priv *wl)
4824 {
4825         if (wl->event_tsk) {
4826                 send_sig(SIGTERM, wl->event_tsk, 1);
4827                 kthread_stop(wl->event_tsk);
4828                 wl->event_tsk = NULL;
4829         }
4830 }
4831
4832 static void wl_term_iscan(struct wl_priv *wl)
4833 {
4834         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
4835         WL_TRACE(("In\n"));
4836         if (wl->iscan_on && iscan->tsk) {
4837                 iscan->state = WL_ISCAN_STATE_IDLE;
4838                 WL_INFO(("SIGTERM\n"));
4839                 send_sig(SIGTERM, iscan->tsk, 1);
4840                 WL_DBG(("kthread_stop\n"));
4841                 kthread_stop(iscan->tsk);
4842                 iscan->tsk = NULL;
4843         }
4844 }
4845
4846 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
4847 {
4848         struct wl_priv *wl = iscan_to_wl(iscan);
4849
4850         WL_DBG(("Enter \n"));
4851         if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
4852                 wl_clr_drv_status(wl, SCANNING);
4853                 WL_ERR(("Scan complete while device not scanning\n"));
4854                 return;
4855         }
4856         wl_clr_drv_status(wl, SCANNING);
4857         if (likely(wl->scan_request)) {
4858                 cfg80211_scan_done(wl->scan_request, aborted);
4859                 wl->scan_request = NULL;
4860         }
4861         wl->iscan_kickstart = false;
4862 }
4863
4864 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
4865 {
4866         if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
4867                 WL_DBG(("wake up iscan\n"));
4868                 up(&iscan->sync);
4869                 return 0;
4870         }
4871
4872         return -EIO;
4873 }
4874
4875 static s32
4876 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
4877         struct wl_scan_results **bss_list)
4878 {
4879         struct wl_iscan_results list;
4880         struct wl_scan_results *results;
4881         struct wl_iscan_results *list_buf;
4882         s32 err = 0;
4883
4884         WL_DBG(("Enter \n"));
4885         memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
4886         list_buf = (struct wl_iscan_results *)iscan->scan_buf;
4887         results = &list_buf->results;
4888         results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
4889         results->version = 0;
4890         results->count = 0;
4891
4892         memset(&list, 0, sizeof(list));
4893         list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
4894         err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list,
4895                 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
4896                 WL_ISCAN_BUF_MAX);
4897         if (unlikely(err)) {
4898                 WL_ERR(("error (%d)\n", err));
4899                 return err;
4900         }
4901         results->buflen = dtoh32(results->buflen);
4902         results->version = dtoh32(results->version);
4903         results->count = dtoh32(results->count);
4904         WL_DBG(("results->count = %d\n", results->count));
4905         WL_DBG(("results->buflen = %d\n", results->buflen));
4906         *status = dtoh32(list_buf->status);
4907         *bss_list = results;
4908
4909         return err;
4910 }
4911
4912 static s32 wl_iscan_done(struct wl_priv *wl)
4913 {
4914         struct wl_iscan_ctrl *iscan = wl->iscan;
4915         s32 err = 0;
4916
4917         iscan->state = WL_ISCAN_STATE_IDLE;
4918         rtnl_lock();
4919         wl_inform_bss(wl);
4920         wl_notify_iscan_complete(iscan, false);
4921         rtnl_unlock();
4922
4923         return err;
4924 }
4925
4926 static s32 wl_iscan_pending(struct wl_priv *wl)
4927 {
4928         struct wl_iscan_ctrl *iscan = wl->iscan;
4929         s32 err = 0;
4930
4931         /* Reschedule the timer */
4932         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
4933         iscan->timer_on = 1;
4934
4935         return err;
4936 }
4937
4938 static s32 wl_iscan_inprogress(struct wl_priv *wl)
4939 {
4940         struct wl_iscan_ctrl *iscan = wl->iscan;
4941         s32 err = 0;
4942
4943         rtnl_lock();
4944         wl_inform_bss(wl);
4945         wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
4946         rtnl_unlock();
4947         /* Reschedule the timer */
4948         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
4949         iscan->timer_on = 1;
4950
4951         return err;
4952 }
4953
4954 static s32 wl_iscan_aborted(struct wl_priv *wl)
4955 {
4956         struct wl_iscan_ctrl *iscan = wl->iscan;
4957         s32 err = 0;
4958
4959         iscan->state = WL_ISCAN_STATE_IDLE;
4960         rtnl_lock();
4961         wl_notify_iscan_complete(iscan, true);
4962         rtnl_unlock();
4963
4964         return err;
4965 }
4966
4967 static s32 wl_iscan_thread(void *data)
4968 {
4969         struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
4970         struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
4971         struct wl_priv *wl = iscan_to_wl(iscan);
4972         u32 status;
4973         int err = 0;
4974
4975         sched_setscheduler(current, SCHED_FIFO, &param);
4976         allow_signal(SIGTERM);
4977         status = WL_SCAN_RESULTS_PARTIAL;
4978         while (likely(!down_interruptible(&iscan->sync))) {
4979                 if (kthread_should_stop())
4980                         break;
4981                 if (iscan->timer_on) {
4982                         del_timer_sync(&iscan->timer);
4983                         iscan->timer_on = 0;
4984                 }
4985                 rtnl_lock();
4986                 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
4987                 if (unlikely(err)) {
4988                         status = WL_SCAN_RESULTS_ABORTED;
4989                         WL_ERR(("Abort iscan\n"));
4990                 }
4991                 rtnl_unlock();
4992                 iscan->iscan_handler[status] (wl);
4993         }
4994         if (iscan->timer_on) {
4995                 del_timer_sync(&iscan->timer);
4996                 iscan->timer_on = 0;
4997         }
4998         WL_DBG(("%s was terminated\n", __func__));
4999
5000         return 0;
5001 }
5002
5003 static void wl_iscan_timer(unsigned long data)
5004 {
5005         struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
5006
5007         if (iscan) {
5008                 iscan->timer_on = 0;
5009                 WL_DBG(("timer expired\n"));
5010                 wl_wakeup_iscan(iscan);
5011         }
5012 }
5013
5014 static s32 wl_invoke_iscan(struct wl_priv *wl)
5015 {
5016         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
5017         int err = 0;
5018
5019         if (wl->iscan_on && !iscan->tsk) {
5020                 iscan->state = WL_ISCAN_STATE_IDLE;
5021                 sema_init(&iscan->sync, 0);
5022                 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
5023                 if (IS_ERR(iscan->tsk)) {
5024                         WL_ERR(("Could not create iscan thread\n"));
5025                         iscan->tsk = NULL;
5026                         return -ENOMEM;
5027                 }
5028         }
5029
5030         return err;
5031 }
5032
5033 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan)
5034 {
5035         memset(iscan->iscan_handler, 0, sizeof(iscan->iscan_handler));
5036         iscan->iscan_handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
5037         iscan->iscan_handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
5038         iscan->iscan_handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
5039         iscan->iscan_handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
5040         iscan->iscan_handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
5041 }
5042
5043 static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
5044 {
5045         WL_DBG(("Enter \n"));
5046         if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
5047                 wl_clr_drv_status(wl, SCANNING);
5048                 WL_ERR(("Scan complete while device not scanning\n"));
5049                 return;
5050         }
5051         wl_clr_drv_status(wl, SCANNING);
5052         if (wl->p2p_supported && p2p_on(wl))
5053                 wl_clr_p2p_status(wl, SCANNING);
5054
5055         if (likely(wl->scan_request)) {
5056                 cfg80211_scan_done(wl->scan_request, aborted);
5057                 wl->scan_request = NULL;
5058         }
5059 }
5060
5061 static s32 wl_escan_handler(struct wl_priv *wl,
5062         struct net_device *ndev,
5063         const wl_event_msg_t *e, void *data)
5064 {
5065         s32 err = BCME_OK;
5066         s32 status = ntoh32(e->status);
5067         wl_bss_info_t *bi;
5068         wl_escan_result_t *escan_result;
5069         wl_bss_info_t *bss = NULL;
5070         wl_scan_results_t *list;
5071         u32 bi_length;
5072         u32 i;
5073         WL_DBG((" enter event type : %d, status : %d \n",
5074                 ntoh32(e->event_type), ntoh32(e->status)));
5075         if (!wl->escan_on &&
5076                 !wl_get_drv_status(wl, SCANNING)) {
5077                 WL_ERR(("escan is not ready \n"));
5078                 return err;
5079         }
5080
5081         if (status == WLC_E_STATUS_PARTIAL) {
5082                 WL_INFO(("WLC_E_STATUS_PARTIAL \n"));
5083                 escan_result = (wl_escan_result_t *) data;
5084                 if (!escan_result) {
5085                         WL_ERR(("Invalid escan result (NULL pointer)\n"));
5086                         goto exit;
5087                 }
5088                 if (dtoh16(escan_result->bss_count) != 1) {
5089                         WL_ERR(("Invalid bss_count %d: ignoring\n", escan_result->bss_count));
5090                         goto exit;
5091                 }
5092                 bi = escan_result->bss_info;
5093                 if (!bi) {
5094                         WL_ERR(("Invalid escan bss info (NULL pointer)\n"));
5095                         goto exit;
5096                 }
5097                 bi_length = dtoh32(bi->length);
5098                 if (bi_length != (dtoh32(escan_result->buflen) - WL_ESCAN_RESULTS_FIXED_SIZE)) {
5099                         WL_ERR(("Invalid bss_info length %d: ignoring\n", bi_length));
5100                         goto exit;
5101                 }
5102                 list = (wl_scan_results_t *)wl->escan_info.escan_buf;
5103                 if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
5104                         WL_ERR(("Buffer is too small: ignoring\n"));
5105                         goto exit;
5106                 }
5107 #define WLC_BSS_RSSI_ON_CHANNEL 0x0002
5108                 for (i = 0; i < list->count; i++) {
5109                         bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
5110                                 : list->bss_info;
5111
5112                         if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
5113                                 CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
5114                                 bi->SSID_len == bss->SSID_len &&
5115                                 !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
5116                                 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
5117                                         (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
5118                                         /* preserve max RSSI if the measurements are
5119                                          * both on-channel or both off-channel
5120                                          */
5121                                         bss->RSSI = MAX(bss->RSSI, bi->RSSI);
5122                                 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
5123                                         (bi->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
5124                                         /* preserve the on-channel rssi measurement
5125                                          * if the new measurement is off channel
5126                                          */
5127                                         bss->RSSI = bi->RSSI;
5128                                         bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
5129                                 }
5130
5131                                 goto exit;
5132                         }
5133                 }
5134                 memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length);
5135                 list->version = dtoh32(bi->version);
5136                 list->buflen += bi_length;
5137                 list->count++;
5138
5139         }
5140         else if (status == WLC_E_STATUS_SUCCESS) {
5141                 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5142                 if (likely(wl->scan_request)) {
5143                         rtnl_lock();
5144                         WL_INFO(("ESCAN COMPLETED\n"));
5145                         wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
5146                         wl_inform_bss(wl);
5147                         wl_notify_escan_complete(wl, false);
5148                         rtnl_unlock();
5149                 }
5150         }
5151         else if (status == WLC_E_STATUS_ABORT) {
5152                 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5153                 if (likely(wl->scan_request)) {
5154                         rtnl_lock();
5155                         WL_INFO(("ESCAN COMPLETED\n"));
5156                         wl_notify_escan_complete(wl, true);
5157                         rtnl_unlock();
5158                 }
5159         }
5160 exit:
5161         return err;
5162 }
5163
5164 static s32 wl_init_scan(struct wl_priv *wl)
5165 {
5166         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
5167         int err = 0;
5168
5169         if (wl->iscan_on) {
5170                 iscan->dev = wl_to_prmry_ndev(wl);
5171                 iscan->state = WL_ISCAN_STATE_IDLE;
5172                 wl_init_iscan_handler(iscan);
5173                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
5174                 init_timer(&iscan->timer);
5175                 iscan->timer.data = (unsigned long) iscan;
5176                 iscan->timer.function = wl_iscan_timer;
5177                 sema_init(&iscan->sync, 0);
5178                 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
5179                 if (IS_ERR(iscan->tsk)) {
5180                         WL_ERR(("Could not create iscan thread\n"));
5181                         iscan->tsk = NULL;
5182                         return -ENOMEM;
5183                 }
5184                 iscan->data = wl;
5185         } else if (wl->escan_on) {
5186                 wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler;
5187                 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
5188         }
5189
5190         return err;
5191 }
5192
5193 static void wl_init_fw(struct wl_fw_ctrl *fw)
5194 {
5195         fw->status = 0;
5196 }
5197
5198 static s32 wl_init_priv(struct wl_priv *wl)
5199 {
5200         struct wiphy *wiphy = wl_to_wiphy(wl);
5201         s32 err = 0;
5202         s32 i = 0;
5203
5204         wl->scan_request = NULL;
5205         wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
5206         wl->iscan_on = false;
5207         wl->escan_on = true;
5208         wl->roam_on = false;
5209         wl->iscan_kickstart = false;
5210         wl->active_scan = true;
5211         wl->dongle_up = false;
5212         wl->rf_blocked = false;
5213
5214         for (i = 0; i < VWDEV_CNT; i++)
5215                 wl->vwdev[i] = NULL;
5216
5217         init_waitqueue_head(&wl->dongle_event_wait);
5218         wl_init_eq(wl);
5219         err = wl_init_priv_mem(wl);
5220         if (unlikely(err))
5221                 return err;
5222         if (unlikely(wl_create_event_handler(wl)))
5223                 return -ENOMEM;
5224         wl_init_event_handler(wl);
5225         mutex_init(&wl->usr_sync);
5226         err = wl_init_scan(wl);
5227         if (unlikely(err))
5228                 return err;
5229         wl_init_fw(wl->fw);
5230         wl_init_conf(wl->conf);
5231         wl_init_prof(wl->profile);
5232         wl_link_down(wl);
5233
5234         return err;
5235 }
5236
5237 static void wl_deinit_priv(struct wl_priv *wl)
5238 {
5239         wl_destroy_event_handler(wl);
5240         wl->dongle_up = false;  /* dongle down */
5241         wl_flush_eq(wl);
5242         wl_link_down(wl);
5243         wl_term_iscan(wl);
5244         wl_deinit_priv_mem(wl);
5245 }
5246
5247 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
5248 s32 wl_cfg80211_sysctl_export_devaddr(void *data)
5249 {
5250         /* Export the p2p_dev_addr via sysctl interface
5251          * so that wpa_supplicant can access it
5252          */
5253         dhd_pub_t *dhd = (dhd_pub_t *)data;
5254         struct wl_priv *wl = WL_PRIV_GET();
5255
5256         wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
5257
5258         sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p->dev_addr.octet));
5259         sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p->int_addr.octet));
5260
5261         return 0;
5262 }
5263 #endif /* CONFIG_SYSCTL */
5264
5265 s32 wl_cfg80211_attach_post(struct net_device *ndev)
5266 {
5267         struct wl_priv * wl = NULL;
5268         s32 err = 0;
5269         WL_TRACE(("In\n"));
5270         if (unlikely(!ndev)) {
5271                 WL_ERR(("ndev is invaild\n"));
5272                 return -ENODEV;
5273         }
5274         wl = WL_PRIV_GET();
5275         if (wl && !wl_get_drv_status(wl, READY)) {
5276                         if (wl->wdev &&
5277                                 wl_cfgp2p_supported(wl, ndev)) {
5278                                 wl->wdev->wiphy->interface_modes |=
5279                                         (BIT(NL80211_IFTYPE_P2P_CLIENT)|
5280                                         BIT(NL80211_IFTYPE_P2P_GO));
5281                                 if ((err = wl_cfgp2p_init_priv(wl)) != 0)
5282                                         goto fail;
5283 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
5284                                 wl_cfg80211_sysctl_export_devaddr(wl->pub);
5285 #endif
5286                                 wl->p2p_supported = true;
5287                         }
5288         } else
5289                 return -ENODEV;
5290
5291         wl_set_drv_status(wl, READY);
5292 fail:
5293         return err;
5294 }
5295 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
5296 {
5297         struct wireless_dev *wdev;
5298         struct wl_priv *wl;
5299         struct wl_iface *ci;
5300         s32 err = 0;
5301
5302         WL_TRACE(("In\n"));
5303         if (unlikely(!ndev)) {
5304                 WL_ERR(("ndev is invaild\n"));
5305                 return -ENODEV;
5306         }
5307         wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
5308         if (unlikely(!wl_cfg80211_dev)) {
5309                 WL_ERR(("wl_cfg80211_dev is invalid\n"));
5310                 return -ENOMEM;
5311         }
5312         WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
5313         wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
5314         if (unlikely(IS_ERR(wdev)))
5315                 return -ENOMEM;
5316
5317         wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
5318         wl = wdev_to_wl(wdev);
5319         wl->wdev = wdev;
5320         wl->pub = data;
5321
5322         ci = (struct wl_iface *)wl_to_ci(wl);
5323         ci->wl = wl;
5324         ndev->ieee80211_ptr = wdev;
5325         SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
5326         wdev->netdev = ndev;
5327
5328         err = wl_init_priv(wl);
5329         if (unlikely(err)) {
5330                 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
5331                 goto cfg80211_attach_out;
5332         }
5333
5334         err = wl_setup_rfkill(wl, TRUE);
5335         if (unlikely(err)) {
5336                 WL_ERR(("Failed to setup rfkill %d\n", err));
5337                 goto cfg80211_attach_out;
5338         }
5339
5340 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
5341         if (!(wl_sysctl_hdr = register_sysctl_table(wl_sysctl_table))) {
5342                 WL_ERR(("%s: sysctl register failed!! \n", __func__));
5343                 goto cfg80211_attach_out;
5344         }
5345 #endif
5346         wl_set_drvdata(wl_cfg80211_dev, ci);
5347         return err;
5348
5349 cfg80211_attach_out:
5350         err = wl_setup_rfkill(wl, FALSE);
5351         wl_free_wdev(wl);
5352         return err;
5353 }
5354
5355 void wl_cfg80211_detach(void)
5356 {
5357         struct wl_priv *wl;
5358
5359         wl = WL_PRIV_GET();
5360
5361         WL_TRACE(("In\n"));
5362 #if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
5363         if (wl_sysctl_hdr)
5364                 unregister_sysctl_table(wl_sysctl_hdr);
5365 #endif
5366         wl_setup_rfkill(wl, FALSE);
5367         if (wl->p2p_supported)
5368                 wl_cfgp2p_deinit_priv(wl);
5369         wl_deinit_priv(wl);
5370         wl_free_wdev(wl);
5371         wl_set_drvdata(wl_cfg80211_dev, NULL);
5372         kfree(wl_cfg80211_dev);
5373         wl_cfg80211_dev = NULL;
5374         wl_clear_sdio_func();
5375 }
5376
5377 static void wl_wakeup_event(struct wl_priv *wl)
5378 {
5379         up(&wl->event_sync);
5380 }
5381
5382 static s32 wl_event_handler(void *data)
5383 {
5384         struct net_device *netdev;
5385         struct wl_priv *wl = (struct wl_priv *)data;
5386         struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
5387         struct wl_event_q *e;
5388
5389         sched_setscheduler(current, SCHED_FIFO, &param);
5390         allow_signal(SIGTERM);
5391         while (likely(!down_interruptible(&wl->event_sync))) {
5392                 if (kthread_should_stop())
5393                         break;
5394                 e = wl_deq_event(wl);
5395                 if (unlikely(!e)) {
5396                         WL_ERR(("equeue empty..\n"));
5397                         return 0;
5398                 }
5399                 WL_DBG(("event type (%d), if idx: %d\n", e->etype, e->emsg.ifidx));
5400                 netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx);
5401                 if (!netdev)
5402                         netdev = wl_to_prmry_ndev(wl);
5403                 if (wl->evt_handler[e->etype]) {
5404                         wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata);
5405                 } else {
5406                         WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
5407                 }
5408                 wl_put_event(e);
5409         }
5410         WL_DBG(("%s was terminated\n", __func__));
5411         return 0;
5412 }
5413
5414 void
5415 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
5416 {
5417         u32 event_type = ntoh32(e->event_type);
5418         struct wl_priv *wl = WL_PRIV_GET();
5419
5420 #if (WL_DBG_LEVEL > 0)
5421         s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
5422             wl_dbg_estr[event_type] : (s8 *) "Unknown";
5423         WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
5424 #endif /* (WL_DBG_LEVEL > 0) */
5425
5426         if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
5427                 wl_wakeup_event(wl);
5428 }
5429
5430 static void wl_init_eq(struct wl_priv *wl)
5431 {
5432         wl_init_eq_lock(wl);
5433         INIT_LIST_HEAD(&wl->eq_list);
5434 }
5435
5436 static void wl_flush_eq(struct wl_priv *wl)
5437 {
5438         struct wl_event_q *e;
5439
5440         wl_lock_eq(wl);
5441         while (!list_empty(&wl->eq_list)) {
5442                 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
5443                 list_del(&e->eq_list);
5444                 kfree(e);
5445         }
5446         wl_unlock_eq(wl);
5447 }
5448
5449 /*
5450 * retrieve first queued event from head
5451 */
5452
5453 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
5454 {
5455         struct wl_event_q *e = NULL;
5456
5457         wl_lock_eq(wl);
5458         if (likely(!list_empty(&wl->eq_list))) {
5459                 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
5460                 list_del(&e->eq_list);
5461         }
5462         wl_unlock_eq(wl);
5463
5464         return e;
5465 }
5466
5467 /*
5468  * push event to tail of the queue
5469  */
5470
5471 static s32
5472 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg,
5473         void *data)
5474 {
5475         struct wl_event_q *e;
5476         s32 err = 0;
5477         uint32 evtq_size;
5478         uint32 data_len;
5479
5480         data_len = 0;
5481         if (data)
5482                 data_len = ntoh32(msg->datalen);
5483         evtq_size = sizeof(struct wl_event_q) + data_len;
5484         e = kzalloc(evtq_size, GFP_ATOMIC);
5485         if (unlikely(!e)) {
5486                 WL_ERR(("event alloc failed\n"));
5487                 return -ENOMEM;
5488         }
5489         e->etype = event;
5490         memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
5491         if (data)
5492                 memcpy(e->edata, data, data_len);
5493         wl_lock_eq(wl);
5494         list_add_tail(&e->eq_list, &wl->eq_list);
5495         wl_unlock_eq(wl);
5496
5497         return err;
5498 }
5499
5500 static void wl_put_event(struct wl_event_q *e)
5501 {
5502         kfree(e);
5503 }
5504
5505 void wl_cfg80211_set_sdio_func(void *func)
5506 {
5507         cfg80211_sdio_func = (struct sdio_func *)func;
5508 }
5509
5510 static void wl_clear_sdio_func(void)
5511 {
5512         cfg80211_sdio_func = NULL;
5513 }
5514
5515 struct sdio_func *wl_cfg80211_get_sdio_func(void)
5516 {
5517         return cfg80211_sdio_func;
5518 }
5519
5520 static s32 wl_dongle_mode(struct wl_priv *wl, struct net_device *ndev, s32 iftype)
5521 {
5522         s32 infra = 0;
5523         s32 err = 0;
5524         s32 mode = 0;
5525         switch (iftype) {
5526         case NL80211_IFTYPE_MONITOR:
5527         case NL80211_IFTYPE_WDS:
5528                 WL_ERR(("type (%d) : currently we do not support this mode\n",
5529                         iftype));
5530                 err = -EINVAL;
5531                 return err;
5532         case NL80211_IFTYPE_ADHOC:
5533                 mode = WL_MODE_IBSS;
5534                 break;
5535         case NL80211_IFTYPE_STATION:
5536         case NL80211_IFTYPE_P2P_CLIENT:
5537                 mode = WL_MODE_BSS;
5538                 infra = 1;
5539                 break;
5540         case NL80211_IFTYPE_AP:
5541         case NL80211_IFTYPE_P2P_GO:
5542                 mode = WL_MODE_AP;
5543                 infra = 1;
5544                 break;
5545         default:
5546                 err = -EINVAL;
5547                 WL_ERR(("invalid type (%d)\n", iftype));
5548                 return err;
5549         }
5550         infra = htod32(infra);
5551         err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), false);
5552         if (unlikely(err)) {
5553                 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
5554                 return err;
5555         }
5556
5557         set_mode_by_netdev(wl, ndev, mode);
5558
5559         return 0;
5560 }
5561 static s32 wl_dongle_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
5562 {
5563         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5564
5565         s8 eventmask[WL_EVENTING_MASK_LEN];
5566         s32 err = 0;
5567
5568         /* Setup event_msgs */
5569         bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5570                 sizeof(iovbuf));
5571         err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
5572         if (unlikely(err)) {
5573                 WL_ERR(("Get event_msgs error (%d)\n", err));
5574                 goto dongle_eventmsg_out;
5575         }
5576         memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
5577         if (add) {
5578                 setbit(eventmask, event);
5579         } else {
5580                 clrbit(eventmask, event);
5581         }
5582         bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5583                 sizeof(iovbuf));
5584         err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5585         if (unlikely(err)) {
5586                 WL_ERR(("Set event_msgs error (%d)\n", err));
5587                 goto dongle_eventmsg_out;
5588         }
5589
5590 dongle_eventmsg_out:
5591         return err;
5592
5593 }
5594
5595 static s32 wl_dongle_eventmsg(struct net_device *ndev)
5596 {
5597         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5598
5599         s8 eventmask[WL_EVENTING_MASK_LEN];
5600         s32 err = 0;
5601
5602         /* Setup event_msgs */
5603         bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5604                 sizeof(iovbuf));
5605         err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
5606         if (unlikely(err)) {
5607                 WL_ERR(("Get event_msgs error (%d)\n", err));
5608                 goto dongle_eventmsg_out;
5609         }
5610         memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
5611
5612         setbit(eventmask, WLC_E_SET_SSID);
5613         setbit(eventmask, WLC_E_PRUNE);
5614         setbit(eventmask, WLC_E_AUTH);
5615         setbit(eventmask, WLC_E_REASSOC);
5616         setbit(eventmask, WLC_E_REASSOC_IND);
5617         setbit(eventmask, WLC_E_DEAUTH_IND);
5618         setbit(eventmask, WLC_E_DEAUTH);
5619         setbit(eventmask, WLC_E_DISASSOC_IND);
5620         setbit(eventmask, WLC_E_DISASSOC);
5621         setbit(eventmask, WLC_E_JOIN);
5622         setbit(eventmask, WLC_E_ASSOC_IND);
5623         setbit(eventmask, WLC_E_PSK_SUP);
5624         setbit(eventmask, WLC_E_LINK);
5625         setbit(eventmask, WLC_E_NDIS_LINK);
5626         setbit(eventmask, WLC_E_MIC_ERROR);
5627         setbit(eventmask, WLC_E_PMKID_CACHE);
5628         setbit(eventmask, WLC_E_TXFAIL);
5629         setbit(eventmask, WLC_E_JOIN_START);
5630         setbit(eventmask, WLC_E_SCAN_COMPLETE);
5631         setbit(eventmask, WLC_E_ACTION_FRAME_RX);
5632         setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE);
5633         setbit(eventmask, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE);
5634         setbit(eventmask, WLC_E_P2P_PROBREQ_MSG);
5635         setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE);
5636         setbit(eventmask, WLC_E_ESCAN_RESULT);
5637         bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
5638                 sizeof(iovbuf));
5639         err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5640         if (unlikely(err)) {
5641                 WL_ERR(("Set event_msgs error (%d)\n", err));
5642                 goto dongle_eventmsg_out;
5643         }
5644
5645 dongle_eventmsg_out:
5646         return err;
5647 }
5648
5649 #ifndef EMBEDDED_PLATFORM
5650 static s32 wl_dongle_country(struct net_device *ndev, u8 ccode)
5651 {
5652
5653         s32 err = 0;
5654
5655         return err;
5656 }
5657
5658 static s32 wl_dongle_up(struct net_device *ndev, u32 up)
5659 {
5660         s32 err = 0;
5661
5662         err = wldev_ioctl(ndev, WLC_UP, &up, sizeof(up), false);
5663         if (unlikely(err)) {
5664                 WL_ERR(("WLC_UP error (%d)\n", err));
5665         }
5666         return err;
5667 }
5668
5669 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
5670 {
5671         s32 err = 0;
5672
5673         WL_TRACE(("In\n"));
5674         err = wldev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode), false);
5675         if (unlikely(err)) {
5676                 WL_ERR(("WLC_SET_PM error (%d)\n", err));
5677         }
5678         return err;
5679 }
5680
5681 static s32
5682 wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align)
5683 {
5684         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5685
5686         s32 err = 0;
5687
5688         /* Match Host and Dongle rx alignment */
5689         bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
5690                 sizeof(iovbuf));
5691         err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5692         if (unlikely(err)) {
5693                 WL_ERR(("txglomalign error (%d)\n", err));
5694                 goto dongle_glom_out;
5695         }
5696         /* disable glom option per default */
5697         bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
5698         err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5699         if (unlikely(err)) {
5700                 WL_ERR(("txglom error (%d)\n", err));
5701                 goto dongle_glom_out;
5702         }
5703 dongle_glom_out:
5704         return err;
5705 }
5706
5707 static s32
5708 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
5709 {
5710         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5711
5712         s32 err = 0;
5713
5714         /* Setup timeout if Beacons are lost and roam is off to report link down */
5715         if (roamvar) {
5716                 bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
5717                         sizeof(iovbuf));
5718                 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5719                 if (unlikely(err)) {
5720                         WL_ERR(("bcn_timeout error (%d)\n", err));
5721                         goto dongle_rom_out;
5722                 }
5723         }
5724         /* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
5725         bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
5726         err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5727         if (unlikely(err)) {
5728                 WL_ERR(("roam_off error (%d)\n", err));
5729                 goto dongle_rom_out;
5730         }
5731 dongle_rom_out:
5732         return err;
5733 }
5734
5735 static s32
5736 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
5737         s32 scan_unassoc_time)
5738 {
5739         s32 err = 0;
5740
5741         err = wldev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
5742                 sizeof(scan_assoc_time), false);
5743         if (err) {
5744                 if (err == -EOPNOTSUPP) {
5745                         WL_INFO(("Scan assoc time is not supported\n"));
5746                 } else {
5747                         WL_ERR(("Scan assoc time error (%d)\n", err));
5748                 }
5749                 goto dongle_scantime_out;
5750         }
5751         err = wldev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
5752                 sizeof(scan_unassoc_time), false);
5753         if (err) {
5754                 if (err == -EOPNOTSUPP) {
5755                         WL_INFO(("Scan unassoc time is not supported\n"));
5756                 } else {
5757                         WL_ERR(("Scan unassoc time error (%d)\n", err));
5758                 }
5759                 goto dongle_scantime_out;
5760         }
5761
5762 dongle_scantime_out:
5763         return err;
5764 }
5765
5766 static s32
5767 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
5768 {
5769         /* Room for "event_msgs" + '\0' + bitvec */
5770         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5771
5772         s32 err = 0;
5773
5774         /* Set ARP offload */
5775         bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
5776         err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5777         if (err) {
5778                 if (err == -EOPNOTSUPP)
5779                         WL_INFO(("arpoe is not supported\n"));
5780                 else
5781                         WL_ERR(("arpoe error (%d)\n", err));
5782
5783                 goto dongle_offload_out;
5784         }
5785         bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
5786         err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5787         if (err) {
5788                 if (err == -EOPNOTSUPP)
5789                         WL_INFO(("arp_ol is not supported\n"));
5790                 else
5791                         WL_ERR(("arp_ol error (%d)\n", err));
5792
5793                 goto dongle_offload_out;
5794         }
5795
5796 dongle_offload_out:
5797         return err;
5798 }
5799
5800 static s32 wl_pattern_atoh(s8 *src, s8 *dst)
5801 {
5802         int i;
5803         if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
5804                 WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
5805                 return -1;
5806         }
5807         src = src + 2;          /* Skip past 0x */
5808         if (strlen(src) % 2 != 0) {
5809                 WL_ERR(("Mask invalid format. Needs to be of even length\n"));
5810                 return -1;
5811         }
5812         for (i = 0; *src != '\0'; i++) {
5813                 char num[3];
5814                 strncpy(num, src, 2);
5815                 num[2] = '\0';
5816                 dst[i] = (u8) simple_strtoul(num, NULL, 16);
5817                 src += 2;
5818         }
5819         return i;
5820 }
5821
5822 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
5823 {
5824         /* Room for "event_msgs" + '\0' + bitvec */
5825         s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
5826
5827         const s8 *str;
5828         struct wl_pkt_filter pkt_filter;
5829         struct wl_pkt_filter *pkt_filterp;
5830         s32 buf_len;
5831         s32 str_len;
5832         u32 mask_size;
5833         u32 pattern_size;
5834         s8 buf[256];
5835         s32 err = 0;
5836
5837         /* add a default packet filter pattern */
5838         str = "pkt_filter_add";
5839         str_len = strlen(str);
5840         strncpy(buf, str, str_len);
5841         buf[str_len] = '\0';
5842         buf_len = str_len + 1;
5843
5844         pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
5845
5846         /* Parse packet filter id. */
5847         pkt_filter.id = htod32(100);
5848
5849         /* Parse filter polarity. */
5850         pkt_filter.negate_match = htod32(0);
5851
5852         /* Parse filter type. */
5853         pkt_filter.type = htod32(0);
5854
5855         /* Parse pattern filter offset. */
5856         pkt_filter.u.pattern.offset = htod32(0);
5857
5858         /* Parse pattern filter mask. */
5859         mask_size = htod32(wl_pattern_atoh("0xff",
5860                 (char *)pkt_filterp->u.pattern.
5861                     mask_and_pattern));
5862
5863         /* Parse pattern filter pattern. */
5864         pattern_size = htod32(wl_pattern_atoh("0x00",
5865                 (char *)&pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
5866
5867         if (mask_size != pattern_size) {
5868                 WL_ERR(("Mask and pattern not the same size\n"));
5869                 err = -EINVAL;
5870                 goto dongle_filter_out;
5871         }
5872
5873         pkt_filter.u.pattern.size_bytes = mask_size;
5874         buf_len += WL_PKT_FILTER_FIXED_LEN;
5875         buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
5876
5877         /* Keep-alive attributes are set in local
5878          * variable (keep_alive_pkt), and
5879          * then memcpy'ed into buffer (keep_alive_pktp) since there is no
5880          * guarantee that the buffer is properly aligned.
5881          */
5882         memcpy((char *)pkt_filterp, &pkt_filter,
5883                 WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
5884
5885         err = wldev_ioctl(ndev, WLC_SET_VAR, buf, buf_len, false);
5886         if (err) {
5887                 if (err == -EOPNOTSUPP) {
5888                         WL_INFO(("filter not supported\n"));
5889                 } else {
5890                         WL_ERR(("filter (%d)\n", err));
5891                 }
5892                 goto dongle_filter_out;
5893         }
5894
5895         /* set mode to allow pattern */
5896         bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf,
5897                 sizeof(iovbuf));
5898         err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), false);
5899         if (err) {
5900                 if (err == -EOPNOTSUPP) {
5901                         WL_INFO(("filter_mode not supported\n"));
5902                 } else {
5903                         WL_ERR(("filter_mode (%d)\n", err));
5904                 }
5905                 goto dongle_filter_out;
5906         }
5907
5908 dongle_filter_out:
5909         return err;
5910 }
5911 #endif                          /* !EMBEDDED_PLATFORM */
5912
5913 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
5914 {
5915 #ifndef DHD_SDALIGN
5916 #define DHD_SDALIGN     32
5917 #endif
5918         struct net_device *ndev;
5919         struct wireless_dev *wdev;
5920         s32 err = 0;
5921
5922         WL_TRACE(("In\n"));
5923         if (wl->dongle_up) {
5924                 WL_ERR(("Dongle is already up\n"));
5925                 return err;
5926         }
5927
5928         ndev = wl_to_prmry_ndev(wl);
5929         wdev = ndev->ieee80211_ptr;
5930         if (need_lock)
5931                 rtnl_lock();
5932         err = wl_dongle_eventmsg(ndev);
5933         if (unlikely(err)) {
5934                 WL_ERR(("wl_dongle_eventmsg failed\n"));
5935                 goto default_conf_out;
5936         }
5937 #ifndef EMBEDDED_PLATFORM
5938         err = wl_dongle_up(ndev, 0);
5939         if (unlikely(err)) {
5940                 WL_ERR(("wl_dongle_up failed\n"));
5941                 goto default_conf_out;
5942         }
5943         err = wl_dongle_country(ndev, 0);
5944         if (unlikely(err)) {
5945                 WL_ERR(("wl_dongle_country failed\n"));
5946                 goto default_conf_out;
5947         }
5948         err = wl_dongle_power(ndev, PM_FAST);
5949         if (unlikely(err)) {
5950                 WL_ERR(("wl_dongle_power failed\n"));
5951                 goto default_conf_out;
5952         }
5953         err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
5954         if (unlikely(err)) {
5955                 WL_ERR(("wl_dongle_glom failed\n"));
5956                 goto default_conf_out;
5957         }
5958         err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
5959         if (unlikely(err)) {
5960                 WL_ERR(("wl_dongle_roam failed\n"));
5961                 goto default_conf_out;
5962         }
5963         err = wl_dongle_eventmsg(ndev);
5964         if (unlikely(err)) {
5965                 WL_ERR(("wl_dongle_eventmsg failed\n"));
5966                 goto default_conf_out;
5967         }
5968
5969         wl_dongle_scantime(ndev, 40, 80);
5970         wl_dongle_offload(ndev, 1, 0xf);
5971         wl_dongle_filter(ndev, 1);
5972 #endif                          /* !EMBEDDED_PLATFORM */
5973
5974         err = wl_dongle_mode(wl, ndev, wdev->iftype);
5975         if (unlikely(err && err != -EINPROGRESS)) {
5976                 WL_ERR(("wl_dongle_mode failed\n"));
5977                 goto default_conf_out;
5978         }
5979         err = wl_dongle_probecap(wl);
5980         if (unlikely(err)) {
5981                 WL_ERR(("wl_dongle_probecap failed\n"));
5982                 goto default_conf_out;
5983         }
5984
5985         /* -EINPROGRESS: Call commit handler */
5986
5987 default_conf_out:
5988         if (need_lock)
5989                 rtnl_unlock();
5990
5991         wl->dongle_up = true;
5992
5993         return err;
5994
5995 }
5996
5997 static s32 wl_update_wiphybands(struct wl_priv *wl)
5998 {
5999         struct wiphy *wiphy;
6000         s32 phy_list;
6001         s8 phy;
6002         s32 err = 0;
6003
6004         err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_PHYLIST, &phy_list,
6005                 sizeof(phy_list), false);
6006         if (unlikely(err)) {
6007                 WL_ERR(("error (%d)\n", err));
6008                 return err;
6009         }
6010
6011         phy = ((char *)&phy_list)[1];
6012         WL_DBG(("%c phy\n", phy));
6013         if (phy == 'a') {
6014                 wiphy = wl_to_wiphy(wl);
6015                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
6016         } else if (phy == 'n') {
6017                 wiphy = wl_to_wiphy(wl);
6018                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
6019         }
6020
6021         return err;
6022 }
6023
6024 static s32 __wl_cfg80211_up(struct wl_priv *wl)
6025 {
6026         s32 err = 0;
6027
6028         WL_TRACE(("In\n"));
6029         wl_debugfs_add_netdev_params(wl);
6030
6031         err = wl_config_dongle(wl, false);
6032         if (unlikely(err))
6033                 return err;
6034         dhd_monitor_init(wl->pub);
6035         wl_invoke_iscan(wl);
6036         wl_set_drv_status(wl, READY);
6037         return err;
6038 }
6039
6040 static s32 __wl_cfg80211_down(struct wl_priv *wl)
6041 {
6042         s32 err = 0;
6043
6044         WL_TRACE(("In\n"));
6045         /* Check if cfg80211 interface is already down */
6046         if (!wl_get_drv_status(wl, READY))
6047                 return err;     /* it is even not ready */
6048
6049         wl_set_drv_status(wl, SCAN_ABORTING);
6050
6051         wl_term_iscan(wl);
6052         if (wl->scan_request) {
6053                 cfg80211_scan_done(wl->scan_request, true);
6054                 wl->scan_request = NULL;
6055         }
6056         wl_clr_drv_status(wl, READY);
6057         wl_clr_drv_status(wl, SCANNING);
6058         wl_clr_drv_status(wl, SCAN_ABORTING);
6059         wl_clr_drv_status(wl, CONNECTED);
6060         if (wl_get_drv_status(wl, AP_CREATED)) {
6061                 wl_clr_drv_status(wl, AP_CREATED);
6062                 wl_clr_drv_status(wl, AP_CREATING);
6063                 wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype =
6064                 NL80211_IFTYPE_STATION;
6065         }
6066         wl->dongle_up = false;
6067         wl_flush_eq(wl);
6068         wl_link_down(wl);
6069         if (wl->p2p_supported)
6070                 wl_cfgp2p_down(wl);
6071         dhd_monitor_uninit();
6072
6073         wl_debugfs_remove_netdev(wl);
6074
6075         return err;
6076 }
6077
6078 s32 wl_cfg80211_up(void)
6079 {
6080         struct wl_priv *wl;
6081         s32 err = 0;
6082
6083         WL_TRACE(("In\n"));
6084         wl = WL_PRIV_GET();
6085         mutex_lock(&wl->usr_sync);
6086         wl_cfg80211_attach_post(wl_to_prmry_ndev(wl));
6087         err = __wl_cfg80211_up(wl);
6088         if (err)
6089                 WL_ERR(("__wl_cfg80211_up failed\n"));
6090         mutex_unlock(&wl->usr_sync);
6091
6092         return err;
6093 }
6094
6095 s32 wl_cfg80211_down(void)
6096 {
6097         struct wl_priv *wl;
6098         s32 err = 0;
6099
6100         WL_TRACE(("In\n"));
6101         wl = WL_PRIV_GET();
6102         mutex_lock(&wl->usr_sync);
6103         err = __wl_cfg80211_down(wl);
6104         mutex_unlock(&wl->usr_sync);
6105
6106         return err;
6107 }
6108 static s32 wl_dongle_probecap(struct wl_priv *wl)
6109 {
6110         s32 err = 0;
6111
6112         err = wl_update_wiphybands(wl);
6113         if (unlikely(err))
6114                 return err;
6115
6116         return err;
6117 }
6118
6119 static void *wl_read_prof(struct wl_priv *wl, s32 item)
6120 {
6121         switch (item) {
6122         case WL_PROF_SEC:
6123                 return &wl->profile->sec;
6124         case WL_PROF_ACT:
6125                 return &wl->profile->active;
6126         case WL_PROF_BSSID:
6127                 return &wl->profile->bssid;
6128         case WL_PROF_SSID:
6129                 return &wl->profile->ssid;
6130         }
6131         WL_ERR(("invalid item (%d)\n", item));
6132         return NULL;
6133 }
6134
6135 static s32
6136 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data,
6137         s32 item)
6138 {
6139         s32 err = 0;
6140         struct wlc_ssid *ssid;
6141
6142         switch (item) {
6143         case WL_PROF_SSID:
6144                 ssid = (wlc_ssid_t *) data;
6145                 memset(wl->profile->ssid.SSID, 0,
6146                         sizeof(wl->profile->ssid.SSID));
6147                 memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
6148                 wl->profile->ssid.SSID_len = ssid->SSID_len;
6149                 break;
6150         case WL_PROF_BSSID:
6151                 if (data)
6152                         memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
6153                 else
6154                         memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
6155                 break;
6156         case WL_PROF_SEC:
6157                 memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
6158                 break;
6159         case WL_PROF_ACT:
6160                 wl->profile->active = *(bool *)data;
6161                 break;
6162         case WL_PROF_BEACONINT:
6163                 wl->profile->beacon_interval = *(u16 *)data;
6164                 break;
6165         case WL_PROF_DTIMPERIOD:
6166                 wl->profile->dtim_period = *(u8 *)data;
6167                 break;
6168         default:
6169                 WL_ERR(("unsupported item (%d)\n", item));
6170                 err = -EOPNOTSUPP;
6171                 break;
6172         }
6173
6174         return err;
6175 }
6176
6177 void wl_cfg80211_dbg_level(u32 level)
6178 {
6179         /*
6180         * prohibit to change debug level
6181         * by insmod parameter.
6182         * eventually debug level will be configured
6183         * in compile time by using CONFIG_XXX
6184         */
6185         /* wl_dbg_level = level; */
6186 }
6187
6188 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev)
6189 {
6190         return get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS;
6191 }
6192
6193 static __used bool wl_is_ibssstarter(struct wl_priv *wl)
6194 {
6195         return wl->ibss_starter;
6196 }
6197
6198 static void wl_rst_ie(struct wl_priv *wl)
6199 {
6200         struct wl_ie *ie = wl_to_ie(wl);
6201
6202         ie->offset = 0;
6203 }
6204
6205 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
6206 {
6207         struct wl_ie *ie = wl_to_ie(wl);
6208         s32 err = 0;
6209
6210         if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
6211                 WL_ERR(("ei crosses buffer boundary\n"));
6212                 return -ENOSPC;
6213         }
6214         ie->buf[ie->offset] = t;
6215         ie->buf[ie->offset + 1] = l;
6216         memcpy(&ie->buf[ie->offset + 2], v, l);
6217         ie->offset += l + 2;
6218
6219         return err;
6220 }
6221
6222 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
6223 {
6224         struct wl_ie *ie = wl_to_ie(wl);
6225         s32 err = 0;
6226
6227         if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
6228                 WL_ERR(("ei_stream crosses buffer boundary\n"));
6229                 return -ENOSPC;
6230         }
6231         memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
6232         ie->offset += ie_size;
6233
6234         return err;
6235 }
6236
6237 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
6238 {
6239         struct wl_ie *ie = wl_to_ie(wl);
6240         s32 err = 0;
6241
6242         if (unlikely(ie->offset > dst_size)) {
6243                 WL_ERR(("dst_size is not enough\n"));
6244                 return -ENOSPC;
6245         }
6246         memcpy(dst, &ie->buf[0], ie->offset);
6247
6248         return err;
6249 }
6250
6251 static u32 wl_get_ielen(struct wl_priv *wl)
6252 {
6253         struct wl_ie *ie = wl_to_ie(wl);
6254
6255         return ie->offset;
6256 }
6257
6258 static void wl_link_up(struct wl_priv *wl)
6259 {
6260         wl->link_up = true;
6261 }
6262
6263 static void wl_link_down(struct wl_priv *wl)
6264 {
6265         struct wl_connect_info *conn_info = wl_to_conn(wl);
6266
6267         WL_DBG(("In\n"));
6268         wl->link_up = false;
6269         kfree(conn_info->req_ie);
6270         conn_info->req_ie = NULL;
6271         conn_info->req_ie_len = 0;
6272         kfree(conn_info->resp_ie);
6273         conn_info->resp_ie = NULL;
6274         conn_info->resp_ie_len = 0;
6275 }
6276
6277 static void wl_lock_eq(struct wl_priv *wl)
6278 {
6279         spin_lock_irq(&wl->eq_lock);
6280 }
6281
6282 static void wl_unlock_eq(struct wl_priv *wl)
6283 {
6284         spin_unlock_irq(&wl->eq_lock);
6285 }
6286
6287 static void wl_init_eq_lock(struct wl_priv *wl)
6288 {
6289         spin_lock_init(&wl->eq_lock);
6290 }
6291
6292 static void wl_delay(u32 ms)
6293 {
6294         if (ms < 1000 / HZ) {
6295                 cond_resched();
6296                 mdelay(ms);
6297         } else {
6298                 msleep(ms);
6299         }
6300 }
6301
6302 static void wl_set_drvdata(struct wl_dev *dev, void *data)
6303 {
6304         dev->driver_data = data;
6305 }
6306
6307 static void *wl_get_drvdata(struct wl_dev *dev)
6308 {
6309         return dev->driver_data;
6310 }
6311
6312 s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
6313 {
6314         const struct firmware *fw_entry;
6315         struct wl_priv *wl;
6316
6317         wl = WL_PRIV_GET();
6318
6319         fw_entry = wl->fw->fw_entry;
6320
6321         if (fw_entry->size < wl->fw->ptr + size)
6322                 size = fw_entry->size - wl->fw->ptr;
6323
6324         memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
6325         wl->fw->ptr += size;
6326         return size;
6327 }
6328
6329 void wl_cfg80211_release_fw(void)
6330 {
6331         struct wl_priv *wl;
6332
6333         wl = WL_PRIV_GET();
6334         release_firmware(wl->fw->fw_entry);
6335         wl->fw->ptr = 0;
6336 }
6337
6338 void *wl_cfg80211_request_fw(s8 *file_name)
6339 {
6340         struct wl_priv *wl;
6341         const struct firmware *fw_entry = NULL;
6342         s32 err = 0;
6343
6344         WL_TRACE(("In\n"));
6345         WL_DBG(("file name : \"%s\"\n", file_name));
6346         wl = WL_PRIV_GET();
6347
6348         if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
6349                 err = request_firmware(&wl->fw->fw_entry, file_name,
6350                         &wl_cfg80211_get_sdio_func()->dev);
6351                 if (unlikely(err)) {
6352                         WL_ERR(("Could not download fw (%d)\n", err));
6353                         goto req_fw_out;
6354                 }
6355                 set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
6356                 fw_entry = wl->fw->fw_entry;
6357                 if (fw_entry) {
6358                         WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size,
6359                                 fw_entry->data));
6360                 }
6361         } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
6362                 err = request_firmware(&wl->fw->fw_entry, file_name,
6363                         &wl_cfg80211_get_sdio_func()->dev);
6364                 if (unlikely(err)) {
6365                         WL_ERR(("Could not download nvram (%d)\n", err));
6366                         goto req_fw_out;
6367                 }
6368                 set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
6369                 fw_entry = wl->fw->fw_entry;
6370                 if (fw_entry) {
6371                         WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size,
6372                                 fw_entry->data));
6373                 }
6374         } else {
6375                 WL_DBG(("Downloading already done. Nothing to do more\n"));
6376                 err = -EPERM;
6377         }
6378
6379 req_fw_out:
6380         if (unlikely(err)) {
6381                 return NULL;
6382         }
6383         wl->fw->ptr = 0;
6384         return (void *)fw_entry->data;
6385 }
6386
6387 s8 *wl_cfg80211_get_fwname(void)
6388 {
6389         struct wl_priv *wl;
6390
6391         wl = WL_PRIV_GET();
6392         strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
6393         return wl->fw->fw_name;
6394 }
6395
6396 s8 *wl_cfg80211_get_nvramname(void)
6397 {
6398         struct wl_priv *wl;
6399
6400         wl = WL_PRIV_GET();
6401         strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
6402         return wl->fw->nvram_name;
6403 }
6404
6405 s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
6406 {
6407         struct wl_priv *wl;
6408         dhd_pub_t *dhd_pub;
6409         struct ether_addr p2pif_addr;
6410
6411         wl = WL_PRIV_GET();
6412         dhd_pub = (dhd_pub_t *)wl->pub;
6413         wl_cfgp2p_generate_bss_mac(&dhd_pub->mac, p2pdev_addr, &p2pif_addr);
6414
6415         return 0;
6416 }
6417
6418 static __used void wl_dongle_poweron(struct wl_priv *wl)
6419 {
6420
6421         WL_DBG(("Enter \n"));
6422         dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
6423
6424 #if defined(BCMLXSDMMC)
6425         sdioh_start(NULL, 0);
6426 #endif
6427 #if defined(BCMLXSDMMC)
6428         sdioh_start(NULL, 1);
6429 #endif
6430         wl_cfg80211_resume(wl_to_wiphy(wl));
6431 }
6432
6433 static __used void wl_dongle_poweroff(struct wl_priv *wl)
6434 {
6435
6436
6437         WL_DBG(("Enter \n"));
6438 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
6439         wl_cfg80211_suspend(wl_to_wiphy(wl), NULL);
6440 #else
6441         wl_cfg80211_suspend(wl_to_wiphy(wl));
6442 #endif
6443
6444 #if defined(BCMLXSDMMC)
6445         sdioh_stop(NULL);
6446 #endif
6447         /* clean up dtim_skip setting */
6448         dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
6449 }
6450 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
6451 {
6452         char buf[10+IFNAMSIZ];
6453         struct dentry *fd;
6454         s32 err = 0;
6455
6456         WL_TRACE(("In\n"));
6457         sprintf(buf, "netdev:%s", wl_to_prmry_ndev(wl)->name);
6458         wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir);
6459
6460         fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir,
6461                 (u16 *)&wl->profile->beacon_interval);
6462         if (!fd) {
6463                 err = -ENOMEM;
6464                 goto err_out;
6465         }
6466
6467         fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir,
6468                 (u8 *)&wl->profile->dtim_period);
6469         if (!fd) {
6470                 err = -ENOMEM;
6471                 goto err_out;
6472         }
6473
6474 err_out:
6475         return err;
6476 }
6477
6478 static void wl_debugfs_remove_netdev(struct wl_priv *wl)
6479 {
6480         WL_DBG(("Enter \n"));
6481 }
6482
6483 static const struct rfkill_ops wl_rfkill_ops = {
6484         .set_block = wl_rfkill_set
6485 };
6486
6487 static int wl_rfkill_set(void *data, bool blocked)
6488 {
6489         struct wl_priv *wl = (struct wl_priv *)data;
6490
6491         WL_DBG(("Enter \n"));
6492         WL_DBG(("RF %s\n", blocked ? "blocked" : "unblocked"));
6493
6494         if (!wl)
6495                 return -EINVAL;
6496
6497         wl->rf_blocked = blocked;
6498
6499         return 0;
6500 }
6501
6502 static int wl_setup_rfkill(struct wl_priv *wl, bool setup)
6503 {
6504         s32 err = 0;
6505
6506         WL_DBG(("Enter \n"));
6507         if (!wl)
6508                 return -EINVAL;
6509         if (setup) {
6510                 wl->rfkill = rfkill_alloc("brcmfmac-wifi",
6511                         &wl_cfg80211_get_sdio_func()->dev,
6512                         RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl);
6513
6514                 if (!wl->rfkill) {
6515                         err = -ENOMEM;
6516                         goto err_out;
6517                 }
6518
6519                 err = rfkill_register(wl->rfkill);
6520
6521                 if (err)
6522                         rfkill_destroy(wl->rfkill);
6523         } else {
6524                 if (!wl->rfkill) {
6525                         err = -ENOMEM;
6526                         goto err_out;
6527                 }
6528
6529                 rfkill_unregister(wl->rfkill);
6530                 rfkill_destroy(wl->rfkill);
6531         }
6532
6533 err_out:
6534         return err;
6535 }