2 * Linux cfg80211 driver
4 * Copyright (C) 1999-2011, Broadcom Corporation
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:
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.
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.
24 * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $
30 #include <linux/kernel.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>
40 #include <dngl_stats.h>
44 #include <dhd_cfg80211.h>
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>
59 #include <wldev_common.h>
60 #include <wl_cfg80211.h>
61 #include <wl_cfgp2p.h>
63 static struct device *cfg80211_parent_dev = NULL;
64 static int vsdb_supported = 0;
65 struct wl_priv *wlcfg_drv_priv = NULL;
67 u32 wl_dbg_level = WL_DBG_ERR;
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 #define WL_FRAME_LEN 300
76 #define DNGL_FUNC(func, parameters) func parameters;
80 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
81 * By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
82 * and NL80211_RRF_NO_IBSS for 5GHz channels (for 36..48 and 149..165).
83 * With respect to these flags, wpa_supplicant doesn't start p2p operations on 5GHz channels.
84 * All the chnages in world regulatory domain are to be done here.
86 static const struct ieee80211_regdomain brcm_regdom = {
90 /* IEEE 802.11b/g, channels 1..11 */
91 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
92 /* IEEE 802.11b/g, channels 12..13. No HT40
97 * IEEE 802.11 channel 14 - is for JP only,
98 * we need cfg80211 to allow it (reg_flags = 0); so that
99 * hostapd could request auto channel by sending down ch 14
101 REG_RULE(2484-10, 2484+10, 20, 6, 20,
102 NL80211_RRF_PASSIVE_SCAN |
103 NL80211_RRF_NO_IBSS |
104 NL80211_RRF_NO_OFDM),
105 /* IEEE 802.11a, channel 36..64 */
106 REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
107 /* IEEE 802.11a, channel 100..165 */
108 REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
112 /* Data Element Definitions */
113 #define WPS_ID_CONFIG_METHODS 0x1008
114 #define WPS_ID_REQ_TYPE 0x103A
115 #define WPS_ID_DEVICE_NAME 0x1011
116 #define WPS_ID_VERSION 0x104A
117 #define WPS_ID_DEVICE_PWD_ID 0x1012
118 #define WPS_ID_REQ_DEV_TYPE 0x106A
119 #define WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS 0x1053
120 #define WPS_ID_PRIM_DEV_TYPE 0x1054
122 /* Device Password ID */
123 #define DEV_PW_DEFAULT 0x0000
124 #define DEV_PW_USER_SPECIFIED 0x0001,
125 #define DEV_PW_MACHINE_SPECIFIED 0x0002
126 #define DEV_PW_REKEY 0x0003
127 #define DEV_PW_PUSHBUTTON 0x0004
128 #define DEV_PW_REGISTRAR_SPECIFIED 0x0005
131 #define WPS_CONFIG_USBA 0x0001
132 #define WPS_CONFIG_ETHERNET 0x0002
133 #define WPS_CONFIG_LABEL 0x0004
134 #define WPS_CONFIG_DISPLAY 0x0008
135 #define WPS_CONFIG_EXT_NFC_TOKEN 0x0010
136 #define WPS_CONFIG_INT_NFC_TOKEN 0x0020
137 #define WPS_CONFIG_NFC_INTERFACE 0x0040
138 #define WPS_CONFIG_PUSHBUTTON 0x0080
139 #define WPS_CONFIG_KEYPAD 0x0100
140 #define WPS_CONFIG_VIRT_PUSHBUTTON 0x0280
141 #define WPS_CONFIG_PHY_PUSHBUTTON 0x0480
142 #define WPS_CONFIG_VIRT_DISPLAY 0x2008
143 #define WPS_CONFIG_PHY_DISPLAY 0x4008
146 * cfg80211_ops api/callback list
148 static s32 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
149 const struct ether_addr *sa, const struct ether_addr *bssid,
150 u8 **pheader, u32 *body_len, u8 *pbody);
151 static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
152 struct cfg80211_scan_request *request,
153 struct cfg80211_ssid *this_ssid);
154 static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
155 struct cfg80211_scan_request *request);
156 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed);
157 static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
158 struct cfg80211_ibss_params *params);
159 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy,
160 struct net_device *dev);
161 static s32 wl_cfg80211_get_station(struct wiphy *wiphy,
162 struct net_device *dev, u8 *mac,
163 struct station_info *sinfo);
164 static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
165 struct net_device *dev, bool enabled,
167 static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
168 struct cfg80211_connect_params *sme);
169 static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
171 static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
172 enum nl80211_tx_power_setting type,
174 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm);
175 static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy,
176 struct net_device *dev,
177 u8 key_idx, bool unicast, bool multicast);
178 static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
179 u8 key_idx, bool pairwise, const u8 *mac_addr,
180 struct key_params *params);
181 static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
182 u8 key_idx, bool pairwise, const u8 *mac_addr);
183 static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
184 u8 key_idx, bool pairwise, const u8 *mac_addr,
185 void *cookie, void (*callback) (void *cookie,
186 struct key_params *params));
187 static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
188 struct net_device *dev, u8 key_idx);
189 static s32 wl_cfg80211_resume(struct wiphy *wiphy);
190 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
191 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
193 static s32 wl_cfg80211_suspend(struct wiphy *wiphy);
195 static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
196 struct cfg80211_pmksa *pmksa);
197 static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
198 struct cfg80211_pmksa *pmksa);
199 static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy,
200 struct net_device *dev);
201 static s32 wl_notify_escan_complete(struct wl_priv *wl,
202 struct net_device *ndev, bool aborted, bool fw_abort);
204 * event & event Q handlers for cfg80211 interfaces
206 static s32 wl_create_event_handler(struct wl_priv *wl);
207 static void wl_destroy_event_handler(struct wl_priv *wl);
208 static s32 wl_event_handler(void *data);
209 static void wl_init_eq(struct wl_priv *wl);
210 static void wl_flush_eq(struct wl_priv *wl);
211 static unsigned long wl_lock_eq(struct wl_priv *wl);
212 static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags);
213 static void wl_init_eq_lock(struct wl_priv *wl);
214 static void wl_init_event_handler(struct wl_priv *wl);
215 static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
216 static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
217 const wl_event_msg_t *msg, void *data);
218 static void wl_put_event(struct wl_event_q *e);
219 static void wl_wakeup_event(struct wl_priv *wl);
220 static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
221 const wl_event_msg_t *e, void *data);
222 static s32 wl_notify_connect_status(struct wl_priv *wl,
223 struct net_device *ndev,
224 const wl_event_msg_t *e, void *data);
225 static s32 wl_notify_roaming_status(struct wl_priv *wl,
226 struct net_device *ndev,
227 const wl_event_msg_t *e, void *data);
228 static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
229 const wl_event_msg_t *e, void *data);
230 static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
231 const wl_event_msg_t *e, void *data, bool completed);
232 static s32 wl_ibss_join_done(struct wl_priv *wl, struct net_device *ndev,
233 const wl_event_msg_t *e, void *data, bool completed);
234 static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
235 const wl_event_msg_t *e, void *data);
236 static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
237 const wl_event_msg_t *e, void *data);
240 wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev,
241 const wl_event_msg_t *e, void *data);
242 #endif /* WL_SCHED_SCAN */
244 static s32 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev,
245 const wl_event_msg_t *e, void *data);
246 #endif /* PNO_SUPPORT */
248 * register/deregister parent device
250 static void wl_cfg80211_clear_parent_dev(void);
253 * cfg80211 set_wiphy_params utilities
255 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
256 static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold);
257 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l);
260 * wl profile utilities
262 static s32 wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
263 const wl_event_msg_t *e, void *data, s32 item);
264 static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item);
265 static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev);
268 * cfg80211 connect utilites
270 static s32 wl_set_wpa_version(struct net_device *dev,
271 struct cfg80211_connect_params *sme);
272 static s32 wl_set_auth_type(struct net_device *dev,
273 struct cfg80211_connect_params *sme);
274 static s32 wl_set_set_cipher(struct net_device *dev,
275 struct cfg80211_connect_params *sme);
276 static s32 wl_set_key_mgmt(struct net_device *dev,
277 struct cfg80211_connect_params *sme);
278 static s32 wl_set_set_sharedkey(struct net_device *dev,
279 struct cfg80211_connect_params *sme);
280 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev);
281 static void wl_ch_to_chanspec(int ch,
282 struct wl_join_params *join_params, size_t *join_params_size);
285 * information element utilities
287 static void wl_rst_ie(struct wl_priv *wl);
288 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
289 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
290 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
291 static u32 wl_get_ielen(struct wl_priv *wl);
294 static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev);
295 static void wl_free_wdev(struct wl_priv *wl);
297 static s32 wl_inform_bss(struct wl_priv *wl);
298 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
299 static s32 wl_inform_ibss(struct wl_priv *wl, const u8 *bssid);
300 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev);
301 static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy);
303 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
304 u8 key_idx, const u8 *mac_addr,
305 struct key_params *params);
307 * key indianess swap utilities
309 static void swap_key_from_BE(struct wl_wsec_key *key);
310 static void swap_key_to_BE(struct wl_wsec_key *key);
313 * wl_priv memory init/deinit utilities
315 static s32 wl_init_priv_mem(struct wl_priv *wl);
316 static void wl_deinit_priv_mem(struct wl_priv *wl);
318 static void wl_delay(u32 ms);
321 * ibss mode utilities
323 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
324 static __used bool wl_is_ibssstarter(struct wl_priv *wl);
327 * link up/down , default configuration utilities
329 static s32 __wl_cfg80211_up(struct wl_priv *wl);
330 static s32 __wl_cfg80211_down(struct wl_priv *wl);
331 static s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
332 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
333 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev);
334 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
335 static void wl_link_up(struct wl_priv *wl);
336 static void wl_link_down(struct wl_priv *wl);
337 static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype);
338 static void wl_init_conf(struct wl_conf *conf);
343 static void wl_iscan_timer(unsigned long data);
344 static void wl_term_iscan(struct wl_priv *wl);
345 static s32 wl_init_scan(struct wl_priv *wl);
346 static s32 wl_iscan_thread(void *data);
347 static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
349 static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request);
350 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
351 static s32 wl_invoke_iscan(struct wl_priv *wl);
352 static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
353 struct wl_scan_results **bss_list);
354 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
355 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan);
356 static s32 wl_iscan_done(struct wl_priv *wl);
357 static s32 wl_iscan_pending(struct wl_priv *wl);
358 static s32 wl_iscan_inprogress(struct wl_priv *wl);
359 static s32 wl_iscan_aborted(struct wl_priv *wl);
362 * find most significant bit set
364 static __used u32 wl_find_msb(u16 bit16);
369 static int wl_setup_rfkill(struct wl_priv *wl, bool setup);
370 static int wl_rfkill_set(void *data, bool blocked);
372 static wl_scan_params_t *wl_cfg80211_scan_alloc_params(int channel,
373 int nprobes, int *out_params_size);
374 static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac);
377 * Some external functions, TODO: move them to dhd_linux.h
379 int dhd_add_monitor(char *name, struct net_device **new_ndev);
380 int dhd_del_monitor(struct net_device *ndev);
381 int dhd_monitor_init(void *dhd_pub);
382 int dhd_monitor_uninit(void);
383 int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
385 #define CHECK_SYS_UP(wlpriv) \
387 struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \
388 if (unlikely(!wl_get_drv_status(wlpriv, READY, ndev))) { \
389 WL_INFO(("device is not ready\n")); \
395 #define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
396 (akm) == RSN_AKM_UNSPECIFIED || \
397 (akm) == RSN_AKM_PSK)
400 extern int dhd_wait_pend8021x(struct net_device *dev);
402 #if (WL_DBG_LEVEL > 0)
403 #define WL_DBG_ESTR_MAX 50
404 static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
405 "SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
406 "DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
407 "REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
408 "BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
409 "TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
410 "EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
411 "BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
413 "RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
415 "RADIO", "PSM_WATCHDOG", "WLC_E_CCX_ASSOC_START", "WLC_E_CCX_ASSOC_ABORT",
417 "SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
418 "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
419 "UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
420 "WLC_E_BTA_HCI_EVENT", "IF", "WLC_E_P2P_DISC_LISTEN_COMPLETE",
421 "RSSI", "PFN_SCAN_COMPLETE", "WLC_E_EXTLOG_MSG",
422 "ACTION_FRAME", "ACTION_FRAME_COMPLETE", "WLC_E_PRE_ASSOC_IND",
423 "WLC_E_PRE_REASSOC_IND", "WLC_E_CHANNEL_ADOPTED", "WLC_E_AP_STARTED",
424 "WLC_E_DFS_AP_STOP", "WLC_E_DFS_AP_RESUME", "WLC_E_WAI_STA_EVENT",
425 "WLC_E_WAI_MSG", "WLC_E_ESCAN_RESULT", "WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE",
426 "WLC_E_PROBRESP_MSG", "WLC_E_P2P_PROBREQ_MSG", "WLC_E_DCS_REQUEST", "WLC_E_FIFO_CREDIT_MAP",
427 "WLC_E_ACTION_FRAME_RX", "WLC_E_WAKE_EVENT", "WLC_E_RM_COMPLETE"
429 #endif /* WL_DBG_LEVEL */
431 #define CHAN2G(_channel, _freq, _flags) { \
432 .band = IEEE80211_BAND_2GHZ, \
433 .center_freq = (_freq), \
434 .hw_value = (_channel), \
436 .max_antenna_gain = 0, \
440 #define CHAN5G(_channel, _flags) { \
441 .band = IEEE80211_BAND_5GHZ, \
442 .center_freq = 5000 + (5 * (_channel)), \
443 .hw_value = (_channel), \
445 .max_antenna_gain = 0, \
449 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
450 #define RATETAB_ENT(_rateid, _flags) \
452 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
453 .hw_value = (_rateid), \
457 static struct ieee80211_rate __wl_rates[] = {
458 RATETAB_ENT(WLC_RATE_1M, 0),
459 RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
460 RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
461 RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
462 RATETAB_ENT(WLC_RATE_6M, 0),
463 RATETAB_ENT(WLC_RATE_9M, 0),
464 RATETAB_ENT(WLC_RATE_12M, 0),
465 RATETAB_ENT(WLC_RATE_18M, 0),
466 RATETAB_ENT(WLC_RATE_24M, 0),
467 RATETAB_ENT(WLC_RATE_36M, 0),
468 RATETAB_ENT(WLC_RATE_48M, 0),
469 RATETAB_ENT(WLC_RATE_54M, 0)
472 #define wl_a_rates (__wl_rates + 4)
473 #define wl_a_rates_size 8
474 #define wl_g_rates (__wl_rates + 0)
475 #define wl_g_rates_size 12
477 static struct ieee80211_channel __wl_2ghz_channels[] = {
494 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
495 CHAN5G(34, 0), CHAN5G(36, 0),
496 CHAN5G(38, 0), CHAN5G(40, 0),
497 CHAN5G(42, 0), CHAN5G(44, 0),
498 CHAN5G(46, 0), CHAN5G(48, 0),
499 CHAN5G(52, 0), CHAN5G(56, 0),
500 CHAN5G(60, 0), CHAN5G(64, 0),
501 CHAN5G(100, 0), CHAN5G(104, 0),
502 CHAN5G(108, 0), CHAN5G(112, 0),
503 CHAN5G(116, 0), CHAN5G(120, 0),
504 CHAN5G(124, 0), CHAN5G(128, 0),
505 CHAN5G(132, 0), CHAN5G(136, 0),
506 CHAN5G(140, 0), CHAN5G(149, 0),
507 CHAN5G(153, 0), CHAN5G(157, 0),
508 CHAN5G(161, 0), CHAN5G(165, 0)
511 static struct ieee80211_supported_band __wl_band_2ghz = {
512 .band = IEEE80211_BAND_2GHZ,
513 .channels = __wl_2ghz_channels,
514 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
515 .bitrates = wl_g_rates,
516 .n_bitrates = wl_g_rates_size
519 static struct ieee80211_supported_band __wl_band_5ghz_a = {
520 .band = IEEE80211_BAND_5GHZ,
521 .channels = __wl_5ghz_a_channels,
522 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
523 .bitrates = wl_a_rates,
524 .n_bitrates = wl_a_rates_size
527 static const u32 __wl_cipher_suites[] = {
528 WLAN_CIPHER_SUITE_WEP40,
529 WLAN_CIPHER_SUITE_WEP104,
530 WLAN_CIPHER_SUITE_TKIP,
531 WLAN_CIPHER_SUITE_CCMP,
532 WLAN_CIPHER_SUITE_AES_CMAC,
535 /* There isn't a lot of sense in it, but you can transmit anything you like */
536 static const struct ieee80211_txrx_stypes
537 wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
538 [NL80211_IFTYPE_ADHOC] = {
540 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
542 [NL80211_IFTYPE_STATION] = {
544 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
545 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
547 [NL80211_IFTYPE_AP] = {
549 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
550 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
551 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
552 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
553 BIT(IEEE80211_STYPE_AUTH >> 4) |
554 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
555 BIT(IEEE80211_STYPE_ACTION >> 4)
557 [NL80211_IFTYPE_AP_VLAN] = {
560 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
561 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
562 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
563 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
564 BIT(IEEE80211_STYPE_AUTH >> 4) |
565 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
566 BIT(IEEE80211_STYPE_ACTION >> 4)
568 [NL80211_IFTYPE_P2P_CLIENT] = {
570 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
571 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
573 [NL80211_IFTYPE_P2P_GO] = {
575 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
576 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
577 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
578 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
579 BIT(IEEE80211_STYPE_AUTH >> 4) |
580 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
581 BIT(IEEE80211_STYPE_ACTION >> 4)
585 static void swap_key_from_BE(struct wl_wsec_key *key)
587 key->index = htod32(key->index);
588 key->len = htod32(key->len);
589 key->algo = htod32(key->algo);
590 key->flags = htod32(key->flags);
591 key->rxiv.hi = htod32(key->rxiv.hi);
592 key->rxiv.lo = htod16(key->rxiv.lo);
593 key->iv_initialized = htod32(key->iv_initialized);
596 static void swap_key_to_BE(struct wl_wsec_key *key)
598 key->index = dtoh32(key->index);
599 key->len = dtoh32(key->len);
600 key->algo = dtoh32(key->algo);
601 key->flags = dtoh32(key->flags);
602 key->rxiv.hi = dtoh32(key->rxiv.hi);
603 key->rxiv.lo = dtoh16(key->rxiv.lo);
604 key->iv_initialized = dtoh32(key->iv_initialized);
607 /* For debug: Dump the contents of the encoded wps ie buffe */
609 wl_validate_wps_ie(char *wps_ie, bool *pbc)
611 #define WPS_IE_FIXED_LEN 6
612 u16 len = (u16) wps_ie[TLV_LEN_OFF];
613 u8 *subel = wps_ie+ WPS_IE_FIXED_LEN;
617 u8 *valptr = (uint8*) &val;
619 WL_DBG(("wps_ie len=%d\n", len));
621 len -= 4; /* for the WPS IE's OUI, oui_type fields */
623 while (len >= 4) { /* must have attr id, attr len fields */
624 valptr[0] = *subel++;
625 valptr[1] = *subel++;
626 subelt_id = HTON16(val);
628 valptr[0] = *subel++;
629 valptr[1] = *subel++;
630 subelt_len = HTON16(val);
632 len -= 4; /* for the attr id, attr len fields */
633 len -= subelt_len; /* for the remaining fields in this attribute */
634 WL_DBG((" subel=%p, subelt_id=0x%x subelt_len=%u\n",
635 subel, subelt_id, subelt_len));
637 if (subelt_id == WPS_ID_VERSION) {
638 WL_DBG((" attr WPS_ID_VERSION: %u\n", *subel));
639 } else if (subelt_id == WPS_ID_REQ_TYPE) {
640 WL_DBG((" attr WPS_ID_REQ_TYPE: %u\n", *subel));
641 } else if (subelt_id == WPS_ID_CONFIG_METHODS) {
643 valptr[1] = *(subel + 1);
644 WL_DBG((" attr WPS_ID_CONFIG_METHODS: %x\n", HTON16(val)));
645 } else if (subelt_id == WPS_ID_DEVICE_NAME) {
647 memcpy(devname, subel, subelt_len);
648 devname[subelt_len] = '\0';
649 WL_DBG((" attr WPS_ID_DEVICE_NAME: %s (len %u)\n",
650 devname, subelt_len));
651 } else if (subelt_id == WPS_ID_DEVICE_PWD_ID) {
653 valptr[1] = *(subel + 1);
654 WL_DBG((" attr WPS_ID_DEVICE_PWD_ID: %u\n", HTON16(val)));
655 *pbc = (HTON16(val) == DEV_PW_PUSHBUTTON) ? true : false;
656 } else if (subelt_id == WPS_ID_PRIM_DEV_TYPE) {
658 valptr[1] = *(subel + 1);
659 WL_DBG((" attr WPS_ID_PRIM_DEV_TYPE: cat=%u \n", HTON16(val)));
660 valptr[0] = *(subel + 6);
661 valptr[1] = *(subel + 7);
662 WL_DBG((" attr WPS_ID_PRIM_DEV_TYPE: subcat=%u\n", HTON16(val)));
663 } else if (subelt_id == WPS_ID_REQ_DEV_TYPE) {
665 valptr[1] = *(subel + 1);
666 WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: cat=%u\n", HTON16(val)));
667 valptr[0] = *(subel + 6);
668 valptr[1] = *(subel + 7);
669 WL_DBG((" attr WPS_ID_REQ_DEV_TYPE: subcat=%u\n", HTON16(val)));
670 } else if (subelt_id == WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS) {
672 valptr[1] = *(subel + 1);
673 WL_DBG((" attr WPS_ID_SELECTED_REGISTRAR_CONFIG_METHODS"
674 ": cat=%u\n", HTON16(val)));
676 WL_DBG((" unknown attr 0x%x\n", subelt_id));
683 static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy)
685 if (vsdb_supported) {
686 return wf_chspec_aton(WL_P2P_TEMP_CHAN);
691 struct wl_priv *wl = wiphy_priv(wiphy);
692 struct net_device *dev = wl_to_prmry_ndev(wl);
693 struct ether_addr bssid;
694 struct wl_bss_info *bss = NULL;
695 if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
696 /* STA interface is not associated. So start the new interface on a temp
697 * channel . Later proper channel will be applied by the above framework
698 * via set_channel (cfg80211 API).
700 WL_DBG(("Not associated. Return a temp channel. \n"));
701 return wf_chspec_aton(WL_P2P_TEMP_CHAN);
705 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
706 if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf,
707 WL_EXTRA_BUF_MAX, false))) {
708 WL_ERR(("Failed to get associated bss info, use temp channel \n"));
709 chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
712 bss = (struct wl_bss_info *) (wl->extra_buf + 4);
713 chspec = bss->chanspec;
714 WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec));
720 static struct net_device* wl_cfg80211_add_monitor_if(char *name)
723 struct net_device* ndev = NULL;
725 ret = dhd_add_monitor(name, &ndev);
726 WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev));
730 static struct net_device *
731 wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
732 enum nl80211_iftype type, u32 *flags,
733 struct vif_params *params)
739 #if defined(WL_ENABLE_P2P_IF)
741 #endif /* (WL_ENABLE_P2P_IF) */
743 struct wl_priv *wl = wiphy_priv(wiphy);
744 struct net_device *_ndev;
745 struct ether_addr primary_mac;
746 int (*net_attach)(void *dhdp, int ifidx);
747 bool rollback_lock = false;
749 /* Use primary I/F for sending cmds down to firmware */
750 _ndev = wl_to_prmry_ndev(wl);
752 WL_DBG(("if name: %s, type: %d\n", name, type));
754 case NL80211_IFTYPE_ADHOC:
755 case NL80211_IFTYPE_AP_VLAN:
756 case NL80211_IFTYPE_WDS:
757 case NL80211_IFTYPE_MESH_POINT:
758 WL_ERR(("Unsupported interface type\n"));
761 case NL80211_IFTYPE_MONITOR:
762 return wl_cfg80211_add_monitor_if(name);
763 case NL80211_IFTYPE_P2P_CLIENT:
764 case NL80211_IFTYPE_STATION:
765 wlif_type = WL_P2P_IF_CLIENT;
768 case NL80211_IFTYPE_P2P_GO:
769 case NL80211_IFTYPE_AP:
770 wlif_type = WL_P2P_IF_GO;
774 WL_ERR(("Unsupported interface type\n"));
780 WL_ERR(("name is NULL\n"));
783 if (wl->iface_cnt == IFACE_MAX_CNT)
784 return ERR_PTR(-ENOMEM);
785 if (wl->p2p_supported && (wlif_type != -1)) {
786 if (wl_get_p2p_status(wl, IF_DELETING)) {
787 /* wait till IF_DEL is complete
788 * release the lock for the unregister to proceed
790 if (rtnl_is_locked()) {
792 rollback_lock = true;
794 WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n",
796 timeout = wait_event_interruptible_timeout(wl->netif_change_event,
797 (wl_get_p2p_status(wl, IF_DELETING) == false),
798 msecs_to_jiffies(MAX_WAIT_TIME));
800 /* put back the rtnl_lock again */
803 rollback_lock = false;
806 WL_ERR(("IF DEL is Success\n"));
809 WL_ERR(("timeount < 0, return -EAGAIN\n"));
810 return ERR_PTR(-EAGAIN);
813 if (wl->p2p && !wl->p2p->on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
815 wl_cfgp2p_set_firm_p2p(wl);
816 wl_cfgp2p_init_discovery(wl);
817 get_primary_mac(wl, &primary_mac);
818 wl_cfgp2p_generate_bss_mac(&primary_mac,
819 &wl->p2p->dev_addr, &wl->p2p->int_addr);
822 memset(wl->p2p->vir_ifname, 0, IFNAMSIZ);
823 strncpy(wl->p2p->vir_ifname, name, IFNAMSIZ - 1);
825 wldev_iovar_setint(_ndev, "mpc", 0);
826 wl_notify_escan_complete(wl, _ndev, true, true);
827 /* In concurrency case, STA may be already associated in a particular channel.
828 * so retrieve the current channel of primary interface and then start the virtual
831 chspec = wl_cfg80211_get_shared_freq(wiphy);
833 /* For P2P mode, use P2P-specific driver features to create the
834 * bss: "wl p2p_ifadd"
836 wl_set_p2p_status(wl, IF_ADD);
837 err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
840 WL_ERR((" virtual iface add failed (%d) \n", err));
841 return ERR_PTR(-ENOMEM);
844 timeout = wait_event_interruptible_timeout(wl->netif_change_event,
845 (wl_get_p2p_status(wl, IF_ADD) == false),
846 msecs_to_jiffies(MAX_WAIT_TIME));
847 if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
849 struct wireless_dev *vwdev;
850 vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
851 if (unlikely(!vwdev)) {
852 WL_ERR(("Could not allocate wireless device\n"));
853 return ERR_PTR(-ENOMEM);
855 vwdev->wiphy = wl->wdev->wiphy;
856 WL_INFO((" virtual interface(%s) is created memalloc done \n",
857 wl->p2p->vir_ifname));
858 vwdev->iftype = type;
859 _ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
860 _ndev->ieee80211_ptr = vwdev;
861 SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
862 vwdev->netdev = _ndev;
863 wl_set_drv_status(wl, READY, _ndev);
864 wl->p2p->vif_created = true;
865 wl_set_mode_by_netdev(wl, _ndev, mode);
866 net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
867 if (rtnl_is_locked()) {
869 rollback_lock = true;
871 if (net_attach && !net_attach(wl->pub, _ndev->ifindex)) {
872 wl_alloc_netinfo(wl, _ndev, vwdev, mode);
873 WL_ERR((" virtual interface(%s) is "
874 "created net attach done\n", wl->p2p->vir_ifname));
875 #if defined(WL_ENABLE_P2P_IF)
876 if (type == NL80211_IFTYPE_P2P_CLIENT)
877 dhd_mode = P2P_GC_ENABLED;
878 else if (type == NL80211_IFTYPE_P2P_GO)
879 dhd_mode = P2P_GO_ENABLED;
880 DNGL_FUNC(dhd_cfg80211_set_p2p_info, (wl, dhd_mode));
881 #endif /* (WL_ENABLE_P2P_IF) */
882 /* Start the P2P I/F with PM disabled. Enable PM from
885 if ((type == NL80211_IFTYPE_P2P_CLIENT) || (
886 type == NL80211_IFTYPE_P2P_GO))
887 vwdev->ps = NL80211_PS_DISABLED;
889 /* put back the rtnl_lock again */
894 /* put back the rtnl_lock again */
900 wl_clr_p2p_status(wl, IF_ADD);
901 WL_ERR((" virtual interface(%s) is not created \n", wl->p2p->vir_ifname));
902 memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
903 wl->p2p->vif_created = false;
907 return ERR_PTR(-ENODEV);
911 wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
913 struct ether_addr p2p_mac;
914 struct wl_priv *wl = wiphy_priv(wiphy);
919 if (wl->p2p_net == dev) {
920 /* Since there is no ifidx corresponding to p2p0, cmds to
921 * firmware should be routed through primary I/F
923 dev = wl_to_prmry_ndev(wl);
926 if (wl->p2p_supported) {
927 memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
929 /* Clear GO_NEG_PHASE bit to take care of GO-NEG-FAIL cases
931 WL_DBG(("P2P: GO_NEG_PHASE status cleared "));
932 wl_clr_p2p_status(wl, GO_NEG_PHASE);
933 if (wl->p2p->vif_created) {
934 if (wl_get_drv_status(wl, SCANNING, dev)) {
935 wl_notify_escan_complete(wl, dev, true, true);
937 wldev_iovar_setint(dev, "mpc", 1);
938 wl_set_p2p_status(wl, IF_DELETING);
939 ret = wl_cfgp2p_ifdel(wl, &p2p_mac);
940 /* Firmware could not delete the interface so we will not get WLC_E_IF
941 * event for cleaning the dhd virtual nw interace
942 * So lets do it here. Failures from fw will ensure the application to do
943 * ifconfig <inter> down and up sequnce, which will reload the fw
944 * however we should cleanup the linux network virtual interfaces
946 /* Request framework to RESET and clean up */
948 struct net_device *ndev = wl_to_prmry_ndev(wl);
949 WL_ERR(("Firmware returned an error (%d) from p2p_ifdel"
950 "HANG Notification sent to %s\n", ret, ndev->name));
951 wl_cfg80211_hang(ndev, WLAN_REASON_UNSPECIFIED);
954 /* Wait for any pending scan req to get aborted from the sysioc context */
955 timeout = wait_event_interruptible_timeout(wl->netif_change_event,
956 (wl->p2p->vif_created == false),
957 msecs_to_jiffies(MAX_WAIT_TIME));
958 if (timeout > 0 && (wl->p2p->vif_created == false)) {
959 WL_DBG(("IFDEL operation done\n"));
960 #if defined(WL_ENABLE_P2P_IF)
961 DNGL_FUNC(dhd_cfg80211_clean_p2p_info, (wl));
962 #endif /* (WL_ENABLE_P2P_IF)) */
964 WL_ERR(("IFDEL didn't complete properly\n"));
966 ret = dhd_del_monitor(dev);
973 wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
974 enum nl80211_iftype type, u32 *flags,
975 struct vif_params *params)
984 struct wl_priv *wl = wiphy_priv(wiphy);
986 WL_DBG(("Enter type %d\n", type));
988 case NL80211_IFTYPE_MONITOR:
989 case NL80211_IFTYPE_WDS:
990 case NL80211_IFTYPE_MESH_POINT:
992 WL_ERR(("type (%d) : currently we do not support this type\n",
995 case NL80211_IFTYPE_ADHOC:
998 case NL80211_IFTYPE_STATION:
999 case NL80211_IFTYPE_P2P_CLIENT:
1003 case NL80211_IFTYPE_AP:
1004 case NL80211_IFTYPE_AP_VLAN:
1005 case NL80211_IFTYPE_P2P_GO:
1012 WL_DBG(("%s : ap (%d), infra (%d), iftype: (%d)\n", ndev->name, ap, infra, type));
1015 wl_set_mode_by_netdev(wl, ndev, mode);
1016 if (wl->p2p_supported && wl->p2p->vif_created) {
1017 WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p->vif_created,
1019 wldev_iovar_setint(ndev, "mpc", 0);
1020 wl_notify_escan_complete(wl, ndev, true, true);
1022 /* In concurrency case, STA may be already associated in a particular
1023 * channel. so retrieve the current channel of primary interface and
1024 * then start the virtual interface on that.
1026 chspec = wl_cfg80211_get_shared_freq(wiphy);
1028 wlif_type = WL_P2P_IF_GO;
1029 WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n",
1030 ndev->name, ap, infra, type));
1031 wl_set_p2p_status(wl, IF_CHANGING);
1032 wl_clr_p2p_status(wl, IF_CHANGED);
1033 err = wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
1034 timeout = wait_event_interruptible_timeout(wl->netif_change_event,
1035 (wl_get_p2p_status(wl, IF_CHANGED) == true),
1036 msecs_to_jiffies(MAX_WAIT_TIME));
1037 wl_set_mode_by_netdev(wl, ndev, mode);
1038 wl_clr_p2p_status(wl, IF_CHANGING);
1039 wl_clr_p2p_status(wl, IF_CHANGED);
1040 } else if (ndev == wl_to_prmry_ndev(wl) &&
1041 !wl_get_drv_status(wl, AP_CREATED, ndev)) {
1042 wl_set_drv_status(wl, AP_CREATING, ndev);
1044 !(wl->ap_info = kzalloc(sizeof(struct ap_info), GFP_KERNEL))) {
1045 WL_ERR(("struct ap_saved_ie allocation failed\n"));
1049 WL_ERR(("Cannot change the interface for GO or SOFTAP\n"));
1053 infra = htod32(infra);
1054 err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(s32), true);
1056 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
1059 wl_set_mode_by_netdev(wl, ndev, mode);
1062 ndev->ieee80211_ptr->iftype = type;
1067 wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
1070 struct wl_priv *wl = wlcfg_drv_priv;
1074 WL_ERR(("net is NULL\n"));
1077 if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) {
1078 WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
1079 "new name: %s\n", ndev->name, wl->p2p->vir_ifname));
1080 /* Assign the net device to CONNECT BSSCFG */
1081 strncpy(ndev->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
1082 wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = ndev;
1083 wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = bssidx;
1084 wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach;
1085 ndev->ifindex = idx;
1086 wl_clr_p2p_status(wl, IF_ADD);
1088 wake_up_interruptible(&wl->netif_change_event);
1090 ret = BCME_NOTREADY;
1096 wl_cfg80211_notify_ifdel(void)
1098 struct wl_priv *wl = wlcfg_drv_priv;
1100 WL_DBG(("Enter \n"));
1101 wl_clr_p2p_status(wl, IF_DELETING);
1107 wl_cfg80211_ifdel_ops(struct net_device *ndev)
1109 struct wl_priv *wl = wlcfg_drv_priv;
1110 bool rollback_lock = false;
1113 if (!ndev || !ndev->name) {
1114 WL_ERR(("net is NULL\n"));
1118 if (p2p_is_on(wl) && wl->p2p->vif_created &&
1119 wl_get_p2p_status(wl, IF_DELETING)) {
1120 if (wl->scan_request &&
1121 (wl->escan_info.ndev == ndev)) {
1122 /* Abort any pending scan requests */
1123 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
1124 if (!rtnl_is_locked()) {
1126 rollback_lock = true;
1128 WL_DBG(("ESCAN COMPLETED\n"));
1129 wl_notify_escan_complete(wl, ndev, true, false);
1133 WL_ERR(("IF_DEL event called from dongle, net %x, vif name: %s\n",
1134 (unsigned int)ndev, wl->p2p->vir_ifname));
1136 memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
1137 index = wl_cfgp2p_find_idx(wl, ndev);
1138 wl_to_p2p_bss_ndev(wl, index) = NULL;
1139 wl_to_p2p_bss_bssidx(wl, index) = 0;
1140 wl->p2p->vif_created = false;
1141 wl_cfgp2p_clear_management_ie(wl,
1143 WL_DBG(("index : %d\n", index));
1147 /* Wake up any waiting thread */
1148 wake_up_interruptible(&wl->netif_change_event);
1154 wl_cfg80211_is_progress_ifadd(void)
1156 s32 is_progress = 0;
1157 struct wl_priv *wl = wlcfg_drv_priv;
1158 if (wl_get_p2p_status(wl, IF_ADD))
1164 wl_cfg80211_is_progress_ifchange(void)
1166 s32 is_progress = 0;
1167 struct wl_priv *wl = wlcfg_drv_priv;
1168 if (wl_get_p2p_status(wl, IF_CHANGING))
1175 wl_cfg80211_notify_ifchange(void)
1177 struct wl_priv *wl = wlcfg_drv_priv;
1178 if (wl_get_p2p_status(wl, IF_CHANGING)) {
1179 wl_set_p2p_status(wl, IF_CHANGED);
1180 wake_up_interruptible(&wl->netif_change_event);
1185 static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request)
1190 chanspec_t chanspec;
1195 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
1196 params->bss_type = DOT11_BSSTYPE_ANY;
1197 params->scan_type = 0;
1198 params->nprobes = -1;
1199 params->active_time = -1;
1200 params->passive_time = -1;
1201 params->home_time = -1;
1202 params->channel_num = 0;
1203 memset(¶ms->ssid, 0, sizeof(wlc_ssid_t));
1205 WL_SCAN(("Preparing Scan request\n"));
1206 WL_SCAN(("nprobes=%d\n", params->nprobes));
1207 WL_SCAN(("active_time=%d\n", params->active_time));
1208 WL_SCAN(("passive_time=%d\n", params->passive_time));
1209 WL_SCAN(("home_time=%d\n", params->home_time));
1210 WL_SCAN(("scan_type=%d\n", params->scan_type));
1212 params->nprobes = htod32(params->nprobes);
1213 params->active_time = htod32(params->active_time);
1214 params->passive_time = htod32(params->passive_time);
1215 params->home_time = htod32(params->home_time);
1217 /* if request is null just exit so it will be all channel broadcast scan */
1221 n_ssids = request->n_ssids;
1222 n_channels = request->n_channels;
1224 /* Copy channel array if applicable */
1225 WL_SCAN(("### List of channelspecs to scan ###\n"));
1226 if (n_channels > 0) {
1227 for (i = 0; i < n_channels; i++) {
1229 channel = ieee80211_frequency_to_channel(request->channels[i]->center_freq);
1230 if (request->channels[i]->band == IEEE80211_BAND_2GHZ)
1231 chanspec |= WL_CHANSPEC_BAND_2G;
1233 chanspec |= WL_CHANSPEC_BAND_5G;
1235 if (request->channels[i]->flags & IEEE80211_CHAN_NO_HT40) {
1236 chanspec |= WL_CHANSPEC_BW_20;
1237 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
1239 chanspec |= WL_CHANSPEC_BW_40;
1240 if (request->channels[i]->flags & IEEE80211_CHAN_NO_HT40PLUS)
1241 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
1243 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
1246 params->channel_list[i] = channel;
1247 params->channel_list[i] &= WL_CHANSPEC_CHAN_MASK;
1248 params->channel_list[i] |= chanspec;
1249 WL_SCAN(("Chan : %d, Channel spec: %x \n",
1250 channel, params->channel_list[i]));
1251 params->channel_list[i] = htod16(params->channel_list[i]);
1254 WL_SCAN(("Scanning all channels\n"));
1257 /* Copy ssid array if applicable */
1258 WL_SCAN(("### List of SSIDs to scan ###\n"));
1260 offset = offsetof(wl_scan_params_t, channel_list) + n_channels * sizeof(u16);
1261 offset = roundup(offset, sizeof(u32));
1262 ptr = (char*)params + offset;
1263 for (i = 0; i < n_ssids; i++) {
1264 memset(&ssid, 0, sizeof(wlc_ssid_t));
1265 ssid.SSID_len = request->ssids[i].ssid_len;
1266 memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len);
1268 WL_SCAN(("%d: Broadcast scan\n", i));
1270 WL_SCAN(("%d: scan for %s size =%d\n", i,
1271 ssid.SSID, ssid.SSID_len));
1272 memcpy(ptr, &ssid, sizeof(wlc_ssid_t));
1273 ptr += sizeof(wlc_ssid_t);
1276 WL_SCAN(("Broadcast scan\n"));
1278 /* Adding mask to channel numbers */
1279 params->channel_num =
1280 htod32((n_ssids << WL_SCAN_PARAMS_NSSID_SHIFT) |
1281 (n_channels & WL_SCAN_PARAMS_COUNT_MASK));
1285 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, u16 action)
1290 (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
1291 struct wl_iscan_params *params;
1294 if (request != NULL) {
1295 n_channels = request->n_channels;
1296 n_ssids = request->n_ssids;
1297 /* Allocate space for populating ssids in wl_iscan_params struct */
1299 /* If n_channels is odd, add a padd of u16 */
1300 params_size += sizeof(u16) * (n_channels + 1);
1302 params_size += sizeof(u16) * n_channels;
1304 /* Allocate space for populating ssids in wl_iscan_params struct */
1305 params_size += sizeof(struct wlc_ssid) * n_ssids;
1307 params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
1312 wl_scan_prep(¶ms->params, request);
1314 params->version = htod32(ISCAN_REQ_VERSION);
1315 params->action = htod16(action);
1316 params->scan_duration = htod16(0);
1318 if (params_size + sizeof("iscan") >= WLC_IOCTL_MEDLEN) {
1319 WL_ERR(("ioctl buffer length is not sufficient\n"));
1323 err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
1324 iscan->ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
1325 if (unlikely(err)) {
1326 if (err == -EBUSY) {
1327 WL_ERR(("system busy : iscan canceled\n"));
1329 WL_ERR(("error (%d)\n", err));
1337 static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request)
1339 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
1340 struct net_device *ndev = wl_to_prmry_ndev(wl);
1344 iscan->state = WL_ISCAN_STATE_SCANING;
1346 passive_scan = wl->active_scan ? 0 : 1;
1347 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1348 &passive_scan, sizeof(passive_scan), false);
1349 if (unlikely(err)) {
1350 WL_DBG(("error (%d)\n", err));
1353 wl->iscan_kickstart = true;
1354 wl_run_iscan(iscan, request, WL_SCAN_ACTION_START);
1355 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
1356 iscan->timer_on = 1;
1362 wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size)
1364 wl_uint32_list_t *list;
1366 if (valid_chan_list == NULL || size <= 0)
1369 memset(valid_chan_list, 0, size);
1370 list = (wl_uint32_list_t *)(void *) valid_chan_list;
1371 list->count = htod32(WL_NUMCHANNELS);
1372 err = wldev_ioctl(ndev, WLC_GET_VALID_CHANNELS, valid_chan_list, size, false);
1374 WL_ERR(("get channels failed with %d\n", err));
1381 wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
1382 struct cfg80211_scan_request *request, uint16 action)
1387 s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
1388 wl_escan_params_t *params = NULL;
1389 struct cfg80211_scan_request *scan_request = wl->scan_request;
1390 u8 chan_buf[sizeof(u32)*(WL_NUMCHANNELS + 1)];
1394 s32 search_state = WL_P2P_DISC_ST_SCAN;
1395 u32 i, j, n_nodfs = 0;
1396 u16 *default_chan_list = NULL;
1397 wl_uint32_list_t *list;
1398 struct net_device *dev = NULL;
1399 WL_DBG(("Enter \n"));
1402 if (!wl->p2p_supported || ((ndev == wl_to_prmry_ndev(wl)) &&
1404 /* LEGACY SCAN TRIGGER */
1405 WL_SCAN((" LEGACY E-SCAN START\n"));
1407 if (request != NULL) {
1408 n_channels = request->n_channels;
1409 n_ssids = request->n_ssids;
1410 /* Allocate space for populating ssids in wl_iscan_params struct */
1412 /* If n_channels is odd, add a padd of u16 */
1413 params_size += sizeof(u16) * (n_channels + 1);
1415 params_size += sizeof(u16) * n_channels;
1417 /* Allocate space for populating ssids in wl_iscan_params struct */
1418 params_size += sizeof(struct wlc_ssid) * n_ssids;
1420 params = (wl_escan_params_t *) kzalloc(params_size, GFP_KERNEL);
1421 if (params == NULL) {
1426 wl_scan_prep(¶ms->params, request);
1427 params->version = htod32(ESCAN_REQ_VERSION);
1428 params->action = htod16(action);
1429 params->sync_id = htod16(0x1234);
1430 if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) {
1431 WL_ERR(("ioctl buffer length not sufficient\n"));
1436 err = wldev_iovar_setbuf(ndev, "escan", params, params_size,
1437 wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
1439 WL_ERR((" Escan set error (%d)\n", err));
1442 else if (p2p_is_on(wl) && p2p_scan(wl)) {
1443 /* P2P SCAN TRIGGER */
1446 if (scan_request && scan_request->n_channels) {
1447 num_chans = scan_request->n_channels;
1448 WL_SCAN((" chann number : %d\n", num_chans));
1449 default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
1451 if (default_chan_list == NULL) {
1452 WL_ERR(("channel list allocation failed \n"));
1456 if (!wl_get_valid_channels(ndev, chan_buf, sizeof(chan_buf))) {
1457 list = (wl_uint32_list_t *) chan_buf;
1458 n_valid_chan = dtoh32(list->count);
1459 for (i = 0; i < num_chans; i++)
1461 _freq = scan_request->channels[i]->center_freq;
1462 channel = ieee80211_frequency_to_channel(_freq);
1463 /* remove DFS channels */
1464 if (channel < 52 || channel > 140) {
1465 for (j = 0; j < n_valid_chan; j++) {
1466 /* allows only supported channel on
1469 if (channel == (dtoh32(list->element[j])))
1470 default_chan_list[n_nodfs++] =
1477 if (num_chans == 3 && (
1478 (default_chan_list[0] == SOCIAL_CHAN_1) &&
1479 (default_chan_list[1] == SOCIAL_CHAN_2) &&
1480 (default_chan_list[2] == SOCIAL_CHAN_3))) {
1481 /* SOCIAL CHANNELS 1, 6, 11 */
1482 search_state = WL_P2P_DISC_ST_SEARCH;
1483 WL_INFO(("P2P SEARCH PHASE START \n"));
1484 } else if ((dev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)) &&
1485 (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP)) {
1486 /* If you are already a GO, then do SEARCH only */
1487 WL_INFO(("Already a GO. Do SEARCH Only"));
1488 search_state = WL_P2P_DISC_ST_SEARCH;
1489 num_chans = n_nodfs;
1492 WL_INFO(("P2P SCAN STATE START \n"));
1493 num_chans = n_nodfs;
1497 err = wl_cfgp2p_escan(wl, ndev, wl->active_scan, num_chans, default_chan_list,
1498 search_state, action,
1499 wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
1500 kfree(default_chan_list);
1503 if (unlikely(err)) {
1504 WL_ERR(("error (%d)\n", err));
1511 wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev,
1512 struct cfg80211_scan_request *request)
1516 wl_scan_results_t *results;
1517 WL_SCAN(("Enter \n"));
1518 wl->escan_info.ndev = ndev;
1519 wl->escan_info.wiphy = wiphy;
1520 wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
1521 passive_scan = wl->active_scan ? 0 : 1;
1522 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1523 &passive_scan, sizeof(passive_scan), false);
1524 if (unlikely(err)) {
1525 WL_ERR(("error (%d)\n", err));
1528 results = (wl_scan_results_t *) wl->escan_info.escan_buf;
1529 results->version = 0;
1531 results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
1533 err = wl_run_escan(wl, ndev, request, WL_SCAN_ACTION_START);
1538 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
1539 struct cfg80211_scan_request *request,
1540 struct cfg80211_ssid *this_ssid)
1542 struct wl_priv *wl = wiphy_priv(wiphy);
1543 struct cfg80211_ssid *ssids;
1544 struct wl_scan_req *sr = wl_to_sr(wl);
1545 struct ether_addr primary_mac;
1546 wpa_ie_fixed_t *wps_ie;
1549 bool escan_req = false;
1554 u8 wpsie[IE_MAX_LEN];
1556 /* If scan req comes for p2p0, send it over primary I/F
1557 * Scan results will be delivered corresponding to cfg80211_scan_request
1559 if (ndev == wl->p2p_net) {
1560 ndev = wl_to_prmry_ndev(wl);
1563 WL_DBG(("Enter wiphy (%p)\n", wiphy));
1564 if (wl_get_drv_status_all(wl, SCANNING)) {
1565 WL_ERR(("Scanning already\n"));
1568 if (wl_get_drv_status(wl, SCAN_ABORTING, ndev)) {
1569 WL_ERR(("Scanning being aborted\n"));
1572 if (request && request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
1573 WL_ERR(("request null or n_ssids > WL_SCAN_PARAMS_SSID_MAX\n"));
1577 /* Arm scan timeout timer */
1578 mod_timer(&wl->scan_timeout, jiffies + WL_SCAN_TIMER_INTERVAL_MS * HZ / 1000);
1580 if (request) { /* scan bss */
1581 ssids = request->ssids;
1582 if (wl->iscan_on && (!ssids || !ssids->ssid_len || request->n_ssids != 1)) {
1584 } else if (wl->escan_on) {
1587 for (i = 0; i < request->n_ssids; i++) {
1588 if (ssids[i].ssid_len && IS_P2P_SSID(ssids[i].ssid)) {
1594 if (wl->p2p_supported) {
1595 /* p2p scan trigger */
1596 if (p2p_on(wl) == false) {
1597 /* p2p on at the first time */
1599 wl_cfgp2p_set_firm_p2p(wl);
1600 get_primary_mac(wl, &primary_mac);
1601 wl_cfgp2p_generate_bss_mac(&primary_mac,
1602 &wl->p2p->dev_addr, &wl->p2p->int_addr);
1604 wl_clr_p2p_status(wl, GO_NEG_PHASE);
1605 WL_DBG(("P2P: GO_NEG_PHASE status cleared \n"));
1606 p2p_scan(wl) = true;
1609 /* legacy scan trigger
1610 * So, we have to disable p2p discovery if p2p discovery is on
1612 if (wl->p2p_supported) {
1613 p2p_scan(wl) = false;
1614 /* If Netdevice is not equals to primary and p2p is on
1615 * , we will do p2p scan using P2PAPI_BSSCFG_DEVICE.
1617 if (p2p_on(wl) && (ndev != wl_to_prmry_ndev(wl)))
1618 p2p_scan(wl) = true;
1620 if (p2p_scan(wl) == false) {
1621 if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
1622 err = wl_cfgp2p_discover_enable_search(wl,
1624 if (unlikely(err)) {
1631 if (!wl->p2p_supported || !p2p_scan(wl)) {
1632 if (ndev == wl_to_prmry_ndev(wl)) {
1633 /* find the WPSIE */
1634 memset(wpsie, 0, sizeof(wpsie));
1635 if ((wps_ie = wl_cfgp2p_find_wpsie(
1637 request->ie_len)) != NULL) {
1639 wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
1640 memcpy(wpsie, wps_ie, wpsie_len);
1644 if (wpsie_len > 0) {
1645 err = wl_cfgp2p_set_management_ie(wl,
1646 ndev, -1, VNDR_IE_PRBREQ_FLAG,
1648 if (unlikely(err)) {
1656 } else { /* scan in ibss */
1657 /* we don't do iscan in ibss */
1660 wl->scan_request = request;
1661 wl_set_drv_status(wl, SCANNING, ndev);
1663 err = wl_do_iscan(wl, request);
1668 } else if (escan_req) {
1669 if (wl->p2p_supported) {
1670 if (p2p_on(wl) && p2p_scan(wl)) {
1672 err = wl_cfgp2p_enable_discovery(wl, ndev,
1673 request->ie, request->ie_len);
1675 if (unlikely(err)) {
1680 err = wl_do_escan(wl, wiphy, ndev, request);
1688 memset(&sr->ssid, 0, sizeof(sr->ssid));
1690 min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len);
1691 if (sr->ssid.SSID_len) {
1692 memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
1693 sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
1694 WL_SCAN(("Specific scan ssid=\"%s\" len=%d\n",
1695 sr->ssid.SSID, sr->ssid.SSID_len));
1697 WL_SCAN(("Broadcast scan\n"));
1699 WL_SCAN(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
1700 passive_scan = wl->active_scan ? 0 : 1;
1701 err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
1702 &passive_scan, sizeof(passive_scan), false);
1703 if (unlikely(err)) {
1704 WL_SCAN(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
1707 err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
1708 sizeof(sr->ssid), false);
1710 if (err == -EBUSY) {
1711 WL_ERR(("system busy : scan for \"%s\" "
1712 "canceled\n", sr->ssid.SSID));
1714 WL_ERR(("WLC_SCAN error (%d)\n", err));
1723 wl_clr_drv_status(wl, SCANNING, ndev);
1724 wl->scan_request = NULL;
1729 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
1730 struct cfg80211_scan_request *request)
1733 struct wl_priv *wl = wiphy_priv(wiphy);
1735 WL_DBG(("Enter \n"));
1738 err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
1739 if (unlikely(err)) {
1740 WL_ERR(("scan error (%d)\n", err));
1747 static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold)
1751 err = wldev_iovar_setint(dev, "rtsthresh", rts_threshold);
1752 if (unlikely(err)) {
1753 WL_ERR(("Error (%d)\n", err));
1759 static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold)
1763 err = wldev_iovar_setint_bsscfg(dev, "fragthresh", frag_threshold, 0);
1764 if (unlikely(err)) {
1765 WL_ERR(("Error (%d)\n", err));
1771 static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
1774 u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
1776 retry = htod32(retry);
1777 err = wldev_ioctl(dev, cmd, &retry, sizeof(retry), false);
1778 if (unlikely(err)) {
1779 WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
1785 static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1787 struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy);
1788 struct net_device *ndev = wl_to_prmry_ndev(wl);
1792 WL_DBG(("Enter\n"));
1793 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1794 (wl->conf->rts_threshold != wiphy->rts_threshold)) {
1795 wl->conf->rts_threshold = wiphy->rts_threshold;
1796 err = wl_set_rts(ndev, wl->conf->rts_threshold);
1800 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1801 (wl->conf->frag_threshold != wiphy->frag_threshold)) {
1802 wl->conf->frag_threshold = wiphy->frag_threshold;
1803 err = wl_set_frag(ndev, wl->conf->frag_threshold);
1807 if (changed & WIPHY_PARAM_RETRY_LONG &&
1808 (wl->conf->retry_long != wiphy->retry_long)) {
1809 wl->conf->retry_long = wiphy->retry_long;
1810 err = wl_set_retry(ndev, wl->conf->retry_long, true);
1814 if (changed & WIPHY_PARAM_RETRY_SHORT &&
1815 (wl->conf->retry_short != wiphy->retry_short)) {
1816 wl->conf->retry_short = wiphy->retry_short;
1817 err = wl_set_retry(ndev, wl->conf->retry_short, false);
1826 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1827 struct cfg80211_ibss_params *params)
1829 struct wl_priv *wl = wiphy_priv(wiphy);
1830 struct wl_join_params join_params;
1831 struct wlc_ssid ssid;
1832 struct ether_addr bssid;
1833 size_t join_params_size = 0;
1842 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
1844 if (wl->scan_request) {
1845 wl_notify_escan_complete(wl, dev, true, true);
1848 bzero(&bssid, sizeof(bssid));
1849 wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
1852 WL_INFO(("SSID: %s\n", params->ssid));
1854 WL_ERR(("SSID: NULL, Not supported\n"));
1860 WL_INFO(("BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
1861 params->bssid[0], params->bssid[1], params->bssid[2],
1862 params->bssid[3], params->bssid[4], params->bssid[5]));
1864 if (params->channel)
1865 WL_INFO(("channel: %d\n", params->channel->center_freq));
1867 if (params->channel_fixed)
1868 WL_INFO(("fixed channel required\n"));
1870 if (params->ie && params->ie_len)
1871 WL_INFO(("ie len: %d\n", params->ie_len));
1873 if (params->beacon_interval)
1874 WL_INFO(("beacon interval: %d\n", params->beacon_interval));
1876 if (params->basic_rates)
1877 WL_INFO(("basic rates: %08X\n", params->basic_rates));
1879 if (params->privacy)
1880 WL_INFO(("privacy required\n"));
1882 wl_set_drv_status(wl, CONNECTING, dev);
1884 /* Configure Privacy for starter */
1885 if (params->privacy)
1886 wsec |= WEP_ENABLED;
1888 err = wldev_iovar_setint(dev, "wsec", wsec);
1890 WL_ERR(("wsec failed (%d)\n", err));
1894 err = wldev_iovar_setint(dev, "auth", WL_AUTH_OPEN_SYSTEM);
1896 WL_ERR(("auth failed (%d)\n", err));
1900 err = wldev_iovar_setint(dev, "wpa_auth", 0);
1902 WL_ERR(("wpa_auth failed (%d)\n", err));
1906 /* Configure Beacon Interval for starter */
1907 if (params->beacon_interval)
1908 bcnprd = params->beacon_interval;
1912 bcnprd = htod32(bcnprd);
1913 err = wldev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd), true);
1915 WL_ERR(("WLC_SET_BCNPRD failed (%d)\n", err));
1919 /* Configure required join parameter */
1920 memset(&join_params, 0, sizeof(struct wl_join_params));
1923 memset(&ssid, 0, sizeof(struct wlc_ssid));
1924 ssid.SSID_len = MIN(params->ssid_len, 32);
1925 join_params.ssid.SSID_len = htod32(ssid.SSID_len);
1926 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
1927 memcpy(join_params.ssid.SSID, params->ssid, ssid.SSID_len);
1928 join_params_size = sizeof(join_params.ssid);
1930 wl_update_prof(wl, dev, NULL, &ssid, WL_PROF_SSID);
1933 if (params->bssid) {
1934 memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN);
1935 join_params_size = sizeof(join_params.ssid) +
1936 WL_ASSOC_PARAMS_FIXED_SIZE;
1938 wl_update_prof(wl, dev, NULL, params->bssid, WL_PROF_BSSID);
1940 memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN);
1944 if (params->channel) {
1947 target_channel = ieee80211_frequency_to_channel(
1948 params->channel->center_freq);
1949 if (params->channel_fixed) {
1950 /* adding chanspec */
1951 wl_ch_to_chanspec(target_channel,
1952 &join_params, &join_params_size);
1955 /* set channel for starter */
1956 target_channel = htod32(target_channel);
1957 err = wldev_ioctl(dev, WLC_SET_CHANNEL,
1958 &target_channel, sizeof(target_channel), true);
1960 WL_ERR(("WLC_SET_CHANNEL failed (%d)\n", err));
1965 wl->ibss_starter = false;
1967 err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true);
1969 WL_ERR(("WLC_SET_SSID failed (%d)\n", err));
1976 wl_clr_drv_status(wl, CONNECTING, dev);
1978 WL_TRACE(("Exit\n"));
1982 static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1984 struct wl_priv *wl = wiphy_priv(wiphy);
1990 WL_TRACE(("Enter\n"));
1993 act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT);
1994 curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID);
1997 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
1999 if (wl->scan_request) {
2000 wl_notify_escan_complete(wl, dev, true, true);
2002 wl_set_drv_status(wl, DISCONNECTING, dev);
2003 scbval.val = DOT11_RC_DISASSOC_LEAVING;
2004 memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
2005 scbval.val = htod32(scbval.val);
2006 err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
2007 sizeof(scb_val_t), true);
2008 if (unlikely(err)) {
2009 wl_clr_drv_status(wl, DISCONNECTING, dev);
2010 WL_ERR(("error (%d)\n", err));
2015 WL_TRACE(("Exit\n"));
2020 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
2022 struct wl_priv *wl = wlcfg_drv_priv;
2023 struct wl_security *sec;
2026 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2028 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2029 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
2030 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2031 val = WPA2_AUTH_PSK| WPA2_AUTH_UNSPECIFIED;
2033 val = WPA_AUTH_DISABLED;
2035 if (is_wps_conn(sme))
2036 val = WPA_AUTH_DISABLED;
2038 WL_DBG(("setting wpa_auth to 0x%0x\n", val));
2039 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
2040 if (unlikely(err)) {
2041 WL_ERR(("set wpa_auth failed (%d)\n", err));
2044 sec = wl_read_prof(wl, dev, WL_PROF_SEC);
2045 sec->wpa_versions = sme->crypto.wpa_versions;
2050 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
2052 struct wl_priv *wl = wlcfg_drv_priv;
2053 struct wl_security *sec;
2056 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2057 switch (sme->auth_type) {
2058 case NL80211_AUTHTYPE_OPEN_SYSTEM:
2059 val = WL_AUTH_OPEN_SYSTEM;
2060 WL_DBG(("open system\n"));
2062 case NL80211_AUTHTYPE_SHARED_KEY:
2063 val = WL_AUTH_SHARED_KEY;
2064 WL_DBG(("shared key\n"));
2066 case NL80211_AUTHTYPE_AUTOMATIC:
2067 val = WL_AUTH_OPEN_SHARED;
2068 WL_DBG(("automatic\n"));
2070 case NL80211_AUTHTYPE_NETWORK_EAP:
2071 WL_DBG(("network eap\n"));
2073 val = WL_AUTH_OPEN_SHARED;
2074 WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
2078 err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
2079 if (unlikely(err)) {
2080 WL_ERR(("set auth failed (%d)\n", err));
2083 sec = wl_read_prof(wl, dev, WL_PROF_SEC);
2084 sec->auth_type = sme->auth_type;
2089 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
2091 struct wl_priv *wl = wlcfg_drv_priv;
2092 struct wl_security *sec;
2096 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2098 if (sme->crypto.n_ciphers_pairwise) {
2099 switch (sme->crypto.ciphers_pairwise[0]) {
2100 case WLAN_CIPHER_SUITE_WEP40:
2101 case WLAN_CIPHER_SUITE_WEP104:
2104 case WLAN_CIPHER_SUITE_TKIP:
2105 pval = TKIP_ENABLED;
2107 case WLAN_CIPHER_SUITE_CCMP:
2110 case WLAN_CIPHER_SUITE_AES_CMAC:
2114 WL_ERR(("invalid cipher pairwise (%d)\n",
2115 sme->crypto.ciphers_pairwise[0]));
2119 if (sme->crypto.cipher_group) {
2120 switch (sme->crypto.cipher_group) {
2121 case WLAN_CIPHER_SUITE_WEP40:
2122 case WLAN_CIPHER_SUITE_WEP104:
2125 case WLAN_CIPHER_SUITE_TKIP:
2126 gval = TKIP_ENABLED;
2128 case WLAN_CIPHER_SUITE_CCMP:
2131 case WLAN_CIPHER_SUITE_AES_CMAC:
2135 WL_ERR(("invalid cipher group (%d)\n",
2136 sme->crypto.cipher_group));
2141 WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
2143 if (is_wps_conn(sme)) {
2145 err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
2147 /* WPS-2.0 allowes no security */
2148 err = wldev_iovar_setint_bsscfg(dev, "wsec", 0, bssidx);
2150 WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC"));
2151 err = wldev_iovar_setint_bsscfg(dev, "wsec",
2152 pval | gval, bssidx);
2154 if (unlikely(err)) {
2155 WL_ERR(("error (%d)\n", err));
2159 sec = wl_read_prof(wl, dev, WL_PROF_SEC);
2160 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
2161 sec->cipher_group = sme->crypto.cipher_group;
2167 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
2169 struct wl_priv *wl = wlcfg_drv_priv;
2170 struct wl_security *sec;
2173 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2175 if (sme->crypto.n_akm_suites) {
2176 err = wldev_iovar_getint(dev, "wpa_auth", &val);
2177 if (unlikely(err)) {
2178 WL_ERR(("could not get wpa_auth (%d)\n", err));
2181 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
2182 switch (sme->crypto.akm_suites[0]) {
2183 case WLAN_AKM_SUITE_8021X:
2184 val = WPA_AUTH_UNSPECIFIED;
2186 case WLAN_AKM_SUITE_PSK:
2190 WL_ERR(("invalid cipher group (%d)\n",
2191 sme->crypto.cipher_group));
2194 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
2195 switch (sme->crypto.akm_suites[0]) {
2196 case WLAN_AKM_SUITE_8021X:
2197 val = WPA2_AUTH_UNSPECIFIED;
2199 case WLAN_AKM_SUITE_PSK:
2200 val = WPA2_AUTH_PSK;
2203 WL_ERR(("invalid cipher group (%d)\n",
2204 sme->crypto.cipher_group));
2208 WL_DBG(("setting wpa_auth to %d\n", val));
2210 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
2211 if (unlikely(err)) {
2212 WL_ERR(("could not set wpa_auth (%d)\n", err));
2216 sec = wl_read_prof(wl, dev, WL_PROF_SEC);
2217 sec->wpa_auth = sme->crypto.akm_suites[0];
2223 wl_set_set_sharedkey(struct net_device *dev,
2224 struct cfg80211_connect_params *sme)
2226 struct wl_priv *wl = wlcfg_drv_priv;
2227 struct wl_security *sec;
2228 struct wl_wsec_key key;
2231 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2233 WL_DBG(("key len (%d)\n", sme->key_len));
2235 sec = wl_read_prof(wl, dev, WL_PROF_SEC);
2236 WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
2237 sec->wpa_versions, sec->cipher_pairwise));
2238 if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 |
2239 NL80211_WPA_VERSION_2)) &&
2240 (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
2241 WLAN_CIPHER_SUITE_WEP104)))
2243 memset(&key, 0, sizeof(key));
2244 key.len = (u32) sme->key_len;
2245 key.index = (u32) sme->key_idx;
2246 if (unlikely(key.len > sizeof(key.data))) {
2247 WL_ERR(("Too long key length (%u)\n", key.len));
2250 memcpy(key.data, sme->key, key.len);
2251 key.flags = WL_PRIMARY_KEY;
2252 switch (sec->cipher_pairwise) {
2253 case WLAN_CIPHER_SUITE_WEP40:
2254 key.algo = CRYPTO_ALGO_WEP1;
2256 case WLAN_CIPHER_SUITE_WEP104:
2257 key.algo = CRYPTO_ALGO_WEP128;
2260 WL_ERR(("Invalid algorithm (%d)\n",
2261 sme->crypto.ciphers_pairwise[0]));
2264 /* Set the new key/index */
2265 WL_DBG(("key length (%d) key index (%d) algo (%d)\n",
2266 key.len, key.index, key.algo));
2267 WL_DBG(("key \"%s\"\n", key.data));
2268 swap_key_from_BE(&key);
2269 err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
2270 wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
2271 if (unlikely(err)) {
2272 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2275 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
2276 WL_DBG(("set auth_type to shared key\n"));
2277 val = WL_AUTH_SHARED_KEY; /* shared key */
2278 err = wldev_iovar_setint_bsscfg(dev, "auth", val, bssidx);
2279 if (unlikely(err)) {
2280 WL_ERR(("set auth failed (%d)\n", err));
2290 wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
2291 struct cfg80211_connect_params *sme)
2293 struct wl_priv *wl = wiphy_priv(wiphy);
2294 struct ieee80211_channel *chan = sme->channel;
2295 wl_extjoin_params_t *ext_join_params;
2296 struct wl_join_params join_params;
2297 size_t join_params_size;
2299 wpa_ie_fixed_t *wpa_ie;
2300 wpa_ie_fixed_t *wps_ie;
2306 u8 wpsie[IE_MAX_LEN];
2307 struct ether_addr bssid;
2313 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
2315 if (wl->scan_request) {
2316 wl_notify_escan_complete(wl, dev, true, true);
2319 bzero(&bssid, sizeof(bssid));
2320 wl_update_prof(wl, dev, NULL, (void *)&bssid, WL_PROF_BSSID);
2322 if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
2323 /* we only allow to connect using virtual interface in case of P2P */
2324 if (p2p_is_on(wl) && is_wps_conn(sme)) {
2325 WL_DBG(("ASSOC1 p2p index : %d sme->ie_len %d\n",
2326 wl_cfgp2p_find_idx(wl, dev), sme->ie_len));
2327 /* Have to apply WPS IE + P2P IE in assoc req frame */
2328 wl_cfgp2p_set_management_ie(wl, dev,
2329 wl_cfgp2p_find_idx(wl, dev), VNDR_IE_PRBREQ_FLAG,
2330 wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie,
2331 wl_to_p2p_bss_saved_ie(wl,
2332 P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
2333 wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
2334 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
2335 } else if (p2p_is_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
2336 /* This is the connect req after WPS is done [credentials exchanged]
2337 * currently identified with WPA_VERSION_2 .
2338 * Update the previously set IEs with
2339 * the newly received IEs from Supplicant. This will remove the WPS IE from
2342 WL_DBG(("ASSOC2 p2p index : %d sme->ie_len %d\n",
2343 wl_cfgp2p_find_idx(wl, dev), sme->ie_len));
2344 wl_cfgp2p_set_management_ie(wl, dev,
2345 wl_cfgp2p_find_idx(wl, dev), VNDR_IE_PRBREQ_FLAG,
2346 sme->ie, sme->ie_len);
2347 wl_cfgp2p_set_management_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
2348 VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
2351 } else if (dev == wl_to_prmry_ndev(wl)) {
2352 /* find the RSN_IE */
2353 if ((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len,
2354 DOT11_MNG_RSN_ID)) != NULL) {
2355 WL_DBG((" WPA2 IE is found\n"));
2357 /* find the WPA_IE */
2358 if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)sme->ie,
2359 sme->ie_len)) != NULL) {
2360 WL_DBG((" WPA IE is found\n"));
2362 if (wpa_ie != NULL || wpa2_ie != NULL) {
2363 wpaie = (wpa_ie != NULL) ? (u8 *)wpa_ie : (u8 *)wpa2_ie;
2364 wpaie_len = (wpa_ie != NULL) ? wpa_ie->length : wpa2_ie->len;
2365 wpaie_len += WPA_RSN_IE_TAG_FIXED_LEN;
2366 wldev_iovar_setbuf(dev, "wpaie", wpaie, wpaie_len,
2367 wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
2369 wldev_iovar_setbuf(dev, "wpaie", NULL, 0,
2370 wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
2373 /* find the WPSIE */
2374 memset(wpsie, 0, sizeof(wpsie));
2375 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)sme->ie,
2376 sme->ie_len)) != NULL) {
2377 wpsie_len = wps_ie->length +WPA_RSN_IE_TAG_FIXED_LEN;
2378 memcpy(wpsie, wps_ie, wpsie_len);
2382 err = wl_cfgp2p_set_management_ie(wl, dev, -1,
2383 VNDR_IE_ASSOCREQ_FLAG, wpsie, wpsie_len);
2384 if (unlikely(err)) {
2388 if (unlikely(!sme->ssid)) {
2389 WL_ERR(("Invalid ssid\n"));
2393 wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
2395 WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
2396 chan->center_freq));
2399 WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
2400 err = wl_set_wpa_version(dev, sme);
2401 if (unlikely(err)) {
2402 WL_ERR(("Invalid wpa_version\n"));
2406 err = wl_set_auth_type(dev, sme);
2407 if (unlikely(err)) {
2408 WL_ERR(("Invalid auth type\n"));
2412 err = wl_set_set_cipher(dev, sme);
2413 if (unlikely(err)) {
2414 WL_ERR(("Invalid ciper\n"));
2418 err = wl_set_key_mgmt(dev, sme);
2419 if (unlikely(err)) {
2420 WL_ERR(("Invalid key mgmt\n"));
2424 err = wl_set_set_sharedkey(dev, sme);
2425 if (unlikely(err)) {
2426 WL_ERR(("Invalid shared key\n"));
2431 * Join with specific BSSID and cached SSID
2432 * If SSID is zero join based on BSSID only
2434 join_params_size = WL_EXTJOIN_PARAMS_FIXED_SIZE +
2435 chan_cnt * sizeof(chanspec_t);
2436 ext_join_params = (wl_extjoin_params_t*)kzalloc(join_params_size, GFP_KERNEL);
2437 if (ext_join_params == NULL) {
2439 wl_clr_drv_status(wl, CONNECTING, dev);
2442 ext_join_params->ssid.SSID_len = min(sizeof(ext_join_params->ssid.SSID), sme->ssid_len);
2443 memcpy(&ext_join_params->ssid.SSID, sme->ssid, ext_join_params->ssid.SSID_len);
2444 ext_join_params->ssid.SSID_len = htod32(ext_join_params->ssid.SSID_len);
2445 /* Set up join scan parameters */
2446 ext_join_params->scan.scan_type = -1;
2447 ext_join_params->scan.nprobes = 2;
2448 /* increate dwell time to receive probe response or detect Beacon
2449 * from target AP at a noisy air only during connect command
2451 ext_join_params->scan.active_time = WL_SCAN_ACTIVE_TIME*3;
2452 ext_join_params->scan.passive_time = WL_SCAN_PASSIVE_TIME*3;
2453 ext_join_params->scan.home_time = -1;
2456 memcpy(&ext_join_params->assoc.bssid, sme->bssid, ETH_ALEN);
2458 memcpy(&ext_join_params->assoc.bssid, ðer_bcast, ETH_ALEN);
2459 ext_join_params->assoc.chanspec_num = chan_cnt;
2461 u16 channel, band, bw, ctl_sb;
2463 channel = wl->channel;
2464 band = (channel <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G
2465 : WL_CHANSPEC_BAND_5G;
2466 bw = WL_CHANSPEC_BW_20;
2467 ctl_sb = WL_CHANSPEC_CTL_SB_NONE;
2468 chspec = (channel | band | bw | ctl_sb);
2469 ext_join_params->assoc.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
2470 ext_join_params->assoc.chanspec_list[0] |= chspec;
2471 ext_join_params->assoc.chanspec_list[0] =
2472 htodchanspec(ext_join_params->assoc.chanspec_list[0]);
2474 ext_join_params->assoc.chanspec_num = htod32(ext_join_params->assoc.chanspec_num);
2475 if (ext_join_params->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
2476 WL_INFO(("ssid \"%s\", len (%d)\n", ext_join_params->ssid.SSID,
2477 ext_join_params->ssid.SSID_len));
2479 wl_set_drv_status(wl, CONNECTING, dev);
2480 err = wldev_iovar_setbuf_bsscfg(dev, "join", ext_join_params, join_params_size,
2481 wl->ioctl_buf, WLC_IOCTL_MAXLEN, wl_cfgp2p_find_idx(wl, dev), &wl->ioctl_buf_sync);
2482 kfree(ext_join_params);
2484 wl_clr_drv_status(wl, CONNECTING, dev);
2485 if (err == BCME_UNSUPPORTED) {
2486 WL_DBG(("join iovar is not supported\n"));
2489 WL_ERR(("error (%d)\n", err));
2494 memset(&join_params, 0, sizeof(join_params));
2495 join_params_size = sizeof(join_params.ssid);
2497 join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len);
2498 memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
2499 join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
2500 wl_update_prof(wl, dev, NULL, &join_params.ssid, WL_PROF_SSID);
2502 memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN);
2504 memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN);
2506 wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
2507 WL_DBG(("join_param_size %d\n", join_params_size));
2509 if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
2510 WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
2511 join_params.ssid.SSID_len));
2513 wl_set_drv_status(wl, CONNECTING, dev);
2514 err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, true);
2516 WL_ERR(("error (%d)\n", err));
2517 wl_clr_drv_status(wl, CONNECTING, dev);
2524 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
2527 struct wl_priv *wl = wiphy_priv(wiphy);
2532 WL_ERR(("Reason %d\n", reason_code));
2534 act = *(bool *) wl_read_prof(wl, dev, WL_PROF_ACT);
2535 curbssid = wl_read_prof(wl, dev, WL_PROF_BSSID);
2538 * Cancel ongoing scan to sync up with sme state machine of cfg80211.
2540 if (wl->scan_request) {
2541 wl_notify_escan_complete(wl, dev, true, true);
2543 wl_set_drv_status(wl, DISCONNECTING, dev);
2544 scbval.val = reason_code;
2545 memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
2546 scbval.val = htod32(scbval.val);
2547 err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
2548 sizeof(scb_val_t), true);
2549 if (unlikely(err)) {
2550 wl_clr_drv_status(wl, DISCONNECTING, dev);
2551 WL_ERR(("error (%d)\n", err));
2560 wl_cfg80211_set_tx_power(struct wiphy *wiphy,
2561 enum nl80211_tx_power_setting type, s32 dbm)
2564 struct wl_priv *wl = wiphy_priv(wiphy);
2565 struct net_device *ndev = wl_to_prmry_ndev(wl);
2572 case NL80211_TX_POWER_AUTOMATIC:
2574 case NL80211_TX_POWER_LIMITED:
2576 WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
2580 case NL80211_TX_POWER_FIXED:
2582 WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
2587 /* Make sure radio is off or on as far as software is concerned */
2588 disable = WL_RADIO_SW_DISABLE << 16;
2589 disable = htod32(disable);
2590 err = wldev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable), true);
2591 if (unlikely(err)) {
2592 WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
2599 txpwrmw = (u16) dbm;
2600 err = wldev_iovar_setint(ndev, "qtxpower",
2601 (s32) (bcm_mw_to_qdbm(txpwrmw)));
2602 if (unlikely(err)) {
2603 WL_ERR(("qtxpower error (%d)\n", err));
2606 wl->conf->tx_power = dbm;
2611 static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
2613 struct wl_priv *wl = wiphy_priv(wiphy);
2614 struct net_device *ndev = wl_to_prmry_ndev(wl);
2620 err = wldev_iovar_getint(ndev, "qtxpower", &txpwrdbm);
2621 if (unlikely(err)) {
2622 WL_ERR(("error (%d)\n", err));
2625 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
2626 *dbm = (s32) bcm_qdbm_to_mw(result);
2632 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
2633 u8 key_idx, bool unicast, bool multicast)
2635 struct wl_priv *wl = wiphy_priv(wiphy);
2639 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2641 WL_DBG(("key index (%d)\n", key_idx));
2643 err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2644 if (unlikely(err)) {
2645 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
2648 if (wsec & WEP_ENABLED) {
2649 /* Just select a new current key */
2650 index = (u32) key_idx;
2651 index = htod32(index);
2652 err = wldev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
2653 sizeof(index), true);
2654 if (unlikely(err)) {
2655 WL_ERR(("error (%d)\n", err));
2662 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
2663 u8 key_idx, const u8 *mac_addr, struct key_params *params)
2665 struct wl_priv *wl = wiphy_priv(wiphy);
2666 struct wl_wsec_key key;
2668 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2669 s32 mode = wl_get_mode_by_netdev(wl, dev);
2670 memset(&key, 0, sizeof(key));
2671 key.index = (u32) key_idx;
2673 if (!ETHER_ISMULTI(mac_addr))
2674 memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
2675 key.len = (u32) params->key_len;
2677 /* check for key index change */
2680 swap_key_from_BE(&key);
2681 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
2682 wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
2683 if (unlikely(err)) {
2684 WL_ERR(("key delete error (%d)\n", err));
2688 if (key.len > sizeof(key.data)) {
2689 WL_ERR(("Invalid key length (%d)\n", key.len));
2692 WL_DBG(("Setting the key index %d\n", key.index));
2693 memcpy(key.data, params->key, key.len);
2695 if ((mode == WL_MODE_BSS) &&
2696 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2698 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2699 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2700 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2703 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2704 if (params->seq && params->seq_len == 6) {
2707 ivptr = (u8 *) params->seq;
2708 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2709 (ivptr[3] << 8) | ivptr[2];
2710 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2711 key.iv_initialized = true;
2714 switch (params->cipher) {
2715 case WLAN_CIPHER_SUITE_WEP40:
2716 key.algo = CRYPTO_ALGO_WEP1;
2717 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2719 case WLAN_CIPHER_SUITE_WEP104:
2720 key.algo = CRYPTO_ALGO_WEP128;
2721 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2723 case WLAN_CIPHER_SUITE_TKIP:
2724 key.algo = CRYPTO_ALGO_TKIP;
2725 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2727 case WLAN_CIPHER_SUITE_AES_CMAC:
2728 key.algo = CRYPTO_ALGO_AES_CCM;
2729 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2731 case WLAN_CIPHER_SUITE_CCMP:
2732 key.algo = CRYPTO_ALGO_AES_CCM;
2733 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
2736 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
2739 swap_key_from_BE(&key);
2740 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key),
2741 wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
2742 if (unlikely(err)) {
2743 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2751 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
2752 u8 key_idx, bool pairwise, const u8 *mac_addr,
2753 struct key_params *params)
2755 struct wl_wsec_key key;
2761 struct wl_priv *wl = wiphy_priv(wiphy);
2762 s32 mode = wl_get_mode_by_netdev(wl, dev);
2763 WL_DBG(("key index (%d)\n", key_idx));
2766 bssidx = wl_cfgp2p_find_idx(wl, dev);
2769 wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
2772 memset(&key, 0, sizeof(key));
2774 key.len = (u32) params->key_len;
2775 key.index = (u32) key_idx;
2777 if (unlikely(key.len > sizeof(key.data))) {
2778 WL_ERR(("Too long key length (%u)\n", key.len));
2781 memcpy(key.data, params->key, key.len);
2783 key.flags = WL_PRIMARY_KEY;
2784 switch (params->cipher) {
2785 case WLAN_CIPHER_SUITE_WEP40:
2786 key.algo = CRYPTO_ALGO_WEP1;
2788 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2790 case WLAN_CIPHER_SUITE_WEP104:
2791 key.algo = CRYPTO_ALGO_WEP128;
2793 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2795 case WLAN_CIPHER_SUITE_TKIP:
2796 key.algo = CRYPTO_ALGO_TKIP;
2798 /* wpa_supplicant switches the third and fourth quarters of the TKIP key */
2799 if (mode == WL_MODE_BSS) {
2800 bcopy(&key.data[24], keybuf, sizeof(keybuf));
2801 bcopy(&key.data[16], &key.data[24], sizeof(keybuf));
2802 bcopy(keybuf, &key.data[16], sizeof(keybuf));
2804 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2806 case WLAN_CIPHER_SUITE_AES_CMAC:
2807 key.algo = CRYPTO_ALGO_AES_CCM;
2809 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2811 case WLAN_CIPHER_SUITE_CCMP:
2812 key.algo = CRYPTO_ALGO_AES_CCM;
2814 WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
2817 WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
2821 /* Set the new key/index */
2822 swap_key_from_BE(&key);
2823 err = wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf,
2824 WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
2825 if (unlikely(err)) {
2826 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2831 err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2832 if (unlikely(err)) {
2833 WL_ERR(("get wsec error (%d)\n", err));
2838 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
2839 if (unlikely(err)) {
2840 WL_ERR(("set wsec error (%d)\n", err));
2848 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
2849 u8 key_idx, bool pairwise, const u8 *mac_addr)
2851 struct wl_wsec_key key;
2852 struct wl_priv *wl = wiphy_priv(wiphy);
2854 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2856 WL_DBG(("Enter\n"));
2858 memset(&key, 0, sizeof(key));
2860 key.flags = WL_PRIMARY_KEY;
2861 key.algo = CRYPTO_ALGO_OFF;
2862 key.index = (u32) key_idx;
2864 WL_DBG(("key index (%d)\n", key_idx));
2865 /* Set the new key/index */
2866 swap_key_from_BE(&key);
2867 wldev_iovar_setbuf_bsscfg(dev, "wsec_key", &key, sizeof(key), wl->ioctl_buf,
2868 WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
2869 if (unlikely(err)) {
2870 if (err == -EINVAL) {
2871 if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
2872 /* we ignore this key index in this case */
2873 WL_DBG(("invalid key index (%d)\n", key_idx));
2876 WL_ERR(("WLC_SET_KEY error (%d)\n", err));
2884 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
2885 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2886 void (*callback) (void *cookie, struct key_params * params))
2888 struct key_params params;
2889 struct wl_wsec_key key;
2890 struct wl_priv *wl = wiphy_priv(wiphy);
2891 struct wl_security *sec;
2894 s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
2896 WL_DBG(("key index (%d)\n", key_idx));
2898 memset(&key, 0, sizeof(key));
2899 key.index = key_idx;
2900 swap_key_to_BE(&key);
2901 memset(¶ms, 0, sizeof(params));
2902 params.key_len = (u8) min_t(u8, DOT11_MAX_KEY_SIZE, key.len);
2903 memcpy(params.key, key.data, params.key_len);
2905 wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
2906 if (unlikely(err)) {
2907 WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
2910 switch (wsec & ~SES_OW_ENABLED) {
2912 sec = wl_read_prof(wl, dev, WL_PROF_SEC);
2913 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2914 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2915 WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
2916 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2917 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2918 WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
2922 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2923 WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
2926 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2927 WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
2930 WL_ERR(("Invalid algo (0x%x)\n", wsec));
2934 callback(cookie, ¶ms);
2939 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2940 struct net_device *dev, u8 key_idx)
2942 WL_INFO(("Not supported\n"));
2947 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
2948 u8 *mac, struct station_info *sinfo)
2950 struct wl_priv *wl = wiphy_priv(wiphy);
2956 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
2957 s8 eabuf[ETHER_ADDR_STR_LEN];
2959 dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
2962 if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
2963 err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac,
2964 ETHER_ADDR_LEN, wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync);
2966 WL_ERR(("GET STA INFO failed, %d\n", err));
2969 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2970 sta = (sta_info_t *)wl->ioctl_buf;
2971 sta->len = dtoh16(sta->len);
2972 sta->cap = dtoh16(sta->cap);
2973 sta->flags = dtoh32(sta->flags);
2974 sta->idle = dtoh32(sta->idle);
2975 sta->in = dtoh32(sta->in);
2976 sinfo->inactive_time = sta->idle * 1000;
2977 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)
2978 if (sta->flags & WL_STA_ASSOC) {
2979 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2980 sinfo->connected_time = sta->in;
2982 WL_INFO(("STA %s : idle time : %d sec, connected time :%d ms\n",
2983 bcm_ether_ntoa((const struct ether_addr *)mac, eabuf), sinfo->inactive_time,
2986 } else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
2987 u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
2989 if (!wl_get_drv_status(wl, CONNECTED, dev) ||
2990 (dhd_is_associated(dhd, NULL, &err) == FALSE)) {
2991 WL_ERR(("NOT assoc: %d\n", err));
2992 goto get_station_err;
2994 if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) {
2995 WL_ERR(("Wrong Mac address: "MACSTR" != "MACSTR"\n",
2996 MAC2STR(mac), MAC2STR(curmacp)));
2999 /* Report the current tx rate */
3000 err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
3002 WL_ERR(("Could not get rate (%d)\n", err));
3004 rate = dtoh32(rate);
3005 sinfo->filled |= STATION_INFO_TX_BITRATE;
3006 sinfo->txrate.legacy = rate * 5;
3007 WL_DBG(("Rate %d Mbps\n", (rate / 2)));
3010 memset(&scb_val, 0, sizeof(scb_val));
3012 err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
3013 sizeof(scb_val_t), false);
3015 WL_ERR(("Could not get rssi (%d)\n", err));
3016 goto get_station_err;
3018 rssi = dtoh32(scb_val.val);
3019 sinfo->filled |= STATION_INFO_SIGNAL;
3020 sinfo->signal = rssi;
3021 WL_DBG(("RSSI %d dBm\n", rssi));
3024 if (err && (err != -ETIMEDOUT) && (err != -EIO)) {
3025 /* Disconnect due to zero BSSID or error to get RSSI */
3026 WL_ERR(("force cfg80211_disconnected: %d\n", err));
3027 wl_clr_drv_status(wl, CONNECTED, dev);
3028 cfg80211_disconnected(dev, 0, NULL, 0, GFP_KERNEL);
3037 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
3038 bool enabled, s32 timeout)
3042 struct wl_priv *wl = wiphy_priv(wiphy);
3046 WL_DBG(("Enter : power save %s\n", (enabled ? "enable" : "disable")));
3047 if (wl->p2p_net == dev) {
3051 pm = enabled ? PM_FAST : PM_OFF;
3053 err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
3054 if (unlikely(err)) {
3056 WL_DBG(("net_device is not ready yet\n"));
3058 WL_ERR(("error (%d)\n", err));
3061 WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
3065 static __used u32 wl_find_msb(u16 bit16)
3069 if (bit16 & 0xff00) {
3092 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
3094 struct wl_priv *wl = wiphy_priv(wiphy);
3095 struct net_device *ndev = wl_to_prmry_ndev(wl);
3098 if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
3099 WL_INFO(("device is not ready\n"));
3103 wl_invoke_iscan(wl);
3108 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
3109 static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
3111 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
3114 #ifdef DHD_CLEAR_ON_SUSPEND
3115 struct wl_priv *wl = wiphy_priv(wiphy);
3116 struct net_info *iter, *next;
3117 struct net_device *ndev = wl_to_prmry_ndev(wl);
3118 unsigned long flags;
3120 if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
3121 WL_INFO(("device is not ready : status (%d)\n",
3125 for_each_ndev(wl, iter, next)
3126 wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev);
3128 spin_lock_irqsave(&wl->cfgdrv_lock, flags);
3129 if (wl->scan_request) {
3130 cfg80211_scan_done(wl->scan_request, true);
3131 wl->scan_request = NULL;
3133 for_each_ndev(wl, iter, next) {
3134 wl_clr_drv_status(wl, SCANNING, iter->ndev);
3135 wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev);
3137 spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
3138 for_each_ndev(wl, iter, next) {
3139 if (wl_get_drv_status(wl, CONNECTING, iter->ndev)) {
3140 wl_bss_connect_done(wl, iter->ndev, NULL, NULL, false);
3143 #endif /* DHD_CLEAR_ON_SUSPEND */
3148 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
3152 struct wl_priv *wl = wlcfg_drv_priv;
3153 struct net_device *primary_dev = wl_to_prmry_ndev(wl);
3156 printk("pmk_list is NULL\n");
3159 /* pmk list is supported only for STA interface i.e. primary interface
3160 * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
3162 if (primary_dev != dev) {
3163 WL_INFO(("Not supporting Flushing pmklist on virtual"
3164 " interfaces than primary interface\n"));
3168 WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
3169 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
3170 WL_DBG(("PMKID[%d]: %pM =\n", i,
3171 &pmk_list->pmkids.pmkid[i].BSSID));
3172 for (j = 0; j < WPA2_PMKID_LEN; j++) {
3173 WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
3177 err = wldev_iovar_setbuf(dev, "pmkid_info", (char *)pmk_list,
3178 sizeof(*pmk_list), wl->ioctl_buf, WLC_IOCTL_MAXLEN, NULL);
3185 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
3186 struct cfg80211_pmksa *pmksa)
3188 struct wl_priv *wl = wiphy_priv(wiphy);
3193 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
3194 if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
3197 if (i < WL_NUM_PMKIDS_MAX) {
3198 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid,
3200 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid,
3202 if (i == wl->pmk_list->pmkids.npmkid)
3203 wl->pmk_list->pmkids.npmkid++;
3207 WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3208 &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].BSSID));
3209 for (i = 0; i < WPA2_PMKID_LEN; i++) {
3211 wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].
3215 err = wl_update_pmklist(dev, wl->pmk_list, err);
3221 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
3222 struct cfg80211_pmksa *pmksa)
3224 struct wl_priv *wl = wiphy_priv(wiphy);
3225 struct _pmkid_list pmkid;
3230 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
3231 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
3233 WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3234 &pmkid.pmkid[0].BSSID));
3235 for (i = 0; i < WPA2_PMKID_LEN; i++) {
3236 WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
3239 for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
3241 (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
3245 if ((wl->pmk_list->pmkids.npmkid > 0) &&
3246 (i < wl->pmk_list->pmkids.npmkid)) {
3247 memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
3248 for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
3249 memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
3250 &wl->pmk_list->pmkids.pmkid[i + 1].BSSID,
3252 memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
3253 &wl->pmk_list->pmkids.pmkid[i + 1].PMKID,
3256 wl->pmk_list->pmkids.npmkid--;
3261 err = wl_update_pmklist(dev, wl->pmk_list, err);
3268 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
3270 struct wl_priv *wl = wiphy_priv(wiphy);
3273 memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
3274 err = wl_update_pmklist(dev, wl->pmk_list, err);
3279 static wl_scan_params_t *
3280 wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
3282 wl_scan_params_t *params;
3286 *out_params_size = 0;
3288 /* Our scan params only need space for 1 channel and 0 ssids */
3289 params_size = WL_SCAN_PARAMS_FIXED_SIZE + 1 * sizeof(uint16);
3290 params = (wl_scan_params_t*) kzalloc(params_size, GFP_KERNEL);
3291 if (params == NULL) {
3292 WL_ERR(("%s: mem alloc failed (%d bytes)\n", __func__, params_size));
3295 memset(params, 0, params_size);
3296 params->nprobes = nprobes;
3298 num_chans = (channel == 0) ? 0 : 1;
3300 memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN);
3301 params->bss_type = DOT11_BSSTYPE_ANY;
3302 params->scan_type = DOT11_SCANTYPE_ACTIVE;
3303 params->nprobes = htod32(1);
3304 params->active_time = htod32(-1);
3305 params->passive_time = htod32(-1);
3306 params->home_time = htod32(10);
3307 params->channel_list[0] = htodchanspec(channel);
3309 /* Our scan params have 1 channel and 0 ssids */
3310 params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
3311 (num_chans & WL_SCAN_PARAMS_COUNT_MASK));
3313 *out_params_size = params_size; /* rtn size to the caller */
3318 wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
3319 struct ieee80211_channel * channel,
3320 enum nl80211_channel_type channel_type,
3321 unsigned int duration, u64 *cookie)
3325 struct ether_addr primary_mac;
3326 struct net_device *ndev = NULL;
3329 struct wl_priv *wl = wiphy_priv(wiphy);
3330 WL_DBG(("Enter, netdev_ifidx: %d \n", dev->ifindex));
3332 if (wl->p2p_net == dev) {
3333 ndev = wl_to_prmry_ndev(wl);
3338 if (wl_get_drv_status(wl, SCANNING, ndev)) {
3339 wl_notify_escan_complete(wl, ndev, true, true);
3341 target_channel = ieee80211_frequency_to_channel(channel->center_freq);
3342 memcpy(&wl->remain_on_chan, channel, sizeof(struct ieee80211_channel));
3343 wl->remain_on_chan_type = channel_type;
3344 id = ++wl->last_roc_id;
3346 id = ++wl->last_roc_id;
3348 cfg80211_ready_on_channel(dev, *cookie, channel,
3349 channel_type, duration, GFP_KERNEL);
3350 if (wl->p2p && !wl->p2p->on) {
3351 get_primary_mac(wl, &primary_mac);
3352 wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
3354 /* In case of p2p_listen command, supplicant send remain_on_channel
3355 * without turning on P2P
3359 err = wl_cfgp2p_enable_discovery(wl, ndev, NULL, 0);
3361 if (unlikely(err)) {
3366 wl_cfgp2p_discover_listen(wl, target_channel, duration);
3374 wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
3378 WL_DBG((" enter ) netdev_ifidx: %d \n", dev->ifindex));
3383 wl_cfg80211_send_pending_tx_act_frm(struct wl_priv *wl)
3385 wl_af_params_t *tx_act_frm;
3386 struct net_device *dev = wl->afx_hdl->dev;
3390 if (dev == wl->p2p_net) {
3391 dev = wl_to_prmry_ndev(wl);
3394 tx_act_frm = wl->afx_hdl->pending_tx_act_frm;
3395 WL_DBG(("Sending the action frame\n"));
3396 wl->afx_hdl->pending_tx_act_frm = NULL;
3397 if (tx_act_frm != NULL) {
3398 /* Suspend P2P discovery's search-listen to prevent it from
3399 * starting a scan or changing the channel.
3401 wl_clr_drv_status(wl, SENDING_ACT_FRM, wl->afx_hdl->dev);
3402 wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
3403 wl_notify_escan_complete(wl, dev, true, true);
3404 wl_cfgp2p_discover_enable_search(wl, false);
3405 tx_act_frm->channel = wl->afx_hdl->peer_chan;
3406 wl->afx_hdl->ack_recv = (wl_cfgp2p_tx_action_frame(wl, dev,
3407 tx_act_frm, wl->afx_hdl->bssidx)) ? false : true;
3412 wl_cfg80211_afx_handler(struct work_struct *work)
3415 struct afx_hdl *afx_instance;
3416 struct wl_priv *wl = wlcfg_drv_priv;
3417 afx_instance = container_of(work, struct afx_hdl, work);
3418 if (afx_instance != NULL) {
3419 wl_cfgp2p_act_frm_search(wl, wl->afx_hdl->dev,
3420 wl->afx_hdl->bssidx, 0);
3425 wl_cfg80211_send_at_common_channel(struct wl_priv *wl,
3426 struct net_device *dev,
3427 wl_af_params_t *af_params)
3429 WL_DBG((" enter ) \n"));
3430 /* initialize afx_hdl */
3431 wl->afx_hdl->pending_tx_act_frm = af_params;
3432 wl->afx_hdl->bssidx = wl_cfgp2p_find_idx(wl, dev);
3433 wl->afx_hdl->dev = dev;
3434 wl->afx_hdl->retry = 0;
3435 wl->afx_hdl->peer_chan = WL_INVALID;
3436 wl->afx_hdl->ack_recv = false;
3437 memcpy(wl->afx_hdl->pending_tx_dst_addr.octet,
3438 af_params->action_frame.da.octet,
3439 sizeof(wl->afx_hdl->pending_tx_dst_addr.octet));
3440 /* Loop to wait until we have sent the pending tx action frame or the
3441 * pending action frame tx is cancelled.
3443 while ((wl->afx_hdl->retry < WL_CHANNEL_SYNC_RETRY) &&
3444 (wl->afx_hdl->peer_chan == WL_INVALID)) {
3445 wl_set_drv_status(wl, SENDING_ACT_FRM, dev);
3446 wl_set_drv_status(wl, SCANNING, dev);
3447 WL_DBG(("Scheduling the action frame for sending.. retry %d\n",
3448 wl->afx_hdl->retry));
3449 /* Do find_peer_for_action */
3450 schedule_work(&wl->afx_hdl->work);
3451 wait_for_completion(&wl->act_frm_scan);
3452 wl->afx_hdl->retry++;
3454 if (wl->afx_hdl->peer_chan != WL_INVALID)
3455 wl_cfg80211_send_pending_tx_act_frm(wl);
3457 WL_ERR(("Couldn't find the peer " MACSTR " after %d retries\n",
3458 MAC2STR(wl->afx_hdl->pending_tx_dst_addr.octet), wl->afx_hdl->retry));
3460 wl->afx_hdl->dev = NULL;
3461 wl->afx_hdl->bssidx = WL_INVALID;
3462 wl_clr_drv_status(wl, SENDING_ACT_FRM, dev);
3463 if (wl->afx_hdl->ack_recv)
3464 return true; /* ACK */
3466 return false; /* NO ACK */
3470 wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
3471 struct ieee80211_channel *channel, bool offchan,
3472 enum nl80211_channel_type channel_type,
3473 bool channel_type_valid, unsigned int wait,
3474 const u8* buf, size_t len,
3475 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
3480 wl_action_frame_t *action_frame;
3481 wl_af_params_t *af_params;
3482 wifi_p2p_ie_t *p2p_ie;
3483 wpa_ie_fixed_t *wps_ie;
3485 const struct ieee80211_mgmt *mgmt;
3486 struct wl_priv *wl = wiphy_priv(wiphy);
3487 struct net_device *dev = NULL;
3495 wifi_p2p_pub_act_frame_t *act_frm = NULL;
3496 wifi_p2p_action_frame_t *p2p_act_frm = NULL;
3497 wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL;
3498 s8 eabuf[ETHER_ADDR_STR_LEN];
3501 WL_DBG(("Enter \n"));
3503 if (ndev == wl->p2p_net) {
3504 dev = wl_to_prmry_ndev(wl);
3506 /* If TX req is for any valid ifidx. Use as is */
3510 /* find bssidx based on ndev */
3511 bssidx = wl_cfgp2p_find_idx(wl, dev);
3514 WL_ERR(("Can not find the bssidx for dev( %p )\n", dev));
3517 if (p2p_is_on(wl)) {
3518 /* Suspend P2P discovery search-listen to prevent it from changing the
3521 if ((err = wl_cfgp2p_discover_enable_search(wl, false)) < 0) {
3522 WL_ERR(("Can not disable discovery mode\n"));
3527 id = wl->send_action_id++;
3529 id = wl->send_action_id++;
3531 mgmt = (const struct ieee80211_mgmt *)buf;
3532 if (ieee80211_is_mgmt(mgmt->frame_control)) {
3533 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
3534 s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3535 s32 ie_len = len - ie_offset;
3536 if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)(buf + ie_offset), ie_len))
3538 /* Total length of P2P Information Element */
3539 p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
3541 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len))
3543 /* Order of Vendor IE is 1) WPS IE +
3544 * 2) P2P IE created by supplicant
3545 * So, it is ok to find start address of WPS IE
3548 wpsie_len = wps_ie->length + sizeof(wps_ie->length) +
3549 sizeof(wps_ie->tag);
3550 wl_cfgp2p_set_management_ie(wl, dev, bssidx,
3551 VNDR_IE_PRBRSP_FLAG,
3552 (u8 *)wps_ie, wpsie_len + p2pie_len);
3554 cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
3556 } else if (ieee80211_is_disassoc(mgmt->frame_control) ||
3557 ieee80211_is_deauth(mgmt->frame_control)) {
3558 memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN);
3559 scb_val.val = mgmt->u.disassoc.reason_code;
3560 wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
3561 sizeof(scb_val_t), true);
3562 WL_DBG(("Disconnect STA : %s scb_val.val %d\n",
3563 bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf),
3565 /* Wait for the deauth event to come, supplicant will do the
3566 * delete iface immediately and we will have problem in sending
3567 * deauth frame if we delete the bss in firmware
3570 cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
3573 } else if (ieee80211_is_action(mgmt->frame_control)) {
3574 /* Abort the dwell time of any previous off-channel
3575 * action frame that may be still in effect. Sending
3576 * off-channel action frames relies on the driver's
3577 * scan engine. If a previous off-channel action frame
3578 * tx is still in progress (including the dwell time),
3579 * then this new action frame will not be sent out.
3581 wl_notify_escan_complete(wl, dev, true, true);
3586 WL_ERR(("Driver only allows MGMT packet type\n"));
3590 af_params = (wl_af_params_t *) kzalloc(WL_WIFI_AF_PARAMS_SIZE, GFP_KERNEL);
3592 if (af_params == NULL)
3594 WL_ERR(("unable to allocate frame\n"));
3598 action_frame = &af_params->action_frame;
3600 /* Add the packet Id */
3601 action_frame->packetId = *cookie;
3602 WL_DBG(("action frame %d\n", action_frame->packetId));
3604 memcpy(&action_frame->da, &mgmt->da[0], ETHER_ADDR_LEN);
3605 memcpy(&af_params->BSSID, &mgmt->bssid[0], ETHER_ADDR_LEN);
3607 /* Add the length exepted for 802.11 header */
3608 action_frame->len = len - DOT11_MGMT_HDR_LEN;
3609 WL_DBG(("action_frame->len: %d\n", action_frame->len));
3611 /* Add the channel */
3612 af_params->channel =
3613 ieee80211_frequency_to_channel(channel->center_freq);
3615 if (channel->band == IEEE80211_BAND_5GHZ) {
3616 WL_DBG(("5GHz channel %d", af_params->channel));
3617 err = wldev_ioctl(dev, WLC_SET_CHANNEL,
3618 &af_params->channel, sizeof(af_params->channel), true);
3620 WL_ERR(("WLC_SET_CHANNEL error %d\n", err));
3624 /* Add the dwell time
3625 * Dwell time to stay off-channel to wait for a response action frame
3626 * after transmitting an GO Negotiation action frame
3628 af_params->dwell_time = WL_DWELL_TIME;
3630 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
3631 if (wl_cfgp2p_is_pub_action(action_frame->data, action_frame->len)) {
3632 act_frm = (wifi_p2p_pub_act_frame_t *) (action_frame->data);
3633 WL_DBG(("P2P PUB action_frame->len: %d chan %d category %d subtype %d\n",
3634 action_frame->len, af_params->channel,
3635 act_frm->category, act_frm->subtype));
3636 if (act_frm && ((act_frm->subtype == P2P_PAF_GON_REQ) ||
3637 (act_frm->subtype == P2P_PAF_GON_RSP) ||
3638 (act_frm->subtype == P2P_PAF_GON_CONF) ||
3639 (act_frm->subtype == P2P_PAF_PROVDIS_REQ))) {
3640 wldev_iovar_setint(dev, "mpc", 0);
3643 if (act_frm->subtype == P2P_PAF_GON_REQ) {
3644 WL_DBG(("P2P: GO_NEG_PHASE status set \n"));
3645 wl_set_p2p_status(wl, GO_NEG_PHASE);
3646 } else if (act_frm->subtype == P2P_PAF_GON_CONF) {
3647 /* If we reached till GO Neg confirmation
3650 WL_DBG(("P2P: GO_NEG_PHASE status cleared \n"));
3651 wl_clr_p2p_status(wl, GO_NEG_PHASE);
3654 if (act_frm->subtype == P2P_PAF_GON_RSP)
3656 else retry_cnt = WL_ACT_FRAME_RETRY;
3658 if (act_frm && act_frm->subtype == P2P_PAF_DEVDIS_REQ) {
3659 af_params->dwell_time = WL_LONG_DWELL_TIME;
3660 } else if (act_frm &&
3661 (act_frm->subtype == P2P_PAF_PROVDIS_REQ ||
3662 act_frm->subtype == P2P_PAF_PROVDIS_RSP ||
3663 act_frm->subtype == P2P_PAF_GON_RSP)) {
3664 af_params->dwell_time = WL_MED_DWELL_TIME;
3666 } else if (wl_cfgp2p_is_p2p_action(action_frame->data, action_frame->len)) {
3667 p2p_act_frm = (wifi_p2p_action_frame_t *) (action_frame->data);
3668 WL_DBG(("P2P action_frame->len: %d chan %d category %d subtype %d\n",
3669 action_frame->len, af_params->channel,
3670 p2p_act_frm->category, p2p_act_frm->subtype));
3671 } else if (wl_cfgp2p_is_gas_action(action_frame->data, action_frame->len)) {
3672 sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *) (action_frame->data);
3673 WL_DBG(("Service Discovery action_frame->len: %d chan %d category %d action %d\n",
3674 action_frame->len, af_params->channel,
3675 sd_act_frm->category, sd_act_frm->action));
3676 af_params->dwell_time = WL_MED_DWELL_TIME;
3677 retry_cnt = WL_ACT_FRAME_RETRY;
3679 wl_cfgp2p_print_actframe(true, action_frame->data, action_frame->len);
3681 * To make sure to send successfully action frame, we have to turn off mpc
3683 if (IS_P2P_SOCIAL(af_params->channel) &&
3684 (IS_P2P_PUB_ACT_REQ(act_frm, &act_frm->elts[0], action_frame->len) ||
3685 IS_GAS_REQ(sd_act_frm, action_frame->len)) &&
3686 wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) {
3687 /* channel offload require P2P IE for Probe request
3688 * otherwise, we will use wl_cfgp2p_tx_action_frame directly.
3689 * channel offload for action request frame
3692 /* channel offload for action request frame */
3693 ack = wl_cfg80211_send_at_common_channel(wl, dev, af_params);
3694 /* We need to retry Service discovery frames as they don't get retried immediately by supplicant*/
3695 if ((!ack) && (IS_GAS_REQ(sd_act_frm, action_frame->len))) {
3696 for (retry = 1; retry < retry_cnt; retry++) {
3697 WL_DBG(("Service Discovery action_frame retry %d len: %d chan %d category %d action %d\n",
3698 retry, action_frame->len, af_params->channel,
3699 sd_act_frm->category, sd_act_frm->action));
3700 ack = (wl_cfgp2p_tx_action_frame(wl, dev,
3701 af_params, bssidx)) ? false : true;
3707 ack = (wl_cfgp2p_tx_action_frame(wl, dev, af_params, bssidx)) ? false : true;
3709 for (retry = 1; retry < retry_cnt; retry++) {
3710 ack = (wl_cfgp2p_tx_action_frame(wl, dev,
3711 af_params, bssidx)) ? false : true;
3718 cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
3719 if (act_frm && act_frm->subtype == P2P_PAF_GON_CONF) {
3720 wldev_iovar_setint(dev, "mpc", 1);
3729 wl_cfg80211_mgmt_frame_register(struct wiphy *wiphy, struct net_device *dev,
3730 u16 frame_type, bool reg)
3733 WL_DBG(("%s: frame_type: %x, reg: %d\n", __func__, frame_type, reg));
3735 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3743 wl_cfg80211_change_bss(struct wiphy *wiphy,
3744 struct net_device *dev,
3745 struct bss_parameters *params)
3747 if (params->use_cts_prot >= 0) {
3750 if (params->use_short_preamble >= 0) {
3753 if (params->use_short_slot_time >= 0) {
3756 if (params->basic_rates) {
3759 if (params->ap_isolate >= 0) {
3762 if (params->ht_opmode >= 0) {
3769 wl_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
3770 struct ieee80211_channel *chan,
3771 enum nl80211_channel_type channel_type)
3775 struct wl_priv *wl = wiphy_priv(wiphy);
3777 if (wl->p2p_net == dev) {
3778 dev = wl_to_prmry_ndev(wl);
3780 channel = ieee80211_frequency_to_channel(chan->center_freq);
3782 if (wl_get_drv_status(wl, AP_CREATING, dev)) {
3783 WL_TRACE(("<0> %s: as!!! in AP creating mode, save chan num:%d\n",
3784 __FUNCTION__, channel));
3785 wl->hostapd_chan = channel;
3787 return err; /* hostapd requested ch auto-select, will be done later */
3790 WL_DBG(("netdev_ifidx(%d), chan_type(%d) target channel(%d) \n",
3791 dev->ifindex, channel_type, channel));
3792 err = wldev_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel), true);
3794 WL_ERR(("WLC_SET_CHANNEL error %d chip may not be supporting this channel\n", err));
3800 wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
3804 u16 auth = WL_AUTH_OPEN_SYSTEM; /* d11 open authentication */
3810 wpa_suite_mcast_t *mcast;
3811 wpa_suite_ucast_t *ucast;
3812 wpa_suite_auth_key_mgmt_t *mgmt;
3816 WL_DBG(("Enter \n"));
3818 /* check the mcast cipher */
3819 mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN];
3821 switch (tmp[DOT11_OUI_LEN]) {
3822 case WPA_CIPHER_NONE:
3825 case WPA_CIPHER_WEP_40:
3826 case WPA_CIPHER_WEP_104:
3829 case WPA_CIPHER_TKIP:
3830 gval = TKIP_ENABLED;
3832 case WPA_CIPHER_AES_CCM:
3836 WL_ERR(("No Security Info\n"));
3839 len -= WPA_SUITE_LEN;
3840 /* check the unicast cipher */
3841 ucast = (wpa_suite_ucast_t *)&mcast[1];
3842 ltoh16_ua(&ucast->count);
3843 tmp = ucast->list[0].oui;
3844 switch (tmp[DOT11_OUI_LEN]) {
3845 case WPA_CIPHER_NONE:
3848 case WPA_CIPHER_WEP_40:
3849 case WPA_CIPHER_WEP_104:
3852 case WPA_CIPHER_TKIP:
3853 pval = TKIP_ENABLED;
3855 case WPA_CIPHER_AES_CCM:
3859 WL_ERR(("No Security Info\n"));
3861 /* FOR WPS , set SEC_OW_ENABLED */
3862 wsec = (pval | gval | SES_OW_ENABLED);
3864 mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[1];
3865 ltoh16_ua(&mgmt->count);
3866 tmp = (u8 *)&mgmt->list[0];
3867 switch (tmp[DOT11_OUI_LEN]) {
3869 wpa_auth = WPA_AUTH_NONE;
3871 case RSN_AKM_UNSPECIFIED:
3872 wpa_auth = WPA2_AUTH_UNSPECIFIED;
3875 wpa_auth = WPA2_AUTH_PSK;
3878 WL_ERR(("No Key Mgmt Info\n"));
3881 err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
3883 WL_ERR(("auth error %d\n", err));
3887 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
3889 WL_ERR(("wsec error %d\n", err));
3892 /* set upper-layer auth */
3893 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
3895 WL_ERR(("wpa_auth error %d\n", err));
3903 wl_validate_wpaie(struct net_device *dev, wpa_ie_fixed_t *wpaie, s32 bssidx)
3905 wpa_suite_mcast_t *mcast;
3906 wpa_suite_ucast_t *ucast;
3907 wpa_suite_auth_key_mgmt_t *mgmt;
3908 u16 auth = WL_AUTH_OPEN_SYSTEM; /* d11 open authentication */
3921 WL_DBG(("Enter \n"));
3922 len = wpaie->length; /* value length */
3923 len -= WPA_IE_TAG_FIXED_LEN;
3924 /* check for multicast cipher suite */
3925 if (len < WPA_SUITE_LEN) {
3926 WL_INFO(("no multicast cipher suite\n"));
3930 /* pick up multicast cipher */
3931 mcast = (wpa_suite_mcast_t *)&wpaie[1];
3932 len -= WPA_SUITE_LEN;
3933 if (!bcmp(mcast->oui, WPA_OUI, WPA_OUI_LEN)) {
3934 if (IS_WPA_CIPHER(mcast->type)) {
3936 switch (mcast->type) {
3937 case WPA_CIPHER_NONE:
3940 case WPA_CIPHER_WEP_40:
3941 case WPA_CIPHER_WEP_104:
3944 case WPA_CIPHER_TKIP:
3947 case WPA_CIPHER_AES_CCM:
3951 WL_ERR(("No Security Info\n"));
3956 /* Check for unicast suite(s) */
3957 if (len < WPA_IE_SUITE_COUNT_LEN) {
3958 WL_INFO(("no unicast suite\n"));
3961 /* walk thru unicast cipher list and pick up what we recognize */
3962 ucast = (wpa_suite_ucast_t *)&mcast[1];
3963 count = ltoh16_ua(&ucast->count);
3964 len -= WPA_IE_SUITE_COUNT_LEN;
3965 for (i = 0; i < count && len >= WPA_SUITE_LEN;
3966 i++, len -= WPA_SUITE_LEN) {
3967 if (!bcmp(ucast->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
3968 if (IS_WPA_CIPHER(ucast->list[i].type)) {
3970 switch (ucast->list[i].type) {
3971 case WPA_CIPHER_NONE:
3974 case WPA_CIPHER_WEP_40:
3975 case WPA_CIPHER_WEP_104:
3978 case WPA_CIPHER_TKIP:
3981 case WPA_CIPHER_AES_CCM:
3985 WL_ERR(("No Security Info\n"));
3991 len -= (count - i) * WPA_SUITE_LEN;
3992 /* Check for auth key management suite(s) */
3993 if (len < WPA_IE_SUITE_COUNT_LEN) {
3994 WL_INFO((" no auth key mgmt suite\n"));
3997 /* walk thru auth management suite list and pick up what we recognize */
3998 mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[count];
3999 count = ltoh16_ua(&mgmt->count);
4000 len -= WPA_IE_SUITE_COUNT_LEN;
4001 for (i = 0; i < count && len >= WPA_SUITE_LEN;
4002 i++, len -= WPA_SUITE_LEN) {
4003 if (!bcmp(mgmt->list[i].oui, WPA_OUI, WPA_OUI_LEN)) {
4004 if (IS_WPA_AKM(mgmt->list[i].type)) {
4006 switch (mgmt->list[i].type) {
4008 tmp = WPA_AUTH_NONE;
4010 case RSN_AKM_UNSPECIFIED:
4011 tmp = WPA_AUTH_UNSPECIFIED;
4017 WL_ERR(("No Key Mgmt Info\n"));
4024 /* FOR WPS , set SEC_OW_ENABLED */
4025 wsec = (pval | gval | SES_OW_ENABLED);
4027 err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx);
4029 WL_ERR(("auth error %d\n", err));
4033 err = wldev_iovar_setint_bsscfg(dev, "wsec", wsec, bssidx);
4035 WL_ERR(("wsec error %d\n", err));
4038 /* set upper-layer auth */
4039 err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx);
4041 WL_ERR(("wpa_auth error %d\n", err));
4049 wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
4050 struct beacon_parameters *info)
4055 struct wl_priv *wl = wiphy_priv(wiphy);
4056 struct wl_join_params join_params;
4057 wpa_ie_fixed_t *wps_ie;
4058 wpa_ie_fixed_t *wpa_ie;
4060 wifi_p2p_ie_t *p2p_ie;
4061 bool is_bssup = false;
4062 bool update_bss = false;
4066 u8 beacon_ie[IE_MAX_LEN];
4070 s32 join_params_size = 0;
4072 WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
4073 info->interval, info->dtim_period, info->head_len, info->tail_len));
4075 if (wl->p2p_net == dev) {
4076 dev = wl_to_prmry_ndev(wl);
4079 bssidx = wl_cfgp2p_find_idx(wl, dev);
4080 if (p2p_is_on(wl) &&
4081 (bssidx == wl_to_p2p_bss_bssidx(wl,
4082 P2PAPI_BSSCFG_CONNECTION))) {
4083 memset(beacon_ie, 0, sizeof(beacon_ie));
4084 /* We don't need to set beacon for P2P_GO,
4085 * but need to parse ssid from beacon_parameters
4086 * because there is no way to set ssid
4088 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4090 if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
4091 info->head_len - ie_offset,
4092 DOT11_MNG_SSID_ID)) != NULL) {
4093 memcpy(wl->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len);
4094 wl->p2p->ssid.SSID_len = ssid_ie->len;
4095 WL_DBG(("SSID (%s) in Head \n", ssid_ie->data));
4098 WL_ERR(("No SSID in beacon \n"));
4101 /* find the WPSIE */
4102 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
4103 wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
4105 * Should be compared with saved ie before saving it
4107 wl_validate_wps_ie((char *) wps_ie, &pbc);
4108 memcpy(beacon_ie, wps_ie, wpsie_len);
4110 WL_ERR(("No WPSIE in beacon \n"));
4114 /* find the P2PIE */
4115 if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)info->tail, info->tail_len)) != NULL) {
4116 /* Total length of P2P Information Element */
4117 p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
4118 memcpy(&beacon_ie[wpsie_len], p2p_ie, p2pie_len);
4121 WL_ERR(("No P2PIE in beacon \n"));
4123 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
4124 wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
4125 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
4126 beacon_ie, wpsie_len + p2pie_len);
4128 /* find the RSN_IE */
4129 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
4130 DOT11_MNG_RSN_ID)) != NULL) {
4131 WL_DBG((" WPA2 IE is found\n"));
4133 is_bssup = wl_cfgp2p_bss_isup(dev, bssidx);
4135 if (!is_bssup && (wpa2_ie != NULL)) {
4136 wldev_iovar_setint(dev, "mpc", 0);
4137 if ((err = wl_validate_wpa2ie(dev, wpa2_ie, bssidx)) < 0) {
4138 WL_ERR(("WPA2 IE parsing error"));
4141 err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
4143 WL_ERR(("SET INFRA error %d\n", err));
4146 err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p->ssid,
4147 sizeof(wl->p2p->ssid), wl->ioctl_buf, WLC_IOCTL_MAXLEN,
4148 bssidx, &wl->ioctl_buf_sync);
4150 WL_ERR(("GO SSID setting error %d\n", err));
4153 if ((err = wl_cfgp2p_bss(wl, dev, bssidx, 1)) < 0) {
4154 WL_ERR(("GO Bring up error %d\n", err));
4158 } else if (wl_get_drv_status(wl, AP_CREATING, dev)) {
4159 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4162 if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
4163 info->head_len - ie_offset,
4164 DOT11_MNG_SSID_ID)) != NULL) {
4165 memset(&ssid, 0, sizeof(wlc_ssid_t));
4166 memcpy(ssid.SSID, ssid_ie->data, ssid_ie->len);
4167 WL_DBG(("SSID is (%s) in Head \n", ssid.SSID));
4168 ssid.SSID_len = ssid_ie->len;
4169 wldev_iovar_setint(dev, "mpc", 0);
4170 wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), true);
4171 wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true);
4172 if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) {
4173 WL_ERR(("setting AP mode failed %d \n", err));
4177 /* if requested, do softap ch autoselect */
4178 if (wl->hostapd_chan == 14) {
4180 if ((err = wldev_get_auto_channel(dev, &auto_chan)) != 0) {
4181 WL_ERR(("softap: auto chan select failed,"
4182 " will use ch 6\n"));
4185 printf("<0>softap: got auto ch:%d\n", auto_chan);
4187 err = wldev_ioctl(dev, WLC_SET_CHANNEL,
4188 &auto_chan, sizeof(auto_chan), true);
4190 WL_ERR(("softap: WLC_SET_CHANNEL error %d chip"
4191 " may not be supporting this channel\n", err));
4196 /* find the RSN_IE */
4197 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
4198 DOT11_MNG_RSN_ID)) != NULL) {
4199 WL_DBG((" WPA2 IE is found\n"));
4201 /* find the WPA_IE */
4202 if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail,
4203 info->tail_len)) != NULL) {
4204 WL_DBG((" WPA IE is found\n"));
4206 if ((wpa_ie != NULL || wpa2_ie != NULL)) {
4207 if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 ||
4208 wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
4209 wl->ap_info->security_mode = false;
4212 wl->ap_info->security_mode = true;
4213 if (wl->ap_info->rsn_ie) {
4214 kfree(wl->ap_info->rsn_ie);
4215 wl->ap_info->rsn_ie = NULL;
4217 if (wl->ap_info->wpa_ie) {
4218 kfree(wl->ap_info->wpa_ie);
4219 wl->ap_info->wpa_ie = NULL;
4221 if (wl->ap_info->wps_ie) {
4222 kfree(wl->ap_info->wps_ie);
4223 wl->ap_info->wps_ie = NULL;
4225 if (wpa_ie != NULL) {
4227 wl->ap_info->rsn_ie = NULL;
4228 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
4229 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
4233 wl->ap_info->wpa_ie = NULL;
4234 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
4235 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
4239 wl->ap_info->security_mode = false;
4240 /* find the WPSIE */
4241 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail,
4242 info->tail_len)) != NULL) {
4243 wpsie_len = wps_ie->length +WPA_RSN_IE_TAG_FIXED_LEN;
4245 * Should be compared with saved ie before saving it
4247 wl_validate_wps_ie((char *) wps_ie, &pbc);
4248 memcpy(beacon_ie, wps_ie, wpsie_len);
4249 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
4250 beacon_ie, wpsie_len);
4251 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
4252 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
4253 wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
4255 WL_DBG(("No WPSIE in beacon \n"));
4257 if (info->interval) {
4258 if ((err = wldev_ioctl(dev, WLC_SET_BCNPRD,
4259 &info->interval, sizeof(s32), true)) < 0) {
4260 WL_ERR(("Beacon Interval Set Error, %d\n", err));
4264 if (info->dtim_period) {
4265 if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD,
4266 &info->dtim_period, sizeof(s32), true)) < 0) {
4267 WL_ERR(("DTIM Interval Set Error, %d\n", err));
4271 err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true);
4272 if (unlikely(err)) {
4273 WL_ERR(("WLC_UP error (%d)\n", err));
4276 memset(&join_params, 0, sizeof(join_params));
4277 /* join parameters starts with ssid */
4278 join_params_size = sizeof(join_params.ssid);
4279 memcpy(join_params.ssid.SSID, ssid.SSID, ssid.SSID_len);
4280 join_params.ssid.SSID_len = htod32(ssid.SSID_len);
4282 if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params,
4283 join_params_size, true)) == 0) {
4284 wl_clr_drv_status(wl, AP_CREATING, dev);
4285 wl_set_drv_status(wl, AP_CREATED, dev);
4288 } else if (wl_get_drv_status(wl, AP_CREATED, dev)) {
4290 /* find the WPSIE */
4291 if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)info->tail, info->tail_len)) != NULL) {
4292 wpsie_len = wps_ie->length + WPA_RSN_IE_TAG_FIXED_LEN;
4294 * Should be compared with saved ie before saving it
4296 wl_validate_wps_ie((char *) wps_ie, &pbc);
4297 memcpy(beacon_ie, wps_ie, wpsie_len);
4298 wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
4299 beacon_ie, wpsie_len);
4300 if (wl->ap_info->wps_ie &&
4301 memcmp(wl->ap_info->wps_ie, wps_ie, wpsie_len)) {
4302 WL_DBG((" WPS IE is changed\n"));
4303 kfree(wl->ap_info->wps_ie);
4304 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
4305 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
4306 wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
4307 } else if (wl->ap_info->wps_ie == NULL) {
4308 WL_DBG((" WPS IE is added\n"));
4309 wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
4310 /* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
4311 wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
4313 /* find the RSN_IE */
4314 if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
4315 DOT11_MNG_RSN_ID)) != NULL) {
4316 WL_DBG((" WPA2 IE is found\n"));
4318 /* find the WPA_IE */
4319 if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)info->tail,
4320 info->tail_len)) != NULL) {
4321 WL_DBG((" WPA IE is found\n"));
4323 if ((wpa_ie != NULL || wpa2_ie != NULL)) {
4324 if (!wl->ap_info->security_mode) {
4325 /* change from open mode to security mode */
4327 if (wpa_ie != NULL) {
4328 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
4329 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
4332 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
4333 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
4336 } else if (wl->ap_info->wpa_ie) {
4337 /* change from WPA mode to WPA2 mode */
4338 if (wpa2_ie != NULL) {
4340 kfree(wl->ap_info->wpa_ie);
4341 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
4342 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
4344 wl->ap_info->wpa_ie = NULL;
4346 else if (memcmp(wl->ap_info->wpa_ie,
4347 wpa_ie, wpa_ie->length +
4348 WPA_RSN_IE_TAG_FIXED_LEN)) {
4349 kfree(wl->ap_info->wpa_ie);
4351 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
4352 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
4354 wl->ap_info->rsn_ie = NULL;
4357 /* change from WPA2 mode to WPA mode */
4358 if (wpa_ie != NULL) {
4360 kfree(wl->ap_info->rsn_ie);
4361 wl->ap_info->rsn_ie = NULL;
4362 wl->ap_info->wpa_ie = kmemdup(wpa_ie,
4363 wpa_ie->length + WPA_RSN_IE_TAG_FIXED_LEN,
4365 } else if (memcmp(wl->ap_info->rsn_ie,
4366 wpa2_ie, wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN)) {
4368 kfree(wl->ap_info->rsn_ie);
4369 wl->ap_info->rsn_ie = kmemdup(wpa2_ie,
4370 wpa2_ie->len + WPA_RSN_IE_TAG_FIXED_LEN,
4372 wl->ap_info->wpa_ie = NULL;
4376 wl->ap_info->security_mode = true;
4377 wl_cfgp2p_bss(wl, dev, bssidx, 0);
4378 if (wl_validate_wpa2ie(dev, wpa2_ie, bssidx) < 0 ||
4379 wl_validate_wpaie(dev, wpa_ie, bssidx) < 0) {
4382 wl_cfgp2p_bss(wl, dev, bssidx, 1);
4386 WL_ERR(("No WPSIE in beacon \n"));
4391 wldev_iovar_setint(dev, "mpc", 1);
4395 #ifdef WL_SCHED_SCAN
4397 #define PNO_REPEAT 4
4398 #define PNO_FREQ_EXPO_MAX 2
4399 int wl_cfg80211_sched_scan_start(struct wiphy *wiphy,
4400 struct net_device *dev,
4401 struct cfg80211_sched_scan_request *request)
4403 ushort pno_time = PNO_TIME;
4404 int pno_repeat = PNO_REPEAT;
4405 int pno_freq_expo_max = PNO_FREQ_EXPO_MAX;
4406 wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
4407 struct wl_priv *wl = wiphy_priv(wiphy);
4408 struct cfg80211_ssid *ssid = NULL;
4413 WL_DBG(("Enter n_match_sets:%d n_ssids:%d \n",
4414 request->n_match_sets, request->n_ssids));
4415 WL_DBG(("ssids:%d pno_time:%d pno_repeat:%d pno_freq:%d \n",
4416 request->n_ssids, pno_time, pno_repeat, pno_freq_expo_max));
4418 #if defined(WL_ENABLE_P2P_IF)
4419 /* While GO is operational, PNO is not supported */
4420 if (dhd_cfg80211_get_opmode(wl) & P2P_GO_ENABLED) {
4421 WL_DBG(("PNO not enabled! op_mode: P2P GO"));
4426 if (!request || !request->n_ssids || !request->n_match_sets) {
4427 WL_ERR(("Invalid sched scan req!! n_ssids:%d \n", request->n_ssids));
4431 memset(&ssids_local, 0, sizeof(ssids_local));
4433 if (request->n_match_sets > 0) {
4434 for (i = 0; i < request->n_match_sets; i++) {
4435 ssid = &request->match_sets[i].ssid;
4436 memcpy(ssids_local[i].SSID, ssid->ssid, ssid->ssid_len);
4437 ssids_local[i].SSID_len = ssid->ssid_len;
4438 WL_DBG((">>> PNO filter set for ssid (%s) \n", ssid->ssid));
4443 if (request->n_ssids > 0) {
4444 for (i = 0; i < request->n_ssids; i++) {
4445 /* Active scan req for ssids */
4446 WL_DBG((">>> Active scan req for ssid (%s) \n", request->ssids[i].ssid));
4448 /* match_set ssids is a supert set of n_ssid list, so we need
4449 * not add these set seperately
4455 if ((ret = dhd_dev_pno_set(dev, ssids_local, request->n_match_sets,
4456 pno_time, pno_repeat, pno_freq_expo_max)) < 0) {
4457 WL_ERR(("PNO setup failed!! ret=%d \n", ret));
4461 /* Enable the PNO */
4462 if (dhd_dev_pno_enable(dev, 1) < 0) {
4463 WL_ERR(("PNO enable failed!! ret=%d \n", ret));
4466 wl->sched_scan_req = request;
4474 int wl_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
4476 struct wl_priv *wl = wiphy_priv(wiphy);
4478 WL_DBG(("Enter \n"));
4480 if (dhd_dev_pno_enable(dev, 0) < 0)
4481 WL_ERR(("PNO disable failed"));
4483 if (dhd_dev_pno_reset(dev) < 0)
4484 WL_ERR(("PNO reset failed"));
4486 if (wl->scan_request && wl->sched_scan_running) {
4487 wl_notify_escan_complete(wl, dev, true, true);
4490 wl->sched_scan_req = NULL;
4491 wl->sched_scan_running = FALSE;
4495 #endif /* WL_SCHED_SCAN */
4497 static struct cfg80211_ops wl_cfg80211_ops = {
4498 .add_virtual_intf = wl_cfg80211_add_virtual_iface,
4499 .del_virtual_intf = wl_cfg80211_del_virtual_iface,
4500 .change_virtual_intf = wl_cfg80211_change_virtual_iface,
4501 .scan = wl_cfg80211_scan,
4502 .set_wiphy_params = wl_cfg80211_set_wiphy_params,
4503 .join_ibss = wl_cfg80211_join_ibss,
4504 .leave_ibss = wl_cfg80211_leave_ibss,
4505 .get_station = wl_cfg80211_get_station,
4506 .set_tx_power = wl_cfg80211_set_tx_power,
4507 .get_tx_power = wl_cfg80211_get_tx_power,
4508 .add_key = wl_cfg80211_add_key,
4509 .del_key = wl_cfg80211_del_key,
4510 .get_key = wl_cfg80211_get_key,
4511 .set_default_key = wl_cfg80211_config_default_key,
4512 .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
4513 .set_power_mgmt = wl_cfg80211_set_power_mgmt,
4514 .connect = wl_cfg80211_connect,
4515 .disconnect = wl_cfg80211_disconnect,
4516 .suspend = wl_cfg80211_suspend,
4517 .resume = wl_cfg80211_resume,
4518 .set_pmksa = wl_cfg80211_set_pmksa,
4519 .del_pmksa = wl_cfg80211_del_pmksa,
4520 .flush_pmksa = wl_cfg80211_flush_pmksa,
4521 .remain_on_channel = wl_cfg80211_remain_on_channel,
4522 .cancel_remain_on_channel = wl_cfg80211_cancel_remain_on_channel,
4523 .mgmt_tx = wl_cfg80211_mgmt_tx,
4524 .mgmt_frame_register = wl_cfg80211_mgmt_frame_register,
4525 .change_bss = wl_cfg80211_change_bss,
4526 .set_channel = wl_cfg80211_set_channel,
4527 .set_beacon = wl_cfg80211_add_set_beacon,
4528 .add_beacon = wl_cfg80211_add_set_beacon,
4529 #ifdef WL_SCHED_SCAN
4530 .sched_scan_start = wl_cfg80211_sched_scan_start,
4531 .sched_scan_stop = wl_cfg80211_sched_scan_stop,
4532 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) */
4535 s32 wl_mode_to_nl80211_iftype(s32 mode)
4541 return NL80211_IFTYPE_STATION;
4543 return NL80211_IFTYPE_ADHOC;
4545 return NL80211_IFTYPE_AP;
4547 return NL80211_IFTYPE_UNSPECIFIED;
4553 static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev)
4557 wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv));
4558 if (unlikely(!wdev->wiphy)) {
4559 WL_ERR(("Couldn not allocate wiphy device\n"));
4563 set_wiphy_dev(wdev->wiphy, sdiofunc_dev);
4564 wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
4565 /* Report how many SSIDs Driver can support per Scan request */
4566 wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX;
4567 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4568 #ifdef WL_SCHED_SCAN
4569 wdev->wiphy->max_sched_scan_ssids = MAX_PFN_LIST_COUNT;
4570 wdev->wiphy->max_match_sets = MAX_PFN_LIST_COUNT;
4571 wdev->wiphy->max_sched_scan_ie_len = WL_SCAN_IE_LEN_MAX;
4572 wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4573 #endif /* WL_SCHED_SCAN */
4574 wdev->wiphy->interface_modes =
4575 BIT(NL80211_IFTYPE_STATION)
4576 | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR);
4578 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4579 /* wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; - set in runtime */
4580 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4581 wdev->wiphy->cipher_suites = __wl_cipher_suites;
4582 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4583 wdev->wiphy->max_remain_on_channel_duration = 5000;
4584 wdev->wiphy->mgmt_stypes = wl_cfg80211_default_mgmt_stypes;
4585 #ifndef WL_POWERSAVE_DISABLED
4586 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
4588 wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
4589 #endif /* !WL_POWERSAVE_DISABLED */
4590 wdev->wiphy->flags |= WIPHY_FLAG_NETNS_OK |
4591 WIPHY_FLAG_4ADDR_AP |
4592 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)
4593 WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS |
4595 WIPHY_FLAG_4ADDR_STATION;
4596 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
4597 wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4599 WL_DBG(("Registering custom regulatory)\n"));
4600 wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
4601 wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
4602 /* Now we can register wiphy with cfg80211 module */
4603 err = wiphy_register(wdev->wiphy);
4604 if (unlikely(err < 0)) {
4605 WL_ERR(("Couldn not register wiphy device (%d)\n", err));
4606 wiphy_free(wdev->wiphy);
4611 static void wl_free_wdev(struct wl_priv *wl)
4613 struct wireless_dev *wdev = wl->wdev;
4614 struct wiphy *wiphy;
4616 WL_ERR(("wdev is invalid\n"));
4619 wiphy = wdev->wiphy;
4620 wiphy_unregister(wdev->wiphy);
4621 wdev->wiphy->dev.parent = NULL;
4623 wl_delete_all_netinfo(wl);
4625 /* PLEASE do NOT call any function after wiphy_free, the driver's private structure "wl",
4626 * which is the private part of wiphy, has been freed in wiphy_free !!!!!!!!!!!
4630 static s32 wl_inform_bss(struct wl_priv *wl)
4632 struct wl_scan_results *bss_list;
4633 struct wl_bss_info *bi = NULL; /* must be initialized */
4637 bss_list = wl->bss_list;
4638 WL_DBG(("scanned AP count (%d)\n", bss_list->count));
4639 bi = next_bss(bss_list, bi);
4640 for_each_bss(bss_list, bi, i) {
4641 err = wl_inform_single_bss(wl, bi);
4648 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
4650 struct wiphy *wiphy = wiphy_from_scan(wl);
4651 struct ieee80211_mgmt *mgmt;
4652 struct ieee80211_channel *channel;
4653 struct ieee80211_supported_band *band;
4654 struct wl_cfg80211_bss_info *notif_bss_info;
4655 struct wl_scan_req *sr = wl_to_sr(wl);
4656 struct beacon_proberesp *beacon_proberesp;
4657 struct cfg80211_bss *cbss = NULL;
4663 if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
4664 WL_DBG(("Beacon is larger than buffer. Discarding\n"));
4667 notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt)
4668 - sizeof(u8) + WL_BSS_INFO_MAX, GFP_KERNEL);
4669 if (unlikely(!notif_bss_info)) {
4670 WL_ERR(("notif_bss_info alloc failed\n"));
4673 mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
4674 notif_bss_info->channel =
4675 bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
4677 if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
4678 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4680 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4682 WL_ERR(("No valid band"));
4683 kfree(notif_bss_info);
4686 notif_bss_info->rssi = dtoh16(bi->RSSI);
4687 memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
4688 mgmt_type = wl->active_scan ?
4689 IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
4690 if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
4691 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type);
4693 beacon_proberesp = wl->active_scan ?
4694 (struct beacon_proberesp *)&mgmt->u.probe_resp :
4695 (struct beacon_proberesp *)&mgmt->u.beacon;
4696 beacon_proberesp->timestamp = 0;
4697 beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
4698 beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
4701 wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
4702 wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
4703 offsetof(struct wl_cfg80211_bss_info, frame_buf));
4704 notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
4705 u.beacon.variable) + wl_get_ielen(wl);
4706 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4707 freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
4709 freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
4711 channel = ieee80211_get_channel(wiphy, freq);
4713 WL_ERR(("No valid channel"));
4714 kfree(notif_bss_info);
4718 WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM "
4719 "mgmt_type %d frame_len %d\n", bi->SSID,
4720 notif_bss_info->rssi, notif_bss_info->channel,
4721 mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type,
4722 notif_bss_info->frame_len));
4724 signal = notif_bss_info->rssi * 100;
4726 #if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
4727 if (wl->p2p && wl->p2p_net && wl->scan_request &&
4728 ((wl->scan_request->dev == wl->p2p_net) ||
4729 (wl->scan_request->dev == wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)))){
4731 if (p2p_is_on(wl) && ( p2p_scan(wl) ||
4732 (wl->scan_request->dev == wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION)))) {
4734 /* find the P2PIE, if we do not find it, we will discard this frame */
4735 wifi_p2p_ie_t * p2p_ie;
4736 if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)beacon_proberesp->variable,
4737 wl_get_ielen(wl))) == NULL) {
4738 WL_ERR(("Couldn't find P2PIE in probe response/beacon\n"));
4739 kfree(notif_bss_info);
4742 else if( wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_DEV_INFO) == NULL)
4744 WL_DBG(("Couldn't find P2P_SEID_DEV_INFO in probe response/beacon\n"));
4745 kfree(notif_bss_info);
4749 if (!mgmt->u.probe_resp.timestamp) {
4752 do_gettimeofday(&tv);
4753 mgmt->u.probe_resp.timestamp = ((u64)tv.tv_sec * 1000000)
4757 cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
4758 le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
4759 if (unlikely(!cbss)) {
4760 WL_ERR(("cfg80211_inform_bss_frame error\n"));
4761 kfree(notif_bss_info);
4765 cfg80211_put_bss(cbss);
4766 kfree(notif_bss_info);
4771 static s32 wl_inform_ibss(struct wl_priv *wl, const u8 *bssid)
4773 struct net_device *ndev = wl_to_prmry_ndev(wl);
4774 struct wiphy *wiphy = wl_to_wiphy(wl);
4775 struct wl_bss_info *bi = NULL;
4776 struct ieee80211_channel *notify_channel;
4777 struct ieee80211_supported_band *band;
4778 struct cfg80211_bss *bss;
4783 u16 notify_capability;
4784 u16 notify_interval;
4786 size_t notify_ielen;
4789 WL_TRACE(("Enter\n"));
4791 if (wl->scan_request) {
4792 wl_notify_escan_complete(wl, ndev, true, true);
4795 mutex_lock(&wl->usr_sync);
4797 *(u32 *)wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
4798 err = wldev_ioctl(ndev, WLC_GET_BSS_INFO, wl->extra_buf,
4799 WL_EXTRA_BUF_MAX, false);
4801 WL_ERR(("Failed to get bss info for IBSS\n"));
4805 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
4807 if (memcmp(bssid, &bi->BSSID, ETHER_ADDR_LEN)) {
4808 WL_ERR(("BSSID mismatch: Inform %02x:%02x:%02x:%02x:%02x:%02x,"
4809 "%02x:%02x:%02x:%02x:%02x:%02x\n",
4810 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
4811 bi->BSSID.octet[0], bi->BSSID.octet[1], bi->BSSID.octet[2],
4812 bi->BSSID.octet[3], bi->BSSID.octet[4],
4813 bi->BSSID.octet[5]));
4818 err = wldev_iovar_getint(ndev, "wsec", &wsec);
4820 WL_ERR(("wsec failed: %d\n", err));
4825 channel = bi->ctl_ch ? bi->ctl_ch :
4826 CHSPEC_CHANNEL(dtohchanspec(bi->chanspec));
4827 if (channel <= CH_MAX_2G_CHANNEL)
4828 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4830 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4832 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
4833 freq = ieee80211_channel_to_frequency(channel);
4836 freq = ieee80211_channel_to_frequency(channel, band->band);
4838 notify_channel = ieee80211_get_channel(wiphy, freq);
4840 notify_capability = dtoh16(bi->capability);
4841 notify_interval = dtoh16(bi->beacon_period);
4842 notify_ie = (u8 *)bi + dtoh16(bi->ie_offset);
4843 notify_ielen = dtoh32(bi->ie_length);
4844 notify_signal = (int16)dtoh16(bi->RSSI) * 100;
4846 if (wl->p2p_supported) {
4847 notify_capability |= DOT11_CAP_IBSS;
4849 notify_capability |= DOT11_CAP_PRIVACY;
4852 WL_DBG(("BSSID %02x:%02x:%02x:%02x:%02x:%02x",
4853 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]));
4854 WL_INFO(("channel: %d(%d)\n", channel, freq));
4855 WL_INFO(("capability: %X\n", notify_capability));
4856 WL_INFO(("beacon interval: %d ms\n", notify_interval));
4857 WL_INFO(("signal: %d dBm\n", notify_signal));
4858 WL_INFO(("ie_len: %d\n", notify_ielen));
4859 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, 0,
4860 notify_capability, notify_interval,
4861 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
4863 WL_ERR(("cfg80211_inform_bss() Failed\n"));
4868 cfg80211_put_bss(bss);
4873 mutex_unlock(&wl->usr_sync);
4875 WL_TRACE(("Exit\n"));
4879 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev)
4881 u32 event = ntoh32(e->event_type);
4882 u32 status = ntoh32(e->status);
4883 u16 flags = ntoh16(e->flags);
4885 WL_DBG(("event %d, status %d flags %x\n", event, status, flags));
4886 if (event == WLC_E_SET_SSID) {
4887 if (status == WLC_E_STATUS_SUCCESS) {
4890 } else if (event == WLC_E_LINK) {
4891 if (flags & WLC_EVENT_MSG_LINK)
4892 if (!wl_is_ibssmode(wl, ndev))
4896 WL_DBG(("wl_is_linkup false\n"));
4900 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
4902 u32 event = ntoh32(e->event_type);
4903 u16 flags = ntoh16(e->flags);
4905 if (event == WLC_E_DEAUTH_IND ||
4906 event == WLC_E_DISASSOC_IND ||
4907 event == WLC_E_DISASSOC ||
4908 event == WLC_E_DEAUTH) {
4910 } else if (event == WLC_E_LINK) {
4911 if (!(flags & WLC_EVENT_MSG_LINK))
4918 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
4920 u32 event = ntoh32(e->event_type);
4921 u32 status = ntoh32(e->status);
4923 if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS)
4925 if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS)
4931 /* The mainline kernel >= 3.2.0 has support for indicating new/del station
4932 * to AP/P2P GO via events. If this change is backported to kernel for which
4933 * this driver is being built, then define WL_CFG80211_STA_EVENT. You
4934 * should use this new/del sta event mechanism for BRCM supplicant >= 22.
4937 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
4938 const wl_event_msg_t *e, void *data)
4941 u32 event = ntoh32(e->event_type);
4942 u32 reason = ntoh32(e->reason);
4943 u32 len = ntoh32(e->datalen);
4945 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT)
4946 bool isfree = false;
4948 u8 bsscfgidx = e->bsscfgidx;
4951 u8 body[WL_FRAME_LEN];
4953 struct ieee80211_supported_band *band;
4954 struct ether_addr da;
4955 struct ether_addr bssid;
4956 struct wiphy *wiphy = wl_to_wiphy(wl);
4959 struct station_info sinfo;
4960 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !WL_CFG80211_STA_EVENT */
4963 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !defined(WL_CFG80211_STA_EVENT)
4964 memset(body, 0, sizeof(body));
4965 memset(&bssid, 0, ETHER_ADDR_LEN);
4966 WL_DBG(("Enter event %d ndev %p\n", event, ndev));
4967 if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID)
4970 if (len > WL_FRAME_LEN) {
4971 WL_ERR(("Received frame length %d from dongle is greater than"
4972 " allocated body buffer len %d", len, WL_FRAME_LEN));
4975 memcpy(body, data, len);
4976 wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
4977 NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
4978 memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
4979 err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
4981 case WLC_E_ASSOC_IND:
4984 case WLC_E_REASSOC_IND:
4985 fc = FC_REASSOC_REQ;
4987 case WLC_E_DISASSOC_IND:
4990 case WLC_E_DEAUTH_IND:
5000 if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
5003 channel = dtoh32(ci.hw_channel);
5004 if (channel <= CH_MAX_2G_CHANNEL)
5005 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5007 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5009 WL_ERR(("No valid band"));
5012 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
5013 freq = ieee80211_channel_to_frequency(channel);
5015 freq = ieee80211_channel_to_frequency(channel, band->band);
5018 err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
5019 &mgmt_frame, &len, body);
5024 if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
5025 cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
5026 } else if (event == WLC_E_DISASSOC_IND) {
5027 cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
5028 } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
5029 cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
5036 #else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */
5038 if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) &&
5039 reason == DOT11_SC_SUCCESS) {
5040 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
5042 WL_ERR(("No IEs present in ASSOC/REASSOC_IND"));
5045 sinfo.assoc_req_ies = data;
5046 sinfo.assoc_req_ies_len = len;
5047 cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC);
5048 } else if (event == WLC_E_DISASSOC_IND) {
5049 cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
5050 } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
5051 cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
5053 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !WL_CFG80211_STA_EVENT */
5058 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
5059 const wl_event_msg_t *e, void *data)
5063 u32 event = ntoh32(e->event_type);
5066 if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
5067 wl_notify_connect_status_ap(wl, ndev, e, data);
5069 WL_DBG(("wl_notify_connect_status : event %d status : %d ndev %p\n",
5070 ntoh32(e->event_type), ntoh32(e->status), ndev));
5071 if((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DISASSOC_IND)) {
5072 reason = ntoh32(e->reason);
5073 wl->deauth_reason = reason;
5074 WL_ERR(("Received %s event with reason code: %d\n",
5075 (event == WLC_E_DEAUTH_IND)?
5076 "WLC_E_DEAUTH_IND":"WLC_E_DISASSOC_IND", reason));
5078 if (wl_is_linkup(wl, e, ndev)) {
5081 wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
5082 wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
5083 wl->deauth_reason = 0;
5084 if (wl_is_ibssmode(wl, ndev)) {
5085 wl_ibss_join_done(wl, ndev, e, data, true);
5086 WL_DBG(("wl_ibss_join_done succeeded\n"));
5088 if (!wl_get_drv_status(wl, DISCONNECTING, ndev)) {
5089 printk("wl_bss_connect_done succeeded\n");
5090 wl_bss_connect_done(wl, ndev, e, data, true);
5091 WL_DBG(("joined in BSS network \"%s\"\n",
5092 ((struct wlc_ssid *)
5093 wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID));
5096 } else if (wl_is_linkdown(wl, e)) {
5097 if (wl->scan_request) {
5099 wl_notify_escan_complete(wl, ndev, true, true);
5101 del_timer_sync(&wl->scan_timeout);
5102 wl_iscan_aborted(wl);
5105 if (wl_get_drv_status(wl, CONNECTED, ndev)) {
5107 u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
5108 wl_clr_drv_status(wl, CONNECTED, ndev);
5109 if (! wl_get_drv_status(wl, DISCONNECTING, ndev)) {
5110 /* To make sure disconnect, explictly send dissassoc
5111 * for BSSID 00:00:00:00:00:00 issue
5113 scbval.val = WLAN_REASON_DEAUTH_LEAVING;
5115 memcpy(&scbval.ea, curbssid, ETHER_ADDR_LEN);
5116 scbval.val = htod32(scbval.val);
5117 wldev_ioctl(ndev, WLC_DISASSOC, &scbval,
5118 sizeof(scb_val_t), true);
5119 WL_ERR(("link down, calling cfg80211_disconnected"
5120 " with deauth_reason:%d\n", wl->deauth_reason));
5121 if (!wl_is_ibssmode(wl, ndev))
5122 cfg80211_disconnected(ndev, wl->deauth_reason,
5123 NULL, 0, GFP_KERNEL);
5125 wl_init_prof(wl, ndev);
5128 else if (wl_get_drv_status(wl, CONNECTING, ndev)) {
5129 printk("link down, during connecting\n");
5130 if (wl_is_ibssmode(wl, ndev))
5131 wl_ibss_join_done(wl, ndev, e, data, false);
5133 wl_bss_connect_done(wl, ndev, e, data, false);
5135 wl_clr_drv_status(wl, DISCONNECTING, ndev);
5137 } else if (wl_is_nonetwork(wl, e)) {
5138 printk("connect failed event=%d e->status 0x%x\n",
5139 event, (int)ntoh32(e->status));
5140 /* Clean up any pending scan request */
5141 if (wl->scan_request) {
5143 wl_notify_escan_complete(wl, ndev, true, true);
5145 del_timer_sync(&wl->scan_timeout);
5146 wl_iscan_aborted(wl);
5149 if (wl_get_drv_status(wl, CONNECTING, ndev))
5150 wl_bss_connect_done(wl, ndev, e, data, false);
5152 printk("%s nothing\n", __FUNCTION__);
5159 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
5160 const wl_event_msg_t *e, void *data)
5164 u32 event = be32_to_cpu(e->event_type);
5165 u32 status = be32_to_cpu(e->status);
5166 WL_DBG(("Enter \n"));
5167 if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
5168 if (wl_get_drv_status(wl, CONNECTED, ndev))
5169 wl_bss_roaming_done(wl, ndev, e, data);
5171 wl_bss_connect_done(wl, ndev, e, data, true);
5173 wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT);
5174 wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID);
5179 static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
5181 wl_assoc_info_t assoc_info;
5182 struct wl_connect_info *conn_info = wl_to_conn(wl);
5185 WL_DBG(("Enter \n"));
5186 err = wldev_iovar_getbuf(ndev, "assoc_info", NULL, 0, wl->extra_buf,
5187 WL_ASSOC_INFO_MAX, NULL);
5188 if (unlikely(err)) {
5189 WL_ERR(("could not get assoc info (%d)\n", err));
5192 memcpy(&assoc_info, wl->extra_buf, sizeof(wl_assoc_info_t));
5193 assoc_info.req_len = htod32(assoc_info.req_len);
5194 assoc_info.resp_len = htod32(assoc_info.resp_len);
5195 assoc_info.flags = htod32(assoc_info.flags);
5196 if (conn_info->req_ie_len) {
5197 conn_info->req_ie_len = 0;
5198 bzero(conn_info->req_ie, sizeof(conn_info->req_ie));
5200 if (conn_info->resp_ie_len) {
5201 conn_info->resp_ie_len = 0;
5202 bzero(conn_info->resp_ie, sizeof(conn_info->resp_ie));
5204 if (assoc_info.req_len) {
5205 err = wldev_iovar_getbuf(ndev, "assoc_req_ies", NULL, 0, wl->extra_buf,
5206 WL_ASSOC_INFO_MAX, NULL);
5207 if (unlikely(err)) {
5208 WL_ERR(("could not get assoc req (%d)\n", err));
5211 conn_info->req_ie_len = assoc_info.req_len - sizeof(struct dot11_assoc_req);
5212 if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
5213 conn_info->req_ie_len -= ETHER_ADDR_LEN;
5215 if (conn_info->req_ie_len <= MAX_REQ_LINE)
5216 memcpy(conn_info->req_ie, wl->extra_buf, conn_info->req_ie_len);
5218 WL_ERR(("%s IE size %d above max %d size \n",
5219 __FUNCTION__, conn_info->req_ie_len, MAX_REQ_LINE));
5223 conn_info->req_ie_len = 0;
5225 if (assoc_info.resp_len) {
5226 err = wldev_iovar_getbuf(ndev, "assoc_resp_ies", NULL, 0, wl->extra_buf,
5227 WL_ASSOC_INFO_MAX, NULL);
5228 if (unlikely(err)) {
5229 WL_ERR(("could not get assoc resp (%d)\n", err));
5232 conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
5233 if (conn_info->resp_ie_len <= MAX_REQ_LINE)
5234 memcpy(conn_info->resp_ie, wl->extra_buf, conn_info->resp_ie_len);
5236 WL_ERR(("%s IE size %d above max %d size \n",
5237 __FUNCTION__, conn_info->resp_ie_len, MAX_REQ_LINE));
5241 conn_info->resp_ie_len = 0;
5243 WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
5244 conn_info->resp_ie_len));
5249 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
5250 size_t *join_params_size)
5252 chanspec_t chanspec = 0;
5255 join_params->params.chanspec_num = 1;
5256 join_params->params.chanspec_list[0] = ch;
5258 if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
5259 chanspec |= WL_CHANSPEC_BAND_2G;
5261 chanspec |= WL_CHANSPEC_BAND_5G;
5263 chanspec |= WL_CHANSPEC_BW_20;
5264 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
5266 *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE +
5267 join_params->params.chanspec_num * sizeof(chanspec_t);
5269 join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
5270 join_params->params.chanspec_list[0] |= chanspec;
5271 join_params->params.chanspec_list[0] =
5272 htodchanspec(join_params->params.chanspec_list[0]);
5274 join_params->params.chanspec_num =
5275 htod32(join_params->params.chanspec_num);
5277 WL_DBG(("%s join_params->params.chanspec_list[0]= %X\n",
5278 __FUNCTION__, join_params->params.chanspec_list[0]));
5283 static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev)
5285 struct cfg80211_bss *bss;
5286 struct wl_bss_info *bi;
5287 struct wlc_ssid *ssid;
5288 struct bcm_tlv *tim;
5289 s32 beacon_interval;
5295 struct wiphy *wiphy;
5297 wiphy = wl_to_wiphy(wl);
5299 if (wl_is_ibssmode(wl, ndev))
5302 ssid = (struct wlc_ssid *)wl_read_prof(wl, ndev, WL_PROF_SSID);
5303 curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
5304 bss = cfg80211_get_bss(wiphy, NULL, curbssid,
5305 ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
5306 WLAN_CAPABILITY_ESS);
5308 mutex_lock(&wl->usr_sync);
5310 WL_DBG(("Could not find the AP\n"));
5311 *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
5312 err = wldev_ioctl(ndev, WLC_GET_BSS_INFO,
5313 wl->extra_buf, WL_EXTRA_BUF_MAX, false);
5314 if (unlikely(err)) {
5315 WL_ERR(("Could not get bss info %d\n", err));
5316 goto update_bss_info_out;
5318 bi = (struct wl_bss_info *)(wl->extra_buf + 4);
5319 if (memcmp(bi->BSSID.octet, curbssid, ETHER_ADDR_LEN)) {
5321 goto update_bss_info_out;
5323 err = wl_inform_single_bss(wl, bi);
5325 goto update_bss_info_out;
5327 ie = ((u8 *)bi) + bi->ie_offset;
5328 ie_len = bi->ie_length;
5329 beacon_interval = cpu_to_le16(bi->beacon_period);
5331 WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid));
5332 ie = bss->information_elements;
5333 ie_len = bss->len_information_elements;
5334 beacon_interval = bss->beacon_interval;
5335 cfg80211_put_bss(bss);
5338 tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
5340 dtim_period = tim->data[1];
5343 * active scan was done so we could not get dtim
5344 * information out of probe response.
5345 * so we speficially query dtim information.
5347 err = wldev_ioctl(ndev, WLC_GET_DTIMPRD,
5348 &dtim_period, sizeof(dtim_period), false);
5349 if (unlikely(err)) {
5350 WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err));
5351 goto update_bss_info_out;
5355 wl_update_prof(wl, ndev, NULL, &beacon_interval, WL_PROF_BEACONINT);
5356 wl_update_prof(wl, ndev, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
5358 update_bss_info_out:
5359 mutex_unlock(&wl->usr_sync);
5364 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
5365 const wl_event_msg_t *e, void *data)
5367 struct wl_connect_info *conn_info = wl_to_conn(wl);
5371 wl_get_assoc_ies(wl, ndev);
5372 wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
5373 curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
5374 wl_update_bss_info(wl, ndev);
5375 wl_update_pmklist(ndev, wl->pmk_list, err);
5376 cfg80211_roamed(ndev,
5377 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
5381 conn_info->req_ie, conn_info->req_ie_len,
5382 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
5383 WL_DBG(("Report roaming result\n"));
5385 wl_set_drv_status(wl, CONNECTED, ndev);
5391 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
5392 const wl_event_msg_t *e, void *data, bool completed)
5394 struct wl_connect_info *conn_info = wl_to_conn(wl);
5396 u8 *curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
5398 WL_DBG((" enter\n"));
5399 if (wl->scan_request) {
5400 wl_notify_escan_complete(wl, ndev, true, true);
5402 if (wl_get_drv_status(wl, CONNECTING, ndev)) {
5403 wl_clr_drv_status(wl, CONNECTING, ndev);
5405 wl_get_assoc_ies(wl, ndev);
5406 wl_update_prof(wl, ndev, NULL, (void *)(e->addr.octet), WL_PROF_BSSID);
5407 curbssid = wl_read_prof(wl, ndev, WL_PROF_BSSID);
5408 wl_update_bss_info(wl, ndev);
5409 wl_update_pmklist(ndev, wl->pmk_list, err);
5410 wl_set_drv_status(wl, CONNECTED, ndev);
5412 cfg80211_connect_result(ndev,
5415 conn_info->req_ie_len,
5417 conn_info->resp_ie_len,
5418 completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
5421 WL_INFO(("Report connect result - connection succeeded\n"));
5423 WL_ERR(("Report connect result - connection failed\n"));
5429 wl_ibss_join_done(struct wl_priv *wl, struct net_device *ndev,
5430 const wl_event_msg_t *e, void *data, bool completed)
5434 WL_TRACE(("Enter\n"));
5436 if (wl->scan_request) {
5437 wl_notify_escan_complete(wl, ndev, true, true);
5439 if (wl_get_drv_status(wl, CONNECTING, ndev)) {
5440 wl_clr_drv_status(wl, CONNECTING, ndev);
5442 err = wl_inform_ibss(wl, (u8 *)&e->addr);
5444 WL_ERR(("wl_inform_ibss() failed: %d\n", err));
5446 wl_set_drv_status(wl, CONNECTED, ndev);
5448 cfg80211_ibss_joined(ndev, (u8 *)&e->addr, GFP_KERNEL);
5449 WL_DBG(("cfg80211_ibss_joined() called with valid BSSID\n"));
5453 WL_TRACE(("Exit\n"));
5458 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
5459 const wl_event_msg_t *e, void *data)
5461 u16 flags = ntoh16(e->flags);
5462 enum nl80211_key_type key_type;
5464 mutex_lock(&wl->usr_sync);
5465 if (flags & WLC_EVENT_MSG_GROUP)
5466 key_type = NL80211_KEYTYPE_GROUP;
5468 key_type = NL80211_KEYTYPE_PAIRWISE;
5470 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
5472 mutex_unlock(&wl->usr_sync);
5479 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev,
5480 const wl_event_msg_t *e, void *data)
5482 WL_ERR((" PNO Event\n"));
5484 mutex_lock(&wl->usr_sync);
5485 #ifndef WL_SCHED_SCAN
5486 /* TODO: Use cfg80211_sched_scan_results(wiphy); */
5487 cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
5489 /* If cfg80211 scheduled scan is supported, report the pno results via sched
5492 wl_notify_sched_scan_results(wl, ndev, e, data);
5493 #endif /* WL_SCHED_SCAN */
5494 mutex_unlock(&wl->usr_sync);
5497 #endif /* PNO_SUPPORT */
5500 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
5501 const wl_event_msg_t *e, void *data)
5503 struct channel_info channel_inform;
5504 struct wl_scan_results *bss_list;
5505 u32 len = WL_SCAN_BUF_MAX;
5507 unsigned long flags;
5509 WL_DBG(("Enter \n"));
5510 if (!wl_get_drv_status(wl, SCANNING, ndev)) {
5511 WL_ERR(("scan is not ready \n"));
5514 if (wl->iscan_on && wl->iscan_kickstart)
5515 return wl_wakeup_iscan(wl_to_iscan(wl));
5517 mutex_lock(&wl->usr_sync);
5518 wl_clr_drv_status(wl, SCANNING, ndev);
5519 err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
5520 sizeof(channel_inform), false);
5521 if (unlikely(err)) {
5522 WL_ERR(("scan busy (%d)\n", err));
5525 channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
5526 if (unlikely(channel_inform.scan_channel)) {
5528 WL_DBG(("channel_inform.scan_channel (%d)\n",
5529 channel_inform.scan_channel));
5531 wl->bss_list = wl->scan_results;
5532 bss_list = wl->bss_list;
5533 memset(bss_list, 0, len);
5534 bss_list->buflen = htod32(len);
5535 err = wldev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len, false);
5536 if (unlikely(err)) {
5537 WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
5541 bss_list->buflen = dtoh32(bss_list->buflen);
5542 bss_list->version = dtoh32(bss_list->version);
5543 bss_list->count = dtoh32(bss_list->count);
5545 err = wl_inform_bss(wl);
5548 del_timer_sync(&wl->scan_timeout);
5549 spin_lock_irqsave(&wl->cfgdrv_lock, flags);
5550 if (wl->scan_request) {
5551 WL_DBG(("cfg80211_scan_done\n"));
5552 cfg80211_scan_done(wl->scan_request, false);
5553 wl->scan_request = NULL;
5555 spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
5556 mutex_unlock(&wl->usr_sync);
5560 wl_frame_get_mgmt(u16 fc, const struct ether_addr *da,
5561 const struct ether_addr *sa, const struct ether_addr *bssid,
5562 u8 **pheader, u32 *body_len, u8 *pbody)
5564 struct dot11_management_header *hdr;
5568 u32 prebody_len = *body_len;
5571 /* capability , listen interval */
5572 totlen = DOT11_ASSOC_REQ_FIXED_LEN;
5573 *body_len += DOT11_ASSOC_REQ_FIXED_LEN;
5576 case FC_REASSOC_REQ:
5577 /* capability, listen inteval, ap address */
5578 totlen = DOT11_REASSOC_REQ_FIXED_LEN;
5579 *body_len += DOT11_REASSOC_REQ_FIXED_LEN;
5582 totlen += DOT11_MGMT_HDR_LEN + prebody_len;
5583 *pheader = kzalloc(totlen, GFP_KERNEL);
5584 if (*pheader == NULL) {
5585 WL_ERR(("memory alloc failed \n"));
5588 hdr = (struct dot11_management_header *) (*pheader);
5589 hdr->fc = htol16(fc);
5592 offset = (u8*)(hdr + 1) + (totlen - DOT11_MGMT_HDR_LEN - prebody_len);
5593 bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN);
5594 bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN);
5595 bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN);
5596 bcopy((const char*)pbody, offset, prebody_len);
5601 wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
5602 const wl_event_msg_t *e, void *data)
5604 struct ieee80211_supported_band *band;
5605 struct wiphy *wiphy = wl_to_wiphy(wl);
5606 struct ether_addr da;
5607 struct ether_addr bssid;
5608 bool isfree = false;
5611 struct net_device *dev = NULL;
5612 wifi_p2p_pub_act_frame_t *act_frm = NULL;
5613 wifi_p2p_action_frame_t *p2p_act_frm = NULL;
5614 wifi_p2psd_gas_pub_act_frame_t *sd_act_frm = NULL;
5615 wl_event_rx_frame_data_t *rxframe =
5616 (wl_event_rx_frame_data_t*)data;
5617 u32 event = ntoh32(e->event_type);
5619 u8 bsscfgidx = e->bsscfgidx;
5620 u32 mgmt_frame_len = ntoh32(e->datalen) - sizeof(wl_event_rx_frame_data_t);
5621 u16 channel = ((ntoh16(rxframe->channel) & WL_CHANSPEC_CHAN_MASK));
5623 memset(&bssid, 0, ETHER_ADDR_LEN);
5625 if (wl->p2p_net == ndev) {
5626 dev = wl_to_prmry_ndev(wl);
5631 if (channel <= CH_MAX_2G_CHANNEL)
5632 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5634 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5636 WL_ERR(("No valid band"));
5640 if ((event == WLC_E_P2P_PROBREQ_MSG) &&
5641 wl->p2p && wl_get_p2p_status(wl, GO_NEG_PHASE)) {
5642 WL_DBG(("Filtering P2P probe_req while being in GO-Neg state\n"));
5646 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
5647 freq = ieee80211_channel_to_frequency(channel);
5649 freq = ieee80211_channel_to_frequency(channel, band->band);
5651 if (event == WLC_E_ACTION_FRAME_RX) {
5652 wldev_iovar_getbuf_bsscfg(dev, "cur_etheraddr",
5653 NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
5655 wldev_ioctl(dev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
5656 memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
5657 err = wl_frame_get_mgmt(FC_ACTION, &da, &e->addr, &bssid,
5658 &mgmt_frame, &mgmt_frame_len,
5659 (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1));
5661 WL_ERR(("%s: Error in receiving action frame len %d channel %d freq %d\n",
5662 __func__, mgmt_frame_len, channel, freq));
5666 if (wl_cfgp2p_is_pub_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
5667 mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
5668 act_frm = (wifi_p2p_pub_act_frame_t *)
5669 (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
5670 } else if (wl_cfgp2p_is_p2p_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
5671 mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
5672 p2p_act_frm = (wifi_p2p_action_frame_t *)
5673 (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
5675 } else if (wl_cfgp2p_is_gas_action(&mgmt_frame[DOT11_MGMT_HDR_LEN],
5676 mgmt_frame_len - DOT11_MGMT_HDR_LEN)) {
5677 sd_act_frm = (wifi_p2psd_gas_pub_act_frame_t *)
5678 (&mgmt_frame[DOT11_MGMT_HDR_LEN]);
5681 wl_cfgp2p_print_actframe(false, &mgmt_frame[DOT11_MGMT_HDR_LEN],
5682 mgmt_frame_len - DOT11_MGMT_HDR_LEN);
5684 * After complete GO Negotiation, roll back to mpc mode
5686 if (act_frm && ((act_frm->subtype == P2P_PAF_GON_CONF) ||
5687 (act_frm->subtype == P2P_PAF_PROVDIS_RSP))) {
5688 wldev_iovar_setint(dev, "mpc", 1);
5691 if (act_frm && (act_frm->subtype == P2P_PAF_GON_CONF)) {
5692 WL_DBG(("P2P: GO_NEG_PHASE status cleared \n"));
5693 wl_clr_p2p_status(wl, GO_NEG_PHASE);
5696 mgmt_frame = (u8 *)((wl_event_rx_frame_data_t *)rxframe + 1);
5699 cfg80211_rx_mgmt(ndev, freq, mgmt_frame, mgmt_frame_len, GFP_ATOMIC);
5701 WL_DBG(("%s: mgmt_frame_len (%d) , e->datalen (%d), channel (%d), freq (%d)\n", __func__,
5702 mgmt_frame_len, ntoh32(e->datalen), channel, freq));
5710 #ifdef WL_SCHED_SCAN
5711 /* If target scan is not reliable, set the below define to "1" to do a
5714 #define FULL_ESCAN_ON_PFN_NET_FOUND 0
5716 wl_notify_sched_scan_results(struct wl_priv *wl, struct net_device *ndev,
5717 const wl_event_msg_t *e, void *data)
5719 wl_pfn_net_info_t *netinfo, *pnetinfo;
5720 struct cfg80211_scan_request request;
5721 struct wiphy *wiphy = wl_to_wiphy(wl);
5723 struct cfg80211_ssid ssid[MAX_PFN_LIST_COUNT];
5724 struct ieee80211_channel *channel = NULL;
5725 int channel_req = 0;
5727 struct wl_pfn_scanresults *pfn_result = (struct wl_pfn_scanresults *)data;
5729 WL_DBG(("Enter\n"));
5731 if (e->event_type == WLC_E_PFN_NET_LOST) {
5732 WL_DBG(("PFN NET LOST event. Do Nothing \n"));
5735 WL_DBG(("PFN NET FOUND event. count:%d \n", pfn_result->count));
5736 if (pfn_result->count > 0) {
5739 memset(&request, 0x00, sizeof(struct cfg80211_scan_request));
5740 memset(&ssid, 0x00, sizeof(ssid));
5741 request.wiphy = wiphy;
5743 pnetinfo = (wl_pfn_net_info_t *)(data + sizeof(wl_pfn_scanresults_t)
5744 - sizeof(wl_pfn_net_info_t));
5745 channel = (struct ieee80211_channel *)kzalloc(
5746 (sizeof(struct ieee80211_channel) * MAX_PFN_LIST_COUNT),
5749 WL_ERR(("No memory"));
5754 for (i = 0; i < pfn_result->count; i++) {
5755 netinfo = &pnetinfo[i];
5757 WL_ERR(("Invalid netinfo ptr. index:%d", i));
5761 WL_DBG(("SSID:%s Channel:%d \n",
5762 netinfo->pfnsubnet.SSID, netinfo->pfnsubnet.channel));
5763 /* PFN result doesn't have all the info which are required by the supplicant
5764 * (For e.g IEs) Do a target Escan so that sched scan results are reported
5765 * via wl_inform_single_bss in the required format. Escan does require the
5766 * scan request in the form of cfg80211_scan_request. For timebeing, create
5767 * cfg80211_scan_request one out of the received PNO event.
5769 memcpy(ssid[i].ssid, netinfo->pfnsubnet.SSID,
5770 netinfo->pfnsubnet.SSID_len);
5771 ssid[i].ssid_len = netinfo->pfnsubnet.SSID_len;
5774 channel_req = netinfo->pfnsubnet.channel;
5775 band = (channel_req <= CH_MAX_2G_CHANNEL) ? NL80211_BAND_2GHZ
5776 : NL80211_BAND_5GHZ;
5777 channel[i].center_freq = ieee80211_channel_to_frequency(channel_req, band);
5778 channel[i].band = band;
5779 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
5780 request.channels[i] = &channel[i];
5781 request.n_channels++;
5784 /* assign parsed ssid array */
5785 if (request.n_ssids)
5786 request.ssids = &ssid[0];
5788 if (wl_get_drv_status_all(wl, SCANNING)) {
5789 /* Abort any on-going scan */
5790 wl_notify_escan_complete(wl, ndev, true, true);
5793 if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
5794 err = wl_cfgp2p_discover_enable_search(wl, false);
5795 if (unlikely(err)) {
5796 wl_clr_drv_status(wl, SCANNING, ndev);
5801 wl_set_drv_status(wl, SCANNING, ndev);
5802 #if FULL_ESCAN_ON_PFN_NET_FOUND
5803 err = wl_do_escan(wl, wiphy, ndev, NULL);
5805 err = wl_do_escan(wl, wiphy, ndev, &request);
5808 wl_clr_drv_status(wl, SCANNING, ndev);
5811 wl->sched_scan_running = TRUE;
5814 WL_ERR(("FALSE PNO Event. (pfn_count == 0) \n"));
5821 #endif /* WL_SCHED_SCAN */
5823 static void wl_init_conf(struct wl_conf *conf)
5825 WL_DBG(("Enter \n"));
5826 conf->frag_threshold = (u32)-1;
5827 conf->rts_threshold = (u32)-1;
5828 conf->retry_short = (u32)-1;
5829 conf->retry_long = (u32)-1;
5830 conf->tx_power = -1;
5833 static void wl_init_prof(struct wl_priv *wl, struct net_device *ndev)
5835 unsigned long flags;
5836 struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
5838 spin_lock_irqsave(&wl->cfgdrv_lock, flags);
5839 memset(profile, 0, sizeof(struct wl_profile));
5840 spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
5843 static void wl_init_event_handler(struct wl_priv *wl)
5845 memset(wl->evt_handler, 0, sizeof(wl->evt_handler));
5847 wl->evt_handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
5848 wl->evt_handler[WLC_E_LINK] = wl_notify_connect_status;
5849 wl->evt_handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
5850 wl->evt_handler[WLC_E_DEAUTH] = wl_notify_connect_status;
5851 wl->evt_handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
5852 wl->evt_handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
5853 wl->evt_handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
5854 wl->evt_handler[WLC_E_ROAM] = wl_notify_roaming_status;
5855 wl->evt_handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
5856 wl->evt_handler[WLC_E_SET_SSID] = wl_notify_connect_status;
5857 wl->evt_handler[WLC_E_ACTION_FRAME_RX] = wl_notify_rx_mgmt_frame;
5858 wl->evt_handler[WLC_E_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
5859 wl->evt_handler[WLC_E_P2P_PROBREQ_MSG] = wl_notify_rx_mgmt_frame;
5860 wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete;
5861 wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
5862 wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
5864 wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status;
5865 #endif /* PNO_SUPPORT */
5868 static s32 wl_init_priv_mem(struct wl_priv *wl)
5870 WL_DBG(("Enter \n"));
5871 wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
5872 if (unlikely(!wl->scan_results)) {
5873 WL_ERR(("Scan results alloc failed\n"));
5874 goto init_priv_mem_out;
5876 wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
5877 if (unlikely(!wl->conf)) {
5878 WL_ERR(("wl_conf alloc failed\n"));
5879 goto init_priv_mem_out;
5882 (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
5883 if (unlikely(!wl->scan_req_int)) {
5884 WL_ERR(("Scan req alloc failed\n"));
5885 goto init_priv_mem_out;
5887 wl->ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
5888 if (unlikely(!wl->ioctl_buf)) {
5889 WL_ERR(("Ioctl buf alloc failed\n"));
5890 goto init_priv_mem_out;
5892 wl->escan_ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
5893 if (unlikely(!wl->escan_ioctl_buf)) {
5894 WL_ERR(("Ioctl buf alloc failed\n"));
5895 goto init_priv_mem_out;
5897 wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5898 if (unlikely(!wl->extra_buf)) {
5899 WL_ERR(("Extra buf alloc failed\n"));
5900 goto init_priv_mem_out;
5902 wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
5903 if (unlikely(!wl->iscan)) {
5904 WL_ERR(("Iscan buf alloc failed\n"));
5905 goto init_priv_mem_out;
5907 wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
5908 if (unlikely(!wl->pmk_list)) {
5909 WL_ERR(("pmk list alloc failed\n"));
5910 goto init_priv_mem_out;
5912 wl->sta_info = (void *)kzalloc(sizeof(*wl->sta_info), GFP_KERNEL);
5913 if (unlikely(!wl->sta_info)) {
5914 WL_ERR(("sta info alloc failed\n"));
5915 goto init_priv_mem_out;
5917 wl->afx_hdl = (void *)kzalloc(sizeof(*wl->afx_hdl), GFP_KERNEL);
5918 if (unlikely(!wl->afx_hdl)) {
5919 WL_ERR(("afx hdl alloc failed\n"));
5920 goto init_priv_mem_out;
5922 init_completion(&wl->act_frm_scan);
5923 INIT_WORK(&wl->afx_hdl->work, wl_cfg80211_afx_handler);
5928 wl_deinit_priv_mem(wl);
5933 static void wl_deinit_priv_mem(struct wl_priv *wl)
5935 kfree(wl->scan_results);
5936 wl->scan_results = NULL;
5939 kfree(wl->scan_req_int);
5940 wl->scan_req_int = NULL;
5941 kfree(wl->ioctl_buf);
5942 wl->ioctl_buf = NULL;
5943 kfree(wl->escan_ioctl_buf);
5944 wl->escan_ioctl_buf = NULL;
5945 kfree(wl->extra_buf);
5946 wl->extra_buf = NULL;
5949 kfree(wl->pmk_list);
5950 wl->pmk_list = NULL;
5951 kfree(wl->sta_info);
5952 wl->sta_info = NULL;
5954 cancel_work_sync(&wl->afx_hdl->work);
5960 kfree(wl->ap_info->wpa_ie);
5961 kfree(wl->ap_info->rsn_ie);
5962 kfree(wl->ap_info->wps_ie);
5968 static s32 wl_create_event_handler(struct wl_priv *wl)
5971 WL_DBG(("Enter \n"));
5973 /* Do not use DHD in cfg driver */
5974 wl->event_tsk.thr_pid = -1;
5975 PROC_START(wl_event_handler, wl, &wl->event_tsk, 0);
5976 if (wl->event_tsk.thr_pid < 0)
5981 static void wl_destroy_event_handler(struct wl_priv *wl)
5983 if (wl->event_tsk.thr_pid >= 0)
5984 PROC_STOP(&wl->event_tsk);
5987 static void wl_term_iscan(struct wl_priv *wl)
5989 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
5991 if (wl->iscan_on && iscan->tsk) {
5992 iscan->state = WL_ISCAN_STATE_IDLE;
5993 WL_INFO(("SIGTERM\n"));
5994 send_sig(SIGTERM, iscan->tsk, 1);
5995 WL_DBG(("kthread_stop\n"));
5996 kthread_stop(iscan->tsk);
6001 static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
6003 struct wl_priv *wl = iscan_to_wl(iscan);
6004 struct net_device *ndev = wl_to_prmry_ndev(wl);
6005 unsigned long flags;
6007 WL_DBG(("Enter \n"));
6008 if (!wl_get_drv_status(wl, SCANNING, ndev)) {
6009 wl_clr_drv_status(wl, SCANNING, ndev);
6010 WL_ERR(("Scan complete while device not scanning\n"));
6013 spin_lock_irqsave(&wl->cfgdrv_lock, flags);
6014 wl_clr_drv_status(wl, SCANNING, ndev);
6015 if (likely(wl->scan_request)) {
6016 cfg80211_scan_done(wl->scan_request, aborted);
6017 wl->scan_request = NULL;
6019 spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
6020 wl->iscan_kickstart = false;
6023 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
6025 if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
6026 WL_DBG(("wake up iscan\n"));
6035 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
6036 struct wl_scan_results **bss_list)
6038 struct wl_iscan_results list;
6039 struct wl_scan_results *results;
6040 struct wl_iscan_results *list_buf;
6043 WL_DBG(("Enter \n"));
6044 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
6045 list_buf = (struct wl_iscan_results *)iscan->scan_buf;
6046 results = &list_buf->results;
6047 results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
6048 results->version = 0;
6051 memset(&list, 0, sizeof(list));
6052 list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
6053 err = wldev_iovar_getbuf(iscan->dev, "iscanresults", &list,
6054 WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
6055 WL_ISCAN_BUF_MAX, NULL);
6056 if (unlikely(err)) {
6057 WL_ERR(("error (%d)\n", err));
6060 results->buflen = dtoh32(results->buflen);
6061 results->version = dtoh32(results->version);
6062 results->count = dtoh32(results->count);
6063 WL_DBG(("results->count = %d\n", results->count));
6064 WL_DBG(("results->buflen = %d\n", results->buflen));
6065 *status = dtoh32(list_buf->status);
6066 *bss_list = results;
6071 static s32 wl_iscan_done(struct wl_priv *wl)
6073 struct wl_iscan_ctrl *iscan = wl->iscan;
6076 iscan->state = WL_ISCAN_STATE_IDLE;
6077 mutex_lock(&wl->usr_sync);
6079 wl_notify_iscan_complete(iscan, false);
6080 mutex_unlock(&wl->usr_sync);
6085 static s32 wl_iscan_pending(struct wl_priv *wl)
6087 struct wl_iscan_ctrl *iscan = wl->iscan;
6090 /* Reschedule the timer */
6091 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
6092 iscan->timer_on = 1;
6097 static s32 wl_iscan_inprogress(struct wl_priv *wl)
6099 struct wl_iscan_ctrl *iscan = wl->iscan;
6102 mutex_lock(&wl->usr_sync);
6104 wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
6105 mutex_unlock(&wl->usr_sync);
6106 /* Reschedule the timer */
6107 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
6108 iscan->timer_on = 1;
6113 static s32 wl_iscan_aborted(struct wl_priv *wl)
6115 struct wl_iscan_ctrl *iscan = wl->iscan;
6118 iscan->state = WL_ISCAN_STATE_IDLE;
6119 mutex_lock(&wl->usr_sync);
6120 wl_notify_iscan_complete(iscan, true);
6121 mutex_unlock(&wl->usr_sync);
6126 static s32 wl_iscan_thread(void *data)
6128 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
6129 struct wl_priv *wl = iscan_to_wl(iscan);
6133 allow_signal(SIGTERM);
6134 status = WL_SCAN_RESULTS_PARTIAL;
6135 while (likely(!down_interruptible(&iscan->sync))) {
6136 if (kthread_should_stop())
6138 if (iscan->timer_on) {
6139 del_timer_sync(&iscan->timer);
6140 iscan->timer_on = 0;
6142 mutex_lock(&wl->usr_sync);
6143 err = wl_get_iscan_results(iscan, &status, &wl->bss_list);
6144 if (unlikely(err)) {
6145 status = WL_SCAN_RESULTS_ABORTED;
6146 WL_ERR(("Abort iscan\n"));
6148 mutex_unlock(&wl->usr_sync);
6149 iscan->iscan_handler[status] (wl);
6151 if (iscan->timer_on) {
6152 del_timer_sync(&iscan->timer);
6153 iscan->timer_on = 0;
6155 WL_DBG(("%s was terminated\n", __func__));
6160 static void wl_scan_timeout(unsigned long data)
6162 struct wl_priv *wl = (struct wl_priv *)data;
6164 if (wl->scan_request) {
6165 WL_ERR(("timer expired\n"));
6167 wl_notify_escan_complete(wl, wl->escan_info.ndev, true, false);
6169 wl_notify_iscan_complete(wl_to_iscan(wl), true);
6173 static void wl_iscan_timer(unsigned long data)
6175 struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
6178 iscan->timer_on = 0;
6179 WL_DBG(("timer expired\n"));
6180 wl_wakeup_iscan(iscan);
6184 static s32 wl_invoke_iscan(struct wl_priv *wl)
6186 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
6189 if (wl->iscan_on && !iscan->tsk) {
6190 iscan->state = WL_ISCAN_STATE_IDLE;
6191 sema_init(&iscan->sync, 0);
6192 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
6193 if (IS_ERR(iscan->tsk)) {
6194 WL_ERR(("Could not create iscan thread\n"));
6203 static void wl_init_iscan_handler(struct wl_iscan_ctrl *iscan)
6205 memset(iscan->iscan_handler, 0, sizeof(iscan->iscan_handler));
6206 iscan->iscan_handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
6207 iscan->iscan_handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
6208 iscan->iscan_handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
6209 iscan->iscan_handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
6210 iscan->iscan_handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
6214 wl_cfg80211_netdev_notifier_call(struct notifier_block * nb,
6215 unsigned long state,
6218 struct net_device *dev = ndev;
6219 struct wireless_dev *wdev = dev->ieee80211_ptr;
6220 struct wl_priv *wl = wlcfg_drv_priv;
6222 WL_DBG(("Enter \n"));
6223 if (!wdev || !wl || dev == wl_to_prmry_ndev(wl))
6226 case NETDEV_UNREGISTER:
6227 /* after calling list_del_rcu(&wdev->list) */
6228 wl_dealloc_netinfo(wl, ndev);
6230 case NETDEV_GOING_DOWN:
6231 /* At NETDEV_DOWN state, wdev_cleanup_work work will be called.
6232 * In front of door, the function checks
6233 * whether current scan is working or not.
6234 * If the scanning is still working, wdev_cleanup_work call WARN_ON and
6235 * make the scan done forcibly.
6237 if (wl_get_drv_status(wl, SCANNING, dev)) {
6239 wl_notify_escan_complete(wl, dev, true, true);
6246 static struct notifier_block wl_cfg80211_netdev_notifier = {
6247 .notifier_call = wl_cfg80211_netdev_notifier_call,
6250 static s32 wl_notify_escan_complete(struct wl_priv *wl,
6251 struct net_device *ndev,
6252 bool aborted, bool fw_abort)
6254 wl_scan_params_t *params = NULL;
6255 s32 params_size = 0;
6257 unsigned long flags;
6258 struct net_device *dev;
6260 WL_DBG(("Enter \n"));
6262 if (wl->scan_request) {
6263 if (wl->scan_request->dev == wl->p2p_net)
6264 dev = wl_to_prmry_ndev(wl);
6266 dev = wl->scan_request->dev;
6269 WL_ERR(("wl->scan_request is NULL may be internal scan."
6270 "doing scan_abort for ndev %p primary %p p2p_net %p",
6271 ndev, wl_to_prmry_ndev(wl), wl->p2p_net));
6274 if (fw_abort && !in_atomic()) {
6275 /* Our scan params only need space for 1 channel and 0 ssids */
6276 params = wl_cfg80211_scan_alloc_params(-1, 0, ¶ms_size);
6277 if (params == NULL) {
6278 WL_ERR(("scan params allocation failed \n"));
6281 /* Do a scan abort to stop the driver's scan engine */
6282 err = wldev_ioctl(dev, WLC_SCAN, params, params_size, true);
6284 WL_ERR(("scan abort failed \n"));
6288 if (timer_pending(&wl->scan_timeout))
6289 del_timer_sync(&wl->scan_timeout);
6290 spin_lock_irqsave(&wl->cfgdrv_lock, flags);
6292 #ifdef WL_SCHED_SCAN
6293 if (wl->sched_scan_req && !wl->scan_request) {
6294 WL_DBG((" REPORTING SCHED SCAN RESULTS \n"));
6296 cfg80211_sched_scan_stopped(wl->sched_scan_req->wiphy);
6298 cfg80211_sched_scan_results(wl->sched_scan_req->wiphy);
6299 wl->sched_scan_running = FALSE;
6300 wl->sched_scan_req = NULL;
6302 #endif /* WL_SCHED_SCAN */
6304 if (likely(wl->scan_request)) {
6305 cfg80211_scan_done(wl->scan_request, aborted);
6306 wl->scan_request = NULL;
6309 wl_clr_p2p_status(wl, SCANNING);
6310 wl_clr_drv_status(wl, SCANNING, dev);
6311 spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
6318 static s32 wl_escan_handler(struct wl_priv *wl,
6319 struct net_device *ndev,
6320 const wl_event_msg_t *e, void *data)
6323 s32 status = ntoh32(e->status);
6325 wl_escan_result_t *escan_result;
6326 wl_bss_info_t *bss = NULL;
6327 wl_scan_results_t *list;
6330 u8 *p2p_dev_addr = NULL;
6331 WL_DBG((" enter event type : %d, status : %d \n",
6332 ntoh32(e->event_type), ntoh32(e->status)));
6333 /* P2P SCAN is coming from primary interface */
6334 if (wl_get_p2p_status(wl, SCANNING)) {
6335 if (wl_get_drv_status_all(wl, SENDING_ACT_FRM))
6336 ndev = wl->afx_hdl->dev;
6338 ndev = wl->escan_info.ndev;
6341 if (!ndev || !wl->escan_on ||
6342 !wl_get_drv_status(wl, SCANNING, ndev)) {
6343 WL_ERR(("escan is not ready ndev %p wl->escan_on %d drv_status 0x%x\n",
6344 ndev, wl->escan_on, wl_get_drv_status(wl, SCANNING, ndev)));
6348 if (status == WLC_E_STATUS_PARTIAL) {
6349 WL_INFO(("WLC_E_STATUS_PARTIAL \n"));
6350 escan_result = (wl_escan_result_t *) data;
6351 if (!escan_result) {
6352 WL_ERR(("Invalid escan result (NULL pointer)\n"));
6355 if (dtoh16(escan_result->bss_count) != 1) {
6356 WL_ERR(("Invalid bss_count %d: ignoring\n", escan_result->bss_count));
6359 bi = escan_result->bss_info;
6361 WL_ERR(("Invalid escan bss info (NULL pointer)\n"));
6364 bi_length = dtoh32(bi->length);
6365 if (bi_length != (dtoh32(escan_result->buflen) - WL_ESCAN_RESULTS_FIXED_SIZE)) {
6366 WL_ERR(("Invalid bss_info length %d: ignoring\n", bi_length));
6370 if (!(wl_to_wiphy(wl)->interface_modes & BIT(NL80211_IFTYPE_ADHOC))) {
6371 if (dtoh16(bi->capability) & DOT11_CAP_IBSS) {
6372 WL_DBG(("Ignoring IBSS result\n"));
6377 if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
6378 p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length);
6379 if (p2p_dev_addr && !memcmp(p2p_dev_addr,
6380 wl->afx_hdl->pending_tx_dst_addr.octet, ETHER_ADDR_LEN)) {
6381 s32 channel = CHSPEC_CHANNEL(dtohchanspec(bi->chanspec));
6382 WL_DBG(("ACTION FRAME SCAN : Peer " MACSTR " found, channel : %d\n",
6383 MAC2STR(wl->afx_hdl->pending_tx_dst_addr.octet), channel));
6384 wl_clr_p2p_status(wl, SCANNING);
6385 wl->afx_hdl->peer_chan = channel;
6386 complete(&wl->act_frm_scan);
6391 list = (wl_scan_results_t *)wl->escan_info.escan_buf;
6392 if (bi_length > ESCAN_BUF_SIZE - list->buflen) {
6393 WL_ERR(("Buffer is too small: ignoring\n"));
6396 #define WLC_BSS_RSSI_ON_CHANNEL 0x0002
6397 for (i = 0; i < list->count; i++) {
6398 bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length))
6401 if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) &&
6402 CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) &&
6403 bi->SSID_len == bss->SSID_len &&
6404 !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) {
6405 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
6406 (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
6407 /* preserve max RSSI if the measurements are
6408 * both on-channel or both off-channel
6410 bss->RSSI = MAX(bss->RSSI, bi->RSSI);
6411 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
6412 (bi->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
6413 /* preserve the on-channel rssi measurement
6414 * if the new measurement is off channel
6416 bss->RSSI = bi->RSSI;
6417 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
6423 memcpy(&(wl->escan_info.escan_buf[list->buflen]), bi, bi_length);
6424 list->version = dtoh32(bi->version);
6425 list->buflen += bi_length;
6431 else if (status == WLC_E_STATUS_SUCCESS) {
6432 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
6433 if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
6434 WL_INFO(("ACTION FRAME SCAN DONE\n"));
6435 wl_clr_p2p_status(wl, SCANNING);
6436 wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
6437 if (wl->afx_hdl->peer_chan == WL_INVALID)
6438 complete(&wl->act_frm_scan);
6439 } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
6440 mutex_lock(&wl->usr_sync);
6441 WL_INFO(("ESCAN COMPLETED\n"));
6442 wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
6444 wl_notify_escan_complete(wl, ndev, false, false);
6445 mutex_unlock(&wl->usr_sync);
6448 else if (status == WLC_E_STATUS_ABORT) {
6449 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
6450 if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
6451 WL_INFO(("ACTION FRAME SCAN DONE\n"));
6452 wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
6453 wl_clr_p2p_status(wl, SCANNING);
6454 if (wl->afx_hdl->peer_chan == WL_INVALID)
6455 complete(&wl->act_frm_scan);
6456 } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
6457 mutex_lock(&wl->usr_sync);
6458 WL_INFO(("ESCAN ABORTED\n"));
6459 wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
6461 wl_notify_escan_complete(wl, ndev, true, false);
6462 mutex_unlock(&wl->usr_sync);
6466 WL_ERR(("unexpected Escan Event %d : abort\n", status));
6467 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
6468 if (wl_get_drv_status_all(wl, SENDING_ACT_FRM)) {
6469 WL_INFO(("ACTION FRAME SCAN DONE\n"));
6470 wl_clr_p2p_status(wl, SCANNING);
6471 wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
6472 if (wl->afx_hdl->peer_chan == WL_INVALID)
6473 complete(&wl->act_frm_scan);
6474 } else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
6475 mutex_lock(&wl->usr_sync);
6476 wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
6478 wl_notify_escan_complete(wl, ndev, true, false);
6479 mutex_unlock(&wl->usr_sync);
6486 static s32 wl_init_scan(struct wl_priv *wl)
6488 struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
6492 iscan->dev = wl_to_prmry_ndev(wl);
6493 iscan->state = WL_ISCAN_STATE_IDLE;
6494 wl_init_iscan_handler(iscan);
6495 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
6496 init_timer(&iscan->timer);
6497 iscan->timer.data = (unsigned long) iscan;
6498 iscan->timer.function = wl_iscan_timer;
6499 sema_init(&iscan->sync, 0);
6500 iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan");
6501 if (IS_ERR(iscan->tsk)) {
6502 WL_ERR(("Could not create iscan thread\n"));
6507 } else if (wl->escan_on) {
6508 wl->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler;
6509 wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
6511 /* Init scan_timeout timer */
6512 init_timer(&wl->scan_timeout);
6513 wl->scan_timeout.data = (unsigned long) wl;
6514 wl->scan_timeout.function = wl_scan_timeout;
6519 static s32 wl_init_priv(struct wl_priv *wl)
6521 struct wiphy *wiphy = wl_to_wiphy(wl);
6522 struct net_device *ndev = wl_to_prmry_ndev(wl);
6525 wl->scan_request = NULL;
6526 wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
6527 wl->iscan_on = false;
6528 wl->escan_on = true;
6529 wl->roam_on = false;
6530 wl->iscan_kickstart = false;
6531 wl->active_scan = true;
6532 wl->rf_blocked = false;
6533 wl->deauth_reason = 0;
6534 spin_lock_init(&wl->cfgdrv_lock);
6535 mutex_init(&wl->ioctl_buf_sync);
6536 init_waitqueue_head(&wl->netif_change_event);
6538 err = wl_init_priv_mem(wl);
6541 if (wl_create_event_handler(wl))
6543 wl_init_event_handler(wl);
6544 mutex_init(&wl->usr_sync);
6545 err = wl_init_scan(wl);
6548 wl_init_conf(wl->conf);
6549 wl_init_prof(wl, ndev);
6551 DNGL_FUNC(dhd_cfg80211_init, (wl));
6556 static void wl_deinit_priv(struct wl_priv *wl)
6558 DNGL_FUNC(dhd_cfg80211_deinit, (wl));
6559 wl_destroy_event_handler(wl);
6562 del_timer_sync(&wl->scan_timeout);
6564 wl_deinit_priv_mem(wl);
6565 unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier);
6568 #if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
6569 static s32 wl_cfg80211_attach_p2p(void)
6571 struct wl_priv *wl = wlcfg_drv_priv;
6573 WL_TRACE(("Enter \n"));
6575 if (wl_cfgp2p_register_ndev(wl) < 0) {
6576 WL_ERR(("%s: P2P attach failed. \n", __func__));
6583 static s32 wl_cfg80211_detach_p2p(void)
6585 struct wl_priv *wl = wlcfg_drv_priv;
6586 struct wireless_dev *wdev = wl->p2p_wdev;
6588 WL_DBG(("Enter \n"));
6590 WL_ERR(("Invalid Ptr\n"));
6594 wl_cfgp2p_unregister_ndev(wl);
6596 wl->p2p_wdev = NULL;
6598 WL_DBG(("Freeing 0x%08x \n", (unsigned int)wdev));
6603 #endif /* defined(WLP2P) && defined(WL_ENABLE_P2P_IF) */
6605 s32 wl_cfg80211_attach_post(struct net_device *ndev)
6607 struct wl_priv * wl = NULL;
6610 if (unlikely(!ndev)) {
6611 WL_ERR(("ndev is invaild\n"));
6614 wl = wlcfg_drv_priv;
6615 if (wl && !wl_get_drv_status(wl, READY, ndev)) {
6617 wl_cfgp2p_supported(wl, ndev)) {
6618 #if !defined(WL_ENABLE_P2P_IF)
6619 wl->wdev->wiphy->interface_modes |=
6620 (BIT(NL80211_IFTYPE_P2P_CLIENT)|
6621 BIT(NL80211_IFTYPE_P2P_GO));
6623 if ((err = wl_cfgp2p_init_priv(wl)) != 0)
6626 #if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
6628 /* Update MAC addr for p2p0 interface here. */
6629 memcpy(wl->p2p_net->dev_addr, ndev->dev_addr, ETH_ALEN);
6630 wl->p2p_net->dev_addr[0] |= 0x02;
6631 printk("%s: p2p_dev_addr="MACSTR "\n",
6632 wl->p2p_net->name, MAC2STR(wl->p2p_net->dev_addr));
6634 WL_ERR(("p2p_net not yet populated."
6635 " Couldn't update the MAC Address for p2p0 \n"));
6638 #endif /* defined(WLP2P) && (WL_ENABLE_P2P_IF) */
6640 wl->p2p_supported = true;
6644 wl_set_drv_status(wl, READY, ndev);
6649 s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
6651 struct wireless_dev *wdev;
6658 WL_ERR(("ndev is invaild\n"));
6661 WL_DBG(("func %p\n", wl_cfg80211_get_parent_dev()));
6662 dev = wl_cfg80211_get_parent_dev();
6664 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
6665 if (unlikely(!wdev)) {
6666 WL_ERR(("Could not allocate wireless device\n"));
6669 err = wl_setup_wiphy(wdev, dev);
6670 if (unlikely(err)) {
6674 wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
6675 wl = (struct wl_priv *)wiphy_priv(wdev->wiphy);
6678 INIT_LIST_HEAD(&wl->net_list);
6679 ndev->ieee80211_ptr = wdev;
6680 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
6681 wdev->netdev = ndev;
6682 err = wl_alloc_netinfo(wl, ndev, wdev, WL_MODE_BSS);
6684 WL_ERR(("Failed to alloc net_info (%d)\n", err));
6685 goto cfg80211_attach_out;
6687 err = wl_init_priv(wl);
6689 WL_ERR(("Failed to init iwm_priv (%d)\n", err));
6690 goto cfg80211_attach_out;
6693 err = wl_setup_rfkill(wl, TRUE);
6695 WL_ERR(("Failed to setup rfkill %d\n", err));
6696 goto cfg80211_attach_out;
6698 err = register_netdevice_notifier(&wl_cfg80211_netdev_notifier);
6700 WL_ERR(("Failed to register notifierl %d\n", err));
6701 goto cfg80211_attach_out;
6703 #if defined(COEX_DHCP)
6704 if (wl_cfg80211_btcoex_init(wl))
6705 goto cfg80211_attach_out;
6708 wlcfg_drv_priv = wl;
6710 #if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
6711 err = wl_cfg80211_attach_p2p();
6713 goto cfg80211_attach_out;
6718 cfg80211_attach_out:
6719 err = wl_setup_rfkill(wl, FALSE);
6724 void wl_cfg80211_detach(void *para)
6728 wl = wlcfg_drv_priv;
6732 #if defined(COEX_DHCP)
6733 wl_cfg80211_btcoex_deinit(wl);
6736 #if defined(WLP2P) && defined(WL_ENABLE_P2P_IF)
6737 wl_cfg80211_detach_p2p();
6739 wl_setup_rfkill(wl, FALSE);
6740 if (wl->p2p_supported)
6741 wl_cfgp2p_deinit_priv(wl);
6743 wlcfg_drv_priv = NULL;
6744 wl_cfg80211_clear_parent_dev();
6746 /* PLEASE do NOT call any function after wl_free_wdev, the driver's private structure "wl",
6747 * which is the private part of wiphy, has been freed in wl_free_wdev !!!!!!!!!!!
6751 static void wl_wakeup_event(struct wl_priv *wl)
6753 if (wl->event_tsk.thr_pid >= 0) {
6754 DHD_OS_WAKE_LOCK(wl->pub);
6755 up(&wl->event_tsk.sema);
6759 static int wl_is_p2p_event(struct wl_event_q *e)
6762 /* We have to seperate out the P2P events received
6763 * on primary interface so that it can be send up
6764 * via p2p0 interface.
6766 case WLC_E_P2P_PROBREQ_MSG:
6767 case WLC_E_P2P_DISC_LISTEN_COMPLETE:
6768 case WLC_E_ACTION_FRAME_RX:
6769 case WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE:
6770 case WLC_E_ACTION_FRAME_COMPLETE:
6772 if (e->emsg.ifidx != 0) {
6773 WL_TRACE(("P2P Event on Virtual I/F (ifidx:%d) \n",
6775 /* We are only bothered about the P2P events received
6776 * on primary interface. For rest of them return false
6777 * so that it is sent over the interface corresponding
6782 WL_TRACE(("P2P Event on Primary I/F (ifidx:%d)."
6783 " Sent it to p2p0 \n", e->emsg.ifidx));
6789 WL_TRACE(("NON-P2P Event %d on ifidx (ifidx:%d) \n",
6790 e->etype, e->emsg.ifidx));
6795 static s32 wl_event_handler(void *data)
6797 struct net_device *netdev;
6798 struct wl_priv *wl = NULL;
6799 struct wl_event_q *e;
6800 tsk_ctl_t *tsk = (tsk_ctl_t *)data;
6802 wl = (struct wl_priv *)tsk->parent;
6803 DAEMONIZE("dhd_cfg80211_event");
6804 complete(&tsk->completed);
6806 while (down_interruptible (&tsk->sema) == 0) {
6807 SMP_RD_BARRIER_DEPENDS();
6808 if (tsk->terminated)
6810 while ((e = wl_deq_event(wl))) {
6811 WL_DBG(("event type (%d), if idx: %d\n", e->etype, e->emsg.ifidx));
6812 /* All P2P device address related events comes on primary interface since
6813 * there is no corresponding bsscfg for P2P interface. Map it to p2p0
6816 if ((wl_is_p2p_event(e) == TRUE) && (wl->p2p_net)) {
6817 netdev = wl->p2p_net;
6819 netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx);
6822 netdev = wl_to_prmry_ndev(wl);
6823 if (e->etype < WLC_E_LAST && wl->evt_handler[e->etype]) {
6824 wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata);
6826 WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
6830 DHD_OS_WAKE_UNLOCK(wl->pub);
6832 WL_ERR(("%s was terminated\n", __func__));
6833 complete_and_exit(&tsk->completed, 0);
6838 wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
6840 u32 event_type = ntoh32(e->event_type);
6841 struct wl_priv *wl = wlcfg_drv_priv;
6843 #if (WL_DBG_LEVEL > 0)
6844 s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
6845 wl_dbg_estr[event_type] : (s8 *) "Unknown";
6846 WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
6847 #endif /* (WL_DBG_LEVEL > 0) */
6849 if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
6850 wl_wakeup_event(wl);
6853 static void wl_init_eq(struct wl_priv *wl)
6855 wl_init_eq_lock(wl);
6856 INIT_LIST_HEAD(&wl->eq_list);
6859 static void wl_flush_eq(struct wl_priv *wl)
6861 struct wl_event_q *e;
6862 unsigned long flags;
6864 flags = wl_lock_eq(wl);
6865 while (!list_empty(&wl->eq_list)) {
6866 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
6867 list_del(&e->eq_list);
6870 wl_unlock_eq(wl, flags);
6874 * retrieve first queued event from head
6877 static struct wl_event_q *wl_deq_event(struct wl_priv *wl)
6879 struct wl_event_q *e = NULL;
6880 unsigned long flags;
6882 flags = wl_lock_eq(wl);
6883 if (likely(!list_empty(&wl->eq_list))) {
6884 e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
6885 list_del(&e->eq_list);
6887 wl_unlock_eq(wl, flags);
6893 * push event to tail of the queue
6897 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg,
6900 struct wl_event_q *e;
6904 unsigned long flags;
6909 data_len = ntoh32(msg->datalen);
6910 evtq_size = sizeof(struct wl_event_q) + data_len;
6911 aflags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
6912 e = kzalloc(evtq_size, aflags);
6914 WL_ERR(("event alloc failed\n"));
6918 memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
6920 memcpy(e->edata, data, data_len);
6921 flags = wl_lock_eq(wl);
6922 list_add_tail(&e->eq_list, &wl->eq_list);
6923 wl_unlock_eq(wl, flags);
6928 static void wl_put_event(struct wl_event_q *e)
6933 static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 iftype)
6939 case NL80211_IFTYPE_MONITOR:
6940 case NL80211_IFTYPE_WDS:
6941 WL_ERR(("type (%d) : currently we do not support this mode\n",
6945 case NL80211_IFTYPE_ADHOC:
6946 mode = WL_MODE_IBSS;
6948 case NL80211_IFTYPE_STATION:
6949 case NL80211_IFTYPE_P2P_CLIENT:
6953 case NL80211_IFTYPE_AP:
6954 case NL80211_IFTYPE_P2P_GO:
6960 WL_ERR(("invalid type (%d)\n", iftype));
6963 infra = htod32(infra);
6964 err = wldev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra), true);
6965 if (unlikely(err)) {
6966 WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
6970 wl_set_mode_by_netdev(wl, ndev, mode);
6975 static s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
6977 s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
6979 s8 eventmask[WL_EVENTING_MASK_LEN];
6982 /* Setup event_msgs */
6983 bcm_mkiovar("event_msgs", NULL, 0, iovbuf,
6985 err = wldev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf), false);
6986 if (unlikely(err)) {
6987 WL_ERR(("Get event_msgs error (%d)\n", err));
6990 memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
6992 setbit(eventmask, event);
6994 clrbit(eventmask, event);
6996 bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
6998 err = wldev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf), true);
6999 if (unlikely(err)) {
7000 WL_ERR(("Set event_msgs error (%d)\n", err));
7009 static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap)
7011 struct net_device *dev = wl_to_prmry_ndev(wl);
7012 struct ieee80211_channel *band_chan_arr = NULL;
7013 wl_uint32_list_t *list;
7014 u32 i, j, index, n_2g, n_5g, band, channel, array_size;
7022 #define LOCAL_BUF_LEN 1024
7023 pbuf = kzalloc(LOCAL_BUF_LEN, GFP_KERNEL);
7025 WL_ERR(("failed to allocate local buf\n"));
7029 list = (wl_uint32_list_t *)(void *)pbuf;
7030 list->count = htod32(WL_NUMCHANSPECS);
7032 err = wldev_iovar_getbuf_bsscfg(dev, "chanspecs", NULL,
7033 0, pbuf, LOCAL_BUF_LEN, 0, &wl->ioctl_buf_sync);
7035 WL_ERR(("get chanspecs failed with %d\n", err));
7039 #undef LOCAL_BUF_LEN
7041 band = array_size = n_2g = n_5g = 0;
7042 for (i = 0; i < dtoh32(list->count); i++) {
7045 ht40_allowed = FALSE;
7046 c = (chanspec_t)dtoh32(list->element[i]);
7047 channel = CHSPEC_CHANNEL(c);
7048 if (CHSPEC_IS40(c)) {
7049 if (CHSPEC_SB_UPPER(c))
7050 channel += CH_10MHZ_APART;
7052 channel -= CH_10MHZ_APART;
7055 if (CHSPEC_IS2G(c) && channel <= CH_MAX_2G_CHANNEL) {
7056 band_chan_arr = __wl_2ghz_channels;
7057 array_size = ARRAYSIZE(__wl_2ghz_channels);
7059 band = IEEE80211_BAND_2GHZ;
7060 ht40_allowed = (bw_cap == WLC_N_BW_40ALL) ? TRUE : FALSE;
7061 } else if (CHSPEC_IS5G(c) && channel > CH_MAX_2G_CHANNEL) {
7062 band_chan_arr = __wl_5ghz_a_channels;
7063 array_size = ARRAYSIZE(__wl_5ghz_a_channels);
7065 band = IEEE80211_BAND_5GHZ;
7066 ht40_allowed = (bw_cap == WLC_N_BW_20ALL) ? FALSE : TRUE;
7069 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
7070 if (band_chan_arr[j].hw_value == channel) {
7081 if (index < array_size) {
7082 #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
7083 band_chan_arr[index].center_freq =
7084 ieee80211_channel_to_frequency(channel);
7086 band_chan_arr[index].center_freq =
7087 ieee80211_channel_to_frequency(channel, band);
7089 band_chan_arr[index].hw_value = channel;
7091 if (CHSPEC_IS40(c) && ht40_allowed) {
7092 u32 ht40_flag = band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40;
7093 if (CHSPEC_SB_UPPER(c)) {
7094 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
7095 band_chan_arr[index].flags &= ~IEEE80211_CHAN_NO_HT40;
7096 band_chan_arr[index].flags |= IEEE80211_CHAN_NO_HT40PLUS;
7098 band_chan_arr[index].flags &= ~IEEE80211_CHAN_NO_HT40;
7099 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
7100 band_chan_arr[index].flags |= IEEE80211_CHAN_NO_HT40MINUS;
7103 band_chan_arr[index].flags = IEEE80211_CHAN_NO_HT40;
7104 if (band == IEEE80211_BAND_2GHZ)
7105 channel |= WL_CHANSPEC_BAND_2G;
7107 channel |= WL_CHANSPEC_BAND_5G;
7108 err = wldev_iovar_getint(dev, "per_chan_info", &channel);
7110 if (channel & WL_CHAN_RADAR) {
7111 band_chan_arr[index].flags |= IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS;
7113 if (channel & WL_CHAN_PASSIVE) {
7114 band_chan_arr[index].flags |= IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS;
7124 __wl_band_2ghz.n_channels = n_2g;
7125 __wl_band_5ghz_a.n_channels = n_5g;
7131 s32 wl_update_wiphybands(struct wl_priv *wl)
7133 struct wiphy *wiphy;
7134 struct net_device *dev;
7146 wl = wlcfg_drv_priv;
7147 dev = wl_to_prmry_ndev(wl);
7149 memset(bandlist, 0, sizeof(bandlist));
7150 err = wldev_ioctl(dev, WLC_GET_BANDLIST, bandlist,
7151 sizeof(bandlist), false);
7152 if (unlikely(err)) {
7153 WL_ERR(("error read bandlist (%d)\n", err));
7156 wiphy = wl_to_wiphy(wl);
7157 nband = bandlist[0];
7158 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
7159 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
7161 err = wldev_iovar_getint(dev, "nmode", &nmode);
7162 if (unlikely(err)) {
7163 WL_ERR(("error reading nmode (%d)\n", err));
7165 /* For nmodeonly check bw cap */
7166 err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
7167 if (unlikely(err)) {
7168 WL_ERR(("error get mimo_bw_cap (%d)\n", err));
7172 err = wl_construct_reginfo(wl, bw_cap);
7174 WL_ERR(("wl_construct_reginfo() fails err=%d\n", err));
7177 for (i = 1; i <= nband && i < sizeof(bandlist)/sizeof(u32); i++) {
7179 if (bandlist[i] == WLC_BAND_5G && __wl_band_5ghz_a.n_channels > 0) {
7180 wiphy->bands[IEEE80211_BAND_5GHZ] =
7182 index = IEEE80211_BAND_5GHZ;
7183 if (bw_cap == WLC_N_BW_40ALL || bw_cap == WLC_N_BW_20IN2G_40IN5G)
7184 wiphy->bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
7185 } else if (bandlist[i] == WLC_BAND_2G && __wl_band_2ghz.n_channels > 0) {
7186 wiphy->bands[IEEE80211_BAND_2GHZ] =
7188 index = IEEE80211_BAND_2GHZ;
7189 if (bandlist[i] == WLC_BAND_2G && bw_cap == WLC_N_BW_40ALL)
7190 wiphy->bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
7192 if ((index >= 0) && nmode) {
7193 wiphy->bands[index]->ht_cap.cap |=
7194 IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40;
7195 wiphy->bands[index]->ht_cap.ht_supported = TRUE;
7196 wiphy->bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
7197 wiphy->bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
7201 wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
7205 static s32 __wl_cfg80211_up(struct wl_priv *wl)
7208 struct net_device *ndev = wl_to_prmry_ndev(wl);
7209 struct wireless_dev *wdev = ndev->ieee80211_ptr;
7213 err = dhd_config_dongle(wl, false);
7217 err = wl_config_ifmode(wl, ndev, wdev->iftype);
7218 if (unlikely(err && err != -EINPROGRESS)) {
7219 WL_ERR(("wl_config_ifmode failed\n"));
7221 err = wl_update_wiphybands(wl);
7222 if (unlikely(err)) {
7223 WL_ERR(("wl_update_wiphybands failed\n"));
7226 err = dhd_monitor_init(wl->pub);
7227 err = wl_invoke_iscan(wl);
7228 wl_set_drv_status(wl, READY, ndev);
7232 static s32 __wl_cfg80211_down(struct wl_priv *wl)
7235 unsigned long flags;
7236 struct net_info *iter, *next;
7237 struct net_device *ndev = wl_to_prmry_ndev(wl);
7238 #ifdef WL_ENABLE_P2P_IF
7239 struct wiphy *wiphy = wl_to_prmry_ndev(wl)->ieee80211_ptr->wiphy;
7240 struct net_device *p2p_net = wl->p2p_net;
7244 /* Check if cfg80211 interface is already down */
7245 if (!wl_get_drv_status(wl, READY, ndev))
7246 return err; /* it is even not ready */
7247 for_each_ndev(wl, iter, next)
7248 wl_set_drv_status(wl, SCAN_ABORTING, iter->ndev);
7251 spin_lock_irqsave(&wl->cfgdrv_lock, flags);
7252 if (wl->scan_request) {
7253 cfg80211_scan_done(wl->scan_request, true);
7254 wl->scan_request = NULL;
7256 for_each_ndev(wl, iter, next) {
7257 wl_clr_drv_status(wl, READY, iter->ndev);
7258 wl_clr_drv_status(wl, SCANNING, iter->ndev);
7259 wl_clr_drv_status(wl, SCAN_ABORTING, iter->ndev);
7260 wl_clr_drv_status(wl, CONNECTING, iter->ndev);
7261 wl_clr_drv_status(wl, CONNECTED, iter->ndev);
7262 wl_clr_drv_status(wl, DISCONNECTING, iter->ndev);
7263 wl_clr_drv_status(wl, AP_CREATED, iter->ndev);
7264 wl_clr_drv_status(wl, AP_CREATING, iter->ndev);
7266 wl_to_prmry_ndev(wl)->ieee80211_ptr->iftype =
7267 NL80211_IFTYPE_STATION;
7268 #ifdef WL_ENABLE_P2P_IF
7269 wiphy->interface_modes = (wiphy->interface_modes)
7270 & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)|
7271 BIT(NL80211_IFTYPE_P2P_GO)));
7272 if ((p2p_net) && (p2p_net->flags & IFF_UP)) {
7273 /* p2p0 interface is still UP. Bring it down */
7274 p2p_net->flags &= ~IFF_UP;
7276 #endif /* WL_ENABLE_P2P_IF */
7277 spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
7279 DNGL_FUNC(dhd_cfg80211_down, (wl));
7282 if (wl->p2p_supported)
7284 dhd_monitor_uninit();
7289 s32 wl_cfg80211_up(void *para)
7295 wl = wlcfg_drv_priv;
7296 mutex_lock(&wl->usr_sync);
7297 wl_cfg80211_attach_post(wl_to_prmry_ndev(wl));
7298 err = __wl_cfg80211_up(wl);
7300 WL_ERR(("__wl_cfg80211_up failed\n"));
7301 mutex_unlock(&wl->usr_sync);
7305 /* Private Event to Supplicant with indication that chip hangs */
7306 int wl_cfg80211_hang(struct net_device *dev, u16 reason)
7309 wl = wlcfg_drv_priv;
7311 WL_ERR(("In : chip crash eventing\n"));
7312 cfg80211_disconnected(dev, reason, NULL, 0, GFP_KERNEL);
7319 s32 wl_cfg80211_down(void *para)
7325 wl = wlcfg_drv_priv;
7326 mutex_lock(&wl->usr_sync);
7327 err = __wl_cfg80211_down(wl);
7328 mutex_unlock(&wl->usr_sync);
7333 static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item)
7335 unsigned long flags;
7337 struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
7341 spin_lock_irqsave(&wl->cfgdrv_lock, flags);
7344 rptr = &profile->sec;
7347 rptr = &profile->active;
7350 rptr = profile->bssid;
7353 rptr = &profile->ssid;
7356 spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
7358 WL_ERR(("invalid item (%d)\n", item));
7363 wl_update_prof(struct wl_priv *wl, struct net_device *ndev,
7364 const wl_event_msg_t *e, void *data, s32 item)
7367 struct wlc_ssid *ssid;
7368 unsigned long flags;
7369 struct wl_profile *profile = wl_get_profile_by_netdev(wl, ndev);
7373 spin_lock_irqsave(&wl->cfgdrv_lock, flags);
7376 ssid = (wlc_ssid_t *) data;
7377 memset(profile->ssid.SSID, 0,
7378 sizeof(profile->ssid.SSID));
7379 memcpy(profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
7380 profile->ssid.SSID_len = ssid->SSID_len;
7384 memcpy(profile->bssid, data, ETHER_ADDR_LEN);
7386 memset(profile->bssid, 0, ETHER_ADDR_LEN);
7389 memcpy(&profile->sec, data, sizeof(profile->sec));
7392 profile->active = *(bool *)data;
7394 case WL_PROF_BEACONINT:
7395 profile->beacon_interval = *(u16 *)data;
7397 case WL_PROF_DTIMPERIOD:
7398 profile->dtim_period = *(u8 *)data;
7401 WL_ERR(("unsupported item (%d)\n", item));
7405 spin_unlock_irqrestore(&wl->cfgdrv_lock, flags);
7409 void wl_cfg80211_dbg_level(u32 level)
7412 * prohibit to change debug level
7413 * by insmod parameter.
7414 * eventually debug level will be configured
7415 * in compile time by using CONFIG_XXX
7417 /* wl_dbg_level = level; */
7420 static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev)
7422 return wl_get_mode_by_netdev(wl, ndev) == WL_MODE_IBSS;
7425 static __used bool wl_is_ibssstarter(struct wl_priv *wl)
7427 return wl->ibss_starter;
7430 static void wl_rst_ie(struct wl_priv *wl)
7432 struct wl_ie *ie = wl_to_ie(wl);
7437 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
7439 struct wl_ie *ie = wl_to_ie(wl);
7442 if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
7443 WL_ERR(("ei crosses buffer boundary\n"));
7446 ie->buf[ie->offset] = t;
7447 ie->buf[ie->offset + 1] = l;
7448 memcpy(&ie->buf[ie->offset + 2], v, l);
7449 ie->offset += l + 2;
7454 static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
7456 struct wl_ie *ie = wl_to_ie(wl);
7459 if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
7460 WL_ERR(("ei_stream crosses buffer boundary\n"));
7463 memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
7464 ie->offset += ie_size;
7469 static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
7471 struct wl_ie *ie = wl_to_ie(wl);
7474 if (unlikely(ie->offset > dst_size)) {
7475 WL_ERR(("dst_size is not enough\n"));
7478 memcpy(dst, &ie->buf[0], ie->offset);
7483 static u32 wl_get_ielen(struct wl_priv *wl)
7485 struct wl_ie *ie = wl_to_ie(wl);
7490 static void wl_link_up(struct wl_priv *wl)
7495 static void wl_link_down(struct wl_priv *wl)
7497 struct wl_connect_info *conn_info = wl_to_conn(wl);
7500 wl->link_up = false;
7501 conn_info->req_ie_len = 0;
7502 conn_info->resp_ie_len = 0;
7505 static unsigned long wl_lock_eq(struct wl_priv *wl)
7507 unsigned long flags;
7509 spin_lock_irqsave(&wl->eq_lock, flags);
7513 static void wl_unlock_eq(struct wl_priv *wl, unsigned long flags)
7515 spin_unlock_irqrestore(&wl->eq_lock, flags);
7518 static void wl_init_eq_lock(struct wl_priv *wl)
7520 spin_lock_init(&wl->eq_lock);
7523 static void wl_delay(u32 ms)
7525 if (in_atomic() || ms < 1000 / HZ) {
7532 s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr)
7534 struct wl_priv *wl = wlcfg_drv_priv;
7535 struct ether_addr p2pif_addr;
7536 struct ether_addr primary_mac;
7540 if (!p2p_is_on(wl)) {
7541 get_primary_mac(wl, &primary_mac);
7542 wl_cfgp2p_generate_bss_mac(&primary_mac, p2pdev_addr, &p2pif_addr);
7544 memcpy(p2pdev_addr->octet,
7545 wl->p2p->dev_addr.octet, ETHER_ADDR_LEN);
7550 s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len)
7554 wl = wlcfg_drv_priv;
7556 return wl_cfgp2p_set_p2p_noa(wl, net, buf, len);
7559 s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len)
7562 wl = wlcfg_drv_priv;
7564 return wl_cfgp2p_get_p2p_noa(wl, net, buf, len);
7567 s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len)
7570 wl = wlcfg_drv_priv;
7572 return wl_cfgp2p_set_p2p_ps(wl, net, buf, len);
7575 s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len,
7576 enum wl_management_type type)
7579 struct net_device *ndev = NULL;
7580 struct ether_addr primary_mac;
7584 wl = wlcfg_drv_priv;
7586 if (wl_get_drv_status(wl, AP_CREATING, net) ||
7587 wl_get_drv_status(wl, AP_CREATED, net)) {
7590 } else if (wl->p2p) {
7591 if (net == wl->p2p_net) {
7592 net = wl_to_prmry_ndev(wl);
7596 get_primary_mac(wl, &primary_mac);
7597 wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr,
7598 &wl->p2p->int_addr);
7599 /* In case of p2p_listen command, supplicant send remain_on_channel
7600 * without turning on P2P
7603 ret = wl_cfgp2p_enable_discovery(wl, ndev, NULL, 0);
7605 if (unlikely(ret)) {
7609 if (net != wl_to_prmry_ndev(wl)) {
7610 if (wl_get_mode_by_netdev(wl, net) == WL_MODE_AP) {
7611 ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
7612 bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION);
7615 ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY);
7616 bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
7622 pktflag = VNDR_IE_BEACON_FLAG;
7625 pktflag = VNDR_IE_PRBRSP_FLAG;
7628 pktflag = VNDR_IE_ASSOCRSP_FLAG;
7632 ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len);
7638 static const struct rfkill_ops wl_rfkill_ops = {
7639 .set_block = wl_rfkill_set
7642 static int wl_rfkill_set(void *data, bool blocked)
7644 struct wl_priv *wl = (struct wl_priv *)data;
7646 WL_DBG(("Enter \n"));
7647 WL_DBG(("RF %s\n", blocked ? "blocked" : "unblocked"));
7652 wl->rf_blocked = blocked;
7657 static int wl_setup_rfkill(struct wl_priv *wl, bool setup)
7661 WL_DBG(("Enter \n"));
7665 wl->rfkill = rfkill_alloc("brcmfmac-wifi",
7666 wl_cfg80211_get_parent_dev(),
7667 RFKILL_TYPE_WLAN, &wl_rfkill_ops, (void *)wl);
7674 err = rfkill_register(wl->rfkill);
7677 rfkill_destroy(wl->rfkill);
7684 rfkill_unregister(wl->rfkill);
7685 rfkill_destroy(wl->rfkill);
7692 struct device *wl_cfg80211_get_parent_dev(void)
7694 return cfg80211_parent_dev;
7697 void wl_cfg80211_set_parent_dev(void *dev)
7699 cfg80211_parent_dev = dev;
7702 static void wl_cfg80211_clear_parent_dev(void)
7704 cfg80211_parent_dev = NULL;
7707 static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac)
7709 wldev_iovar_getbuf_bsscfg(wl_to_prmry_ndev(wl), "cur_etheraddr", NULL,
7710 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
7711 memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN);
7714 int wl_cfg80211_do_driver_init(struct net_device *net)
7716 struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net);
7718 if (!wl || !wl->wdev)
7721 if (dhd_do_driver_init(wl->wdev->netdev) < 0)
7727 void wl_cfg80211_enable_trace(int level)
7729 wl_dbg_level |= WL_DBG_DBG;