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