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