e34437748adb11d35c20d96901142b206d7f1d38
[linux-3.10.git] / drivers / net / wireless / bcmdhd_88 / wl_cfg80211.c
1
2 /*
3  * Linux cfg80211 driver
4  *
5  * Copyright (C) 1999-2013, Broadcom Corporation
6  * 
7  *      Unless you and Broadcom execute a separate written software license
8  * agreement governing use of this software, this software is licensed to you
9  * under the terms of the GNU General Public License version 2 (the "GPL"),
10  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
11  * following added to such license:
12  * 
13  *      As a special exception, the copyright holders of this software give you
14  * permission to link this software with independent modules, and to copy and
15  * distribute the resulting executable under terms of your choice, provided that
16  * you also meet, for each linked independent module, the terms and conditions of
17  * the license of that module.  An independent module is a module which is not
18  * derived from this software.  The special exception does not apply to any
19  * modifications of the software.
20  * 
21  *      Notwithstanding the above, under no circumstances may you combine this
22  * software in any way with any other Broadcom software provided under a license
23  * other than the GPL, without Broadcom's express prior written consent.
24  *
25  * $Id: wl_cfg80211.c 432088 2013-10-25 15:02:04Z $
26  */
27 /* */
28 #include <typedefs.h>
29 #include <linuxver.h>
30 #include <osl.h>
31 #include <linux/kernel.h>
32
33 #include <bcmutils.h>
34 #include <bcmwifi_channels.h>
35 #include <bcmendian.h>
36 #include <proto/ethernet.h>
37 #include <proto/802.11.h>
38 #include <linux/if_arp.h>
39 #include <asm/uaccess.h>
40
41 #include <dngl_stats.h>
42 #include <dhd.h>
43 #include <dhdioctl.h>
44 #include <wlioctl.h>
45 #include <dhd_cfg80211.h>
46 #ifdef PNO_SUPPORT
47 #include <dhd_pno.h>
48 #endif /* PNO_SUPPORT */
49
50 #include <proto/ethernet.h>
51 #include <linux/kernel.h>
52 #include <linux/kthread.h>
53 #include <linux/netdevice.h>
54 #include <linux/sched.h>
55 #include <linux/etherdevice.h>
56 #include <linux/wireless.h>
57 #include <linux/ieee80211.h>
58 #include <linux/wait.h>
59 #include <net/cfg80211.h>
60 #include <net/rtnetlink.h>
61
62 #include <wlioctl.h>
63 #include <wldev_common.h>
64 #include <wl_cfg80211.h>
65 #include <wl_cfgp2p.h>
66 #include <wl_android.h>
67
68 #ifdef PROP_TXSTATUS
69 #include <dhd_wlfc.h>
70 #endif
71
72 #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT)
73 #include <wl_cfgvendor.h>
74 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) || defined(WL_VENDOR_EXT_SUPPORT) */
75
76 #ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
77 #include "dhd_custom_sysfs_tegra.h"
78 #include "dhd_custom_sysfs_tegra_scan.h"
79 #endif
80
81
82 #define IW_WSEC_ENABLED(wsec)   ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
83
84 static struct device *cfg80211_parent_dev = NULL;
85 struct wl_priv *wlcfg_drv_priv = NULL;
86 u32 wl_dbg_level = WL_DBG_ERR;
87
88 #define MAX_WAIT_TIME 1500
89
90 #ifdef VSDB
91 /* sleep time to keep STA's connecting or connection for continuous af tx or finding a peer */
92 #define DEFAULT_SLEEP_TIME_VSDB         120
93 #define OFF_CHAN_TIME_THRESHOLD_MS      200
94 #define AF_RETRY_DELAY_TIME             40
95
96 /* if sta is connected or connecting, sleep for a while before retry af tx or finding a peer */
97 #define WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl)   \
98         do {    \
99                 if (wl_get_drv_status(wl, CONNECTED, wl_to_prmry_ndev(wl)) ||   \
100                         wl_get_drv_status(wl, CONNECTING, wl_to_prmry_ndev(wl))) {      \
101                         OSL_SLEEP(DEFAULT_SLEEP_TIME_VSDB);     \
102                 }       \
103         } while (0)
104 #else /* VSDB */
105 /* if not VSDB, do nothing */
106 #define WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl)
107 #endif /* VSDB */
108
109 #ifdef WL_CFG80211_SYNC_GON
110 #define WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl) \
111         (wl_get_drv_status_all(wl, SENDING_ACT_FRM) || \
112                 wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN))
113 #else
114 #define WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl) wl_get_drv_status_all(wl, SENDING_ACT_FRM)
115 #endif /* WL_CFG80211_SYNC_GON */
116
117 #define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL
118
119
120 #define DNGL_FUNC(func, parameters) func parameters;
121 #define COEX_DHCP
122
123 #define WLAN_EID_SSID   0
124 #define CH_MIN_5G_CHANNEL 34
125 #define CH_MIN_2G_CHANNEL 1
126
127 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
128  * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
129  * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165).
130  * With respect to these flags, wpa_supplicant doesn't start p2p operations on 5GHz channels.
131  * All the chnages in world regulatory domain are to be done here.
132  */
133 static const struct ieee80211_regdomain brcm_regdom = {
134         .n_reg_rules = 4,
135         .alpha2 =  "99",
136         .reg_rules = {
137                 /* IEEE 802.11b/g, channels 1..11 */
138                 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
139                 /* If any */
140                 /* IEEE 802.11 channel 14 - Only JP enables
141                  * this and for 802.11b only
142                  */
143                 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
144                 /* IEEE 802.11a, channel 36..64 */
145                 REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
146                 /* IEEE 802.11a, channel 100..165 */
147                 REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
148 };
149
150 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) && \
151         (defined(WL_IFACE_COMB_NUM_CHANNELS) || defined(WL_CFG80211_P2P_DEV_IF))
152 /*
153  * Possible interface combinations supported by driver
154  *
155  * ADHOC Mode     - #ADHOC <= 1 on channels = 1
156  * SoftAP Mode    - #AP <= 1 on channels = 1
157  * STA + P2P Mode - #STA <= 2, #{P2P-GO, P2P-client} <= 1, #P2P-device <= 1
158  *                  on channels = 2
159  */
160 static const struct ieee80211_iface_limit softap_limits[] = {
161         {
162         .max = 1,
163         .types = BIT(NL80211_IFTYPE_AP),
164         },
165 };
166
167 static const struct ieee80211_iface_limit sta_p2p_limits[] = {
168         /*
169          * During P2P-GO removal, P2P-GO is first changed to STA and later only
170          * removed. So setting maximum possible number of STA interfaces as 3 to
171          * accommodate the above behaviour.
172          */
173         {
174 #ifdef WL_ENABLE_P2P_IF
175         .max = 3,
176 #else
177         .max = 2,
178 #endif /* WL_ENABLE_P2P_IF */
179
180         .types = BIT(NL80211_IFTYPE_STATION),
181         },
182         {
183         .max = 2,
184         .types = BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT),
185         },
186 #if defined(WL_CFG80211_P2P_DEV_IF)
187         {
188         .max = 1,
189         .types = BIT(NL80211_IFTYPE_P2P_DEVICE),
190         },
191 #endif /* WL_CFG80211_P2P_DEV_IF */
192         {
193         .max = 1,
194         .types = BIT(NL80211_IFTYPE_ADHOC),
195         },
196 };
197
198 static const struct ieee80211_iface_combination
199 softap_iface_combinations[] = {
200         {
201         .num_different_channels = 1,
202         .max_interfaces = 1,
203         .limits = softap_limits,
204         .n_limits = ARRAY_SIZE(softap_limits),
205         },
206 };
207
208 static const struct ieee80211_iface_combination
209 sta_p2p_iface_combinations[] = {
210         {
211 #ifdef DHD_ENABLE_MCC
212         .num_different_channels = 2,
213 #else
214         .num_different_channels = 1,
215 #endif
216         .max_interfaces = 3,
217         .limits = sta_p2p_limits,
218         .n_limits = ARRAY_SIZE(sta_p2p_limits),
219         },
220 };
221 #endif /* LINUX_VER >= 3.0 && (WL_IFACE_COMB_NUM_CHANNELS || WL_CFG80211_P2P_DEV_IF) */
222
223 /* Data Element Definitions */
224 #define WPS_ID_CONFIG_METHODS     0x1008
225 #define WPS_ID_REQ_TYPE           0x103A
226 #define WPS_ID_DEVICE_NAME        0x1011
227 #define WPS_ID_VERSION            0x104A
228 #define WPS_ID_DEVICE_PWD_ID      0x1012
229 #define WPS_ID_REQ_DEV_TYPE       0x106A
230 #define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053
231 #define WPS_ID_PRIM_DEV_TYPE      0x1054
232
233 /* Device Password ID */
234 #define DEV_PW_DEFAULT 0x0000
235 #define DEV_PW_USER_SPECIFIED 0x0001,
236 #define DEV_PW_MACHINE_SPECIFIED 0x0002
237 #define DEV_PW_REKEY 0x0003
238 #define DEV_PW_PUSHBUTTON 0x0004
239 #define DEV_PW_REGISTRAR_SPECIFIED 0x0005
240
241 /* Config Methods */
242 #define WPS_CONFIG_USBA 0x0001
243 #define WPS_CONFIG_ETHERNET 0x0002
244 #define WPS_CONFIG_LABEL 0x0004
245 #define WPS_CONFIG_DISPLAY 0x0008
246 #define WPS_CONFIG_EXT_NFC_TOKEN 0x0010
247 #define WPS_CONFIG_INT_NFC_TOKEN 0x0020
248 #define WPS_CONFIG_NFC_INTERFACE 0x0040
249 #define WPS_CONFIG_PUSHBUTTON 0x0080
250 #define WPS_CONFIG_KEYPAD 0x0100
251 #define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
252 #define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
253 #define WPS_CONFIG_VIRT_DISPLAY 0x2008
254 #define WPS_CONFIG_PHY_DISPLAY 0x4008
255
256 #define PM_BLOCK 1
257 #define PM_ENABLE 0
258
259
260
261 #ifndef IBSS_COALESCE_ALLOWED
262 #define IBSS_COALESCE_ALLOWED   0
263 #endif
264
265 #ifndef IBSS_INITIAL_SCAN_ALLOWED
266 #define IBSS_INITIAL_SCAN_ALLOWED       0
267 #endif
268 /*
269  * cfg80211_ops api/callback list
270  */
271 static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
272         const struct ether_addr *sa, const struct ether_addr *bssid,
273         u8 **pheader, u32 *body_len, u8 *pbody);
274 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
275         struct cfg80211_scan_request *request,
276         struct cfg80211_ssid *this_ssid);
277 #if defined(WL_CFG80211_P2P_DEV_IF)
278 static s32
279 wl_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request);
280 #else
281 static s32
282 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
283         struct cfg80211_scan_request *request);
284 #endif /* WL_CFG80211_P2P_DEV_IF */
285 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
286 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
287         struct cfg80211_ibss_params *params);
288 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
289         struct net_device *dev);
290 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
291         struct net_device *dev, u8 *mac,
292         struct station_info *sinfo);
293 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
294         struct net_device *dev, bool enabled,
295         s32 timeout);
296 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
297         struct cfg80211_connect_params *sme);
298 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
299         u16 reason_code);
300 #if defined(WL_CFG80211_P2P_DEV_IF)
301 static s32
302 wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
303         enum nl80211_tx_power_setting type, s32 mbm);
304 #else
305 static s32
306 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
307         enum nl80211_tx_power_setting type, s32 dbm);
308 #endif /* WL_CFG80211_P2P_DEV_IF */
309 #if defined(WL_CFG80211_P2P_DEV_IF)
310 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy,
311         struct wireless_dev *wdev, s32 *dbm);
312 #else
313 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
314 #endif /* WL_CFG80211_P2P_DEV_IF */
315 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
316         struct net_device *dev,
317         u8 key_idx, bool unicast, bool multicast);
318 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
319         u8 key_idx, bool pairwise, const u8 *mac_addr,
320         struct key_params *params);
321 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
322         u8 key_idx, bool pairwise, const u8 *mac_addr);
323 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
324         u8 key_idx, bool pairwise, const u8 *mac_addr,
325         void *cookie, void (*callback) (void *cookie,
326         struct key_params *params));
327 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
328         struct net_device *dev, u8 key_idx);
329 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
330 #if defined(WL_SUPPORT_BACKPORTED_KPATCHES) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3, \
331         2, 0))
332 static s32 wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
333         bcm_struct_cfgdev *cfgdev, u64 cookie);
334 static s32 wl_cfg80211_del_station(struct wiphy *wiphy,
335         struct net_device *ndev, u8* mac_addr);
336 #endif /* WL_SUPPORT_BACKPORTED_KPATCHES || KERNEL_VER >= KERNEL_VERSION(3, 2, 0)) */
337 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) || 0
338 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
339 #else
340 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
341 #endif
342 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
343         struct cfg80211_pmksa *pmksa);
344 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
345         struct cfg80211_pmksa *pmksa);
346 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
347         struct net_device *dev);
348 static void wl_cfg80211_scan_abort(struct wl_priv *wl);
349 static s32 wl_notify_escan_complete(struct wl_priv *wl,
350         struct net_device *ndev, bool aborted, bool fw_abort);
351 #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)) || 0
352 static s32 wl_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
353         u8 *peer, enum nl80211_tdls_operation oper);
354 #endif 
355
356 /*
357  * event & event Q handlers for cfg80211 interfaces
358  */
359 static s32 wl_create_event_handler(struct wl_priv *wl);
360 static void wl_destroy_event_handler(struct wl_priv *wl);
361 static s32 wl_event_handler(void *data);
362 static void wl_init_eq(struct wl_priv *wl);
363 static void wl_flush_eq(struct wl_priv *wl);
364 static unsigned long wl_lock_eq(struct wl_priv *wl);
365 static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags);
366 static void wl_init_eq_lock(struct wl_priv *wl);
367 static void wl_init_event_handler(struct wl_priv *wl);
368 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
369 static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
370         const wl_event_msg_t *msg, void *data);
371 static void wl_put_event(struct wl_event_q *e);
372 static void wl_wakeup_event(struct wl_priv *wl);
373 static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
374         const wl_event_msg_t *e, void *data);
375 static s32 wl_notify_connect_status(struct wl_priv *wl,
376         bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data);
377 static s32 wl_notify_roaming_status(struct wl_priv *wl,
378         bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data);
379 static s32 wl_notify_scan_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev,
380         const wl_event_msg_t *e, void *data);
381 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
382         const wl_event_msg_t *e, void *data, bool completed);
383 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
384         const wl_event_msg_t *e, void *data);
385 static s32 wl_notify_mic_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev,
386         const wl_event_msg_t *e, void *data);
387 #ifdef WL_SCHED_SCAN
388 static s32
389 wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev,
390         const wl_event_msg_t *e, void *data);
391 #endif /* WL_SCHED_SCAN */
392 #ifdef PNO_SUPPORT
393 static s32 wl_notify_pfn_status(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev,
394         const wl_event_msg_t *e, void *data);
395 #endif /* PNO_SUPPORT */
396 static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_info,
397         enum wl_status state, bool set);
398
399 #ifdef WLTDLS
400 static s32 wl_tdls_event_handler(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev,
401         const wl_event_msg_t *e, void *data);
402 #endif /* WLTDLS */
403 #ifdef BCMCCX_S69
404 static s32 wl_ccx_s69_response(struct wl_priv *wl, bcm_struct_cfgdev *cfgdev,
405         const wl_event_msg_t *e, void *data);
406 #endif
407 /*
408  * register/deregister parent device
409  */
410 static void wl_cfg80211_clear_parent_dev(void);
411
412 /*
413  * ioctl utilites
414  */
415
416 /*
417  * cfg80211 set_wiphy_params utilities
418  */
419 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
420 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
421 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
422
423 /*
424  * wl profile utilities
425  */
426 static s32 wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
427         const wl_event_msg_t *e, void *data, s32 item);
428 static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item);
429 static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev);
430
431 /*
432  * cfg80211 connect utilites
433  */
434 static s32 wl_set_wpa_version(struct net_device *dev,
435         struct cfg80211_connect_params *sme);
436 static s32 wl_set_auth_type(struct net_device *dev,
437         struct cfg80211_connect_params *sme);
438 static s32 wl_set_set_cipher(struct net_device *dev,
439         struct cfg80211_connect_params *sme);
440 static s32 wl_set_key_mgmt(struct net_device *dev,
441         struct cfg80211_connect_params *sme);
442 static s32 wl_set_set_sharedkey(struct net_device *dev,
443         struct cfg80211_connect_params *sme);
444 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev);
445 static void wl_ch_to_chanspec(int ch,
446         struct wl_join_params *join_params, size_t *join_params_size);
447
448 /*
449  * information element utilities
450  */
451 static void wl_rst_ie(struct wl_priv *wl);
452 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
453 static void wl_update_hidden_ap_ie(struct wl_bss_info *bi, u8 *ie_stream, u32 *ie_size);
454 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
455 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
456 static u32 wl_get_ielen(struct wl_priv *wl);
457
458
459 static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev, void *data);
460 static void wl_free_wdev(struct wl_priv *wl);
461 #ifdef CONFIG_CFG80211_INTERNAL_REGDB
462 static int
463 wl_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
464 #endif /* CONFIG_CFG80211_INTERNAL_REGDB */
465
466 static s32 wl_inform_bss(struct wl_priv *wl);
467 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
468 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev);
469 static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy);
470 s32 wl_cfg80211_channel_to_freq(u32 channel);
471
472
473 static void wl_cfg80211_work_handler(struct work_struct *work);
474 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
475         u8 key_idx, const u8 *mac_addr,
476         struct key_params *params);
477 /*
478  * key indianess swap utilities
479  */
480 static void swap_key_from_BE(struct wl_wsec_key *key);
481 static void swap_key_to_BE(struct wl_wsec_key *key);
482
483 /*
484  * wl_priv memory init/deinit utilities
485  */
486 static s32 wl_init_priv_mem(struct wl_priv *wl);
487 static void wl_deinit_priv_mem(struct wl_priv *wl);
488
489 static void wl_delay(u32 ms);
490
491 /*
492  * ibss mode utilities
493  */
494 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
495 static __used bool wl_is_ibssstarter(struct wl_priv *wl);
496
497 /*
498  * link up/down , default configuration utilities
499  */
500 static s32 __wl_cfg80211_up(struct wl_priv *wl);
501 static s32 __wl_cfg80211_down(struct wl_priv *wl);
502 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
503 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
504 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
505 static void wl_link_up(struct wl_priv *wl);
506 static void wl_link_down(struct wl_priv *wl);
507 static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
508 static void wl_init_conf(struct wl_conf *conf);
509
510 /*
511  * iscan handler
512  */
513 static void wl_iscan_timer(unsigned long data);
514 static void wl_term_iscan(struct wl_priv *wl);
515 static s32 wl_init_scan(struct wl_priv *wl);
516 static s32 wl_iscan_thread(void *data);
517 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
518         u16 action);
519 static s32 wl_do_iscan(struct wl_priv *wl,  struct cfg80211_scan_request *request);
520 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
521 static s32 wl_invoke_iscan(struct wl_priv *wl);
522 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
523         struct wl_scan_results **bss_list);
524 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
525 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan);
526 static s32 wl_iscan_done(struct wl_priv *wl);
527 static s32 wl_iscan_pending(struct wl_priv *wl);
528 static s32 wl_iscan_inprogress(struct wl_priv *wl);
529 static s32 wl_iscan_aborted(struct wl_priv *wl);
530
531 /*
532  * find most significant bit set
533  */
534 static __used u32 wl_find_msb(u16 bit16);
535
536 /*
537  * rfkill support
538  */
539 static int wl_setup_rfkill(struct wl_priv *wl, bool setup);
540 static int wl_rfkill_set(void *data, bool blocked);
541 #ifdef DEBUGFS_CFG80211
542 static s32 wl_setup_debugfs(struct wl_priv *wl);
543 static s32 wl_free_debugfs(struct wl_priv *wl);
544 #endif
545
546 static wl_scan_params_t *wl_cfg80211_scan_alloc_params(int channel,
547         int nprobes, int *out_params_size);
548 static bool check_dev_role_integrity(struct wl_priv *wl, u32 dev_role);
549
550 /*
551  * Some external functions, TODO: move them to dhd_linux.h
552  */
553 int dhd_add_monitor(char *name, struct net_device **new_ndev);
554 int dhd_del_monitor(struct net_device *ndev);
555 int dhd_monitor_init(void *dhd_pub);
556 int dhd_monitor_uninit(void);
557 int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
558
559
560
561 #define RETURN_EIO_IF_NOT_UP(wlpriv)                                            \
562 do {                                                                    \
563         struct net_device *checkSysUpNDev = wl_to_prmry_ndev(wlpriv);           \
564         if (unlikely(!wl_get_drv_status(wlpriv, READY, checkSysUpNDev))) {      \
565                 WL_INFO(("device is not ready\n"));                     \
566                 return -EIO;                                            \
567         }                                                               \
568 } while (0)
569
570 #ifdef RSSI_OFFSET
571 static s32 wl_rssi_offset(s32 rssi)
572 {
573         rssi += RSSI_OFFSET;
574         if (rssi > 0)
575                 rssi = 0;
576         return rssi;
577 }
578 #else
579 #define wl_rssi_offset(x)       x
580 #endif
581
582 #define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE ||                       \
583                                  (akm) == RSN_AKM_UNSPECIFIED ||        \
584                                  (akm) == RSN_AKM_PSK)
585
586
587 extern int dhd_wait_pend8021x(struct net_device *dev);
588 #ifdef PROP_TXSTATUS_VSDB
589 extern int disable_proptx;
590 extern int dhd_wlfc_init(dhd_pub_t *dhd);
591 extern void dhd_wlfc_deinit(dhd_pub_t *dhd);
592 #endif /* PROP_TXSTATUS_VSDB */
593
594 #if (WL_DBG_LEVEL > 0)
595 #define WL_DBG_ESTR_MAX 50
596 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
597         "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
598         "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
599         "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
600         "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
601         "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
602         "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
603         "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
604         "PFN_NET_LOST",
605         "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
606         "IBSS_ASSOC",
607         "RADIO", "PSM_WATCHDOG", "WLC_E_CCX_ASSOC_START", "WLC_E_CCX_ASSOC_ABORT",
608         "PROBREQ_MSG",
609         "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
610         "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
611         "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
612         "WLC_E_BTA_HCI_EVENT", "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE",
613         "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG",
614         "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND",
615         "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED",
616         "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT",
617         "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE",
618         "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP",
619         "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE"
620 };
621 #endif                          /* WL_DBG_LEVEL */
622
623 #define CHAN2G(_channel, _freq, _flags) {                       \
624         .band                   = IEEE80211_BAND_2GHZ,          \
625         .center_freq            = (_freq),                      \
626         .hw_value               = (_channel),                   \
627         .flags                  = (_flags),                     \
628         .max_antenna_gain       = 0,                            \
629         .max_power              = 30,                           \
630 }
631
632 #define CHAN5G(_channel, _flags) {                              \
633         .band                   = IEEE80211_BAND_5GHZ,          \
634         .center_freq            = 5000 + (5 * (_channel)),      \
635         .hw_value               = (_channel),                   \
636         .flags                  = (_flags),                     \
637         .max_antenna_gain       = 0,                            \
638         .max_power              = 30,                           \
639 }
640
641 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
642 #define RATETAB_ENT(_rateid, _flags) \
643         {                                                               \
644                 .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
645                 .hw_value       = (_rateid),                        \
646                 .flags    = (_flags),                        \
647         }
648
649 static struct ieee80211_rate __wl_rates[] = {
650         RATETAB_ENT(DOT11_RATE_1M, 0),
651         RATETAB_ENT(DOT11_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
652         RATETAB_ENT(DOT11_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
653         RATETAB_ENT(DOT11_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
654         RATETAB_ENT(DOT11_RATE_6M, 0),
655         RATETAB_ENT(DOT11_RATE_9M, 0),
656         RATETAB_ENT(DOT11_RATE_12M, 0),
657         RATETAB_ENT(DOT11_RATE_18M, 0),
658         RATETAB_ENT(DOT11_RATE_24M, 0),
659         RATETAB_ENT(DOT11_RATE_36M, 0),
660         RATETAB_ENT(DOT11_RATE_48M, 0),
661         RATETAB_ENT(DOT11_RATE_54M, 0)
662 };
663
664 #define wl_a_rates              (__wl_rates + 4)
665 #define wl_a_rates_size 8
666 #define wl_g_rates              (__wl_rates + 0)
667 #define wl_g_rates_size 12
668
669 static struct ieee80211_channel __wl_2ghz_channels[] = {
670         CHAN2G(1, 2412, 0),
671         CHAN2G(2, 2417, 0),
672         CHAN2G(3, 2422, 0),
673         CHAN2G(4, 2427, 0),
674         CHAN2G(5, 2432, 0),
675         CHAN2G(6, 2437, 0),
676         CHAN2G(7, 2442, 0),
677         CHAN2G(8, 2447, 0),
678         CHAN2G(9, 2452, 0),
679         CHAN2G(10, 2457, 0),
680         CHAN2G(11, 2462, 0),
681         CHAN2G(12, 2467, 0),
682         CHAN2G(13, 2472, 0),
683         CHAN2G(14, 2484, 0)
684 };
685
686 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
687         CHAN5G(34, 0), CHAN5G(36, 0),
688         CHAN5G(38, 0), CHAN5G(40, 0),
689         CHAN5G(42, 0), CHAN5G(44, 0),
690         CHAN5G(46, 0), CHAN5G(48, 0),
691         CHAN5G(52, 0), CHAN5G(56, 0),
692         CHAN5G(60, 0), CHAN5G(64, 0),
693         CHAN5G(100, 0), CHAN5G(104, 0),
694         CHAN5G(108, 0), CHAN5G(112, 0),
695         CHAN5G(116, 0), CHAN5G(120, 0),
696         CHAN5G(124, 0), CHAN5G(128, 0),
697         CHAN5G(132, 0), CHAN5G(136, 0),
698         CHAN5G(140, 0), CHAN5G(149, 0),
699         CHAN5G(153, 0), CHAN5G(157, 0),
700         CHAN5G(161, 0), CHAN5G(165, 0)
701 };
702
703 static struct ieee80211_supported_band __wl_band_2ghz = {
704         .band = IEEE80211_BAND_2GHZ,
705         .channels = __wl_2ghz_channels,
706         .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
707         .bitrates = wl_g_rates,
708         .n_bitrates = wl_g_rates_size
709 };
710
711 static struct ieee80211_supported_band __wl_band_5ghz_a = {
712         .band = IEEE80211_BAND_5GHZ,
713         .channels = __wl_5ghz_a_channels,
714         .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
715         .bitrates = wl_a_rates,
716         .n_bitrates = wl_a_rates_size
717 };
718
719 static const u32 __wl_cipher_suites[] = {
720         WLAN_CIPHER_SUITE_WEP40,
721         WLAN_CIPHER_SUITE_WEP104,
722         WLAN_CIPHER_SUITE_TKIP,
723         WLAN_CIPHER_SUITE_CCMP,
724         WLAN_CIPHER_SUITE_AES_CMAC,
725 };
726
727
728 #if defined(USE_DYNAMIC_MAXPKT_RXGLOM)
729 static int maxrxpktglom = 0;
730 #endif
731
732 /* IOCtl version read from targeted driver */
733 static int ioctl_version;
734 #ifdef DEBUGFS_CFG80211
735 #define S_SUBLOGLEVEL 20
736 static const struct {
737         u32 log_level;
738         char *sublogname;
739 } sublogname_map[] = {
740         {WL_DBG_ERR, "ERR"},
741         {WL_DBG_INFO, "INFO"},
742         {WL_DBG_DBG, "DBG"},
743         {WL_DBG_SCAN, "SCAN"},
744         {WL_DBG_TRACE, "TRACE"},
745         {WL_DBG_P2P_ACTION, "P2PACTION"}
746 };
747 #endif
748
749
750 static void wl_add_remove_pm_enable_work(struct wl_priv *wl, bool add_remove,
751         enum wl_handler_del_type type)
752 {
753         if (wl->pm_enable_work_on) {
754                 if (add_remove) {
755                         schedule_delayed_work(&wl->pm_enable_work,
756                                 msecs_to_jiffies(WL_PM_ENABLE_TIMEOUT));
757                 } else {
758                         cancel_delayed_work_sync(&wl->pm_enable_work);
759                         switch (type) {
760                                 case WL_HANDLER_MAINTAIN:
761                                         schedule_delayed_work(&wl->pm_enable_work,
762                                                 msecs_to_jiffies(WL_PM_ENABLE_TIMEOUT));
763                                         break;
764                                 case WL_HANDLER_PEND:
765                                         schedule_delayed_work(&wl->pm_enable_work,
766                                                 msecs_to_jiffies(WL_PM_ENABLE_TIMEOUT*2));
767                                         break;
768                                 case WL_HANDLER_DEL:
769                                 default:
770                                         wl->pm_enable_work_on = false;
771                                         break;
772                         }
773                 }
774         }
775 }
776
777 /* Return a new chanspec given a legacy chanspec
778  * Returns INVCHANSPEC on error
779  */
780 static chanspec_t
781 wl_chspec_from_legacy(chanspec_t legacy_chspec)
782 {
783         chanspec_t chspec;
784
785         /* get the channel number */
786         chspec = LCHSPEC_CHANNEL(legacy_chspec);
787
788         /* convert the band */
789         if (LCHSPEC_IS2G(legacy_chspec)) {
790                 chspec |= WL_CHANSPEC_BAND_2G;
791         } else {
792                 chspec |= WL_CHANSPEC_BAND_5G;
793         }
794
795         /* convert the bw and sideband */
796         if (LCHSPEC_IS20(legacy_chspec)) {
797                 chspec |= WL_CHANSPEC_BW_20;
798         } else {
799                 chspec |= WL_CHANSPEC_BW_40;
800                 if (LCHSPEC_CTL_SB(legacy_chspec) == WL_LCHANSPEC_CTL_SB_LOWER) {
801                         chspec |= WL_CHANSPEC_CTL_SB_L;
802                 } else {
803                         chspec |= WL_CHANSPEC_CTL_SB_U;
804                 }
805         }
806
807         if (wf_chspec_malformed(chspec)) {
808                 WL_ERR(("wl_chspec_from_legacy: output chanspec (0x%04X) malformed\n",
809                         chspec));
810                 return INVCHANSPEC;
811         }
812
813         return chspec;
814 }
815
816 /* Return a legacy chanspec given a new chanspec
817  * Returns INVCHANSPEC on error
818  */
819 static chanspec_t
820 wl_chspec_to_legacy(chanspec_t chspec)
821 {
822         chanspec_t lchspec;
823
824         if (wf_chspec_malformed(chspec)) {
825                 WL_ERR(("wl_chspec_to_legacy: input chanspec (0x%04X) malformed\n",
826                         chspec));
827                 return INVCHANSPEC;
828         }
829
830         /* get the channel number */
831         lchspec = CHSPEC_CHANNEL(chspec);
832
833         /* convert the band */
834         if (CHSPEC_IS2G(chspec)) {
835                 lchspec |= WL_LCHANSPEC_BAND_2G;
836         } else {
837                 lchspec |= WL_LCHANSPEC_BAND_5G;
838         }
839
840         /* convert the bw and sideband */
841         if (CHSPEC_IS20(chspec)) {
842                 lchspec |= WL_LCHANSPEC_BW_20;
843                 lchspec |= WL_LCHANSPEC_CTL_SB_NONE;
844         } else if (CHSPEC_IS40(chspec)) {
845                 lchspec |= WL_LCHANSPEC_BW_40;
846                 if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_L) {
847                         lchspec |= WL_LCHANSPEC_CTL_SB_LOWER;
848                 } else {
849                         lchspec |= WL_LCHANSPEC_CTL_SB_UPPER;
850                 }
851         } else {
852                 /* cannot express the bandwidth */
853                 char chanbuf[CHANSPEC_STR_LEN];
854                 WL_ERR((
855                         "wl_chspec_to_legacy: unable to convert chanspec %s (0x%04X) "
856                         "to pre-11ac format\n",
857                         wf_chspec_ntoa(chspec, chanbuf), chspec));
858                 return INVCHANSPEC;
859         }
860
861         return lchspec;
862 }
863
864 /* given a chanspec value, do the endian and chanspec version conversion to
865  * a chanspec_t value
866  * Returns INVCHANSPEC on error
867  */
868 static chanspec_t
869 wl_chspec_host_to_driver(chanspec_t chanspec)
870 {
871         if (ioctl_version == 1) {
872                 chanspec = wl_chspec_to_legacy(chanspec);
873                 if (chanspec == INVCHANSPEC) {
874                         return chanspec;
875                 }
876         }
877         chanspec = htodchanspec(chanspec);
878
879         return chanspec;
880 }
881
882 /* given a channel value, do the endian and chanspec version conversion to
883  * a chanspec_t value
884  * Returns INVCHANSPEC on error
885  */
886 chanspec_t
887 wl_ch_host_to_driver(u16 channel)
888 {
889
890         chanspec_t chanspec;
891
892         chanspec = channel & WL_CHANSPEC_CHAN_MASK;
893
894         if (channel <= CH_MAX_2G_CHANNEL)
895                 chanspec |= WL_CHANSPEC_BAND_2G;
896         else
897                 chanspec |= WL_CHANSPEC_BAND_5G;
898
899         chanspec |= WL_CHANSPEC_BW_20;
900         chanspec |= WL_CHANSPEC_CTL_SB_NONE;
901
902         return wl_chspec_host_to_driver(chanspec);
903 }
904
905 /* given a chanspec value from the driver, do the endian and chanspec version conversion to
906  * a chanspec_t value
907  * Returns INVCHANSPEC on error
908  */
909 static chanspec_t
910 wl_chspec_driver_to_host(chanspec_t chanspec)
911 {
912         chanspec = dtohchanspec(chanspec);
913         if (ioctl_version == 1) {
914                 chanspec = wl_chspec_from_legacy(chanspec);
915         }
916
917         return chanspec;
918 }
919
920 /* There isn't a lot of sense in it, but you can transmit anything you like */
921 static const struct ieee80211_txrx_stypes
922 wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
923         [NL80211_IFTYPE_ADHOC] = {
924                 .tx = 0xffff,
925                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
926         },
927         [NL80211_IFTYPE_STATION] = {
928                 .tx = 0xffff,
929                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
930                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
931         },
932         [NL80211_IFTYPE_AP] = {
933                 .tx = 0xffff,
934                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
935                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
936                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
937                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
938                 BIT(IEEE80211_STYPE_AUTH >> 4) |
939                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
940                 BIT(IEEE80211_STYPE_ACTION >> 4)
941         },
942         [NL80211_IFTYPE_AP_VLAN] = {
943                 /* copy AP */
944                 .tx = 0xffff,
945                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
946                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
947                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
948                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
949                 BIT(IEEE80211_STYPE_AUTH >> 4) |
950                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
951                 BIT(IEEE80211_STYPE_ACTION >> 4)
952         },
953         [NL80211_IFTYPE_P2P_CLIENT] = {
954                 .tx = 0xffff,
955                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
956                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
957         },
958         [NL80211_IFTYPE_P2P_GO] = {
959                 .tx = 0xffff,
960                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
961                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
962                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
963                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
964                 BIT(IEEE80211_STYPE_AUTH >> 4) |
965                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
966                 BIT(IEEE80211_STYPE_ACTION >> 4)
967         },
968 #if defined(WL_CFG80211_P2P_DEV_IF)
969         [NL80211_IFTYPE_P2P_DEVICE] = {
970                 .tx = 0xffff,
971                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
972                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
973         },
974 #endif /* WL_CFG80211_P2P_DEV_IF */
975 };
976
977 static void swap_key_from_BE(struct wl_wsec_key *key)
978 {
979         key->index = htod32(key->index);
980         key->len = htod32(key->len);
981         key->algo = htod32(key->algo);
982         key->flags = htod32(key->flags);
983         key->rxiv.hi = htod32(key->rxiv.hi);
984         key->rxiv.lo = htod16(key->rxiv.lo);
985         key->iv_initialized = htod32(key->iv_initialized);
986 }
987
988 static void swap_key_to_BE(struct wl_wsec_key *key)
989 {
990         key->index = dtoh32(key->index);
991         key->len = dtoh32(key->len);
992         key->algo = dtoh32(key->algo);
993         key->flags = dtoh32(key->flags);
994         key->rxiv.hi = dtoh32(key->rxiv.hi);
995         key->rxiv.lo = dtoh16(key->rxiv.lo);
996         key->iv_initialized = dtoh32(key->iv_initialized);
997 }
998
999 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !0
1000 /* For debug: Dump the contents of the encoded wps ie buffe */
1001 static void
1002 wl_validate_wps_ie(char *wps_ie, s32 wps_ie_len, bool *pbc)
1003 {
1004         #define WPS_IE_FIXED_LEN 6
1005         u16 len;
1006         u8 *subel = NULL;
1007         u16 subelt_id;
1008         u16 subelt_len;
1009         u16 val;
1010         u8 *valptr = (uint8*) &val;
1011         if (wps_ie == NULL || wps_ie_len < WPS_IE_FIXED_LEN) {
1012                 WL_ERR(("invalid argument : NULL\n"));
1013                 return;
1014         }
1015         len = (u16)wps_ie[TLV_LEN_OFF];
1016
1017         if (len > wps_ie_len) {
1018                 WL_ERR(("invalid length len %d, wps ie len %d\n", len, wps_ie_len));
1019                 return;
1020         }
1021         WL_DBG(("wps_ie len=%d\n", len));
1022         len -= 4;       /* for the WPS IE's OUI, oui_type fields */
1023         subel = wps_ie + WPS_IE_FIXED_LEN;
1024         while (len >= 4) {              /* must have attr id, attr len fields */
1025                 valptr[0] = *subel++;
1026                 valptr[1] = *subel++;
1027                 subelt_id = HTON16(val);
1028
1029                 valptr[0] = *subel++;
1030                 valptr[1] = *subel++;
1031                 subelt_len = HTON16(val);
1032
1033                 len -= 4;                       /* for the attr id, attr len fields */
1034                 len -= subelt_len;      /* for the remaining fields in this attribute */
1035                 WL_DBG((" subel=%p, subelt_id=0x%x subelt_len=%u\n",
1036                         subel, subelt_id, subelt_len));
1037
1038                 if (subelt_id == WPS_ID_VERSION) {
1039                         WL_DBG(("  attr WPS_ID_VERSION: %u\n", *subel));
1040                 } else if (subelt_id == WPS_ID_REQ_TYPE) {
1041                         WL_DBG(("  attr WPS_ID_REQ_TYPE: %u\n", *subel));
1042                 } else if (subelt_id == WPS_ID_CONFIG_METHODS) {
1043                         valptr[0] = *subel;
1044                         valptr[1] = *(subel + 1);
1045                         WL_DBG(("  attr WPS_ID_CONFIG_METHODS: %x\n", HTON16(val)));
1046                 } else if (subelt_id == WPS_ID_DEVICE_NAME) {
1047                         char devname[100];
1048                         size_t namelen = MIN(subelt_len, sizeof(devname)-1);
1049                         memcpy(devname, subel, namelen);
1050                         devname[namelen] = '\0';
1051                         WL_DBG(("  attr WPS_ID_DEVICE_NAME: %s (len %u)\n",
1052                                 devname, subelt_len));
1053                 } else if (subelt_id == WPS_ID_DEVICE_PWD_ID) {
1054                         valptr[0] = *subel;
1055                         valptr[1] = *(subel + 1);
1056                         WL_DBG(("  attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val)));
1057                         *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false;
1058                 } else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) {
1059                         valptr[0] = *subel;
1060                         valptr[1] = *(subel + 1);
1061                         WL_DBG(("  attr WPS_ID_PRIM_DEV_TYPE: cat=%u \n", HTON16(val)));
1062                         valptr[0] = *(subel + 6);
1063                         valptr[1] = *(subel + 7);
1064                         WL_DBG(("  attr WPS_ID_PRIM_DEV_TYPE: subcat=%u\n", HTON16(val)));
1065                 } else if (subelt_id == WPS_ID_REQ_DEV_TYPE) {
1066                         valptr[0] = *subel;
1067                         valptr[1] = *(subel + 1);
1068                         WL_DBG(("  attr WPS_ID_REQ_DEV_TYPE: cat=%u\n", HTON16(val)));
1069                         valptr[0] = *(subel + 6);
1070                         valptr[1] = *(subel + 7);
1071                         WL_DBG(("  attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val)));
1072                 } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) {
1073                         valptr[0] = *subel;
1074                         valptr[1] = *(subel + 1);
1075                         WL_DBG(("  attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS"
1076                                 ": cat=%u\n", HTON16(val)));
1077                 } else {
1078                         WL_DBG(("  unknown attr 0x%x\n", subelt_id));
1079                 }
1080
1081                 subel += subelt_len;
1082         }
1083 }
1084 #endif 
1085
1086 static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy)
1087 {
1088         chanspec_t chspec;
1089         int cur_band, err = 0;
1090         struct wl_priv *wl = wiphy_priv(wiphy);
1091         struct net_device *dev = wl_to_prmry_ndev(wl);
1092         struct ether_addr bssid;
1093         struct wl_bss_info *bss = NULL;
1094
1095         if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
1096                 /* STA interface is not associated. So start the new interface on a temp
1097                  * channel . Later proper channel will be applied by the above framework
1098                  * via set_channel (cfg80211 API).
1099                  */
1100                 WL_DBG(("Not associated. Return a temp channel. \n"));
1101                 err = wldev_ioctl(dev, WLC_GET_BAND, &cur_band, sizeof(int), false);
1102                 if (unlikely(err)) {
1103                         WL_ERR(("Get band failed\n"));
1104                         return wl_ch_host_to_driver(WL_P2P_TEMP_CHAN);
1105                 }
1106                 if (cur_band == WLC_BAND_5G)
1107                         return wl_ch_host_to_driver(WL_P2P_TEMP_CHAN_5G);
1108                 else
1109                         return wl_ch_host_to_driver(WL_P2P_TEMP_CHAN);
1110         }
1111
1112
1113         *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
1114         if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf,
1115                 WL_EXTRA_BUF_MAX, false))) {
1116                         WL_ERR(("Failed to get associated bss info, use temp channel \n"));
1117                         chspec = wl_ch_host_to_driver(WL_P2P_TEMP_CHAN);
1118         }
1119         else {
1120                         bss = (struct wl_bss_info *) (wl->extra_buf + 4);
1121                         chspec =  bss->chanspec;
1122
1123                         WL_DBG(("Valid BSS Found. chanspec:%d \n", chspec));
1124         }
1125         return chspec;
1126 }
1127
1128 static bcm_struct_cfgdev *
1129 wl_cfg80211_add_monitor_if(char *name)
1130 {
1131 #if defined(WL_ENABLE_P2P_IF) || defined(WL_CFG80211_P2P_DEV_IF)
1132         WL_INFO(("wl_cfg80211_add_monitor_if: No more support monitor interface\n"));
1133         return ERR_PTR(-EOPNOTSUPP);
1134 #else
1135         struct net_device* ndev = NULL;
1136
1137         dhd_add_monitor(name, &ndev);
1138         WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev));
1139         return ndev_to_cfgdev(ndev);
1140 #endif /* WL_ENABLE_P2P_IF || WL_CFG80211_P2P_DEV_IF */
1141 }
1142
1143 static bcm_struct_cfgdev *
1144 wl_cfg80211_add_virtual_iface(struct wiphy *wiphy,
1145 #if defined(WL_CFG80211_P2P_DEV_IF)
1146         const char *name,
1147 #else
1148         char *name,
1149 #endif /* WL_CFG80211_P2P_DEV_IF */
1150         enum nl80211_iftype type, u32 *flags,
1151         struct vif_params *params)
1152 {
1153         s32 err;
1154         s32 timeout = -1;
1155         s32 wlif_type = -1;
1156         s32 mode = 0;
1157         s32 val = 0;
1158         s32 dhd_mode = 0;
1159         chanspec_t chspec;
1160         struct wl_priv *wl = wiphy_priv(wiphy);
1161         struct net_device *_ndev;
1162         struct ether_addr primary_mac;
1163         int (*net_attach)(void *dhdp, int ifidx);
1164         bool rollback_lock = false;
1165 #ifdef PROP_TXSTATUS_VSDB
1166         s32 up = 1;
1167         dhd_pub_t *dhd;
1168 #endif /* PROP_TXSTATUS_VSDB */
1169
1170         if (!wl)
1171                 return ERR_PTR(-EINVAL);
1172
1173 #ifdef PROP_TXSTATUS_VSDB
1174         dhd = (dhd_pub_t *)(wl->pub);
1175 #endif /* PROP_TXSTATUS_VSDB */
1176
1177         /* Use primary I/F for sending cmds down to firmware */
1178         _ndev = wl_to_prmry_ndev(wl);
1179
1180         if (wl_get_drv_status(wl, CONNECTING, _ndev)) {
1181                 WL_ERR(("Already AP connection going on\n"));
1182                 return -EBUSY;
1183         }
1184
1185         WL_DBG(("if name: %s, type: %d\n", name, type));
1186         switch (type) {
1187         case NL80211_IFTYPE_ADHOC:
1188         case NL80211_IFTYPE_AP_VLAN:
1189         case NL80211_IFTYPE_WDS:
1190         case NL80211_IFTYPE_MESH_POINT:
1191                 WL_ERR(("Unsupported interface type\n"));
1192                 mode = WL_MODE_IBSS;
1193                 return NULL;
1194         case NL80211_IFTYPE_MONITOR:
1195                 return wl_cfg80211_add_monitor_if((char *)name);
1196 #if defined(WL_CFG80211_P2P_DEV_IF)
1197         case NL80211_IFTYPE_P2P_DEVICE:
1198                 return wl_cfgp2p_add_p2p_disc_if();
1199 #endif /* WL_CFG80211_P2P_DEV_IF */
1200         case NL80211_IFTYPE_P2P_CLIENT:
1201         case NL80211_IFTYPE_STATION:
1202                 wlif_type = WL_P2P_IF_CLIENT;
1203                 mode = WL_MODE_BSS;
1204                 break;
1205         case NL80211_IFTYPE_P2P_GO:
1206         case NL80211_IFTYPE_AP:
1207                 wlif_type = WL_P2P_IF_GO;
1208                 mode = WL_MODE_AP;
1209                 break;
1210         default:
1211                 WL_ERR(("Unsupported interface type\n"));
1212                 return NULL;
1213                 break;
1214         }
1215
1216         if (!name) {
1217                 WL_ERR(("name is NULL\n"));
1218                 return NULL;
1219         }
1220         if (wl->p2p_supported && (wlif_type != -1)) {
1221                 ASSERT(wl->p2p); /* ensure expectation of p2p initialization */
1222                 if (wl_get_p2p_status(wl, IF_DELETING)) {
1223                         /* wait till IF_DEL is complete
1224                          * release the lock for the unregister to proceed
1225                          */
1226                         if (rtnl_is_locked()) {
1227                                 rtnl_unlock();
1228                                 rollback_lock = true;
1229                         }
1230                         WL_INFO(("Released the lock and wait till IF_DEL is complete\n"));
1231                         timeout = wait_event_interruptible_timeout(wl->netif_change_event,
1232                                 (wl_get_p2p_status(wl, IF_DELETING) == false),
1233                                 msecs_to_jiffies(MAX_WAIT_TIME));
1234
1235                         /* put back the rtnl_lock again */
1236                         if (rollback_lock) {
1237                                 rtnl_lock();
1238                                 rollback_lock = false;
1239                         }
1240                         if (timeout > 0) {
1241                                 WL_ERR(("IF DEL is Success\n"));
1242
1243                         } else {
1244                                 WL_ERR(("timeount < 0, return -EAGAIN\n"));
1245                                 return ERR_PTR(-EAGAIN);
1246                         }
1247                         /* It should be now be safe to put this check here since we are sure
1248                          * by now netdev_notifier (unregister) would have been called
1249                          */
1250                         if (wl->iface_cnt == IFACE_MAX_CNT)
1251                                 return ERR_PTR(-ENOMEM);
1252                 }
1253
1254 #ifdef PROP_TXSTATUS_VSDB
1255                 if (!dhd)
1256                         return ERR_PTR(-ENODEV);
1257 #endif /* PROP_TXSTATUS_VSDB */
1258                 if (!wl->p2p)
1259                         return ERR_PTR(-ENODEV);
1260
1261                 if (wl->p2p && !wl->p2p->on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
1262                         p2p_on(wl) = true;
1263                         wl_cfgp2p_set_firm_p2p(wl);
1264                         wl_cfgp2p_init_discovery(wl);
1265                         get_primary_mac(wl, &primary_mac);
1266                         wl_cfgp2p_generate_bss_mac(&primary_mac,
1267                                 &wl->p2p->dev_addr, &wl->p2p->int_addr);
1268                 }
1269
1270                 memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
1271                 strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
1272
1273                 wl_cfg80211_scan_abort(wl);
1274 #ifdef PROP_TXSTATUS_VSDB
1275                 if (dhd->op_mode != DHD_FLAG_IBSS_MODE && !wl->wlfc_on && !disable_proptx) {
1276                         dhd->wlfc_enabled = true;
1277                         dhd_wlfc_init(dhd);
1278                         err = wldev_ioctl(_ndev, WLC_UP, &up, sizeof(s32), true);
1279                         if (err < 0)
1280                                 WL_ERR(("WLC_UP return err:%d\n", err));
1281                         wl->wlfc_on = true;
1282                 }
1283 #endif /* PROP_TXSTATUS_VSDB */
1284
1285                 /* In concurrency case, STA may be already associated in a particular channel.
1286                  * so retrieve the current channel of primary interface and then start the virtual
1287                  * interface on that.
1288                  */
1289                  chspec = wl_cfg80211_get_shared_freq(wiphy);
1290
1291                 /* For P2P mode, use P2P-specific driver features to create the
1292                  * bss: "wl p2p_ifadd"
1293                  */
1294                 wl_set_p2p_status(wl, IF_ADD);
1295                 if (wlif_type == WL_P2P_IF_GO)
1296                         wldev_iovar_setint(_ndev, "mpc", 0);
1297                 err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
1298
1299                 if (unlikely(err)) {
1300                         WL_ERR((" virtual iface add failed (%d) \n", err));
1301                         return ERR_PTR(-ENOMEM);
1302                 }
1303
1304                 timeout = wait_event_interruptible_timeout(wl->netif_change_event,
1305                         (wl_get_p2p_status(wl, IF_ADD) == false),
1306                         msecs_to_jiffies(MAX_WAIT_TIME));
1307                 if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
1308
1309                         struct wireless_dev *vwdev;
1310                         vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
1311                         if (unlikely(!vwdev)) {
1312                                 WL_ERR(("Could not allocate wireless device\n"));
1313                                 return ERR_PTR(-ENOMEM);
1314                         }
1315                         vwdev->wiphy = wl->wdev->wiphy;
1316                         WL_INFO((" virtual interface(%s) is created memalloc done \n",
1317                                 wl->p2p->vir_ifname));
1318                         vwdev->iftype = type;
1319                         _ndev =  wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
1320                         _ndev->ieee80211_ptr = vwdev;
1321 #ifndef CONFIG_BCMDHD88_DISABLE_P2P_SYSFS_DEVICE_NODE
1322                         SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
1323 #endif
1324                         vwdev->netdev = _ndev;
1325                         wl_set_drv_status(wl, READY, _ndev);
1326                         wl->p2p->vif_created = true;
1327                         wl_set_mode_by_netdev(wl, _ndev, mode);
1328                         net_attach =  wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
1329                         if (net_attach && !net_attach(wl->pub, _ndev->ifindex)) {
1330                                 wl_alloc_netinfo(wl, _ndev, vwdev, mode, PM_ENABLE);
1331                                 val = 1;
1332                                 /* Disable firmware roaming for P2P interface  */
1333                                 wldev_iovar_setint(_ndev, "roam_off", val);
1334
1335                                 if (mode != WL_MODE_AP)
1336                                         wldev_iovar_setint(_ndev, "buf_key_b4_m4", 1);
1337
1338                                 WL_ERR((" virtual interface(%s) is "
1339                                         "created net attach done\n", wl->p2p->vir_ifname));
1340                                 if (mode == WL_MODE_AP)
1341                                         wl_set_drv_status(wl, CONNECTED, _ndev);
1342                                 if (type == NL80211_IFTYPE_P2P_CLIENT)
1343                                         dhd_mode = DHD_FLAG_P2P_GC_MODE;
1344                                 else if (type == NL80211_IFTYPE_P2P_GO)
1345                                         dhd_mode = DHD_FLAG_P2P_GO_MODE;
1346                                 DNGL_FUNC(dhd_cfg80211_set_p2p_info, (wl, dhd_mode));
1347 #ifdef PROP_TXSTATUS_VSDB
1348                                 if (dhd->op_mode != DHD_FLAG_IBSS_MODE && dhd->plat_enable)
1349                                         dhd->plat_enable((void *)dhd);
1350 #endif /* PROP_TXSTATUS_VSDB */
1351                                 /* reinitialize completion to clear previous count */
1352                                 INIT_COMPLETION(wl->iface_disable);
1353                         } else {
1354                                 goto fail;
1355                         }
1356                         return ndev_to_cfgdev(_ndev);
1357                 } else {
1358                         wl_clr_p2p_status(wl, IF_ADD);
1359                         WL_ERR((" virtual interface(%s) is not created \n", wl->p2p->vir_ifname));
1360                         memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
1361                         wl->p2p->vif_created = false;
1362 #ifdef PROP_TXSTATUS_VSDB
1363                 if (dhd->op_mode != DHD_FLAG_IBSS_MODE && dhd->wlfc_enabled && wl->wlfc_on) {
1364                         dhd->wlfc_enabled = false;
1365                         dhd_wlfc_deinit(dhd);
1366                         if (dhd->plat_deinit)
1367                                 dhd->plat_deinit((void *)dhd);
1368                         wl->wlfc_on = false;
1369                 }
1370 #endif /* PROP_TXSTATUS_VSDB */
1371                 }
1372         }
1373 fail:
1374         if (wlif_type == WL_P2P_IF_GO)
1375                 wldev_iovar_setint(_ndev, "mpc", 1);
1376         return ERR_PTR(-ENODEV);
1377 }
1378
1379 static s32
1380 wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev)
1381 {
1382         struct net_device *dev = NULL;
1383         struct ether_addr p2p_mac;
1384         struct wl_priv *wl = wiphy_priv(wiphy);
1385         s32 timeout = -1;
1386         s32 ret = 0;
1387         s32 index = -1;
1388         WL_DBG(("Enter\n"));
1389
1390         if (!wl)
1391                 return ERR_PTR(-EINVAL);
1392
1393 #if defined(WL_CFG80211_P2P_DEV_IF)
1394         if (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
1395                 return wl_cfgp2p_del_p2p_disc_if(cfgdev);
1396         }
1397 #endif /* WL_CFG80211_P2P_DEV_IF */
1398         dev = cfgdev_to_wlc_ndev(cfgdev, wl);
1399
1400         if (wl_cfgp2p_find_idx(wl, dev, &index) != BCME_OK) {
1401                 WL_ERR(("Find p2p index from ndev(%p) failed\n", dev));
1402                 return BCME_ERROR;
1403         }
1404         if (wl->p2p_supported) {
1405                 memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
1406
1407                 /* Clear GO_NEG_PHASE bit to take care of GO-NEG-FAIL cases
1408                  */
1409                 WL_DBG(("P2P: GO_NEG_PHASE status cleared "));
1410                 wl_clr_p2p_status(wl, GO_NEG_PHASE);
1411                 if (wl->p2p->vif_created) {
1412                         if (wl_get_drv_status(wl, SCANNING, dev)) {
1413                                 wl_notify_escan_complete(wl, dev, true, true);
1414                         }
1415                         wldev_iovar_setint(dev, "mpc", 1);
1416                         /* Delete pm_enable_work */
1417                         wl_add_remove_pm_enable_work(wl, FALSE, WL_HANDLER_DEL);
1418
1419                         /* for GC */
1420                         if (wl_get_drv_status(wl, DISCONNECTING, dev) &&
1421                                 (wl_get_mode_by_netdev(wl, dev) != WL_MODE_AP)) {
1422                                 WL_ERR(("Wait for Link Down event for GC !\n"));
1423                                 wait_for_completion_timeout
1424                                         (&wl->iface_disable, msecs_to_jiffies(500));
1425                         }
1426                         wl_set_p2p_status(wl, IF_DELETING);
1427                         DNGL_FUNC(dhd_cfg80211_clean_p2p_info, (wl));
1428
1429                         /* for GO */
1430                         if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
1431                                 wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, false);
1432                                 /* disable interface before bsscfg free */
1433                                 ret = wl_cfgp2p_ifdisable(wl, &p2p_mac);
1434                                 /* if fw doesn't support "ifdis",
1435                                    do not wait for link down of ap mode
1436                                  */
1437                                 if (ret == 0) {
1438                                         WL_ERR(("Wait for Link Down event for GO !!!\n"));
1439                                         wait_for_completion_timeout(&wl->iface_disable,
1440                                                 msecs_to_jiffies(500));
1441                                 } else if (ret != BCME_UNSUPPORTED) {
1442                                         msleep(300);
1443                                 }
1444                         }
1445                         wl_cfgp2p_clear_management_ie(wl, index);
1446
1447                         if (wl_get_mode_by_netdev(wl, dev) != WL_MODE_AP)
1448                                 wldev_iovar_setint(dev, "buf_key_b4_m4", 0);
1449
1450                         /* delete interface after link down */
1451                         ret = wl_cfgp2p_ifdel(wl, &p2p_mac);
1452                         /* Firmware could not delete the interface so we will not get WLC_E_IF
1453                         * event for cleaning the dhd virtual nw interace
1454                         * So lets do it here. Failures from fw will ensure the application to do
1455                         * ifconfig <inter> down and up sequnce, which will reload the fw
1456                         * however we should cleanup the linux network virtual interfaces
1457                         */
1458                         /* Request framework to RESET and clean up */
1459                         if (ret) {
1460                                 struct net_device *ndev = wl_to_prmry_ndev(wl);
1461                                 WL_ERR(("Firmware returned an error (%d) from p2p_ifdel"
1462                                         "HANG Notification sent to %s\n", ret, ndev->name));
1463                                 net_os_send_hang_message(ndev);
1464                         }
1465                         /* Wait for IF_DEL operation to be finished in firmware */
1466                         timeout = wait_event_interruptible_timeout(wl->netif_change_event,
1467                                 (wl->p2p->vif_created == false),
1468                                 msecs_to_jiffies(MAX_WAIT_TIME));
1469                         if (timeout > 0 && (wl->p2p->vif_created == false)) {
1470                                 WL_DBG(("IFDEL operation done\n"));
1471                         } else {
1472                                 WL_ERR(("IFDEL didn't complete properly\n"));
1473                         }
1474                         ret = dhd_del_monitor(dev);
1475                 }
1476         }
1477         return ret;
1478 }
1479
1480 static s32
1481 wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
1482         enum nl80211_iftype type, u32 *flags,
1483         struct vif_params *params)
1484 {
1485         s32 ap = 0;
1486         s32 infra = 0;
1487         s32 ibss = 0;
1488         s32 wlif_type;
1489         s32 mode = 0;
1490         s32 err = BCME_OK;
1491         chanspec_t chspec;
1492         struct wl_priv *wl = wiphy_priv(wiphy);
1493         dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
1494         WL_DBG(("Enter type %d\n", type));
1495
1496         if (!wl)
1497                 return ERR_PTR(-EINVAL);
1498         switch (type) {
1499         case NL80211_IFTYPE_MONITOR:
1500         case NL80211_IFTYPE_WDS:
1501         case NL80211_IFTYPE_MESH_POINT:
1502                 ap = 1;
1503                 WL_ERR(("type (%d) : currently we do not support this type\n",
1504                         type));
1505                 break;
1506         case NL80211_IFTYPE_ADHOC:
1507                 mode = WL_MODE_IBSS;
1508                 ibss = 1;
1509                 break;
1510         case NL80211_IFTYPE_STATION:
1511         case NL80211_IFTYPE_P2P_CLIENT:
1512                 mode = WL_MODE_BSS;
1513                 infra = 1;
1514                 break;
1515         case NL80211_IFTYPE_AP:
1516         case NL80211_IFTYPE_AP_VLAN:
1517         case NL80211_IFTYPE_P2P_GO:
1518                 mode = WL_MODE_AP;
1519                 ap = 1;
1520                 break;
1521         default:
1522                 return -EINVAL;
1523         }
1524         if (!dhd)
1525                 return -EINVAL;
1526         if (ap) {
1527                 wl_set_mode_by_netdev(wl, ndev, mode);
1528                 if (wl->p2p_supported && wl->p2p->vif_created) {
1529                         WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
1530                         p2p_on(wl)));
1531                         wldev_iovar_setint(ndev, "mpc", 0);
1532                         wl_notify_escan_complete(wl, ndev, true, true);
1533
1534                         /* In concurrency case, STA may be already associated in a particular
1535                          * channel. so retrieve the current channel of primary interface and
1536                          * then start the virtual interface on that.
1537                          */
1538                         chspec = wl_cfg80211_get_shared_freq(wiphy);
1539
1540                         wlif_type = WL_P2P_IF_GO;
1541                         WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n",
1542                                 ndev->name, ap, infra, type));
1543                         wl_set_p2p_status(wl, IF_CHANGING);
1544                         wl_clr_p2p_status(wl, IF_CHANGED);
1545                         wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
1546                         wait_event_interruptible_timeout(wl->netif_change_event,
1547                                 (wl_get_p2p_status(wl, IF_CHANGED) == true),
1548                                 msecs_to_jiffies(MAX_WAIT_TIME));
1549                         wl_set_mode_by_netdev(wl, ndev, mode);
1550                         dhd->op_mode &= ~DHD_FLAG_P2P_GC_MODE;
1551                         dhd->op_mode |= DHD_FLAG_P2P_GO_MODE;
1552                         wl_clr_p2p_status(wl, IF_CHANGING);
1553                         wl_clr_p2p_status(wl, IF_CHANGED);
1554                         if (mode == WL_MODE_AP)
1555                                 wl_set_drv_status(wl, CONNECTED, ndev);
1556                 } else if (ndev == wl_to_prmry_ndev(wl) &&
1557                         !wl_get_drv_status(wl, AP_CREATED, ndev)) {
1558                         wl_set_drv_status(wl, AP_CREATING, ndev);
1559                         if (!wl->ap_info &&
1560                                 !(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) {
1561                                 WL_ERR(("struct ap_saved_ie allocation failed\n"));
1562                                 return -ENOMEM;
1563                         }
1564                 } else {
1565                         WL_ERR(("Cannot change the interface for GO or SOFTAP\n"));
1566                         return -EINVAL;
1567                 }
1568         } else {
1569                 WL_DBG(("Change_virtual_iface for transition from GO/AP to client/STA"));
1570         }
1571
1572         if (ibss) {
1573                 infra = 0;
1574                 wl_set_mode_by_netdev(wl, ndev, mode);
1575                 err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(s32), true);
1576                 if (err < 0) {
1577                         WL_ERR(("SET Adhoc error %d\n", err));
1578                         return -EINVAL;
1579         }
1580         }
1581
1582         ndev->ieee80211_ptr->iftype = type;
1583         return 0;
1584 }
1585
1586 s32
1587 wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
1588         void* _net_attach)
1589 {
1590         struct wl_priv *wl = wlcfg_drv_priv;
1591         s32 ret = BCME_OK;
1592         WL_DBG(("Enter"));
1593         if (!ndev) {
1594                 WL_ERR(("net is NULL\n"));
1595                 return 0;
1596         }
1597         if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) {
1598                 WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
1599                         "new name: %s\n", ndev->name, wl->p2p->vir_ifname));
1600                 /* Assign the net device to CONNECT BSSCFG */
1601                 strncpy(ndev->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
1602                 wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = ndev;
1603                 wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = bssidx;
1604                 wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach;
1605                 ndev->ifindex = idx;
1606                 wl_clr_p2p_status(wl, IF_ADD);
1607
1608                 wake_up_interruptible(&wl->netif_change_event);
1609         } else {
1610                 ret = BCME_NOTREADY;
1611         }
1612         return ret;
1613 }
1614
1615 s32
1616 wl_cfg80211_notify_ifdel(void)
1617 {
1618         struct wl_priv *wl = wlcfg_drv_priv;
1619
1620         WL_DBG(("Enter \n"));
1621         wl_clr_p2p_status(wl, IF_DELETING);
1622         wake_up_interruptible(&wl->netif_change_event);
1623         return 0;
1624 }
1625
1626 s32
1627 wl_cfg80211_ifdel_ops(struct net_device *ndev)
1628 {
1629         struct wl_priv *wl = wlcfg_drv_priv;
1630         bool rollback_lock = false;
1631         s32 type = -1;
1632         s32 bssidx = -1;
1633
1634 #ifdef PROP_TXSTATUS_VSDB
1635         dhd_pub_t *dhd =  (dhd_pub_t *)(wl->pub);
1636 #endif /* PROP_TXSTATUS_VSDB */
1637         if (!ndev || (strlen(ndev->name) == 0)) {
1638                 WL_ERR(("net is NULL\n"));
1639                 return 0;
1640         }
1641
1642         if (p2p_is_on(wl) && wl->p2p->vif_created &&
1643                 wl_get_p2p_status(wl, IF_DELETING)) {
1644                 if (wl->scan_request &&
1645                         (wl->escan_info.ndev == ndev)) {
1646                         /* Abort any pending scan requests */
1647                         wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
1648                         if (!rtnl_is_locked()) {
1649                                 rtnl_lock();
1650                                 rollback_lock = true;
1651                         }
1652                         WL_DBG(("ESCAN COMPLETED\n"));
1653                         wl_notify_escan_complete(wl, ndev, true, false);
1654                         if (rollback_lock)
1655                                 rtnl_unlock();
1656                 }
1657                 WL_ERR(("IF_DEL event called from dongle, net %p, vif name: %s\n",
1658                         ndev, wl->p2p->vir_ifname));
1659
1660                 memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
1661                 if (wl_cfgp2p_find_idx(wl, ndev, &bssidx) != BCME_OK) {
1662                         WL_ERR(("Find p2p bssidx from ndev(%p) failed\n", ndev));
1663                         return BCME_ERROR;
1664                 }
1665                 if (wl_cfgp2p_find_type(wl, bssidx, &type) != BCME_OK) {
1666                         WL_ERR(("Find p2p type from bssidx(%d) failed\n", bssidx));
1667                         return BCME_ERROR;
1668                 }
1669                 wl_to_p2p_bss_ndev(wl, type) = NULL;
1670                 wl_to_p2p_bss_bssidx(wl, type) = WL_INVALID;
1671                 wl->p2p->vif_created = false;
1672
1673                 WL_DBG(("type : %d\n", type));
1674 #ifdef PROP_TXSTATUS_VSDB
1675                 if (dhd->op_mode != DHD_FLAG_IBSS_MODE && dhd->wlfc_enabled && wl->wlfc_on) {
1676                         dhd->wlfc_enabled = false;
1677                         dhd_wlfc_deinit(dhd);
1678                         if (dhd->plat_deinit)
1679                                 dhd->plat_deinit((void *)dhd);
1680                         wl->wlfc_on = false;
1681                 }
1682 #endif /* PROP_TXSTATUS_VSDB */
1683                 wl_clr_drv_status(wl, CONNECTED, ndev);
1684         }
1685         /* Wake up any waiting thread */
1686         wake_up_interruptible(&wl->netif_change_event);
1687
1688         return 0;
1689 }
1690
1691 s32
1692 wl_cfg80211_is_progress_ifadd(void)
1693 {
1694         s32 is_progress = 0;
1695         struct wl_priv *wl = wlcfg_drv_priv;
1696         if (wl_get_p2p_status(wl, IF_ADD))
1697                 is_progress = 1;
1698         return is_progress;
1699 }
1700
1701 s32
1702 wl_cfg80211_is_progress_ifchange(void)
1703 {
1704         s32 is_progress = 0;
1705         struct wl_priv *wl = wlcfg_drv_priv;
1706         if (wl_get_p2p_status(wl, IF_CHANGING))
1707                 is_progress = 1;
1708         return is_progress;
1709 }
1710
1711
1712 s32
1713 wl_cfg80211_notify_ifchange(void)
1714 {
1715         struct wl_priv *wl = wlcfg_drv_priv;
1716         if (wl_get_p2p_status(wl, IF_CHANGING)) {
1717                 wl_set_p2p_status(wl, IF_CHANGED);
1718                 wake_up_interruptible(&wl->netif_change_event);
1719         }
1720         return 0;
1721 }
1722
1723 /* Find listen channel */
1724 static s32 wl_find_listen_channel(struct wl_priv *wl,
1725         const u8 *ie, u32 ie_len)
1726 {
1727         wifi_p2p_ie_t *p2p_ie;
1728         u8 *end, *pos;
1729         s32 listen_channel;
1730
1731         pos = (u8 *)ie;
1732         p2p_ie = wl_cfgp2p_find_p2pie(pos, ie_len);
1733
1734         if (p2p_ie == NULL)
1735                 return 0;
1736
1737         pos = p2p_ie->subelts;
1738         end = p2p_ie->subelts + (p2p_ie->len - 4);
1739
1740         CFGP2P_DBG((" found p2p ie ! lenth %d \n",
1741                 p2p_ie->len));
1742
1743         while (pos < end) {
1744                 uint16 attr_len;
1745                 if (pos + 2 >= end) {
1746                         CFGP2P_DBG((" -- Invalid P2P attribute"));
1747                         return 0;
1748                 }
1749                 attr_len = ((uint16) (((pos + 1)[1] << 8) | (pos + 1)[0]));
1750
1751                 if (pos + 3 + attr_len > end) {
1752                         CFGP2P_DBG(("P2P: Attribute underflow "
1753                                    "(len=%u left=%d)",
1754                                    attr_len, (int) (end - pos - 3)));
1755                         return 0;
1756                 }
1757
1758                 /* if Listen Channel att id is 6 and the vailue is valid,
1759                  * return the listen channel
1760                  */
1761                 if (pos[0] == 6) {
1762                         /* listen channel subel length format
1763                          * 1(id) + 2(len) + 3(country) + 1(op. class) + 1(chan num)
1764                          */
1765                         listen_channel = pos[1 + 2 + 3 + 1];
1766
1767                         if (listen_channel == SOCIAL_CHAN_1 ||
1768                                 listen_channel == SOCIAL_CHAN_2 ||
1769                                 listen_channel == SOCIAL_CHAN_3) {
1770                                 CFGP2P_DBG((" Found my Listen Channel %d \n", listen_channel));
1771                                 return listen_channel;
1772                         }
1773                 }
1774                 pos += 3 + attr_len;
1775         }
1776         return 0;
1777 }
1778
1779 static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request)
1780 {
1781         u32 n_ssids;
1782         u32 n_channels;
1783         u16 channel;
1784         chanspec_t chanspec;
1785         s32 i = 0, j = 0, offset;
1786         char *ptr;
1787         wlc_ssid_t ssid;
1788         struct wl_priv *wl = wlcfg_drv_priv;
1789
1790         memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
1791         params->bss_type = DOT11_BSSTYPE_ANY;
1792         params->scan_type = 0;
1793         params->nprobes = -1;
1794         params->active_time = -1;
1795         params->passive_time = -1;
1796         params->home_time = -1;
1797         params->channel_num = 0;
1798         memset(&params->ssid, 0, sizeof(wlc_ssid_t));
1799 #ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
1800         TEGRA_SCAN_PREPARE(params, request)
1801 #endif
1802
1803         WL_SCAN(("Preparing Scan request\n"));
1804         WL_SCAN(("nprobes=%d\n", params->nprobes));
1805         WL_SCAN(("active_time=%d\n", params->active_time));
1806         WL_SCAN(("passive_time=%d\n", params->passive_time));
1807         WL_SCAN(("home_time=%d\n", params->home_time));
1808         WL_SCAN(("scan_type=%d\n", params->scan_type));
1809
1810         params->nprobes = htod32(params->nprobes);
1811         params->active_time = htod32(params->active_time);
1812         params->passive_time = htod32(params->passive_time);
1813         params->home_time = htod32(params->home_time);
1814
1815         /* if request is null just exit so it will be all channel broadcast scan */
1816         if (!request)
1817                 return;
1818
1819         n_ssids = request->n_ssids;
1820         n_channels = request->n_channels;
1821
1822         /* Copy channel array if applicable */
1823         WL_SCAN(("### List of channelspecs to scan ###\n"));
1824         if (n_channels > 0) {
1825                 for (i = 0; i < n_channels; i++) {
1826                         chanspec = 0;
1827                         channel = ieee80211_frequency_to_channel(request->channels[i]->center_freq);
1828                         /* SKIP DFS channels for Secondary interface */
1829                         if ((wl->escan_info.ndev != wl_to_prmry_ndev(wl)) &&
1830                                 (request->channels[i]->flags &
1831                                 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_PASSIVE_SCAN)))
1832                                 continue;
1833
1834                         if (request->channels[i]->band == IEEE80211_BAND_2GHZ) {
1835                                 chanspec |= WL_CHANSPEC_BAND_2G;
1836                         } else {
1837                                 chanspec |= WL_CHANSPEC_BAND_5G;
1838                         }
1839
1840                         chanspec |= WL_CHANSPEC_BW_20;
1841                         chanspec |= WL_CHANSPEC_CTL_SB_NONE;
1842
1843                         params->channel_list[j] = channel;
1844                         params->channel_list[j] &= WL_CHANSPEC_CHAN_MASK;
1845                         params->channel_list[j] |= chanspec;
1846                         WL_SCAN(("Chan : %d, Channel spec: %x \n",
1847                                 channel, params->channel_list[j]));
1848                         params->channel_list[j] = wl_chspec_host_to_driver(params->channel_list[j]);
1849                         j++;
1850                 }
1851         } else {
1852                 WL_SCAN(("Scanning all channels\n"));
1853         }
1854         n_channels = j;
1855         /* Copy ssid array if applicable */
1856         WL_SCAN(("### List of SSIDs to scan ###\n"));
1857         if (n_ssids > 0) {
1858                 offset = offsetof(wl_scan_params_t, channel_list) + n_channels * sizeof(u16);
1859                 offset = roundup(offset, sizeof(u32));
1860                 ptr = (char*)params + offset;
1861                 for (i = 0; i < n_ssids; i++) {
1862                         memset(&ssid, 0, sizeof(wlc_ssid_t));
1863                         ssid.SSID_len = request->ssids[i].ssid_len;
1864                         memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len);
1865                         if (!ssid.SSID_len)
1866                                 WL_SCAN(("%d: Broadcast scan\n", i));
1867                         else
1868                                 WL_SCAN(("%d: scan  for  %s size =%d\n", i,
1869                                 ssid.SSID, ssid.SSID_len));
1870                         memcpy(ptr, &ssid, sizeof(wlc_ssid_t));
1871                         ptr += sizeof(wlc_ssid_t);
1872                 }
1873         } else {
1874                 WL_SCAN(("Broadcast scan\n"));
1875         }
1876         /* Adding mask to channel numbers */
1877         params->channel_num =
1878                 htod32((n_ssids << WL_SCAN_PARAMS_NSSID_SHIFT) |
1879                        (n_channels & WL_SCAN_PARAMS_COUNT_MASK));
1880
1881 #ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
1882         /* skip original code for single channel scan parameter override if
1883          * processing scan request from one of the scan work(s)
1884          * - the scan request in the scan work(s) has specific scan parameters
1885          *   which should not be overridden
1886          */
1887         TEGRA_SCAN_WORK_ACTIVE_CHECK(request,
1888                 goto skip_single_channel_scan_parameter_override)
1889 #endif
1890         if (n_channels == 1) {
1891                 params->active_time = htod32(WL_SCAN_CONNECT_DWELL_TIME_MS);
1892                 params->nprobes = htod32(params->active_time / WL_SCAN_JOIN_PROBE_INTERVAL_MS);
1893         }
1894 #ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
1895 skip_single_channel_scan_parameter_override:
1896         ;
1897 #endif
1898 }
1899
1900 static s32
1901 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, u16 action)
1902 {
1903         u32 n_channels;
1904         u32 n_ssids;
1905         s32 params_size =
1906             (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
1907         struct wl_iscan_params *params = NULL;
1908         s32 err = 0;
1909
1910         if (request != NULL) {
1911                 n_channels = request->n_channels;
1912                 n_ssids = request->n_ssids;
1913                 /* Allocate space for populating ssids in wl_iscan_params struct */
1914                 if (n_channels % 2)
1915                         /* If n_channels is odd, add a padd of u16 */
1916                         params_size += sizeof(u16) * (n_channels + 1);
1917                 else
1918                         params_size += sizeof(u16) * n_channels;
1919
1920                 /* Allocate space for populating ssids in wl_iscan_params struct */
1921                 params_size += sizeof(struct wlc_ssid) * n_ssids;
1922         }
1923         params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
1924         if (!params) {
1925                 err = -ENOMEM;
1926                 goto done;
1927         }
1928         wl_scan_prep(&params->params, request);
1929
1930         params->version = htod32(ISCAN_REQ_VERSION);
1931         params->action = htod16(action);
1932         params->scan_duration = htod16(0);
1933
1934         if (params_size + sizeof("iscan") >= WLC_IOCTL_MEDLEN) {
1935                 WL_ERR(("ioctl buffer length is not sufficient\n"));
1936                 err = -ENOMEM;
1937                 goto done;
1938         }
1939         err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
1940                 iscan->ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
1941         if (unlikely(err)) {
1942                 if (err == -EBUSY) {
1943                         WL_ERR(("system busy : iscan canceled\n"));
1944                 } else {
1945                         WL_ERR(("error (%d)\n", err));
1946                 }
1947         }
1948
1949 done:
1950         if (params)
1951                 kfree(params);
1952         return err;
1953 }
1954
1955 static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request)
1956 {
1957         struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
1958         struct net_device *ndev = wl_to_prmry_ndev(wl);
1959         s32 passive_scan;
1960         s32 err = 0;
1961
1962         iscan->state = WL_ISCAN_STATE_SCANING;
1963
1964         passive_scan = wl->active_scan ? 0 : 1;
1965         err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1966                 &passive_scan, sizeof(passive_scan), true);
1967         if (unlikely(err)) {
1968                 WL_DBG(("error (%d)\n", err));
1969                 return err;
1970         }
1971         wl->iscan_kickstart = true;
1972         wl_run_iscan(iscan, request, WL_SCAN_ACTION_START);
1973         mod_timer(&iscan->timer, jiffies + msecs_to_jiffies(iscan->timer_ms));
1974         iscan->timer_on = 1;
1975
1976         return err;
1977 }
1978 static s32
1979 wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size)
1980 {
1981         wl_uint32_list_t *list;
1982         s32 err = BCME_OK;
1983         if (valid_chan_list == NULL || size <= 0)
1984                 return -ENOMEM;
1985
1986         memset(valid_chan_list, 0, size);
1987         list = (wl_uint32_list_t *)(void *) valid_chan_list;
1988         list->count = htod32(WL_NUMCHANNELS);
1989         err = wldev_ioctl(ndev, WLC_GET_VALID_CHANNELS, valid_chan_list, size, false);
1990         if (err != 0) {
1991                 WL_ERR(("get channels failed with %d\n", err));
1992         }
1993
1994         return err;
1995 }
1996
1997 #if defined(USE_INITIAL_SHORT_DWELL_TIME)
1998 #define FIRST_SCAN_ACTIVE_DWELL_TIME_MS 40
1999 static bool
2000 g_first_broadcast_scan = TRUE;
2001 #endif 
2002
2003 static s32
2004 wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
2005         struct cfg80211_scan_request *request, uint16 action)
2006 {
2007         s32 err = BCME_OK;
2008         u32 n_channels;
2009         u32 n_ssids;
2010         s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
2011         wl_escan_params_t *params = NULL;
2012         u8 chan_buf[sizeof(u32)*(WL_NUMCHANNELS + 1)];
2013         u32 num_chans = 0;
2014         s32 channel;
2015         s32 n_valid_chan;
2016         s32 search_state = WL_P2P_DISC_ST_SCAN;
2017         u32 i, j, n_nodfs = 0;
2018         u16 *default_chan_list = NULL;
2019         wl_uint32_list_t *list;
2020         struct net_device *dev = NULL;
2021 #if defined(USE_INITIAL_SHORT_DWELL_TIME)
2022         bool is_first_init_2g_scan = false;
2023 #endif 
2024         p2p_scan_purpose_t      p2p_scan_purpose = P2P_SCAN_PURPOSE_MIN;
2025
2026         WL_DBG(("Enter \n"));
2027
2028         /* scan request can come with empty request : perform all default scan */
2029         if (!wl) {
2030                 err = -EINVAL;
2031                 goto exit;
2032         }
2033         if (!wl->p2p_supported || !p2p_scan(wl)) {
2034                 /* LEGACY SCAN TRIGGER */
2035                 WL_SCAN((" LEGACY E-SCAN START\n"));
2036
2037 #if defined(USE_INITIAL_SHORT_DWELL_TIME)
2038                 if (!request) {
2039                         err = -EINVAL;
2040                         goto exit;
2041                 }
2042                 if (ndev == wl_to_prmry_ndev(wl) && g_first_broadcast_scan == true) {
2043                         is_first_init_2g_scan = true;
2044                         g_first_broadcast_scan = false;
2045                 }
2046 #endif 
2047
2048                 /* if scan request is not empty parse scan request paramters */
2049                 if (request != NULL) {
2050                         n_channels = request->n_channels;
2051                         n_ssids = request->n_ssids;
2052                         /* Allocate space for populating ssids in wl_iscan_params struct */
2053                         if (n_channels % 2)
2054                                 /* If n_channels is odd, add a padd of u16 */
2055                                 params_size += sizeof(u16) * (n_channels + 1);
2056                         else
2057                                 params_size += sizeof(u16) * n_channels;
2058
2059                         /* Allocate space for populating ssids in wl_iscan_params struct */
2060                         params_size += sizeof(struct wlc_ssid) * n_ssids;
2061                 }
2062                 params = (wl_escan_params_t *) kzalloc(params_size, GFP_KERNEL);
2063                 if (params == NULL) {
2064                         err = -ENOMEM;
2065                         goto exit;
2066                 }
2067                 wl_scan_prep(&params->params, request);
2068
2069 #if defined(USE_INITIAL_SHORT_DWELL_TIME)
2070                 /* Override active_time to reduce scan time if it's first bradcast scan. */
2071                 if (is_first_init_2g_scan)
2072                         params->params.active_time = FIRST_SCAN_ACTIVE_DWELL_TIME_MS;
2073 #endif 
2074
2075                 params->version = htod32(ESCAN_REQ_VERSION);
2076                 params->action =  htod16(action);
2077                 wl_escan_set_sync_id(params->sync_id, wl);
2078                 if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) {
2079                         WL_ERR(("ioctl buffer length not sufficient\n"));
2080                         kfree(params);
2081                         err = -ENOMEM;
2082                         goto exit;
2083                 }
2084                 err = wldev_iovar_setbuf(ndev, "escan", params, params_size,
2085                         wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
2086                 if (unlikely(err)) {
2087                         if (err == BCME_EPERM)
2088                                 /* Scan Not permitted at this point of time */
2089                                 WL_DBG((" Escan not permitted at this time (%d)\n", err));
2090                         else
2091                                 WL_ERR((" Escan set error (%d)\n", err));
2092                 }
2093                 kfree(params);
2094         }
2095         else if (p2p_is_on(wl) && p2p_scan(wl)) {
2096                 /* P2P SCAN TRIGGER */
2097                 s32 _freq = 0;
2098                 n_nodfs = 0;
2099                 if (request && request->n_channels) {
2100                         num_chans = request->n_channels;
2101                         WL_SCAN((" chann number : %d\n", num_chans));
2102                         default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
2103                                 GFP_KERNEL);
2104                         if (default_chan_list == NULL) {
2105                                 WL_ERR(("channel list allocation failed \n"));
2106                                 err = -ENOMEM;
2107                                 goto exit;
2108                         }
2109                         if (!wl_get_valid_channels(ndev, chan_buf, sizeof(chan_buf))) {
2110                                 list = (wl_uint32_list_t *) chan_buf;
2111                                 n_valid_chan = dtoh32(list->count);
2112                                 for (i = 0; i < num_chans; i++)
2113                                 {
2114                                         _freq = request->channels[i]->center_freq;
2115                                         channel = ieee80211_frequency_to_channel(_freq);
2116
2117                                         /* ignore DFS channels */
2118                                         if (request->channels[i]->flags &
2119                                                 (IEEE80211_CHAN_RADAR
2120                                                 | IEEE80211_CHAN_PASSIVE_SCAN))
2121                                                 continue;
2122
2123                                         for (j = 0; j < n_valid_chan; j++) {
2124                                                 /* allows only supported channel on
2125                                                 *  current reguatory
2126                                                 */
2127                                                 if (channel == (dtoh32(list->element[j])))
2128                                                         default_chan_list[n_nodfs++] =
2129                                                                 channel;
2130                                         }
2131
2132                                 }
2133                         }
2134                         if (num_chans == SOCIAL_CHAN_CNT && (
2135                                                 (default_chan_list[0] == SOCIAL_CHAN_1) &&
2136                                                 (default_chan_list[1] == SOCIAL_CHAN_2) &&
2137                                                 (default_chan_list[2] == SOCIAL_CHAN_3))) {
2138                                 /* SOCIAL CHANNELS 1, 6, 11 */
2139                                 search_state = WL_P2P_DISC_ST_SEARCH;
2140                                 p2p_scan_purpose = P2P_SCAN_SOCIAL_CHANNEL;
2141                                 WL_INFO(("P2P SEARCH PHASE START \n"));
2142                         } else if ((dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)) &&
2143                                 (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP)) {
2144                                 /* If you are already a GO, then do SEARCH only */
2145                                 WL_INFO(("Already a GO. Do SEARCH Only"));
2146                                 search_state = WL_P2P_DISC_ST_SEARCH;
2147                                 num_chans = n_nodfs;
2148                                 p2p_scan_purpose = P2P_SCAN_NORMAL;
2149
2150                         } else if (num_chans == 1) {
2151                                 p2p_scan_purpose = P2P_SCAN_CONNECT_TRY;
2152                         } else if (num_chans == SOCIAL_CHAN_CNT + 1) {
2153                         /* SOCIAL_CHAN_CNT + 1 takes care of the Progressive scan supported by
2154                          * the supplicant
2155                          */
2156                                 p2p_scan_purpose = P2P_SCAN_SOCIAL_CHANNEL;
2157                         } else {
2158                                 WL_INFO(("P2P SCAN STATE START \n"));
2159                                 num_chans = n_nodfs;
2160                                 p2p_scan_purpose = P2P_SCAN_NORMAL;
2161                         }
2162                 } else {
2163                         err = -EINVAL;
2164                         goto exit;
2165                 }
2166                 err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list,
2167                         search_state, action,
2168                         wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE), NULL,
2169                         p2p_scan_purpose);
2170
2171                 if (!err)
2172                         wl->p2p->search_state = search_state;
2173
2174                 kfree(default_chan_list);
2175         }
2176 exit:
2177         if (unlikely(err)) {
2178                 /* Don't print Error incase of Scan suppress */
2179                 if ((err == BCME_EPERM) && wl->scan_suppressed)
2180                         WL_DBG(("Escan failed: Scan Suppressed \n"));
2181                 else
2182                         WL_ERR(("error (%d)\n", err));
2183         }
2184         return err;
2185 }
2186
2187
2188 static s32
2189 wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev,
2190         struct cfg80211_scan_request *request)
2191 {
2192         s32 err = BCME_OK;
2193         s32 passive_scan;
2194         wl_scan_results_t *results;
2195         WL_SCAN(("Enter \n"));
2196         mutex_lock(&wl->usr_sync);
2197
2198         results = wl_escan_get_buf(wl, FALSE);
2199         results->version = 0;
2200         results->count = 0;
2201         results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
2202
2203         wl->escan_info.ndev = ndev;
2204         wl->escan_info.wiphy = wiphy;
2205         wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
2206         passive_scan = wl->active_scan ? 0 : 1;
2207         err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
2208                 &passive_scan, sizeof(passive_scan), true);
2209         if (unlikely(err)) {
2210                 WL_ERR(("error (%d)\n", err));
2211                 goto exit;
2212         }
2213
2214         TEGRA_SYSFS_HISTOGRAM_SCAN_REQUEST(ndev, request, sizeof(*request))
2215         err = wl_run_escan(wl, ndev, request, WL_SCAN_ACTION_START);
2216 exit:
2217         mutex_unlock(&wl->usr_sync);
2218         return err;
2219 }
2220
2221 static s32
2222 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
2223         struct cfg80211_scan_request *request,
2224         struct cfg80211_ssid *this_ssid)
2225 {
2226         struct wl_priv *wl = wiphy_priv(wiphy);
2227         struct cfg80211_ssid *ssids;
2228         struct wl_scan_req *sr = wl_to_sr(wl);
2229         struct ether_addr primary_mac;
2230         s32 passive_scan;
2231         bool iscan_req;
2232         bool escan_req = false;
2233         bool p2p_ssid;
2234         s32 err = 0;
2235         s32 bssidx = -1;
2236         s32 i;
2237
2238         unsigned long flags;
2239         static s32 busy_count = 0;
2240
2241         dhd_pub_t *dhd;
2242
2243         dhd = (dhd_pub_t *)(wl->pub);
2244         if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
2245                 WL_ERR(("Invalid Scan Command at SoftAP mode\n"));
2246                 return -EINVAL;
2247         }
2248
2249         ndev = ndev_to_wlc_ndev(ndev, wl);
2250
2251         if (WL_DRV_STATUS_SENDING_AF_FRM_EXT(wl)) {
2252                 WL_ERR(("Sending Action Frames. Try it again.\n"));
2253                 return -EAGAIN;
2254         }
2255
2256         WL_DBG(("Enter wiphy (%p)\n", wiphy));
2257         if (wl_get_drv_status_all(wl, SCANNING)) {
2258                 if (wl->scan_request == NULL) {
2259                         wl_clr_drv_status_all(wl, SCANNING);
2260                         WL_DBG(("<<<<<<<<<<<Force Clear Scanning Status>>>>>>>>>>>\n"));
2261                 } else {
2262                         WL_ERR(("Scanning already\n"));
2263                         return -EAGAIN;
2264                 }
2265         }
2266         if (wl_get_drv_status(wl, SCAN_ABORTING, ndev)) {
2267                 WL_ERR(("Scanning being aborted\n"));
2268                 return -EAGAIN;
2269         }
2270         if (request && request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
2271                 WL_ERR(("request null or n_ssids > WL_SCAN_PARAMS_SSID_MAX\n"));
2272                 return -EOPNOTSUPP;
2273         }
2274 #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
2275         if (wl_get_drv_status_all(wl, REMAINING_ON_CHANNEL)) {
2276                 WL_DBG(("Remain_on_channel bit is set, somehow it didn't get cleared\n"));
2277                 wl_notify_escan_complete(wl, ndev, true, true);
2278         }
2279 #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
2280
2281
2282         /* Arm scan timeout timer */
2283         mod_timer(&wl->scan_timeout, jiffies + msecs_to_jiffies(WL_SCAN_TIMER_INTERVAL_MS));
2284         iscan_req = false;
2285         if (request) {          /* scan bss */
2286                 ssids = request->ssids;
2287                 if (wl->iscan_on && (!ssids || !ssids->ssid_len || request->n_ssids != 1)) {
2288                         iscan_req = true;
2289                 } else if (wl->escan_on) {
2290                         escan_req = true;
2291                         p2p_ssid = false;
2292                         for (i = 0; i < request->n_ssids; i++) {
2293                                 if (ssids[i].ssid_len &&
2294                                         IS_P2P_SSID(ssids[i].ssid, ssids[i].ssid_len)) {
2295                                         p2p_ssid = true;
2296                                         break;
2297                                 }
2298                         }
2299                         if (p2p_ssid) {
2300                                 if (wl->p2p_supported) {
2301                                         /* p2p scan trigger */
2302                                         if (p2p_on(wl) == false) {
2303                                                 /* p2p on at the first time */
2304                                                 p2p_on(wl) = true;
2305                                                 wl_cfgp2p_set_firm_p2p(wl);
2306                                                 get_primary_mac(wl, &primary_mac);
2307                                                 wl_cfgp2p_generate_bss_mac(&primary_mac,
2308                                                         &wl->p2p->dev_addr, &wl->p2p->int_addr);
2309                                         }
2310                                         wl_clr_p2p_status(wl, GO_NEG_PHASE);
2311                                         WL_DBG(("P2P: GO_NEG_PHASE status cleared \n"));
2312                                         p2p_scan(wl) = true;
2313                                 }
2314                         } else {
2315                                 /* legacy scan trigger
2316                                  * So, we have to disable p2p discovery if p2p discovery is on
2317                                  */
2318                                 if (wl->p2p_supported) {
2319                                         p2p_scan(wl) = false;
2320                                         /* If Netdevice is not equals to primary and p2p is on
2321                                         *  , we will do p2p scan using P2PAPI_BSSCFG_DEVICE.
2322                                         */
2323
2324                                         if (p2p_scan(wl) == false) {
2325                                                 if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
2326                                                         err = wl_cfgp2p_discover_enable_search(wl,
2327                                                         false);
2328                                                         if (unlikely(err)) {
2329                                                                 goto scan_out;
2330                                                         }
2331
2332                                                 }
2333                                         }
2334                                 }
2335                                 if (!wl->p2p_supported || !p2p_scan(wl)) {
2336
2337                                         if (wl_cfgp2p_find_idx(wl, ndev, &bssidx) != BCME_OK) {
2338                                                 WL_ERR(("Find p2p index from ndev(%p) failed\n",
2339                                                         ndev));
2340                                                 err = BCME_ERROR;
2341                                                 goto scan_out;
2342                                         }
2343                                         err = wl_cfgp2p_set_management_ie(wl, ndev, bssidx,
2344                                                 VNDR_IE_PRBREQ_FLAG, (u8 *)request->ie,
2345                                                 request->ie_len);
2346
2347                                         if (unlikely(err)) {
2348                                                 goto scan_out;
2349                                         }
2350
2351                                 }
2352                         }
2353                 }
2354         } else {                /* scan in ibss */
2355                 /* we don't do iscan in ibss */
2356                 ssids = this_ssid;
2357         }
2358         if (request && !p2p_scan(wl))
2359                 WL_TRACE_HW4(("START SCAN\n"));
2360         wl->scan_request = request;
2361         wl_set_drv_status(wl, SCANNING, ndev);
2362         if (iscan_req) {
2363                 err = wl_do_iscan(wl, request);
2364                 if (likely(!err))
2365                         goto scan_success;
2366                 else
2367                         goto scan_out;
2368         } else if (escan_req) {
2369                 if (wl->p2p_supported) {
2370                         if (p2p_on(wl) && p2p_scan(wl)) {
2371
2372                                 /* find my listen channel */
2373                                 wl->afx_hdl->my_listen_chan =
2374                                         wl_find_listen_channel(wl, request->ie,
2375                                         request->ie_len);
2376                                 err = wl_cfgp2p_enable_discovery(wl, ndev,
2377                                 request->ie, request->ie_len);
2378
2379                                 if (unlikely(err)) {
2380                                         goto scan_out;
2381                                 }
2382                         }
2383                 }
2384                 err = wl_do_escan(wl, wiphy, ndev, request);
2385                 if (likely(!err))
2386                         goto scan_success;
2387                 else
2388                         goto scan_out;
2389
2390
2391         } else {
2392                 memset(&sr->ssid, 0, sizeof(sr->ssid));
2393                 sr->ssid.SSID_len =
2394                         min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
2395                 if (sr->ssid.SSID_len) {
2396                         memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
2397                         sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
2398                         WL_SCAN(("Specific scan ssid=\"%s\" len=%d\n",
2399                                 sr->ssid.SSID, sr->ssid.SSID_len));
2400                 } else {
2401                         WL_SCAN(("Broadcast scan\n"));
2402                 }
2403                 WL_SCAN(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
2404                 passive_scan = wl->active_scan ? 0 : 1;
2405                 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
2406                         &passive_scan, sizeof(passive_scan), true);
2407                 if (unlikely(err)) {
2408                         WL_SCAN(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
2409                         goto scan_out;
2410                 }
2411                 err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
2412                         sizeof(sr->ssid), false);
2413                 if (err) {
2414                         if (err == -EBUSY) {
2415                                 WL_ERR(("system busy : scan for \"%s\" "
2416                                         "canceled\n", sr->ssid.SSID));
2417                         } else {
2418                                 WL_ERR(("WLC_SCAN error (%d)\n", err));
2419                         }
2420                         goto scan_out;
2421                 }
2422         }
2423
2424 scan_success:
2425         busy_count = 0;
2426
2427         return 0;
2428
2429 scan_out:
2430         if (err == BCME_BUSY || err == BCME_NOTREADY) {
2431                 WL_ERR(("Scan err = (%d), busy?%d", err, -EBUSY));
2432                 err = -EBUSY;
2433         }
2434
2435 #define SCAN_EBUSY_RETRY_LIMIT 1
2436         if (err == -EBUSY) {
2437                 if (busy_count++ > SCAN_EBUSY_RETRY_LIMIT) {
2438                         struct ether_addr bssid;
2439                         s32 ret = 0;
2440                         busy_count = 0;
2441                         WL_ERR(("Unusual continuous EBUSY error, %d %d %d %d %d %d %d %d %d\n",
2442                                 wl_get_drv_status(wl, SCANNING, ndev),
2443                                 wl_get_drv_status(wl, SCAN_ABORTING, ndev),
2444                                 wl_get_drv_status(wl, CONNECTING, ndev),
2445                                 wl_get_drv_status(wl, CONNECTED, ndev),
2446                                 wl_get_drv_status(wl, DISCONNECTING, ndev),
2447                                 wl_get_drv_status(wl, AP_CREATING, ndev),
2448                                 wl_get_drv_status(wl, AP_CREATED, ndev),
2449                                 wl_get_drv_status(wl, SENDING_ACT_FRM, ndev),
2450                                 wl_get_drv_status(wl, SENDING_ACT_FRM, ndev)));
2451
2452                         bzero(&bssid, sizeof(bssid));
2453                         if ((ret = wldev_ioctl(ndev, WLC_GET_BSSID,
2454                                 &bssid, ETHER_ADDR_LEN, false)) == 0)
2455                                 WL_ERR(("FW is connected with " MACDBG "/n",
2456                                         MAC2STRDBG(bssid.octet)));
2457                         else
2458                                 WL_ERR(("GET BSSID failed with %d\n", ret));
2459
2460                         wl_cfg80211_scan_abort(wl);
2461                 }
2462         } else {
2463                 busy_count = 0;
2464         }
2465
2466         wl_clr_drv_status(wl, SCANNING, ndev);
2467         if (timer_pending(&wl->scan_timeout))
2468                 del_timer_sync(&wl->scan_timeout);
2469         spin_lock_irqsave(&wl->cfgdrv_lock, flags);
2470 #ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
2471         TEGRA_SCAN_DONE(wl->scan_request, true)
2472         skip_cfg80211_scan_done: ;
2473 #endif
2474         wl->scan_request = NULL;
2475         spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
2476
2477         return err;
2478 }
2479
2480 #if defined(WL_CFG80211_P2P_DEV_IF)
2481 static s32
2482 wl_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
2483 #else
2484 static s32
2485 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
2486         struct cfg80211_scan_request *request)
2487 #endif /* WL_CFG80211_P2P_DEV_IF */
2488 {
2489         s32 err = 0;
2490         struct wl_priv *wl = wiphy_priv(wiphy);
2491 #if defined(WL_CFG80211_P2P_DEV_IF)
2492         struct net_device *ndev = wdev_to_wlc_ndev(request->wdev, wl);
2493 #endif /* WL_CFG80211_P2P_DEV_IF */
2494
2495         WL_DBG(("Enter \n"));
2496         RETURN_EIO_IF_NOT_UP(wl);
2497
2498 #ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
2499         {
2500                 int status = wifi_scan_request(wl_cfg80211_scan,
2501                         wiphy, ndev, request);
2502                 if (status > 0) {
2503                         WIFI_SCAN_DEBUG("%s: substituted wifi scan policy"
2504                                 " with %d rule(s)\n",
2505                                 __func__, status);
2506                         return (0);
2507                 } else if (status < 0) {
2508                         WIFI_SCAN_DEBUG("%s: wifi scan policy active\n",
2509                                 __func__);
2510                         return (status);
2511                 }
2512                 /* continue scan request if status is 0 */
2513         }
2514 #endif
2515
2516         err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
2517         if (unlikely(err)) {
2518                 if ((err == BCME_EPERM) && wl->scan_suppressed)
2519                         WL_DBG(("scan not permitted at this time (%d)\n", err));
2520                 else
2521                         WL_ERR(("scan error (%d)\n", err));
2522                 return err;
2523         }
2524
2525         return err;
2526 }
2527
2528 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
2529 {
2530         s32 err = 0;
2531
2532         err = wldev_iovar_setint(dev, "rtsthresh", rts_threshold);
2533         if (unlikely(err)) {
2534                 WL_ERR(("Error (%d)\n", err));
2535                 return err;
2536         }
2537         return err;
2538 }
2539
2540 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
2541 {
2542         s32 err = 0;
2543
2544         err = wldev_iovar_setint_bsscfg(dev, "fragthresh", frag_threshold, 0);
2545         if (unlikely(err)) {
2546                 WL_ERR(("Error (%d)\n", err));
2547                 return err;
2548         }
2549         return err;
2550 }
2551
2552 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
2553 {
2554         s32 err = 0;
2555         u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
2556
2557         retry = htod32(retry);
2558         err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), true);
2559         if (unlikely(err)) {
2560                 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
2561                 return err;
2562         }
2563         return err;
2564 }
2565
2566 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
2567 {
2568         struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy);
2569         struct net_device *ndev = wl_to_prmry_ndev(wl);
2570         s32 err = 0;
2571
2572         RETURN_EIO_IF_NOT_UP(wl);
2573         WL_DBG(("Enter\n"));
2574         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
2575                 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
2576                 wl->conf->rts_threshold = wiphy->rts_threshold;
2577                 err = wl_set_rts(ndev, wl->conf->rts_threshold);
2578                 if (!err)
2579                         return err;
2580         }
2581         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
2582                 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
2583                 wl->conf->frag_threshold = wiphy->frag_threshold;
2584                 err = wl_set_frag(ndev, wl->conf->frag_threshold);
2585                 if (!err)
2586                         return err;
2587         }
2588         if (changed & WIPHY_PARAM_RETRY_LONG &&
2589                 (wl->conf->retry_long != wiphy->retry_long)) {
2590                 wl->conf->retry_long = wiphy->retry_long;
2591                 err = wl_set_retry(ndev, wl->conf->retry_long, true);
2592                 if (!err)
2593                         return err;
2594         }
2595         if (changed & WIPHY_PARAM_RETRY_SHORT &&
2596                 (wl->conf->retry_short != wiphy->retry_short)) {
2597                 wl->conf->retry_short = wiphy->retry_short;
2598                 err = wl_set_retry(ndev, wl->conf->retry_short, false);
2599                 if (!err) {
2600                         return err;
2601                 }
2602         }
2603
2604         return err;
2605 }
2606 static chanspec_t
2607 channel_to_chanspec(struct wiphy *wiphy, struct net_device *dev, u32 channel, u32 bw_cap)
2608 {
2609         struct wl_priv *wl = wiphy_priv(wiphy);
2610         u8 *buf = NULL;
2611         wl_uint32_list_t *list;
2612         int err = BCME_OK;
2613         chanspec_t c = 0, ret_c = 0;
2614         int bw = 0, tmp_bw = 0;
2615         int i;
2616         u32 tmp_c, sb;
2617         u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
2618 #define LOCAL_BUF_SIZE  1024
2619         buf = (u8 *) kzalloc(LOCAL_BUF_SIZE, kflags);
2620         if (!buf) {
2621                 WL_ERR(("buf memory alloc failed\n"));
2622                 goto exit;
2623         }
2624         list = (wl_uint32_list_t *)(void *)buf;
2625         list->count = htod32(WL_NUMCHANSPECS);
2626         err = wldev_iovar_getbuf_bsscfg(dev, "chanspecs", NULL,
2627                 0, buf, LOCAL_BUF_SIZE, 0, &wl->ioctl_buf_sync);
2628         if (err != BCME_OK) {
2629                 WL_ERR(("get chanspecs failed with %d\n", err));
2630                 goto exit;
2631         }
2632         for (i = 0; i < dtoh32(list->count); i++) {
2633                 c = dtoh32(list->element[i]);
2634                 if (channel <= CH_MAX_2G_CHANNEL) {
2635                         if (!CHSPEC_IS20(c))
2636                                 continue;
2637                         if (channel == CHSPEC_CHANNEL(c)) {
2638                                 ret_c = c;
2639                                 bw = 20;
2640                                 goto exit;
2641                         }
2642                 }
2643                 if (CHSPEC_IS20(c)) {
2644                         tmp_c = CHSPEC_CHANNEL(c);
2645                         tmp_bw = WLC_BW_CAP_20MHZ;
2646                 }
2647                 else if (CHSPEC_IS40(c)) {
2648                         tmp_c = CHSPEC_CHANNEL(c);
2649                         if (CHSPEC_SB_UPPER(c)) {
2650                                 tmp_c += CH_10MHZ_APART;
2651                         } else {
2652                                 tmp_c -= CH_10MHZ_APART;
2653                         }
2654                         tmp_bw = WLC_BW_CAP_40MHZ;
2655                 }
2656                 else {
2657                         tmp_c = CHSPEC_CHANNEL(c);
2658                         sb = c & WL_CHANSPEC_CTL_SB_MASK;
2659                         if (sb == WL_CHANSPEC_CTL_SB_LL) {
2660                                 tmp_c -= (CH_10MHZ_APART + CH_20MHZ_APART);
2661                         } else if (sb == WL_CHANSPEC_CTL_SB_LU) {
2662                                 tmp_c -= CH_10MHZ_APART;
2663                         } else if (sb == WL_CHANSPEC_CTL_SB_UL) {
2664                                 tmp_c += CH_10MHZ_APART;
2665                         } else {
2666                                 /* WL_CHANSPEC_CTL_SB_UU */
2667                                 tmp_c += (CH_10MHZ_APART + CH_20MHZ_APART);
2668                         }
2669                         tmp_bw = WLC_BW_CAP_80MHZ;
2670                 }
2671                 if (tmp_c != channel)
2672                         continue;
2673
2674                 if ((tmp_bw > bw) && (tmp_bw <= bw_cap)) {
2675                         bw = tmp_bw;
2676                         ret_c = c;
2677                         if (bw == bw_cap)
2678                                 goto exit;
2679                 }
2680         }
2681 exit:
2682         if (buf)
2683                 kfree(buf);
2684 #undef LOCAL_BUF_SIZE
2685         WL_INFO(("return chanspec %x %d\n", ret_c, bw));
2686         return ret_c;
2687 }
2688
2689 void
2690 wl_cfg80211_ibss_vsie_set_buffer(vndr_ie_setbuf_t *ibss_vsie, int ibss_vsie_len)
2691 {
2692         struct wl_priv *wl = wlcfg_drv_priv;
2693
2694         if (wl != NULL && ibss_vsie != NULL) {
2695                 if (wl->ibss_vsie != NULL) {
2696                         kfree(wl->ibss_vsie);
2697                 }
2698                 wl->ibss_vsie = ibss_vsie;
2699                 wl->ibss_vsie_len = ibss_vsie_len;
2700         }
2701 }
2702
2703 static void
2704 wl_cfg80211_ibss_vsie_free(struct wl_priv *wl)
2705 {
2706         /* free & initiralize VSIE (Vendor Specific IE) */
2707         if (wl->ibss_vsie != NULL) {
2708                 kfree(wl->ibss_vsie);
2709                 wl->ibss_vsie = NULL;
2710                 wl->ibss_vsie_len = 0;
2711         }
2712 }
2713
2714 s32
2715 wl_cfg80211_ibss_vsie_delete(struct net_device *dev)
2716 {
2717         struct wl_priv *wl = wlcfg_drv_priv;
2718         char *ioctl_buf = NULL;
2719         s32 ret = BCME_OK;
2720
2721         if (wl != NULL && wl->ibss_vsie != NULL) {
2722                 ioctl_buf = kmalloc(WLC_IOCTL_MEDLEN, GFP_KERNEL);
2723                 if (!ioctl_buf) {
2724                         WL_ERR(("ioctl memory alloc failed\n"));
2725                         return -ENOMEM;
2726                 }
2727
2728                 /* change the command from "add" to "del" */
2729                 strncpy(wl->ibss_vsie->cmd, "del", VNDR_IE_CMD_LEN - 1);
2730                 wl->ibss_vsie->cmd[VNDR_IE_CMD_LEN - 1] = '\0';
2731
2732                 ret = wldev_iovar_setbuf(dev, "ie",
2733                         wl->ibss_vsie, wl->ibss_vsie_len,
2734                         ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
2735                 WL_ERR(("ret=%d\n", ret));
2736
2737                 if (ret == BCME_OK) {
2738                         /* free & initiralize VSIE */
2739                         kfree(wl->ibss_vsie);
2740                         wl->ibss_vsie = NULL;
2741                         wl->ibss_vsie_len = 0;
2742                 }
2743
2744                 if (ioctl_buf) {
2745                         kfree(ioctl_buf);
2746                 }
2747         }
2748
2749         return ret;
2750 }
2751
2752 static s32
2753 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
2754         struct cfg80211_ibss_params *params)
2755 {
2756         struct wl_priv *wl = wiphy_priv(wiphy);
2757         struct cfg80211_bss *bss;
2758         struct ieee80211_channel *chan;
2759         struct wl_join_params join_params;
2760         struct cfg80211_ssid ssid;
2761         s32 scan_retry = 0;
2762         s32 err = 0;
2763         int scan_suppress = 1;
2764         size_t join_params_size;
2765         chanspec_t chanspec = 0;
2766         u32 param[2] = {0, 0};
2767         u32 bw_cap = 0;
2768
2769         WL_TRACE(("In\n"));
2770         RETURN_EIO_IF_NOT_UP(wl);
2771         WL_INFO(("JOIN BSSID:" MACDBG "\n", MAC2STRDBG(params->bssid)));
2772         if (!params->ssid || params->ssid_len <= 0) {
2773                 WL_ERR(("Invalid parameter\n"));
2774                 return -EINVAL;
2775         }
2776
2777 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
2778         chan = params->chandef.chan;
2779 #else
2780         chan = params->channel;
2781 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) */
2782         if (chan)
2783                 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
2784         if (wl_get_drv_status(wl, CONNECTED, dev)) {
2785                 struct wlc_ssid *ssid = (struct wlc_ssid *)wl_read_prof(wl, dev, WL_PROF_SSID);
2786                 u8 *bssid = (u8 *)wl_read_prof(wl, dev, WL_PROF_BSSID);
2787                 u32 *channel = (u32 *)wl_read_prof(wl, dev, WL_PROF_CHAN);
2788                 if (!params->bssid || ((memcmp(params->bssid, bssid, ETHER_ADDR_LEN) == 0) &&
2789                         (memcmp(params->ssid, ssid->SSID, ssid->SSID_len) == 0) &&
2790                         (*channel == wl->channel))) {
2791                         WL_ERR(("Connection already existed to " MACDBG "\n",
2792                                 MAC2STRDBG((u8 *)wl_read_prof(wl, dev, WL_PROF_BSSID))));
2793                         return -EISCONN;
2794                 }
2795                 WL_ERR(("Ignore Previous connecton to %s (" MACDBG ")\n",
2796                         ssid->SSID, MAC2STRDBG(bssid)));
2797         }
2798
2799         /* remove the VSIE */
2800         wl_cfg80211_ibss_vsie_delete(dev);
2801
2802         bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
2803         if (!bss) {
2804                 if (IBSS_INITIAL_SCAN_ALLOWED == TRUE) {
2805                         memcpy(ssid.ssid, params->ssid, params->ssid_len);
2806                         ssid.ssid_len = params->ssid_len;
2807                         do {
2808                                 if (unlikely
2809                                         (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
2810                                          -EBUSY)) {
2811                                         wl_delay(150);
2812                                 } else {
2813                                         break;
2814                                 }
2815                         } while (++scan_retry < WL_SCAN_RETRY_MAX);
2816
2817                         /* wait 4 secons till scan done.... */
2818                         schedule_timeout_interruptible(msecs_to_jiffies(4000));
2819                         bss = cfg80211_get_ibss(wiphy, NULL,
2820                                 params->ssid, params->ssid_len);
2821                 }
2822         }
2823         if (bss && ((IBSS_COALESCE_ALLOWED == TRUE) ||
2824                 ((IBSS_COALESCE_ALLOWED == FALSE) && params->bssid &&
2825                 !memcmp(bss->bssid, params->bssid, ETHER_ADDR_LEN)))) {
2826                 wl->ibss_starter = false;
2827                 WL_DBG(("Found IBSS\n"));
2828         } else {
2829                 wl->ibss_starter = true;
2830         }
2831         if (chan) {
2832                 if (chan->band == IEEE80211_BAND_5GHZ)
2833                         param[0] = WLC_BAND_5G;
2834                 else if (chan->band == IEEE80211_BAND_2GHZ)
2835                         param[0] = WLC_BAND_2G;
2836                 err = wldev_iovar_getint(dev, "bw_cap", param);
2837                 if (unlikely(err)) {
2838                         WL_ERR(("Get bw_cap Failed (%d)\n", err));
2839                         return err;
2840                 }
2841                 bw_cap = param[0];
2842                 chanspec = channel_to_chanspec(wiphy, dev, wl->channel, bw_cap);
2843         }
2844         /*
2845          * Join with specific BSSID and cached SSID
2846          * If SSID is zero join based on BSSID only
2847          */
2848         memset(&join_params, 0, sizeof(join_params));
2849         memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
2850                 params->ssid_len);
2851         join_params.ssid.SSID_len = htod32(params->ssid_len);
2852         if (params->bssid) {
2853                 memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN);
2854                 err = wldev_ioctl(dev, WLC_SET_DESIRED_BSSID, &join_params.params.bssid,
2855                         ETHER_ADDR_LEN, true);
2856                 if (unlikely(err)) {
2857                         WL_ERR(("Error (%d)\n", err));
2858                         return err;
2859                 }
2860         } else
2861                 memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
2862
2863         wldev_iovar_setint(dev, "ibss_coalesce_allowed", IBSS_COALESCE_ALLOWED);
2864
2865         if (IBSS_INITIAL_SCAN_ALLOWED == FALSE) {
2866                 scan_suppress = TRUE;
2867                 /* Set the SCAN SUPRESS Flag in the firmware to skip join scan */
2868                 err = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS, &scan_suppress, sizeof(int), true);
2869                 if (unlikely(err)) {
2870                         WL_ERR(("Scan Supress Setting failed(%d)\n", err));
2871                         return err;
2872                 }
2873         }
2874
2875         join_params.params.chanspec_list[0] = chanspec;
2876         join_params.params.chanspec_num = 1;
2877         wldev_iovar_setint(dev, "chanspec", chanspec);
2878         join_params_size = sizeof(join_params);
2879
2880         /* Disable Authentication, IBSS will add key if it required */
2881         wldev_iovar_setint(dev, "wpa_auth", WPA_AUTH_DISABLED);
2882         wldev_iovar_setint(dev, "wsec", 0);
2883
2884         err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
2885                 join_params_size, true);
2886         if (unlikely(err)) {
2887                 WL_ERR(("Error (%d)\n", err));
2888                 return err;
2889         }
2890
2891         if (IBSS_INITIAL_SCAN_ALLOWED == FALSE) {
2892                 scan_suppress = FALSE;
2893                 /* Restore the SCAN SUPPRESS Falg */
2894                 err = wldev_ioctl(dev, WLC_SET_SCANSUPPRESS,
2895                         &scan_suppress, sizeof(int), true);
2896                 if (unlikely(err)) {
2897                         WL_ERR(("Reset SCAN Suppress Flag failed (%d)\n", err));
2898                 return err;
2899                 }
2900         }
2901         wl_update_prof(wl, dev, NULL, &join_params.ssid, WL_PROF_SSID);
2902         wl_update_prof(wl, dev, NULL, &wl->channel, WL_PROF_CHAN);
2903         return err;
2904 }
2905
2906 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
2907 {
2908         struct wl_priv *wl = wiphy_priv(wiphy);
2909         s32 err = 0;
2910         scb_val_t scbval;
2911         u8 *curbssid;
2912
2913         RETURN_EIO_IF_NOT_UP(wl);
2914         wl_link_down(wl);
2915         WL_ERR(("Leave IBSS\n"));
2916         curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID);
2917         wl_set_drv_status(wl, DISCONNECTING, dev);
2918         scbval.val = 0;
2919         memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
2920         err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
2921                 sizeof(scb_val_t), true);
2922         if (unlikely(err)) {
2923                 wl_clr_drv_status(wl, DISCONNECTING, dev);
2924                 WL_ERR(("error(%d)\n", err));
2925                 return err;
2926         }
2927
2928         /* remove the VSIE */
2929         wl_cfg80211_ibss_vsie_delete(dev);
2930
2931         return err;
2932 }
2933
2934
2935 static s32
2936 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
2937 {
2938         struct wl_priv *wl = wlcfg_drv_priv;
2939         struct wl_security *sec;
2940         s32 val = 0;
2941         s32 err = 0;
2942         s32 bssidx;
2943         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
2944                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
2945                 return BCME_ERROR;
2946         }
2947
2948         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2949                 val = WPA_AUTH_PSK |
2950                         WPA_AUTH_UNSPECIFIED;
2951         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2952                 val = WPA2_AUTH_PSK|
2953                         WPA2_AUTH_UNSPECIFIED;
2954         else
2955                 val = WPA_AUTH_DISABLED;
2956
2957         if (is_wps_conn(sme))
2958                 val = WPA_AUTH_DISABLED;
2959
2960         WL_DBG(("setting wpa_auth to 0x%0x\n", val));
2961         err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
2962         if (unlikely(err)) {
2963                 WL_ERR(("set wpa_auth failed (%d)\n", err));
2964                 return err;
2965         }
2966         sec = wl_read_prof(wl, dev, WL_PROF_SEC);
2967         sec->wpa_versions = sme->crypto.wpa_versions;
2968         return err;
2969 }
2970
2971
2972 static s32
2973 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
2974 {
2975         struct wl_priv *wl = wlcfg_drv_priv;
2976         struct wl_security *sec;
2977         s32 val = 0;
2978         s32 err = 0;
2979         s32 bssidx;
2980         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
2981                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
2982                 return BCME_ERROR;
2983         }
2984
2985         switch (sme->auth_type) {
2986         case NL80211_AUTHTYPE_OPEN_SYSTEM:
2987                 val = WL_AUTH_OPEN_SYSTEM;
2988                 WL_DBG(("open system\n"));
2989                 break;
2990         case NL80211_AUTHTYPE_SHARED_KEY:
2991                 val = WL_AUTH_SHARED_KEY;
2992                 WL_DBG(("shared key\n"));
2993                 break;
2994         case NL80211_AUTHTYPE_AUTOMATIC:
2995                 val = WL_AUTH_OPEN_SHARED;
2996                 WL_DBG(("automatic\n"));
2997                 break;
2998         default:
2999                 val = 2;
3000                 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
3001                 break;
3002         }
3003
3004         err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
3005         if (unlikely(err)) {
3006                 WL_ERR(("set auth failed (%d)\n", err));
3007                 return err;
3008         }
3009         sec = wl_read_prof(wl, dev, WL_PROF_SEC);
3010         sec->auth_type = sme->auth_type;
3011         return err;
3012 }
3013
3014 static s32
3015 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
3016 {
3017         struct wl_priv *wl = wlcfg_drv_priv;
3018         struct wl_security *sec;
3019         s32 pval = 0;
3020         s32 gval = 0;
3021         s32 err = 0;
3022         s32 wsec_val = 0;
3023
3024         s32 bssidx;
3025         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3026                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3027                 return BCME_ERROR;
3028         }
3029
3030         if (sme->crypto.n_ciphers_pairwise) {
3031                 switch (sme->crypto.ciphers_pairwise[0]) {
3032                 case WLAN_CIPHER_SUITE_WEP40:
3033                 case WLAN_CIPHER_SUITE_WEP104:
3034                         pval = WEP_ENABLED;
3035                         break;
3036                 case WLAN_CIPHER_SUITE_TKIP:
3037                         pval = TKIP_ENABLED;
3038                         break;
3039                 case WLAN_CIPHER_SUITE_CCMP:
3040                 case WLAN_CIPHER_SUITE_AES_CMAC:
3041                         pval = AES_ENABLED;
3042                         break;
3043                 default:
3044                         WL_ERR(("invalid cipher pairwise (%d)\n",
3045                                 sme->crypto.ciphers_pairwise[0]));
3046                         return -EINVAL;
3047                 }
3048         }
3049         if (sme->crypto.cipher_group) {
3050                 switch (sme->crypto.cipher_group) {
3051                 case WLAN_CIPHER_SUITE_WEP40:
3052                 case WLAN_CIPHER_SUITE_WEP104:
3053                         gval = WEP_ENABLED;
3054                         break;
3055                 case WLAN_CIPHER_SUITE_TKIP:
3056                         gval = TKIP_ENABLED;
3057                         break;
3058                 case WLAN_CIPHER_SUITE_CCMP:
3059                         gval = AES_ENABLED;
3060                         break;
3061                 case WLAN_CIPHER_SUITE_AES_CMAC:
3062                         gval = AES_ENABLED;
3063                         break;
3064                 default:
3065                         WL_ERR(("invalid cipher group (%d)\n",
3066                                 sme->crypto.cipher_group));
3067                         return -EINVAL;
3068                 }
3069         }
3070
3071         WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
3072
3073         if (is_wps_conn(sme)) {
3074                 if (sme->privacy)
3075                         err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
3076                 else
3077                         /* WPS-2.0 allows no security */
3078                         err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx);
3079         } else {
3080                         WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC"));
3081                         wsec_val = pval | gval;
3082
3083                         WL_DBG((" Set WSEC to fW 0x%x \n", wsec_val));
3084                         err = wldev_iovar_setint_bsscfg(dev, "wsec",
3085                                 wsec_val, bssidx);
3086         }
3087         if (unlikely(err)) {
3088                 WL_ERR(("error (%d)\n", err));
3089                 return err;
3090         }
3091
3092         sec = wl_read_prof(wl, dev, WL_PROF_SEC);
3093         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
3094         sec->cipher_group = sme->crypto.cipher_group;
3095
3096         return err;
3097 }
3098
3099 static s32
3100 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
3101 {
3102         struct wl_priv *wl = wlcfg_drv_priv;
3103         struct wl_security *sec;
3104         s32 val = 0;
3105         s32 err = 0;
3106         s32 bssidx;
3107         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3108                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3109                 return BCME_ERROR;
3110         }
3111
3112         if (sme->crypto.n_akm_suites) {
3113                 err = wldev_iovar_getint(dev, "wpa_auth", &val);
3114                 if (unlikely(err)) {
3115                         WL_ERR(("could not get wpa_auth (%d)\n", err));
3116                         return err;
3117                 }
3118                 if (val & (WPA_AUTH_PSK |
3119                         WPA_AUTH_UNSPECIFIED)) {
3120                         switch (sme->crypto.akm_suites[0]) {
3121                         case WLAN_AKM_SUITE_8021X:
3122                                 val = WPA_AUTH_UNSPECIFIED;
3123                                 break;
3124                         case WLAN_AKM_SUITE_PSK:
3125                                 val = WPA_AUTH_PSK;
3126                                 break;
3127                         default:
3128                                 WL_ERR(("invalid cipher group (%d)\n",
3129                                         sme->crypto.cipher_group));
3130                                 return -EINVAL;
3131                         }
3132                 } else if (val & (WPA2_AUTH_PSK |
3133                         WPA2_AUTH_UNSPECIFIED)) {
3134                         switch (sme->crypto.akm_suites[0]) {
3135                         case WLAN_AKM_SUITE_8021X:
3136                                 val = WPA2_AUTH_UNSPECIFIED;
3137                                 break;
3138                         case WLAN_AKM_SUITE_PSK:
3139                                 val = WPA2_AUTH_PSK;
3140                                 break;
3141                         default:
3142                                 WL_ERR(("invalid cipher group (%d)\n",
3143                                         sme->crypto.cipher_group));
3144                                 return -EINVAL;
3145                         }
3146                 }
3147                 WL_DBG(("setting wpa_auth to %d\n", val));
3148
3149
3150                 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
3151                 if (unlikely(err)) {
3152                         WL_ERR(("could not set wpa_auth (%d)\n", err));
3153                         return err;
3154                 }
3155         }
3156         sec = wl_read_prof(wl, dev, WL_PROF_SEC);
3157         sec->wpa_auth = sme->crypto.akm_suites[0];
3158
3159         return err;
3160 }
3161
3162 static s32
3163 wl_set_set_sharedkey(struct net_device *dev,
3164         struct cfg80211_connect_params *sme)
3165 {
3166         struct wl_priv *wl = wlcfg_drv_priv;
3167         struct wl_security *sec;
3168         struct wl_wsec_key key;
3169         s32 val;
3170         s32 err = 0;
3171         s32 bssidx;
3172         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3173                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3174                 return BCME_ERROR;
3175         }
3176
3177         WL_DBG(("key len (%d)\n", sme->key_len));
3178         if (sme->key_len) {
3179                 sec = wl_read_prof(wl, dev, WL_PROF_SEC);
3180                 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
3181                         sec->wpa_versions, sec->cipher_pairwise));
3182                 if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 |
3183                         NL80211_WPA_VERSION_2)) &&
3184                         (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
3185                 WLAN_CIPHER_SUITE_WEP104)))
3186                 {
3187                         memset(&key, 0, sizeof(key));
3188                         key.len = (u32) sme->key_len;
3189                         key.index = (u32) sme->key_idx;
3190                         if (unlikely(key.len > sizeof(key.data))) {
3191                                 WL_ERR(("Too long key length (%u)\n", key.len));
3192                                 return -EINVAL;
3193                         }
3194                         memcpy(key.data, sme->key, key.len);
3195                         key.flags = WL_PRIMARY_KEY;
3196                         switch (sec->cipher_pairwise) {
3197                         case WLAN_CIPHER_SUITE_WEP40:
3198                                 key.algo = CRYPTO_ALGO_WEP1;
3199                                 break;
3200                         case WLAN_CIPHER_SUITE_WEP104:
3201                                 key.algo = CRYPTO_ALGO_WEP128;
3202                                 break;
3203                         default:
3204                                 WL_ERR(("Invalid algorithm (%d)\n",
3205                                         sme->crypto.ciphers_pairwise[0]));
3206                                 return -EINVAL;
3207                         }
3208                         /* Set the new key/index */
3209                         WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
3210                                 key.len, key.index, key.algo));
3211                         WL_DBG(("key \"%s\"\n", key.data));
3212                         swap_key_from_BE(&key);
3213                         err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
3214                                 wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
3215                         if (unlikely(err)) {
3216                                 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
3217                                 return err;
3218                         }
3219                         if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
3220                                 WL_DBG(("set auth_type to shared key\n"));
3221                                 val = WL_AUTH_SHARED_KEY;       /* shared key */
3222                                 err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
3223                                 if (unlikely(err)) {
3224                                         WL_ERR(("set auth failed (%d)\n", err));
3225                                         return err;
3226                                 }
3227                         }
3228                 }
3229         }
3230         return err;
3231 }
3232
3233 #if defined(ESCAN_RESULT_PATCH)
3234 static u8 connect_req_bssid[6];
3235 static u8 broad_bssid[6];
3236 #endif /* ESCAN_RESULT_PATCH */
3237
3238
3239
3240 static s32
3241 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
3242         struct cfg80211_connect_params *sme)
3243 {
3244         struct wl_priv *wl = wiphy_priv(wiphy);
3245         struct ieee80211_channel *chan = sme->channel;
3246         wl_extjoin_params_t *ext_join_params;
3247         struct wl_join_params join_params;
3248         size_t join_params_size;
3249         s32 err = 0;
3250         wpa_ie_fixed_t *wpa_ie;
3251         bcm_tlv_t *wpa2_ie;
3252         u8* wpaie  = 0;
3253         u32 wpaie_len = 0;
3254         u32 chan_cnt = 0;
3255         struct ether_addr bssid;
3256         s32 bssidx;
3257         int ret;
3258         int wait_cnt;
3259
3260         WL_DBG(("In\n"));
3261
3262         if (unlikely(!sme->ssid)) {
3263                 WL_ERR(("Invalid ssid\n"));
3264                 return -EOPNOTSUPP;
3265         }
3266
3267         if (unlikely(sme->ssid_len > DOT11_MAX_SSID_LEN)) {
3268                 WL_ERR(("Invalid SSID info: SSID=%s, length=%d\n",
3269                         sme->ssid, sme->ssid_len));
3270                 return -EINVAL;
3271         }
3272
3273         RETURN_EIO_IF_NOT_UP(wl);
3274
3275         /*
3276          * Cancel ongoing scan to sync up with sme state machine of cfg80211.
3277          */
3278 #if !defined(ESCAN_RESULT_PATCH)
3279         if (wl->scan_request) {
3280                 wl_notify_escan_complete(wl, dev, true, true);
3281         }
3282 #endif
3283 #if defined(ESCAN_RESULT_PATCH)
3284         if (sme->bssid)
3285                 memcpy(connect_req_bssid, sme->bssid, ETHER_ADDR_LEN);
3286         else
3287                 bzero(connect_req_bssid, ETHER_ADDR_LEN);
3288         bzero(broad_bssid, ETHER_ADDR_LEN);
3289 #endif
3290 #if defined(USE_DYNAMIC_MAXPKT_RXGLOM)
3291         maxrxpktglom = 0;
3292 #endif
3293         bzero(&bssid, sizeof(bssid));
3294         if (!wl_get_drv_status(wl, CONNECTED, dev)&&
3295                 (ret = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false)) == 0) {
3296                 if (!ETHER_ISNULLADDR(&bssid)) {
3297                         scb_val_t scbval;
3298                         wl_set_drv_status(wl, DISCONNECTING, dev);
3299                         scbval.val = DOT11_RC_DISASSOC_LEAVING;
3300                         memcpy(&scbval.ea, &bssid, ETHER_ADDR_LEN);
3301                         scbval.val = htod32(scbval.val);
3302
3303                         WL_DBG(("drv status CONNECTED is not set, but connected in FW!" MACDBG "/n",
3304                                 MAC2STRDBG(bssid.octet)));
3305                         err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
3306                                 sizeof(scb_val_t), true);
3307                         if (unlikely(err)) {
3308                                 wl_clr_drv_status(wl, DISCONNECTING, dev);
3309                                 WL_ERR(("error (%d)\n", err));
3310                                 return err;
3311                         }
3312                         wait_cnt = 500/10;
3313                         while (wl_get_drv_status(wl, DISCONNECTING, dev) && wait_cnt) {
3314                                 WL_DBG(("Waiting for disconnection terminated, wait_cnt: %d\n",
3315                                         wait_cnt));
3316                                 wait_cnt--;
3317                                 OSL_SLEEP(10);
3318                         }
3319                 } else
3320                         WL_DBG(("Currently not associated!\n"));
3321         } else {
3322                 /* if status is DISCONNECTING, wait for disconnection terminated max 500 ms */
3323                 wait_cnt = 500/10;
3324                 while (wl_get_drv_status(wl, DISCONNECTING, dev) && wait_cnt) {
3325                         WL_DBG(("Waiting for disconnection terminated, wait_cnt: %d\n", wait_cnt));
3326                         wait_cnt--;
3327                         OSL_SLEEP(10);
3328                 }
3329         }
3330
3331         /* Clean BSSID */
3332         bzero(&bssid, sizeof(bssid));
3333         if (!wl_get_drv_status(wl, DISCONNECTING, dev))
3334                 wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
3335
3336         if (p2p_is_on(wl) && (dev != wl_to_prmry_ndev(wl))) {
3337                 /* we only allow to connect using virtual interface in case of P2P */
3338                         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3339                                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3340                                 return BCME_ERROR;
3341                         }
3342                         wl_cfgp2p_set_management_ie(wl, dev, bssidx,
3343                                 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
3344         } else if (dev == wl_to_prmry_ndev(wl)) {
3345                 /* find the RSN_IE */
3346                 if ((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len,
3347                         DOT11_MNG_RSN_ID)) != NULL) {
3348                         WL_DBG((" WPA2 IE is found\n"));
3349                 }
3350                 /* find the WPA_IE */
3351                 if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)sme->ie,
3352                         sme->ie_len)) != NULL) {
3353                         WL_DBG((" WPA IE is found\n"));
3354                 }
3355                 if (wpa_ie != NULL || wpa2_ie != NULL) {
3356                         wpaie = (wpa_ie != NULL) ? (u8 *)wpa_ie : (u8 *)wpa2_ie;
3357                         wpaie_len = (wpa_ie != NULL) ? wpa_ie->length : wpa2_ie->len;
3358                         wpaie_len += WPA_RSN_IE_TAG_FIXED_LEN;
3359                         wldev_iovar_setbuf(dev, "wpaie", wpaie, wpaie_len,
3360                                 wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
3361                 } else {
3362                         wldev_iovar_setbuf(dev, "wpaie", NULL, 0,
3363                                 wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
3364                 }
3365
3366                 if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3367                         WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3368                         return BCME_ERROR;
3369                 }
3370                 err = wl_cfgp2p_set_management_ie(wl, dev, bssidx,
3371                         VNDR_IE_ASSOCREQ_FLAG, (u8 *)sme->ie, sme->ie_len);
3372                 if (unlikely(err)) {
3373                         return err;
3374                 }
3375         }
3376         if (chan) {
3377                 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
3378                 chan_cnt = 1;
3379                 WL_DBG(("channel (%d), center_req (%d), %d channels\n", wl->channel,
3380                         chan->center_freq, chan_cnt));
3381         } else
3382                 wl->channel = 0;
3383         WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
3384         WL_DBG(("3. set wapi version \n"));
3385         err = wl_set_wpa_version(dev, sme);
3386         if (unlikely(err)) {
3387                 WL_ERR(("Invalid wpa_version\n"));
3388                 return err;
3389         }
3390                 err = wl_set_auth_type(dev, sme);
3391                 if (unlikely(err)) {
3392                         WL_ERR(("Invalid auth type\n"));
3393                         return err;
3394                 }
3395
3396         err = wl_set_set_cipher(dev, sme);
3397         if (unlikely(err)) {
3398                 WL_ERR(("Invalid ciper\n"));
3399                 return err;
3400         }
3401
3402         err = wl_set_key_mgmt(dev, sme);
3403         if (unlikely(err)) {
3404                 WL_ERR(("Invalid key mgmt\n"));
3405                 return err;
3406         }
3407
3408         err = wl_set_set_sharedkey(dev, sme);
3409         if (unlikely(err)) {
3410                 WL_ERR(("Invalid shared key\n"));
3411                 return err;
3412         }
3413
3414         /*
3415          *  Join with specific BSSID and cached SSID
3416          *  If SSID is zero join based on BSSID only
3417          */
3418         join_params_size = WL_EXTJOIN_PARAMS_FIXED_SIZE +
3419                 chan_cnt * sizeof(chanspec_t);
3420         ext_join_params =  (wl_extjoin_params_t*)kzalloc(join_params_size, GFP_KERNEL);
3421         if (ext_join_params == NULL) {
3422                 err = -ENOMEM;
3423                 wl_clr_drv_status(wl, CONNECTING, dev);
3424                 goto exit;
3425         }
3426         ext_join_params->ssid.SSID_len = min(sizeof(ext_join_params->ssid.SSID), sme->ssid_len);
3427         memcpy(&ext_join_params->ssid.SSID, sme->ssid, ext_join_params->ssid.SSID_len);
3428         wl_update_prof(wl, dev, NULL, &ext_join_params->ssid, WL_PROF_SSID);
3429         ext_join_params->ssid.SSID_len = htod32(ext_join_params->ssid.SSID_len);
3430         /* increate dwell time to receive probe response or detect Beacon
3431         * from target AP at a noisy air only when channel info is provided in connect command
3432         */
3433         ext_join_params->scan.active_time = chan_cnt ? WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS : -1;
3434         ext_join_params->scan.passive_time = chan_cnt ? WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS : -1;
3435         /* Set up join scan parameters */
3436         ext_join_params->scan.scan_type = -1;
3437         ext_join_params->scan.nprobes = chan_cnt ?
3438                 (ext_join_params->scan.active_time/WL_SCAN_JOIN_PROBE_INTERVAL_MS) : -1;
3439         ext_join_params->scan.home_time = -1;
3440
3441         if (sme->bssid)
3442                 memcpy(&ext_join_params->assoc.bssid, sme->bssid, ETH_ALEN);
3443         else
3444                 memcpy(&ext_join_params->assoc.bssid, &ether_bcast, ETH_ALEN);
3445         ext_join_params->assoc.chanspec_num = chan_cnt;
3446         if (chan_cnt) {
3447                 u16 channel, band, bw, ctl_sb;
3448                 chanspec_t chspec;
3449                 channel = wl->channel;
3450                 band = (channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G
3451                         : WL_CHANSPEC_BAND_5G;
3452                 bw = WL_CHANSPEC_BW_20;
3453                 ctl_sb = WL_CHANSPEC_CTL_SB_NONE;
3454                 chspec = (channel | band | bw | ctl_sb);
3455                 ext_join_params->assoc.chanspec_list[0]  &= WL_CHANSPEC_CHAN_MASK;
3456                 ext_join_params->assoc.chanspec_list[0] |= chspec;
3457                 ext_join_params->assoc.chanspec_list[0] =
3458                         wl_chspec_host_to_driver(ext_join_params->assoc.chanspec_list[0]);
3459         }
3460         ext_join_params->assoc.chanspec_num = htod32(ext_join_params->assoc.chanspec_num);
3461         if (ext_join_params->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
3462                 WL_INFO(("ssid \"%s\", len (%d)\n", ext_join_params->ssid.SSID,
3463                         ext_join_params->ssid.SSID_len));
3464         }
3465         wl_set_drv_status(wl, CONNECTING, dev);
3466
3467         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3468                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3469                 return BCME_ERROR;
3470         }
3471         err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size,
3472                 wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
3473
3474         WL_ERR(("Connectting with" MACDBG " channel (%d) ssid \"%s\", len (%d)\n\n",
3475                 MAC2STRDBG((u8*)(&ext_join_params->assoc.bssid)), wl->channel,
3476                 ext_join_params->ssid.SSID, ext_join_params->ssid.SSID_len));
3477
3478         kfree(ext_join_params);
3479         if (err) {
3480                 wl_clr_drv_status(wl, CONNECTING, dev);
3481                 if (err == BCME_UNSUPPORTED) {
3482                         WL_DBG(("join iovar is not supported\n"));
3483                         goto set_ssid;
3484                 } else
3485                         WL_ERR(("error (%d)\n", err));
3486         } else
3487                 goto exit;
3488
3489 set_ssid:
3490         memset(&join_params, 0, sizeof(join_params));
3491         join_params_size = sizeof(join_params.ssid);
3492
3493         join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
3494         memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
3495         join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
3496         wl_update_prof(wl, dev, NULL, &join_params.ssid, WL_PROF_SSID);
3497         if (sme->bssid)
3498                 memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN);
3499         else
3500                 memcpy(&join_params.params.bssid, &ether_bcast, ETH_ALEN);
3501
3502         wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
3503         WL_DBG(("join_param_size %zu\n", join_params_size));
3504
3505         if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
3506                 WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
3507                         join_params.ssid.SSID_len));
3508         }
3509         wl_set_drv_status(wl, CONNECTING, dev);
3510         err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true);
3511         if (err) {
3512                 WL_ERR(("error (%d)\n", err));
3513                 wl_clr_drv_status(wl, CONNECTING, dev);
3514         }
3515 exit:
3516         return err;
3517 }
3518
3519 static s32
3520 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
3521         u16 reason_code)
3522 {
3523         struct wl_priv *wl = wiphy_priv(wiphy);
3524         scb_val_t scbval;
3525         bool act = false;
3526         s32 err = 0;
3527         u8 *curbssid;
3528         WL_ERR(("Reason %d\n", reason_code));
3529         RETURN_EIO_IF_NOT_UP(wl);
3530         act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT);
3531         curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID);
3532         if (act || wl_get_drv_status(wl, CONNECTING, dev)) {
3533                 /*
3534                 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
3535                 */
3536 #if !defined(ESCAN_RESULT_PATCH)
3537                 /* Let scan aborted by F/W */
3538                 if (wl->scan_request) {
3539                         wl_notify_escan_complete(wl, dev, true, true);
3540                 }
3541 #endif /* ESCAN_RESULT_PATCH */
3542                 wl_clr_drv_status(wl, CONNECTING, dev);
3543                 wl_set_drv_status(wl, DISCONNECTING, dev);
3544                 scbval.val = reason_code;
3545                 memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
3546                 scbval.val = htod32(scbval.val);
3547                 err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
3548                         sizeof(scb_val_t), true);
3549                 if (unlikely(err)) {
3550                         wl_clr_drv_status(wl, DISCONNECTING, dev);
3551                         WL_ERR(("error (%d)\n", err));
3552                         return err;
3553                 }
3554         }
3555
3556         return err;
3557 }
3558
3559 #if defined(WL_CFG80211_P2P_DEV_IF)
3560 static s32
3561 wl_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
3562         enum nl80211_tx_power_setting type, s32 mbm)
3563 #else
3564 static s32
3565 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
3566         enum nl80211_tx_power_setting type, s32 dbm)
3567 #endif /* WL_CFG80211_P2P_DEV_IF */
3568 {
3569
3570         struct wl_priv *wl = wiphy_priv(wiphy);
3571         struct net_device *ndev = wl_to_prmry_ndev(wl);
3572         u16 txpwrmw;
3573         s32 err = 0;
3574         s32 disable = 0;
3575         s32 txpwrqdbm;
3576 #if defined(WL_CFG80211_P2P_DEV_IF)
3577         s32 dbm = MBM_TO_DBM(mbm);
3578 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) || \
3579         defined(WL_COMPAT_WIRELESS) || defined(WL_SUPPORT_BACKPORTED_KPATCHES)
3580         dbm = MBM_TO_DBM(dbm);
3581 #endif /* WL_CFG80211_P2P_DEV_IF */
3582
3583         RETURN_EIO_IF_NOT_UP(wl);
3584         switch (type) {
3585         case NL80211_TX_POWER_AUTOMATIC:
3586                 break;
3587         case NL80211_TX_POWER_LIMITED:
3588                 if (dbm < 0) {
3589                         WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
3590                         return -EINVAL;
3591                 }
3592                 break;
3593         case NL80211_TX_POWER_FIXED:
3594                 if (dbm < 0) {
3595                         WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
3596                         return -EINVAL;
3597                 }
3598                 break;
3599         }
3600         /* Make sure radio is off or on as far as software is concerned */
3601         disable = WL_RADIO_SW_DISABLE << 16;
3602         disable = htod32(disable);
3603         err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), true);
3604         if (unlikely(err)) {
3605                 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
3606                 return err;
3607         }
3608
3609         if (dbm > 0xffff)
3610                 txpwrmw = 0xffff;
3611         else
3612                 txpwrmw = (u16) dbm;
3613         txpwrqdbm = (s32)bcm_mw_to_qdbm(txpwrmw);
3614 #ifdef SUPPORT_WL_TXPOWER
3615         if (type == NL80211_TX_POWER_AUTOMATIC)
3616                 txpwrqdbm = 127;
3617         else
3618                 txpwrqdbm |= WL_TXPWR_OVERRIDE;
3619 #endif /* SUPPORT_WL_TXPOWER */
3620         err = wldev_iovar_setint(ndev, "qtxpower", txpwrqdbm);
3621         if (unlikely(err)) {
3622                 WL_ERR(("qtxpower error (%d)\n", err));
3623                 return err;
3624         }
3625         wl->conf->tx_power = dbm;
3626
3627         return err;
3628 }
3629
3630 #if defined(WL_CFG80211_P2P_DEV_IF)
3631 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy,
3632         struct wireless_dev *wdev, s32 *dbm)
3633 #else
3634 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
3635 #endif /* WL_CFG80211_P2P_DEV_IF */
3636 {
3637         struct wl_priv *wl = wiphy_priv(wiphy);
3638         struct net_device *ndev = wl_to_prmry_ndev(wl);
3639         s32 txpwrdbm;
3640         u8 result;
3641         s32 err = 0;
3642
3643         RETURN_EIO_IF_NOT_UP(wl);
3644         err = wldev_iovar_getint(ndev, "qtxpower", &txpwrdbm);
3645         if (unlikely(err)) {
3646                 WL_ERR(("error (%d)\n", err));
3647                 return err;
3648         }
3649         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
3650         *dbm = (s32) bcm_qdbm_to_mw(result);
3651
3652         return err;
3653 }
3654
3655 static s32
3656 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
3657         u8 key_idx, bool unicast, bool multicast)
3658 {
3659         struct wl_priv *wl = wiphy_priv(wiphy);
3660         u32 index;
3661         s32 wsec;
3662         s32 err = 0;
3663         s32 bssidx;
3664         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3665                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3666                 return BCME_ERROR;
3667         }
3668
3669         WL_DBG(("key index (%d)\n", key_idx));
3670         RETURN_EIO_IF_NOT_UP(wl);
3671         err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
3672         if (unlikely(err)) {
3673                 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
3674                 return err;
3675         }
3676         /* fix IOT issue with Apple Airport */
3677         if (wsec == WEP_ENABLED) {
3678                 /* Just select a new current key */
3679                 index = (u32) key_idx;
3680                 index = htod32(index);
3681                 err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
3682                         sizeof(index), true);
3683                 if (unlikely(err)) {
3684                         WL_ERR(("error (%d)\n", err));
3685                 }
3686         }
3687         return err;
3688 }
3689
3690 static s32
3691 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
3692         u8 key_idx, const u8 *mac_addr, struct key_params *params)
3693 {
3694         struct wl_priv *wl = wiphy_priv(wiphy);
3695         struct wl_wsec_key key;
3696         s32 err = 0;
3697         s32 bssidx;
3698         s32 mode = wl_get_mode_by_netdev(wl, dev);
3699         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3700                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3701                 return BCME_ERROR;
3702         }
3703         memset(&key, 0, sizeof(key));
3704         key.index = (u32) key_idx;
3705
3706         if (!ETHER_ISMULTI(mac_addr))
3707                 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
3708         key.len = (u32) params->key_len;
3709
3710         /* check for key index change */
3711         if (key.len == 0) {
3712                 /* key delete */
3713                 swap_key_from_BE(&key);
3714                 err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
3715                         wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
3716                 if (unlikely(err)) {
3717                         WL_ERR(("key delete error (%d)\n", err));
3718                         return err;
3719                 }
3720         } else {
3721                 if (key.len > sizeof(key.data)) {
3722                         WL_ERR(("Invalid key length (%d)\n", key.len));
3723                         return -EINVAL;
3724                 }
3725                 WL_DBG(("Setting the key index %d\n", key.index));
3726                 memcpy(key.data, params->key, key.len);
3727
3728                 if ((mode == WL_MODE_BSS) &&
3729                         (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
3730                         u8 keybuf[8];
3731                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
3732                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
3733                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
3734                 }
3735
3736                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
3737                 if (params->seq && params->seq_len == 6) {
3738                         /* rx iv */
3739                         u8 *ivptr;
3740                         ivptr = (u8 *) params->seq;
3741                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
3742                                 (ivptr[3] << 8) | ivptr[2];
3743                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
3744                         key.iv_initialized = true;
3745                 }
3746
3747                 switch (params->cipher) {
3748                 case WLAN_CIPHER_SUITE_WEP40:
3749                         key.algo = CRYPTO_ALGO_WEP1;
3750                         WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
3751                         break;
3752                 case WLAN_CIPHER_SUITE_WEP104:
3753                         key.algo = CRYPTO_ALGO_WEP128;
3754                         WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
3755                         break;
3756                 case WLAN_CIPHER_SUITE_TKIP:
3757                         key.algo = CRYPTO_ALGO_TKIP;
3758                         WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
3759                         break;
3760                 case WLAN_CIPHER_SUITE_AES_CMAC:
3761                         key.algo = CRYPTO_ALGO_AES_CCM;
3762                         WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
3763                         break;
3764                 case WLAN_CIPHER_SUITE_CCMP:
3765                         key.algo = CRYPTO_ALGO_AES_CCM;
3766                         WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
3767                         break;
3768                 default:
3769                         WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
3770                         return -EINVAL;
3771                 }
3772                 swap_key_from_BE(&key);
3773                 /* need to guarantee EAPOL 4/4 send out before set key */
3774                 if (mode != WL_MODE_AP)
3775                         dhd_wait_pend8021x(dev);
3776                 err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
3777                         wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
3778                 if (unlikely(err)) {
3779                         WL_ERR(("WLC_SET_KEY error (%d)\n", err));
3780                         return err;
3781                 }
3782         }
3783         return err;
3784 }
3785
3786 static s32
3787 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
3788         u8 key_idx, bool pairwise, const u8 *mac_addr,
3789         struct key_params *params)
3790 {
3791         struct wl_wsec_key key;
3792         s32 val = 0;
3793         s32 wsec = 0;
3794         s32 err = 0;
3795         u8 keybuf[8];
3796         s32 bssidx = 0;
3797         struct wl_priv *wl = wiphy_priv(wiphy);
3798         s32 mode = wl_get_mode_by_netdev(wl, dev);
3799         WL_DBG(("key index (%d)\n", key_idx));
3800         RETURN_EIO_IF_NOT_UP(wl);
3801
3802         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3803                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3804                 return BCME_ERROR;
3805         }
3806
3807         if (mac_addr &&
3808                 ((params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
3809                 (params->cipher != WLAN_CIPHER_SUITE_WEP104))) {
3810                         wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
3811                         goto exit;
3812         }
3813         memset(&key, 0, sizeof(key));
3814
3815         key.len = (u32) params->key_len;
3816         key.index = (u32) key_idx;
3817
3818         if (unlikely(key.len > sizeof(key.data))) {
3819                 WL_ERR(("Too long key length (%u)\n", key.len));
3820                 return -EINVAL;
3821         }
3822         memcpy(key.data, params->key, key.len);
3823
3824         key.flags = WL_PRIMARY_KEY;
3825         switch (params->cipher) {
3826         case WLAN_CIPHER_SUITE_WEP40:
3827                 key.algo = CRYPTO_ALGO_WEP1;
3828                 val = WEP_ENABLED;
3829                 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
3830                 break;
3831         case WLAN_CIPHER_SUITE_WEP104:
3832                 key.algo = CRYPTO_ALGO_WEP128;
3833                 val = WEP_ENABLED;
3834                 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
3835                 break;
3836         case WLAN_CIPHER_SUITE_TKIP:
3837                 key.algo = CRYPTO_ALGO_TKIP;
3838                 val = TKIP_ENABLED;
3839                 /* wpa_supplicant switches the third and fourth quarters of the TKIP key */
3840                 if (mode == WL_MODE_BSS) {
3841                         bcopy(&key.data[24], keybuf, sizeof(keybuf));
3842                         bcopy(&key.data[16], &key.data[24], sizeof(keybuf));
3843                         bcopy(keybuf, &key.data[16], sizeof(keybuf));
3844                 }
3845                 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
3846                 break;
3847         case WLAN_CIPHER_SUITE_AES_CMAC:
3848                 key.algo = CRYPTO_ALGO_AES_CCM;
3849                 val = AES_ENABLED;
3850                 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
3851                 break;
3852         case WLAN_CIPHER_SUITE_CCMP:
3853                 key.algo = CRYPTO_ALGO_AES_CCM;
3854                 val = AES_ENABLED;
3855                 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
3856                 break;
3857         default:
3858                 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
3859                 return -EINVAL;
3860         }
3861
3862         /* Set the new key/index */
3863         if ((mode == WL_MODE_IBSS) && (val & (TKIP_ENABLED | AES_ENABLED))) {
3864                 WL_ERR(("IBSS KEY setted\n"));
3865                 wldev_iovar_setint(dev, "wpa_auth", WPA_AUTH_NONE);
3866         }
3867         swap_key_from_BE(&key);
3868         err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf,
3869                 WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
3870         if (unlikely(err)) {
3871                 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
3872                 return err;
3873         }
3874
3875 exit:
3876         err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
3877         if (unlikely(err)) {
3878                 WL_ERR(("get wsec error (%d)\n", err));
3879                 return err;
3880         }
3881
3882         wsec |= val;
3883         err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
3884         if (unlikely(err)) {
3885                 WL_ERR(("set wsec error (%d)\n", err));
3886                 return err;
3887         }
3888
3889         return err;
3890 }
3891
3892 static s32
3893 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
3894         u8 key_idx, bool pairwise, const u8 *mac_addr)
3895 {
3896         struct wl_wsec_key key;
3897         struct wl_priv *wl = wiphy_priv(wiphy);
3898         s32 err = 0;
3899         s32 bssidx;
3900
3901         if (!wl)
3902                 return ERR_PTR(-EINVAL);
3903
3904         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3905                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3906                 return BCME_ERROR;
3907         }
3908         WL_DBG(("Enter\n"));
3909
3910 #ifndef IEEE80211W
3911         if ((key_idx >= DOT11_MAX_DEFAULT_KEYS) && (key_idx < DOT11_MAX_DEFAULT_KEYS+2))
3912                 return -EINVAL;
3913 #endif
3914
3915         RETURN_EIO_IF_NOT_UP(wl);
3916         memset(&key, 0, sizeof(key));
3917
3918         key.flags = WL_PRIMARY_KEY;
3919         key.algo = CRYPTO_ALGO_OFF;
3920         key.index = (u32) key_idx;
3921
3922         WL_DBG(("key index (%d)\n", key_idx));
3923         /* Set the new key/index */
3924         swap_key_from_BE(&key);
3925         err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf,
3926                 WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
3927         if (unlikely(err)) {
3928                 if (err == -EINVAL) {
3929                         if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
3930                                 /* we ignore this key index in this case */
3931                                 WL_DBG(("invalid key index (%d)\n", key_idx));
3932                         }
3933                 } else {
3934                         WL_ERR(("WLC_SET_KEY error (%d)\n", err));
3935                 }
3936                 return err;
3937         }
3938         return err;
3939 }
3940
3941 static s32
3942 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
3943         u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
3944         void (*callback) (void *cookie, struct key_params * params))
3945 {
3946         struct key_params params;
3947         struct wl_wsec_key key;
3948         struct wl_priv *wl = wiphy_priv(wiphy);
3949         struct wl_security *sec;
3950         s32 wsec;
3951         s32 err = 0;
3952         s32 bssidx;
3953         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
3954                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
3955                 return BCME_ERROR;
3956         }
3957         WL_DBG(("key index (%d)\n", key_idx));
3958         RETURN_EIO_IF_NOT_UP(wl);
3959         memset(&key, 0, sizeof(key));
3960         key.index = key_idx;
3961         swap_key_to_BE(&key);
3962         memset(&params, 0, sizeof(params));
3963         params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
3964         memcpy(params.key, key.data, params.key_len);
3965
3966         err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
3967         if (unlikely(err)) {
3968                 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
3969                 return err;
3970         }
3971         switch (wsec & ~SES_OW_ENABLED) {
3972                 case WEP_ENABLED:
3973                         sec = wl_read_prof(wl, dev, WL_PROF_SEC);
3974                         if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
3975                                 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3976                                 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
3977                         } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
3978                                 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3979                                 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
3980                         }
3981                         break;
3982                 case TKIP_ENABLED:
3983                         params.cipher = WLAN_CIPHER_SUITE_TKIP;
3984                         WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
3985                         break;
3986                 case AES_ENABLED:
3987                         params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3988                         WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
3989                         break;
3990                 default:
3991                         WL_ERR(("Invalid algo (0x%x)\n", wsec));
3992                         return -EINVAL;
3993         }
3994
3995         callback(cookie, &params);
3996         return err;
3997 }
3998
3999 static s32
4000 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
4001         struct net_device *dev, u8 key_idx)
4002 {
4003         WL_INFO(("Not supported\n"));
4004         return -EOPNOTSUPP;
4005 }
4006
4007 static s32
4008 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
4009         u8 *mac, struct station_info *sinfo)
4010 {
4011         struct wl_priv *wl = wiphy_priv(wiphy);
4012         scb_val_t scb_val;
4013         s32 rssi;
4014         s32 rate;
4015         s32 err = 0;
4016         sta_info_t *sta;
4017 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) || 0
4018         s8 eabuf[ETHER_ADDR_STR_LEN];
4019 #endif
4020         dhd_pub_t *dhd =  (dhd_pub_t *)(wl->pub);
4021         RETURN_EIO_IF_NOT_UP(wl);
4022         if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
4023                 err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac,
4024                         ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_SMLEN, &wl->ioctl_buf_sync);
4025                 if (err < 0) {
4026                         WL_ERR(("GET STA INFO failed, %d\n", err));
4027                         return err;
4028                 }
4029                 sinfo->filled = STATION_INFO_INACTIVE_TIME;
4030                 sta = (sta_info_t *)wl->ioctl_buf;
4031                 sta->len = dtoh16(sta->len);
4032                 sta->cap = dtoh16(sta->cap);
4033                 sta->flags = dtoh32(sta->flags);
4034                 sta->idle = dtoh32(sta->idle);
4035                 sta->in = dtoh32(sta->in);
4036                 sinfo->inactive_time = sta->idle * 1000;
4037 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) || 0
4038                 if (sta->flags & WL_STA_ASSOC) {
4039                         sinfo->filled |= STATION_INFO_CONNECTED_TIME;
4040                         sinfo->connected_time = sta->in;
4041                 }
4042                 WL_INFO(("STA %s : idle time : %d sec, connected time :%d ms\n",
4043                         bcm_ether_ntoa((const struct ether_addr *)mac, eabuf), sinfo->inactive_time,
4044                         sta->idle * 1000));
4045 #endif
4046         } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS ||
4047                 wl_get_mode_by_netdev(wl, dev) == WL_MODE_IBSS) {
4048                 get_pktcnt_t pktcnt;
4049                 u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
4050                 if (!wl_get_drv_status(wl, CONNECTED, dev) ||
4051                         (dhd_is_associated(dhd, NULL, &err) == FALSE)) {
4052                         WL_ERR(("NOT assoc\n"));
4053                         if (err == -ERESTARTSYS)
4054                                 return err;
4055                         err = -ENODEV;
4056                         return err;
4057                 }
4058                 if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) {
4059                         WL_ERR(("Wrong Mac address: "MACDBG" != "MACDBG"\n",
4060                                 MAC2STRDBG(mac), MAC2STRDBG(curmacp)));
4061                 }
4062
4063                 /* Report the current tx rate */
4064                 err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
4065                 if (err) {
4066                         WL_ERR(("Could not get rate (%d)\n", err));
4067                 } else {
4068 #if defined(USE_DYNAMIC_MAXPKT_RXGLOM)
4069                         int rxpktglom;
4070 #endif
4071                         rate = dtoh32(rate);
4072                         sinfo->filled |= STATION_INFO_TX_BITRATE;
4073                         sinfo->txrate.legacy = rate * 5;
4074                         WL_DBG(("Rate %d Mbps\n", (rate / 2)));
4075 #if defined(USE_DYNAMIC_MAXPKT_RXGLOM)
4076                         rxpktglom = ((rate/2) > 150) ? 20 : 10;
4077
4078                         if (maxrxpktglom != rxpktglom) {
4079                                 maxrxpktglom = rxpktglom;
4080                                 WL_DBG(("Rate %d Mbps, update bus:maxtxpktglom=%d\n", (rate/2),
4081                                         maxrxpktglom));
4082                                 err = wldev_iovar_setbuf(dev, "bus:maxtxpktglom",
4083                                         (char*)&maxrxpktglom, 4, wl->ioctl_buf,
4084                                         WLC_IOCTL_MAXLEN, NULL);
4085                                 if (err < 0) {
4086                                         WL_ERR(("set bus:maxtxpktglom failed, %d\n", err));
4087                                 }
4088                         }
4089 #endif
4090                 }
4091
4092                 memset(&scb_val, 0, sizeof(scb_val));
4093                 scb_val.val = 0;
4094                 err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
4095                         sizeof(scb_val_t), false);
4096                 if (err) {
4097                         WL_ERR(("Could not get rssi (%d)\n", err));
4098                         goto get_station_err;
4099                 }
4100                 rssi = wl_rssi_offset(dtoh32(scb_val.val));
4101                 sinfo->filled |= STATION_INFO_SIGNAL;
4102                 sinfo->signal = rssi;
4103                 WL_DBG(("RSSI %d dBm\n", rssi));
4104                 err = wldev_ioctl(dev, WLC_GET_PKTCNTS, &pktcnt,
4105                         sizeof(pktcnt), false);
4106                 if (!err) {
4107                         sinfo->filled |= (STATION_INFO_RX_PACKETS |
4108                                 STATION_INFO_RX_DROP_MISC |
4109                                 STATION_INFO_TX_PACKETS |
4110                                 STATION_INFO_TX_FAILED);
4111                         sinfo->rx_packets = pktcnt.rx_good_pkt;
4112                         sinfo->rx_dropped_misc = pktcnt.rx_bad_pkt;
4113                         sinfo->tx_packets = pktcnt.tx_good_pkt;
4114                         sinfo->tx_failed  = pktcnt.tx_bad_pkt;
4115                 }
4116 get_station_err:
4117                 if (err && (err != -ERESTARTSYS)) {
4118                         /* Disconnect due to zero BSSID or error to get RSSI */
4119                         WL_ERR(("force cfg80211_disconnected: %d\n", err));
4120                         wl_clr_drv_status(wl, CONNECTED, dev);
4121                         cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL);
4122                         wl_link_down(wl);
4123                 }
4124         }
4125         else {
4126                 WL_ERR(("Invalid device mode %d\n", wl_get_mode_by_netdev(wl, dev)));
4127         }
4128
4129         return err;
4130 }
4131
4132 /* Function to update sta power save mode for Kernel wifi stack */
4133 int wl_cfg80211_update_power_mode(struct net_device *dev)
4134 {
4135         int pm = -1;
4136         int err;
4137
4138         err = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), false);
4139         if (err || (pm == -1)) {
4140                 WL_ERR(("error (%d)\n", err));
4141         } else {
4142                 pm = (pm == PM_OFF) ? false : true;
4143                 WL_DBG(("%s: %d\n", __func__, pm));
4144                 if (dev->ieee80211_ptr)
4145                         dev->ieee80211_ptr->ps = pm;
4146         }
4147         return err;
4148 }
4149
4150 static s32
4151 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
4152         bool enabled, s32 timeout)
4153 {
4154         s32 pm;
4155         s32 err = 0;
4156         struct wl_priv *wl = wiphy_priv(wiphy);
4157         struct net_info *_net_info = wl_get_netinfo_by_netdev(wl, dev);
4158 #if !defined(SUPPORT_PM2_ONLY)
4159         dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
4160 #endif /* (OEM_ANDROID) */
4161         RETURN_EIO_IF_NOT_UP(wl);
4162         WL_DBG(("Enter\n"));
4163 #if defined(WL_ENABLE_P2P_IF)
4164         if (wl->p2p_net == dev || _net_info == NULL || wl->vsdb_mode ||
4165                 !wl_get_drv_status(wl, CONNECTED, dev)) {
4166 #else
4167         if (_net_info == NULL || wl->vsdb_mode ||
4168                 !wl_get_drv_status(wl, CONNECTED, dev)) {
4169 #endif /* WL_ENABLE_P2P_IF */
4170                 return err;
4171         }
4172         WL_DBG(("%s: Enter power save enabled %d\n", dev->name, enabled));
4173
4174         /* Delete pm_enable_work */
4175                 wl_add_remove_pm_enable_work(wl, FALSE, WL_HANDLER_PEND);
4176
4177 #if !defined(SUPPORT_PM2_ONLY)
4178         /* android has special hooks to change pm when kernel suspended */
4179         pm = enabled ? ((dhd->in_suspend) ? PM_MAX : PM_FAST) : PM_OFF;
4180 #else
4181         pm = enabled ? PM_FAST : PM_OFF;
4182 #endif /* SUPPORT_PM2_ONLY */
4183         if (_net_info->pm_block) {
4184                 WL_ERR(("%s:Do not enable the power save for pm_block %d\n",
4185                         dev->name, _net_info->pm_block));
4186                 pm = PM_OFF;
4187         }
4188         pm = htod32(pm);
4189         WL_DBG(("%s:power save %s\n", dev->name, (pm ? "enabled" : "disabled")));
4190         err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
4191         if (unlikely(err)) {
4192                 if (err == -ENODEV)
4193                         WL_DBG(("net_device is not ready yet\n"));
4194                 else
4195                         WL_ERR(("error (%d)\n", err));
4196                 return err;
4197         }
4198         return err;
4199 }
4200
4201 static __used u32 wl_find_msb(u16 bit16)
4202 {
4203         u32 ret = 0;
4204
4205         if (bit16 & 0xff00) {
4206                 ret += 8;
4207                 bit16 >>= 8;
4208         }
4209
4210         if (bit16 & 0xf0) {
4211                 ret += 4;
4212                 bit16 >>= 4;
4213         }
4214
4215         if (bit16 & 0xc) {
4216                 ret += 2;
4217                 bit16 >>= 2;
4218         }
4219
4220         if (bit16 & 2)
4221                 ret += bit16 & 2;
4222         else if (bit16)
4223                 ret += bit16;
4224
4225         return ret;
4226 }
4227
4228 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
4229 {
4230         struct wl_priv *wl = wiphy_priv(wiphy);
4231         struct net_device *ndev = wl_to_prmry_ndev(wl);
4232         s32 err = 0;
4233
4234         if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
4235                 WL_INFO(("device is not ready\n"));
4236                 return 0;
4237         }
4238
4239         wl_invoke_iscan(wl);
4240
4241         return err;
4242 }
4243
4244 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) || 0
4245 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
4246 #else
4247 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
4248 #endif
4249 {
4250 #ifdef DHD_CLEAR_ON_SUSPEND
4251         struct wl_priv *wl = wiphy_priv(wiphy);
4252         struct net_info *iter, *next;
4253         struct net_device *ndev = wl_to_prmry_ndev(wl);
4254         unsigned long flags;
4255         if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
4256                 WL_INFO(("device is not ready : status (%d)\n",
4257                         (int)wl->status));
4258                 return 0;
4259         }
4260         for_each_ndev(wl, iter, next)
4261                 wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev);
4262         wl_term_iscan(wl);
4263         spin_lock_irqsave(&wl->cfgdrv_lock, flags);
4264         if (wl->scan_request) {
4265 #ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
4266                 TEGRA_SCAN_DONE(wl->scan_request, true)
4267 #endif
4268                 cfg80211_scan_done(wl->scan_request, true);
4269 #ifdef CONFIG_BCMDHD_CUSTOM_SYSFS_TEGRA
4270 skip_cfg80211_scan_done:
4271 #endif
4272                 wl->scan_request = NULL;
4273         }
4274         for_each_ndev(wl, iter, next) {
4275                 wl_clr_drv_status(wl, SCANNING, iter->ndev);
4276                 wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev);
4277         }
4278         spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
4279         for_each_ndev(wl, iter, next) {
4280                 if (wl_get_drv_status(wl, CONNECTING, iter->ndev)) {
4281                         wl_bss_connect_done(wl, iter->ndev, NULL, NULL, false);
4282                 }
4283         }
4284 #endif /* DHD_CLEAR_ON_SUSPEND */
4285         return 0;
4286 }
4287
4288 static s32
4289 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
4290         s32 err)
4291 {
4292         int i, j;
4293         struct wl_priv *wl = wlcfg_drv_priv;
4294         struct net_device *primary_dev = wl_to_prmry_ndev(wl);
4295
4296         if (!pmk_list) {
4297                 printk("pmk_list is NULL\n");
4298                 return -EINVAL;
4299         }
4300         /* pmk list is supported only for STA interface i.e. primary interface
4301          * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
4302          */
4303         if (primary_dev != dev) {
4304                 WL_INFO(("Not supporting Flushing pmklist on virtual"
4305                         " interfaces than primary interface\n"));
4306                 return err;
4307         }
4308
4309         WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
4310         for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
4311                 WL_DBG(("PMKID[%d]: %pM =\n", i,
4312                         &pmk_list->pmkids.pmkid[i].BSSID));
4313                 for (j = 0; j < WPA2_PMKID_LEN; j++) {
4314                         WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
4315                 }
4316         }
4317         if (likely(!err)) {
4318                 err = wldev_iovar_setbuf(dev, "pmkid_info", (char *)pmk_list,
4319                         sizeof(*pmk_list), wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
4320         }
4321
4322         return err;
4323 }
4324
4325 static s32
4326 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
4327         struct cfg80211_pmksa *pmksa)
4328 {
4329         struct wl_priv *wl = wiphy_priv(wiphy);
4330         s32 err = 0;
4331         int i;
4332
4333         RETURN_EIO_IF_NOT_UP(wl);
4334         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
4335                 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
4336                         ETHER_ADDR_LEN))
4337                         break;
4338         if (i < WL_NUM_PMKIDS_MAX) {
4339                 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
4340                         ETHER_ADDR_LEN);
4341                 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
4342                         WPA2_PMKID_LEN);
4343                 if (i == wl->pmk_list->pmkids.npmkid)
4344                         wl->pmk_list->pmkids.npmkid++;
4345         } else {
4346                 err = -EINVAL;
4347         }
4348         WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
4349                 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].BSSID));
4350         for (i = 0; i < WPA2_PMKID_LEN; i++) {
4351                 WL_DBG(("%02x\n",
4352                         wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].
4353                         PMKID[i]));
4354         }
4355
4356         err = wl_update_pmklist(dev, wl->pmk_list, err);
4357
4358         return err;
4359 }
4360
4361 static s32
4362 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
4363         struct cfg80211_pmksa *pmksa)
4364 {
4365         struct wl_priv *wl = wiphy_priv(wiphy);
4366         struct _pmkid_list pmkid = {0};
4367         s32 err = 0;
4368         int i;
4369
4370         RETURN_EIO_IF_NOT_UP(wl);
4371         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
4372         memcpy(pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
4373
4374         WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
4375                 &pmkid.pmkid[0].BSSID));
4376         for (i = 0; i < WPA2_PMKID_LEN; i++) {
4377                 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
4378         }
4379
4380         for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
4381                 if (!memcmp
4382                     (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
4383                      ETHER_ADDR_LEN))
4384                         break;
4385
4386         if ((wl->pmk_list->pmkids.npmkid > 0) &&
4387                 (i < wl->pmk_list->pmkids.npmkid)) {
4388                 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
4389                 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
4390                         memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
4391                                 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
4392                                 ETHER_ADDR_LEN);
4393                         memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
4394                                 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
4395                                 WPA2_PMKID_LEN);
4396                 }
4397                 wl->pmk_list->pmkids.npmkid--;
4398         } else {
4399                 err = -EINVAL;
4400         }
4401
4402         err = wl_update_pmklist(dev, wl->pmk_list, err);
4403
4404         return err;
4405
4406 }
4407
4408 static s32
4409 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
4410 {
4411         struct wl_priv *wl = wiphy_priv(wiphy);
4412         s32 err = 0;
4413         RETURN_EIO_IF_NOT_UP(wl);
4414         memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
4415         err = wl_update_pmklist(dev, wl->pmk_list, err);
4416         return err;
4417
4418 }
4419
4420 static wl_scan_params_t *
4421 wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
4422 {
4423         wl_scan_params_t *params;
4424         int params_size;
4425         int num_chans;
4426
4427         *out_params_size = 0;
4428
4429         /* Our scan params only need space for 1 channel and 0 ssids */
4430         params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16);
4431         params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL);
4432         if (params == NULL) {
4433                 WL_ERR(("mem alloc failed (%d bytes)\n", params_size));
4434                 return params;
4435         }
4436         memset(params, 0, params_size);
4437         params->nprobes = nprobes;
4438
4439         num_chans = (channel == 0) ? 0 : 1;
4440
4441         memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
4442         params->bss_type = DOT11_BSSTYPE_ANY;
4443         params->scan_type = DOT11_SCANTYPE_ACTIVE;
4444         params->nprobes = htod32(1);
4445         params->active_time = htod32(-1);
4446         params->passive_time = htod32(-1);
4447         params->home_time = htod32(10);
4448         if (channel == -1)
4449                 params->channel_list[0] = htodchanspec(channel);
4450         else
4451                 params->channel_list[0] = wl_ch_host_to_driver(channel);
4452
4453         /* Our scan params have 1 channel and 0 ssids */
4454         params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
4455                 (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
4456
4457         *out_params_size = params_size; /* rtn size to the caller */
4458         return params;
4459 }
4460
4461 #if defined(WL_CFG80211_P2P_DEV_IF)
4462 static s32
4463 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
4464         struct ieee80211_channel *channel, unsigned int duration, u64 *cookie)
4465 #else
4466 static s32
4467 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
4468         struct ieee80211_channel * channel,
4469         enum nl80211_channel_type channel_type,
4470         unsigned int duration, u64 *cookie)
4471 #endif /* WL_CFG80211_P2P_DEV_IF */
4472 {
4473         s32 target_channel;
4474         u32 id;
4475         s32 err = BCME_OK;
4476         struct ether_addr primary_mac;
4477         struct net_device *ndev = NULL;
4478         struct wl_priv *wl = wiphy_priv(wiphy);
4479
4480         if (!wl)
4481                 return ERR_PTR(-EINVAL);
4482
4483         ndev = cfgdev_to_wlc_ndev(cfgdev, wl);
4484
4485         WL_DBG(("Enter, channel: %d, duration ms (%d) SCANNING ?? %s \n",
4486                 ieee80211_frequency_to_channel(channel->center_freq),
4487                 duration, (wl_get_drv_status(wl, SCANNING, ndev)) ? "YES":"NO"));
4488
4489         if (!wl->p2p) {
4490                 WL_ERR(("wl->p2p is not initialized\n"));
4491                 err = BCME_ERROR;
4492                 goto exit;
4493         }
4494
4495 #ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
4496         if (wl_get_drv_status_all(wl, SCANNING)) {
4497                 wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true);
4498         }
4499 #endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
4500
4501         target_channel = ieee80211_frequency_to_channel(channel->center_freq);
4502         memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel));
4503 #if defined(WL_ENABLE_P2P_IF)
4504         wl->remain_on_chan_type = channel_type;
4505 #endif /* WL_ENABLE_P2P_IF */
4506         id = ++wl->last_roc_id;
4507         if (id == 0)
4508                 id = ++wl->last_roc_id;
4509         *cookie = id;
4510
4511 #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
4512         if (wl_get_drv_status(wl, SCANNING, ndev)) {
4513                 struct timer_list *_timer;
4514                 WL_DBG(("scan is running. go to fake listen state\n"));
4515
4516                 wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev);
4517
4518                 if (timer_pending(&wl->p2p->listen_timer)) {
4519                         WL_DBG(("cancel current listen timer \n"));
4520                         del_timer_sync(&wl->p2p->listen_timer);
4521                 }
4522
4523                 _timer = &wl->p2p->listen_timer;
4524                 wl_clr_p2p_status(wl, LISTEN_EXPIRED);
4525
4526                 INIT_TIMER(_timer, wl_cfgp2p_listen_expired, duration, 0);
4527
4528                 err = BCME_OK;
4529                 goto exit;
4530         }
4531 #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
4532
4533 #ifdef WL_CFG80211_SYNC_GON
4534         if (wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM_LISTEN)) {
4535                 /* do not enter listen mode again if we are in listen mode already for next af.
4536                  * remain on channel completion will be returned by waiting next af completion.
4537                  */
4538 #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
4539                 wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev);
4540 #else
4541                 wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev);
4542 #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
4543                 goto exit;
4544         }
4545 #endif /* WL_CFG80211_SYNC_GON */
4546         if (wl->p2p && !wl->p2p->on) {
4547                 /* In case of p2p_listen command, supplicant send remain_on_channel
4548                  * without turning on P2P
4549                  */
4550                 get_primary_mac(wl, &primary_mac);
4551                 wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
4552                 p2p_on(wl) = true;
4553         }
4554
4555         if (p2p_is_on(wl)) {
4556                 err = wl_cfgp2p_enable_discovery(wl, ndev, NULL, 0);
4557                 if (unlikely(err)) {
4558                         goto exit;
4559                 }
4560 #ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
4561                 wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev);
4562 #endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
4563                 err = wl_cfgp2p_discover_listen(wl, target_channel, duration);
4564
4565 #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
4566                 if (err == BCME_OK) {
4567                         wl_set_drv_status(wl, REMAINING_ON_CHANNEL, ndev);
4568                 } else {
4569                         /* if failed, firmware may be internal scanning state.
4570                          * so other scan request shall not abort it
4571                          */
4572                         wl_set_drv_status(wl, FAKE_REMAINING_ON_CHANNEL, ndev);
4573                 }
4574 #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
4575                 /* WAR: set err = ok to prevent cookie mismatch in wpa_supplicant
4576                  * and expire timer will send a completion to the upper layer
4577                  */
4578                 err = BCME_OK;
4579         }
4580
4581 exit:
4582         if (err == BCME_OK) {
4583                 WL_INFO(("Success\n"));
4584 #if defined(WL_CFG80211_P2P_DEV_IF)
4585                 cfg80211_ready_on_channel(cfgdev, *cookie, channel,
4586                         duration, GFP_KERNEL);
4587 #else
4588                 cfg80211_ready_on_channel(cfgdev, *cookie, channel,
4589                         channel_type, duration, GFP_KERNEL);
4590 #endif /* WL_CFG80211_P2P_DEV_IF */
4591         } else {
4592                 WL_ERR(("Fail to Set (err=%d cookie:%llu)\n", err, *cookie));
4593         }
4594         return err;
4595 }
4596
4597 static s32
4598 wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4599         bcm_struct_cfgdev *cfgdev, u64 cookie)
4600 {
4601         s32 err = 0;
4602
4603 #if defined(WL_CFG80211_P2P_DEV_IF)
4604         if (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
4605                 WL_DBG((" enter ) on P2P dedicated discover interface\n"));
4606         }
4607 #else
4608         WL_DBG((" enter ) netdev_ifidx: %d \n", cfgdev->ifindex));
4609 #endif /* WL_CFG80211_P2P_DEV_IF */
4610         return err;
4611 }
4612
4613 static void
4614 wl_cfg80211_afx_handler(struct work_struct *work)
4615 {
4616         struct afx_hdl *afx_instance;
4617         struct wl_priv *wl = wlcfg_drv_priv;
4618         s32 ret = BCME_OK;
4619
4620         afx_instance = container_of(work, struct afx_hdl, work);
4621         if (afx_instance != NULL && wl->afx_hdl->is_active) {
4622                 if (wl->afx_hdl->is_listen && wl->afx_hdl->my_listen_chan) {
4623                         ret = wl_cfgp2p_discover_listen(wl, wl->afx_hdl->my_listen_chan,
4624                                 (100 * (1 + (RANDOM32() % 3)))); /* 100ms ~ 300ms */
4625                 } else {
4626                         ret = wl_cfgp2p_act_frm_search(wl, wl->afx_hdl->dev,
4627                                 wl->afx_hdl->bssidx, wl->afx_hdl->peer_listen_chan,
4628                                 NULL);
4629                 }
4630                 if (unlikely(ret != BCME_OK)) {
4631                         WL_ERR(("ERROR occurred! returned value is (%d)\n", ret));
4632                         if (wl_get_drv_status_all(wl, FINDING_COMMON_CHANNEL))
4633                                 complete(&wl->act_frm_scan);
4634                 }
4635         }
4636 }
4637
4638 static s32
4639 wl_cfg80211_af_searching_channel(struct wl_priv *wl, struct net_device *dev)
4640 {
4641         u32 max_retry = WL_CHANNEL_SYNC_RETRY;
4642
4643         if (dev == NULL)
4644                 return -1;
4645
4646         WL_DBG((" enter ) \n"));
4647
4648         wl_set_drv_status(wl, FINDING_COMMON_CHANNEL, dev);
4649         wl->afx_hdl->is_active = TRUE;
4650
4651         /* Loop to wait until we find a peer's channel or the
4652          * pending action frame tx is cancelled.
4653          */
4654         while ((wl->afx_hdl->retry < max_retry) &&
4655                 (wl->afx_hdl->peer_chan == WL_INVALID)) {
4656                 wl->afx_hdl->is_listen = FALSE;
4657                 wl_set_drv_status(wl, SCANNING, dev);
4658                 WL_DBG(("Scheduling the action frame for sending.. retry %d\n",
4659                         wl->afx_hdl->retry));
4660                 /* search peer on peer's listen channel */
4661                 schedule_work(&wl->afx_hdl->work);
4662                 wait_for_completion_timeout(&wl->act_frm_scan,
4663                         msecs_to_jiffies(WL_AF_SEARCH_TIME_MAX));
4664
4665                 if ((wl->afx_hdl->peer_chan != WL_INVALID) ||
4666                         !(wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev)))
4667                         break;
4668
4669                 if (wl->afx_hdl->my_listen_chan) {
4670                         WL_DBG(("Scheduling Listen peer in my listen channel = %d\n",
4671                                 wl->afx_hdl->my_listen_chan));
4672                         /* listen on my listen channel */
4673                         wl->afx_hdl->is_listen = TRUE;
4674                         schedule_work(&wl->afx_hdl->work);
4675                         wait_for_completion_timeout(&wl->act_frm_scan,
4676                                 msecs_to_jiffies(WL_AF_SEARCH_TIME_MAX));
4677                 }
4678                 if ((wl->afx_hdl->peer_chan != WL_INVALID) ||
4679                         !(wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev)))
4680                         break;
4681
4682                 wl->afx_hdl->retry++;
4683
4684                 WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl);
4685         }
4686
4687         wl->afx_hdl->is_active = FALSE;
4688
4689         wl_clr_drv_status(wl, SCANNING, dev);
4690         wl_clr_drv_status(wl, FINDING_COMMON_CHANNEL, dev);
4691
4692         return (wl->afx_hdl->peer_chan);
4693 }
4694
4695 struct p2p_config_af_params {
4696         s32 max_tx_retry;       /* max tx retry count if tx no ack */
4697         /* To make sure to send successfully action frame, we have to turn off mpc
4698          * 0: off, 1: on,  (-1): do nothing
4699          */
4700         s32 mpc_onoff;
4701 #ifdef WL_CFG80211_SYNC_GON
4702         bool extra_listen;
4703 #endif
4704         bool search_channel;    /* 1: search peer's channel to send af */
4705 };
4706
4707 static s32
4708 wl_cfg80211_config_p2p_pub_af_tx(struct wiphy *wiphy,
4709         wl_action_frame_t *action_frame, wl_af_params_t *af_params,
4710         struct p2p_config_af_params *config_af_params)
4711 {
4712         s32 err = BCME_OK;
4713         struct wl_priv *wl = wiphy_priv(wiphy);
4714         wifi_p2p_pub_act_frame_t *act_frm =
4715                 (wifi_p2p_pub_act_frame_t *) (action_frame->data);
4716
4717         /* initialize default value */
4718 #ifdef WL_CFG80211_SYNC_GON
4719         config_af_params->extra_listen = true;
4720 #endif
4721         config_af_params->search_channel = false;
4722         config_af_params->max_tx_retry = WL_AF_TX_MAX_RETRY;
4723         config_af_params->mpc_onoff = -1;
4724         wl->next_af_subtype = P2P_PAF_SUBTYPE_INVALID;
4725
4726         switch (act_frm->subtype) {
4727         case P2P_PAF_GON_REQ: {
4728                 WL_DBG(("P2P: GO_NEG_PHASE status set \n"));
4729                 wl_set_p2p_status(wl, GO_NEG_PHASE);
4730
4731                 config_af_params->mpc_onoff = 0;
4732                 config_af_params->search_channel = true;
4733                 wl->next_af_subtype = act_frm->subtype + 1;
4734
4735                 /* increase dwell time to wait for RESP frame */
4736                 af_params->dwell_time = WL_MED_DWELL_TIME;
4737
4738                 break;
4739         }
4740         case P2P_PAF_GON_RSP: {
4741                 wl->next_af_subtype = act_frm->subtype + 1;
4742                 /* increase dwell time to wait for CONF frame */
4743                 af_params->dwell_time = WL_MED_DWELL_TIME + 100;
4744                 break;
4745         }
4746         case P2P_PAF_GON_CONF: {
4747                 /* If we reached till GO Neg confirmation reset the filter */
4748                 WL_DBG(("P2P: GO_NEG_PHASE status cleared \n"));
4749                 wl_clr_p2p_status(wl, GO_NEG_PHASE);
4750
4751                 /* turn on mpc again if go nego is done */
4752                 config_af_params->mpc_onoff = 1;
4753
4754                 /* minimize dwell time */
4755                 af_params->dwell_time = WL_MIN_DWELL_TIME;
4756
4757 #ifdef WL_CFG80211_SYNC_GON
4758                 config_af_params->extra_listen = false;
4759 #endif /* WL_CFG80211_SYNC_GON */
4760                 break;
4761         }
4762         case P2P_PAF_INVITE_REQ: {
4763                 config_af_params->search_channel = true;
4764                 wl->next_af_subtype = act_frm->subtype + 1;
4765
4766                 /* increase dwell time */
4767                 af_params->dwell_time = WL_MED_DWELL_TIME;
4768                 break;
4769         }
4770         case P2P_PAF_INVITE_RSP:
4771                 /* minimize dwell time */
4772                 af_params->dwell_time = WL_MIN_DWELL_TIME;
4773 #ifdef WL_CFG80211_SYNC_GON
4774                 config_af_params->extra_listen = false;
4775 #endif /* WL_CFG80211_SYNC_GON */
4776                 break;
4777         case P2P_PAF_DEVDIS_REQ: {
4778                 if (IS_ACTPUB_WITHOUT_GROUP_ID(&act_frm->elts[0],
4779                         action_frame->len)) {
4780                         config_af_params->search_channel = true;
4781                 }
4782
4783                 wl->next_af_subtype = act_frm->subtype + 1;
4784                 /* maximize dwell time to wait for RESP frame */
4785                 af_params->dwell_time = WL_LONG_DWELL_TIME;
4786                 break;
4787         }
4788         case P2P_PAF_DEVDIS_RSP:
4789                 /* minimize dwell time */
4790                 af_params->dwell_time = WL_MIN_DWELL_TIME;
4791 #ifdef WL_CFG80211_SYNC_GON
4792                 config_af_params->extra_listen = false;
4793 #endif /* WL_CFG80211_SYNC_GON */
4794                 break;
4795         case P2P_PAF_PROVDIS_REQ: {
4796                 if (IS_ACTPUB_WITHOUT_GROUP_ID(&act_frm->elts[0],
4797                         action_frame->len)) {
4798                         config_af_params->search_channel = true;
4799                 }
4800
4801                 config_af_params->mpc_onoff = 0;
4802                 wl->next_af_subtype = act_frm->subtype + 1;
4803                 /* increase dwell time to wait for RESP frame */
4804                 af_params->dwell_time = WL_MED_DWELL_TIME;
4805                 break;
4806         }
4807         case P2P_PAF_PROVDIS_RSP: {
4808                 wl->next_af_subtype = P2P_PAF_GON_REQ;
4809                 af_params->dwell_time = WL_MIN_DWELL_TIME;
4810 #ifdef WL_CFG80211_SYNC_GON
4811                 config_af_params->extra_listen = false;
4812 #endif /* WL_CFG80211_SYNC_GON */
4813                 break;
4814         }
4815         default:
4816                 WL_DBG(("Unknown p2p pub act frame subtype: %d\n",
4817                         act_frm->subtype));
4818                 err = BCME_BADARG;
4819         }
4820         return err;
4821 }
4822
4823
4824
4825 static bool
4826 wl_cfg80211_send_action_frame(struct wiphy *wiphy, struct net_device *dev,
4827         bcm_struct_cfgdev *cfgdev, wl_af_params_t *af_params,
4828         wl_action_frame_t *action_frame, u16 action_frame_len, s32 bssidx)
4829 {
4830         struct wl_priv *wl = wiphy_priv(wiphy);
4831         bool ack = false;
4832         u8 category, action;
4833         s32 tx_retry;
4834         struct p2p_config_af_params config_af_params;
4835 #ifdef VSDB
4836         ulong off_chan_started_jiffies = 0;
4837 #endif
4838         dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
4839
4840
4841         category = action_frame->data[DOT11_ACTION_CAT_OFF];
4842         action = action_frame->data[DOT11_ACTION_ACT_OFF];
4843
4844         /* initialize variables */
4845         tx_retry = 0;
4846         wl->next_af_subtype = P2P_PAF_SUBTYPE_INVALID;
4847         config_af_params.max_tx_retry = WL_AF_TX_MAX_RETRY;
4848         config_af_params.mpc_onoff = -1;
4849         config_af_params.search_channel = false;
4850 #ifdef WL_CFG80211_SYNC_GON
4851         config_af_params.extra_listen = false;
4852 #endif
4853
4854         /* config parameters */
4855         /* Public Action Frame Process - DOT11_ACTION_CAT_PUBLIC */
4856         if (category == DOT11_ACTION_CAT_PUBLIC) {
4857                 if ((action == P2P_PUB_AF_ACTION) &&
4858                         (action_frame_len >= sizeof(wifi_p2p_pub_act_frame_t))) {
4859                         /* p2p public action frame process */
4860                         if (BCME_OK != wl_cfg80211_config_p2p_pub_af_tx(wiphy,
4861                                 action_frame, af_params, &config_af_params)) {
4862                                 WL_DBG(("Unknown subtype.\n"));
4863                         }
4864
4865                 } else if (action_frame_len >= sizeof(wifi_p2psd_gas_pub_act_frame_t)) {
4866                         /* service discovery process */
4867                         if (action == P2PSD_ACTION_ID_GAS_IREQ ||
4868                                 action == P2PSD_ACTION_ID_GAS_CREQ) {
4869                                 /* configure service discovery query frame */
4870
4871                                 config_af_params.search_channel = true;
4872
4873                                 /* save next af suptype to cancel remained dwell time */
4874                                 wl->next_af_subtype = action + 1;
4875
4876                                 af_params->dwell_time = WL_MED_DWELL_TIME;
4877                         } else if (action == P2PSD_ACTION_ID_GAS_IRESP ||
4878                                 action == P2PSD_ACTION_ID_GAS_CRESP) {
4879                                 /* configure service discovery response frame */
4880                                 af_params->dwell_time = WL_MIN_DWELL_TIME;
4881                         } else {
4882                                 WL_DBG(("Unknown action type: %d\n", action));
4883                         }
4884                 } else {
4885                         WL_DBG(("Unknown Frame: category 0x%x, action 0x%x, length %d\n",
4886                                 category, action, action_frame_len));
4887         }
4888         } else if (category == P2P_AF_CATEGORY) {
4889                 /* do not configure anything. it will be sent with a default configuration */
4890         } else {
4891                 WL_DBG(("Unknown Frame: category 0x%x, action 0x%x\n",
4892                         category, action));
4893                 if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
4894                         wl_clr_drv_status(wl, SENDING_ACT_FRM, dev);
4895                         return false;
4896                 }
4897         }
4898
4899         /* To make sure to send successfully action frame, we have to turn off mpc */
4900         if (config_af_params.mpc_onoff == 0) {
4901                 wldev_iovar_setint(dev, "mpc", 0);
4902         }
4903
4904         /* validate channel and p2p ies */
4905         if (config_af_params.search_channel && IS_P2P_SOCIAL(af_params->channel) &&
4906                 wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) {
4907                 config_af_params.search_channel = true;
4908         } else {
4909                 config_af_params.search_channel = false;
4910         }
4911
4912 #ifdef VSDB
4913         /* if connecting on primary iface, sleep for a while before sending af tx for VSDB */
4914         if (wl_get_drv_status(wl, CONNECTING, wl_to_prmry_ndev(wl))) {
4915                 OSL_SLEEP(50);
4916         }
4917 #endif
4918
4919         /* if scan is ongoing, abort current scan. */
4920         if (wl_get_drv_status_all(wl, SCANNING)) {
4921                 wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true);
4922         }
4923
4924
4925         /* set status and destination address before sending af */
4926         if (wl->next_af_subtype != P2P_PAF_SUBTYPE_INVALID) {
4927                 /* set this status to cancel the remained dwell time in rx process */
4928                 wl_set_drv_status(wl, WAITING_NEXT_ACT_FRM, dev);
4929         }
4930         wl_set_drv_status(wl, SENDING_ACT_FRM, dev);
4931         memcpy(wl->afx_hdl->tx_dst_addr.octet,
4932                 af_params->action_frame.da.octet,
4933                 sizeof(wl->afx_hdl->tx_dst_addr.octet));
4934
4935         /* save af_params for rx process */
4936         wl->afx_hdl->pending_tx_act_frm = af_params;
4937
4938         /* search peer's channel */
4939         if (config_af_params.search_channel) {
4940                 /* initialize afx_hdl */
4941                 if (wl_cfgp2p_find_idx(wl, dev, &wl->afx_hdl->bssidx) != BCME_OK) {
4942                         WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
4943                         goto exit;
4944                 }
4945                 wl->afx_hdl->dev = dev;
4946                 wl->afx_hdl->retry = 0;
4947                 wl->afx_hdl->peer_chan = WL_INVALID;
4948
4949                 if (wl_cfg80211_af_searching_channel(wl, dev) == WL_INVALID) {
4950                         WL_ERR(("couldn't find peer's channel.\n"));
4951                         wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len,
4952                                 af_params->channel);
4953                         goto exit;
4954                 }
4955
4956                 wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
4957                 /*
4958                  * Abort scan even for VSDB scenarios. Scan gets aborted in firmware
4959                  * but after the check of piggyback algorithm.
4960                  * To take care of current piggback algo, lets abort the scan here itself.
4961                  */
4962                 wl_notify_escan_complete(wl, dev, true, true);
4963                 /* Suspend P2P discovery's search-listen to prevent it from
4964                  * starting a scan or changing the channel.
4965                  */
4966                 wl_cfgp2p_discover_enable_search(wl, false);
4967
4968                 /* update channel */
4969                 af_params->channel = wl->afx_hdl->peer_chan;
4970         }
4971
4972 #ifdef VSDB
4973         off_chan_started_jiffies = jiffies;
4974 #endif /* VSDB */
4975
4976         wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len, af_params->channel);
4977
4978         /* Now send a tx action frame */
4979         ack = wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx) ? false : true;
4980
4981         /* if failed, retry it. tx_retry_max value is configure by .... */
4982         while ((ack == false) && (tx_retry++ < config_af_params.max_tx_retry)) {
4983 #ifdef VSDB
4984                 if (af_params->channel) {
4985                         if (jiffies_to_msecs(jiffies - off_chan_started_jiffies) >
4986                                 OFF_CHAN_TIME_THRESHOLD_MS) {
4987                                 WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl);
4988                                 off_chan_started_jiffies = jiffies;
4989                         } else
4990                                 OSL_SLEEP(AF_RETRY_DELAY_TIME);
4991                 }
4992 #endif /* VSDB */
4993                 ack = wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx) ?
4994                         false : true;
4995         }
4996         if (ack == false) {
4997                 WL_ERR(("Failed to send Action Frame(retry %d)\n", tx_retry));
4998         }
4999 exit:
5000         /* Clear SENDING_ACT_FRM after all sending af is done */
5001         wl_clr_drv_status(wl, SENDING_ACT_FRM, dev);
5002
5003 #ifdef WL_CFG80211_SYNC_GON
5004         /* WAR: sometimes dongle does not keep the dwell time of 'actframe'.
5005          * if we coundn't get the next action response frame and dongle does not keep
5006          * the dwell time, go to listen state again to get next action response frame.
5007          */
5008         if (ack && config_af_params.extra_listen &&
5009                 wl_get_drv_status_all(wl, WAITING_NEXT_ACT_FRM) &&
5010                 wl->af_sent_channel == wl->afx_hdl->my_listen_chan) {
5011                 s32 extar_listen_time;
5012
5013                 extar_listen_time = af_params->dwell_time -
5014                         jiffies_to_msecs(jiffies - wl->af_tx_sent_jiffies);
5015
5016                 if (extar_listen_time > 50) {
5017                         wl_set_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, dev);
5018                         WL_DBG(("Wait more time! actual af time:%d,"
5019                                 "calculated extar listen:%d\n",
5020                                 af_params->dwell_time, extar_listen_time));
5021                         if (wl_cfgp2p_discover_listen(wl, wl->af_sent_channel,
5022                                 extar_listen_time + 100) == BCME_OK) {
5023                                 wait_for_completion_timeout(&wl->wait_next_af,
5024                                         msecs_to_jiffies(extar_listen_time + 100 + 300));
5025                         }
5026                         wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM_LISTEN, dev);
5027                 }
5028         }
5029 #endif /* WL_CFG80211_SYNC_GON */
5030         wl_clr_drv_status(wl, WAITING_NEXT_ACT_FRM, dev);
5031
5032         if (wl->afx_hdl->pending_tx_act_frm)
5033                 wl->afx_hdl->pending_tx_act_frm = NULL;
5034
5035         WL_INFO(("-- sending Action Frame is %s, listen chan: %d\n",
5036                 (ack) ? "Succeeded!!":"Failed!!", wl->afx_hdl->my_listen_chan));
5037
5038
5039         /* if all done, turn mpc on again */
5040         if (config_af_params.mpc_onoff == 1) {
5041                 wldev_iovar_setint(dev, "mpc", 1);
5042         }
5043
5044         return ack;
5045 }
5046
5047 #define MAX_NUM_OF_ASSOCIATED_DEV       64
5048 #if defined(WL_CFG80211_P2P_DEV_IF)
5049 static s32
5050 wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
5051         struct ieee80211_channel *channel, bool offchan,
5052         unsigned int wait, const u8* buf, size_t len, bool no_cck,
5053         bool dont_wait_for_ack, u64 *cookie)
5054 #else
5055 static s32
5056 wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
5057         struct ieee80211_channel *channel, bool offchan,
5058         enum nl80211_channel_type channel_type,
5059         bool channel_type_valid, unsigned int wait,
5060         const u8* buf, size_t len,
5061 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)) || 0
5062         bool no_cck,
5063 #endif
5064 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) || 0
5065         bool dont_wait_for_ack,
5066 #endif
5067         u64 *cookie)
5068 #endif /* WL_CFG80211_P2P_DEV_IF */
5069 {
5070         wl_action_frame_t *action_frame;
5071         wl_af_params_t *af_params;
5072         scb_val_t scb_val;
5073         const struct ieee80211_mgmt *mgmt;
5074         struct wl_priv *wl = wiphy_priv(wiphy);
5075         struct net_device *dev = NULL;
5076         s32 err = BCME_OK;
5077         s32 bssidx = 0;
5078         u32 id;
5079         bool ack = false;
5080         s8 eabuf[ETHER_ADDR_STR_LEN];
5081
5082         WL_DBG(("Enter \n"));
5083
5084         if (!wl)
5085                 return ERR_PTR(-EINVAL);
5086         dev = cfgdev_to_wlc_ndev(cfgdev, wl);
5087
5088         /* find bssidx based on dev */
5089         if (wl_cfgp2p_find_idx(wl, dev, &bssidx) != BCME_OK) {
5090                 WL_ERR(("Find p2p index from dev(%p) failed\n", dev));
5091                 return BCME_ERROR;
5092         }
5093         if (p2p_is_on(wl)) {
5094                 /* Suspend P2P discovery search-listen to prevent it from changing the
5095                  * channel.
5096                  */
5097                 if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) {
5098                         WL_ERR(("Can not disable discovery mode\n"));
5099                         return -EFAULT;
5100                 }
5101         }
5102         *cookie = 0;
5103         id = wl->send_action_id++;
5104         if (id == 0)
5105                 id = wl->send_action_id++;
5106         *cookie = id;
5107         mgmt = (const struct ieee80211_mgmt *)buf;
5108         if (ieee80211_is_mgmt(mgmt->frame_control)) {
5109                 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
5110                         s32 ie_offset =  DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
5111                         s32 ie_len = len - ie_offset;
5112                         if (dev == wl_to_prmry_ndev(wl))
5113                                 bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
5114                                 wl_cfgp2p_set_management_ie(wl, dev, bssidx,
5115                                 VNDR_IE_PRBRSP_FLAG, (u8 *)(buf + ie_offset), ie_len);
5116                         cfg80211_mgmt_tx_status(cfgdev, *cookie, buf, len, true, GFP_KERNEL);
5117                         goto exit;
5118                 } else if (ieee80211_is_disassoc(mgmt->frame_control) ||
5119                         ieee80211_is_deauth(mgmt->frame_control)) {
5120                         char mac_buf[MAX_NUM_OF_ASSOCIATED_DEV *
5121                                 sizeof(struct ether_addr) + sizeof(uint)] = {0};
5122                         int num_associated = 0;
5123                         struct maclist *assoc_maclist = (struct maclist *)mac_buf;
5124                         if (!bcmp((const uint8 *)BSSID_BROADCAST,
5125                                 (const struct ether_addr *)mgmt->da, ETHER_ADDR_LEN)) {
5126                                 assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV;
5127                                 err = wldev_ioctl(dev, WLC_GET_ASSOCLIST,
5128                                         assoc_maclist, sizeof(mac_buf), false);
5129                                 if (err < 0)
5130                                         WL_ERR(("WLC_GET_ASSOCLIST error %d\n", err));
5131                                 else
5132                                         num_associated = assoc_maclist->count;
5133                         }
5134                         memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN);
5135                         scb_val.val = mgmt->u.disassoc.reason_code;
5136                         err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
5137                                 sizeof(scb_val_t), true);
5138                         if (err < 0)
5139                                 WL_ERR(("WLC_SCB_DEAUTHENTICATE_FOR_REASON error %d\n", err));
5140                         WL_ERR(("Disconnect STA : %s scb_val.val %d\n",
5141                                 bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf),
5142                                 scb_val.val));
5143
5144                         if (num_associated > 0 && ETHER_ISBCAST(mgmt->da))
5145                                 wl_delay(400);
5146
5147                         cfg80211_mgmt_tx_status(cfgdev, *cookie, buf, len, true, GFP_KERNEL);
5148                         goto exit;
5149
5150                 } else if (ieee80211_is_action(mgmt->frame_control)) {
5151                         /* Abort the dwell time of any previous off-channel
5152                         * action frame that may be still in effect.  Sending
5153                         * off-channel action frames relies on the driver's
5154                         * scan engine.  If a previous off-channel action frame
5155                         * tx is still in progress (including the dwell time),
5156                         * then this new action frame will not be sent out.
5157                         */
5158 /* Do not abort scan for VSDB. Scan will be aborted in firmware if necessary.
5159  * And previous off-channel action frame must be ended before new af tx.
5160  */
5161 #ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
5162                         wl_notify_escan_complete(wl, dev, true, true);
5163 #endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
5164                 }
5165
5166         } else {
5167                 WL_ERR(("Driver only allows MGMT packet type\n"));
5168                 goto exit;
5169         }
5170
5171         af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
5172
5173         if (af_params == NULL)
5174         {
5175                 WL_ERR(("unable to allocate frame\n"));
5176                 return -ENOMEM;
5177         }
5178
5179         action_frame = &af_params->action_frame;
5180
5181         /* Add the packet Id */
5182         action_frame->packetId = *cookie;
5183         WL_DBG(("action frame %d\n", action_frame->packetId));
5184         /* Add BSSID */
5185         memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN);
5186         memcpy(&af_params->BSSID, &mgmt->bssid[0], ETHER_ADDR_LEN);
5187
5188         /* Add the length exepted for 802.11 header  */
5189         action_frame->len = len - DOT11_MGMT_HDR_LEN;
5190         WL_DBG(("action_frame->len: %d\n", action_frame->len));
5191
5192         /* Add the channel */
5193         af_params->channel =
5194                 ieee80211_frequency_to_channel(channel->center_freq);
5195
5196         /* Save listen_chan for searching common channel */
5197         wl->afx_hdl->peer_listen_chan = af_params->channel;
5198         WL_DBG(("channel from upper layer %d\n", wl->afx_hdl->peer_listen_chan));
5199
5200         /* Add the default dwell time
5201          * Dwell time to stay off-channel to wait for a response action frame
5202          * after transmitting an GO Negotiation action frame
5203          */
5204         af_params->dwell_time = WL_DWELL_TIME;
5205
5206         memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
5207
5208         ack = wl_cfg80211_send_action_frame(wiphy, dev, cfgdev, af_params,
5209                 action_frame, action_frame->len, bssidx);
5210         cfg80211_mgmt_tx_status(cfgdev, *cookie, buf, len, ack, GFP_KERNEL);
5211
5212         kfree(af_params);
5213 exit:
5214         return err;
5215 }
5216
5217
5218 static void
5219 wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev,
5220         u16 frame_type, bool reg)
5221 {
5222
5223         WL_DBG(("frame_type: %x, reg: %d\n", frame_type, reg));
5224
5225         if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
5226                 return;
5227
5228         return;
5229 }
5230
5231
5232 static s32
5233 wl_cfg80211_change_bss(struct wiphy *wiphy,
5234         struct net_device *dev,
5235         struct bss_parameters *params)
5236 {
5237         if (params->use_cts_prot >= 0) {
5238         }
5239
5240         if (params->use_short_preamble >= 0) {
5241         }
5242
5243         if (params->use_short_slot_time >= 0) {
5244         }
5245
5246         if (params->basic_rates) {
5247         }
5248
5249         if (params->ap_isolate >= 0) {
5250         }
5251
5252         if (params->ht_opmode >= 0) {
5253         }
5254
5255         return 0;
5256 }
5257
5258 static s32
5259 wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
5260         struct ieee80211_channel *chan,
5261         enum nl80211_channel_type channel_type)
5262 {
5263         s32 _chan;
5264         chanspec_t chspec = 0;
5265         chanspec_t fw_chspec = 0;
5266         u32 bw = WL_CHANSPEC_BW_40;
5267         u32 chanspec = 0;
5268         struct net_info *iter, *next;
5269
5270         s32 err = BCME_OK;
5271         struct wl_priv *wl = wiphy_priv(wiphy);
5272
5273         if (!wl)
5274                 return ERR_PTR(-EINVAL);
5275         dev = ndev_to_wlc_ndev(dev, wl);
5276         _chan = ieee80211_frequency_to_channel(chan->center_freq);
5277         WL_ERR(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
5278                 dev->ifindex, channel_type, _chan));
5279
5280         /* In 5GHz band If AP is connected in 20 MHz then follow AP's bw
5281            else 40MHz by default. */
5282         for_each_ndev(wl, iter, next) {
5283                 /* In case interface name is not wlan0 put the right
5284                    interface name. */
5285                 if(!strncmp(iter->ndev->name, "wlan0", strlen("wlan0"))) {
5286                         if (wl_get_drv_status(wl, CONNECTED, iter->ndev)) {
5287                                 if (chan->band == IEEE80211_BAND_5GHZ) {
5288                                         if(wldev_iovar_getint(iter->ndev,
5289                                                 "chanspec", (s32 *)&chanspec) == BCME_OK) {
5290                                                 chanspec = wl_chspec_driver_to_host(chanspec);
5291                                                 /* bits 11,12 and 13 starting from 0 are bw
5292                                                    bits. So, values formed with these bits
5293                                                    are 0 ,1, 2, 3, 4, 5, 6 which are mapped
5294                                                    to 5, 10, 20 ,40 ,80, 160, 80+80 MHz
5295                                                    respectively. In below case, 0x1000 = 2
5296                                                    which is for 20 MHz */
5297                                                 if((chanspec & 0x3800) == 0x1000)
5298                                                         bw = WL_CHANSPEC_BW_20;
5299                                         }
5300                                 } else {
5301                                         /* In 2.4 GHz supported bw is 20 MHz */
5302                                         bw = WL_CHANSPEC_BW_20;
5303                                 }
5304                         }
5305                 }
5306         }
5307 set_channel:
5308         chspec = wf_channel2chspec(_chan, bw);
5309         if (wf_chspec_valid(chspec)) {
5310                 fw_chspec = wl_chspec_host_to_driver(chspec);
5311                 if (fw_chspec != INVCHANSPEC) {
5312                         if ((err = wldev_iovar_setint(dev, "chanspec",
5313                                 fw_chspec)) == BCME_BADCHAN) {
5314                                 if (bw == WL_CHANSPEC_BW_80)
5315                                         goto change_bw;
5316                                 err = wldev_ioctl(dev, WLC_SET_CHANNEL,
5317                                         &_chan, sizeof(_chan), true);
5318                                 if (err < 0) {
5319                                         WL_ERR(("WLC_SET_CHANNEL error %d"
5320                                         "chip may not be supporting this channel\n", err));
5321                                 }
5322                         } else if (err) {
5323                                 WL_ERR(("failed to set chanspec error %d\n", err));
5324                         }
5325                 } else {
5326                         WL_ERR(("failed to convert host chanspec to fw chanspec\n"));
5327                         err = BCME_ERROR;
5328                 }
5329         } else {
5330 change_bw:
5331                 if (bw == WL_CHANSPEC_BW_80)
5332                         bw = WL_CHANSPEC_BW_40;
5333                 else if (bw == WL_CHANSPEC_BW_40)
5334                         bw = WL_CHANSPEC_BW_20;
5335                 else
5336                         bw = 0;
5337                 if (bw)
5338                         goto set_channel;
5339                 WL_ERR(("Invalid chanspec 0x%x\n", chspec));
5340                 err = BCME_ERROR;
5341         }
5342         return err;
5343 }
5344
5345 static s32
5346 wl_validate_opensecurity(struct net_device *dev, s32 bssidx)
5347 {
5348         s32 err = BCME_OK;
5349
5350         /* set auth */
5351         err = wldev_iovar_setint_bsscfg(dev, "auth", 0, bssidx);
5352         if (err < 0) {
5353                 WL_ERR(("auth error %d\n", err));
5354                 return BCME_ERROR;
5355         }
5356         /* set wsec */
5357         err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx);
5358         if (err < 0) {
5359                 WL_ERR(("wsec error %d\n", err));
5360                 return BCME_ERROR;
5361         }
5362         /* set upper-layer auth */
5363         err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", WPA_AUTH_NONE, bssidx);
5364         if (err < 0) {
5365                 WL_ERR(("wpa_auth error %d\n", err));
5366                 return BCME_ERROR;
5367         }
5368
5369         return 0;
5370 }
5371
5372 static s32
5373 wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
5374 {
5375         s32 len = 0;
5376         s32 err = BCME_OK;
5377         u16 auth = 0; /* d11 open authentication */
5378         u32 wsec;
5379         u32 pval = 0;
5380         u32 gval = 0;
5381         u32 wpa_auth = 0;
5382         wpa_suite_mcast_t *mcast;
5383         wpa_suite_ucast_t *ucast;
5384         wpa_suite_auth_key_mgmt_t *mgmt;
5385
5386         u16 suite_count;
5387         u8 rsn_cap[2];
5388         u32 wme_bss_disable;
5389
5390         if (wpa2ie == NULL)
5391                 goto exit;
5392
5393         WL_DBG(("Enter \n"));
5394         len =  wpa2ie->len;
5395         /* check the mcast cipher */
5396         mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN];
5397         switch (mcast->type) {
5398                 case WPA_CIPHER_NONE:
5399                         gval = 0;
5400                         break;
5401                 case WPA_CIPHER_WEP_40:
5402                 case WPA_CIPHER_WEP_104:
5403                         gval = WEP_ENABLED;
5404                         break;
5405                 case WPA_CIPHER_TKIP:
5406                         gval = TKIP_ENABLED;
5407                         break;
5408                 case WPA_CIPHER_AES_CCM:
5409                         gval = AES_ENABLED;
5410                         break;
5411                 default:
5412                         WL_ERR(("No Security Info\n"));
5413                         break;
5414         }
5415         if ((len -= WPA_SUITE_LEN) <= 0)
5416                 return BCME_BADLEN;
5417
5418         /* check the unicast cipher */
5419         ucast = (wpa_suite_ucast_t *)&mcast[1];
5420         suite_count = ltoh16_ua(&ucast->count);
5421         switch (ucast->list[0].type) {
5422                 case WPA_CIPHER_NONE:
5423                         pval = 0;
5424                         break;
5425                 case WPA_CIPHER_WEP_40:
5426                 case WPA_CIPHER_WEP_104:
5427                         pval = WEP_ENABLED;
5428                         break;
5429                 case WPA_CIPHER_TKIP:
5430                         pval = TKIP_ENABLED;
5431                         break;
5432                 case WPA_CIPHER_AES_CCM:
5433                         pval = AES_ENABLED;
5434                         break;
5435                 default:
5436                         WL_ERR(("No Security Info\n"));
5437         }
5438         if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) <= 0)
5439                 return BCME_BADLEN;
5440
5441         /* FOR WPS , set SEC_OW_ENABLED */
5442         wsec = (pval | gval | SES_OW_ENABLED);
5443         /* check the AKM */
5444         mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[suite_count];
5445         suite_count = ltoh16_ua(&mgmt->count);
5446         switch (mgmt->list[0].type) {
5447                 case RSN_AKM_NONE:
5448                         wpa_auth = WPA_AUTH_NONE;
5449                         break;
5450                 case RSN_AKM_UNSPECIFIED:
5451                         wpa_auth = WPA2_AUTH_UNSPECIFIED;
5452                         break;
5453                 case RSN_AKM_PSK:
5454                         wpa_auth = WPA2_AUTH_PSK;
5455                         break;
5456                 default:
5457                         WL_ERR(("No Key Mgmt Info\n"));
5458         }
5459
5460         if ((len -= (WPA_IE_SUITE_COUNT_LEN + (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) {
5461                 rsn_cap[0] = *(u8 *)&mgmt->list[suite_count];
5462                 rsn_cap[1] = *((u8 *)&mgmt->list[suite_count] + 1);
5463
5464                 if (rsn_cap[0] & (RSN_CAP_16_REPLAY_CNTRS << RSN_CAP_PTK_REPLAY_CNTR_SHIFT)) {
5465                         wme_bss_disable = 0;
5466                 } else {
5467                         wme_bss_disable = 1;
5468                 }
5469
5470                 /* set wme_bss_disable to sync RSN Capabilities */
5471                 err = wldev_iovar_setint_bsscfg(dev, "wme_bss_disable", wme_bss_disable, bssidx);
5472                 if (err < 0) {
5473                         WL_ERR(("wme_bss_disable error %d\n", err));
5474                         return BCME_ERROR;
5475                 }
5476         } else {
5477                 WL_DBG(("There is no RSN Capabilities. remained len %d\n", len));
5478         }
5479
5480         /* set auth */
5481         err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
5482         if (err < 0) {
5483                 WL_ERR(("auth error %d\n", err));
5484                 return BCME_ERROR;
5485         }
5486         /* set wsec */
5487         err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
5488         if (err < 0) {
5489                 WL_ERR(("wsec error %d\n", err));
5490                 return BCME_ERROR;
5491         }
5492         /* set upper-layer auth */
5493         err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
5494         if (err < 0) {
5495                 WL_ERR(("wpa_auth error %d\n", err));
5496                 return BCME_ERROR;
5497         }
5498 exit:
5499         return 0;
5500 }
5501
5502 static s32
5503 wl_validate_wpaie(struct net_device *dev, wpa_ie_fixed_t *wpaie, s32 bssidx)
5504 {
5505         wpa_suite_mcast_t *mcast;
5506         wpa_suite_ucast_t *ucast;
5507         wpa_suite_auth_key_mgmt_t *mgmt;
5508         u16 auth = 0; /* d11 open authentication */
5509         u16 count;
5510         s32 err = BCME_OK;
5511         s32 len = 0;
5512         u32 i;
5513         u32 wsec;
5514         u32 pval = 0;
5515         u32 gval = 0;
5516         u32 wpa_auth = 0;
5517         u32 tmp = 0;
5518
5519         if (wpaie == NULL)
5520                 goto exit;
5521         WL_DBG(("Enter \n"));
5522         len = wpaie->length;    /* value length */
5523         len -= WPA_IE_TAG_FIXED_LEN;
5524         /* check for multicast cipher suite */
5525         if (len < WPA_SUITE_LEN) {
5526                 WL_INFO(("no multicast cipher suite\n"));
5527                 goto exit;
5528         }
5529
5530         /* pick up multicast cipher */
5531         mcast = (wpa_suite_mcast_t *)&wpaie[1];
5532         len -= WPA_SUITE_LEN;
5533         if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) {
5534                 if (IS_WPA_CIPHER(mcast->type)) {
5535                         tmp = 0;
5536                         switch (mcast->type) {
5537                                 case WPA_CIPHER_NONE:
5538                                         tmp = 0;
5539                                         break;
5540                                 case WPA_CIPHER_WEP_40:
5541                                 case WPA_CIPHER_WEP_104:
5542                                         tmp = WEP_ENABLED;
5543                                         break;
5544                                 case WPA_CIPHER_TKIP:
5545                                         tmp = TKIP_ENABLED;
5546                                         break;
5547                                 case WPA_CIPHER_AES_CCM:
5548                                         tmp = AES_ENABLED;
5549                                         break;
5550                                 default:
5551                                         WL_ERR(("No Security Info\n"));
5552                         }
5553                         gval |= tmp;
5554                 }
5555         }
5556         /* Check for unicast suite(s) */
5557         if (len < WPA_IE_SUITE_COUNT_LEN) {
5558                 WL_INFO(("no unicast suite\n"));
5559                 goto exit;
5560         }
5561         /* walk thru unicast cipher list and pick up what we recognize */
5562         ucast = (wpa_suite_ucast_t *)&mcast[1];
5563         count = ltoh16_ua(&ucast->count);
5564         len -= WPA_IE_SUITE_COUNT_LEN;
5565         for (i = 0; i < count && len >= WPA_SUITE_LEN;
5566                 i++, len -= WPA_SUITE_LEN) {
5567                 if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
5568                         if (IS_WPA_CIPHER(ucast->list[i].type)) {
5569                                 tmp = 0;
5570                                 switch (ucast->list[i].type) {
5571                                         case WPA_CIPHER_NONE:
5572                                                 tmp = 0;
5573                                                 break;
5574                                         case WPA_CIPHER_WEP_40:
5575                                         case WPA_CIPHER_WEP_104:
5576                                                 tmp = WEP_ENABLED;
5577                                                 break;
5578                                         case WPA_CIPHER_TKIP:
5579                                                 tmp = TKIP_ENABLED;
5580                                                 break;
5581                                         case WPA_CIPHER_AES_CCM:
5582                                                 tmp = AES_ENABLED;
5583       &n