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