19984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
29984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * Linux Cfg80211 support
39984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt *
49984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * Copyright (C) 1999-2010, Broadcom Corporation
59984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt *
69984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt *      Unless you and Broadcom execute a separate written software license
79984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * agreement governing use of this software, this software is licensed to you
89984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * under the terms of the GNU General Public License version 2 (the "GPL"),
99984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * available at http://www.broadcom.com/licenses/GPLv2.php, with the
109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * following added to such license:
119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt *
129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt *      As a special exception, the copyright holders of this software give you
139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * permission to link this software with independent modules, and to copy and
149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * distribute the resulting executable under terms of your choice, provided that
159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * you also meet, for each linked independent module, the terms and conditions of
169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * the license of that module.  An independent module is a module which is not
179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * derived from this software.  The special exception does not apply to any
189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * modifications of the software.
199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt *
209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt *      Notwithstanding the above, under no circumstances may you combine this
219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * software in any way with any other Broadcom software provided under a license
229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * other than the GPL, without Broadcom's express prior written consent.
239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt *
249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt * $Id: wl_cfg80211.c,v 1.1.2.28 2010/05/04 21:43:38 Exp $
259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt */
269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <typedefs.h>
289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linuxver.h>
299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <osl.h>
309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <bcmutils.h>
329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <bcmendian.h>
339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <proto/ethernet.h>
349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/if_arp.h>
369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <asm/uaccess.h>
379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <dngl_stats.h>
399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <dhd.h>
409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <dhdioctl.h>
419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <wlioctl.h>
429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <proto/ethernet.h>
449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <dngl_stats.h>
459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <dhd.h>
469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/kernel.h>
489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/netdevice.h>
499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/sched.h>
509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/etherdevice.h>
519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/wireless.h>
529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/ieee80211.h>
539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <net/cfg80211.h>
549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <net/rtnetlink.h>
569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/mmc/sdio_func.h>
579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <linux/firmware.h>
589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#include <wl_cfg80211.h>
599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct sdio_func *cfg80211_sdio_func = NULL;
619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct wl_dev *wl_cfg80211_dev = NULL;
629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtuint32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO | WL_DBG_DBG;
659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtuint32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define WL_4329_FW_FILE "brcm/fw_4329.bin"
709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define WL_4329_NVRAM_FILE "brcm/nvram_4329.txt"
719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** cfg80211_ops api/callback list
749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	enum nl80211_iftype type, uint32 *flags, struct vif_params *params);
779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_scan_request *request, struct cfg80211_ssid *this_ssid);
799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_scan_request *request);
819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, uint32 changed);
829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_ibss_params *params);
849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint8 *mac, struct station_info *sinfo);
879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt      struct net_device *dev, bool enabled, int32 timeout);
899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt      struct net_device *dev, const uint8 *addr,
919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt      const struct cfg80211_bitrate_mask *mask);
929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_connect_params *sme);
949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint16 reason_code);
969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, int32 dbm);
979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, int32 *dbm);
989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint8 key_idx);
1009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     uint8 key_idx, const uint8 *mac_addr, struct key_params *params);
1029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     uint8 key_idx, const uint8 *mac_addr);
1049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     uint8 key_idx, const uint8 *mac_addr, void *cookie,
1069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     void (*callback)(void *cookie, struct key_params *params));
1079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct net_device *dev, uint8 key_idx);
1099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_resume(struct wiphy *wiphy);
1109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_suspend(struct wiphy *wiphy);
1119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \
1129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	defined(CHROMIUMOS_COMPAT_WIRELESS)
1139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
1149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_pmksa *pmksa);
1159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
1169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_pmksa *pmksa);
1179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev);
1189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
1199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
1209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** event & event Q handlers for cfg80211 interfaces
1219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
1229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_create_event_handler(struct wl_priv *wl);
1239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_destroy_event_handler(struct wl_priv *wl);
1249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_event_handler(void *data);
1259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_init_eq(struct wl_priv *wl);
1269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_flush_eq(struct wl_priv *wl);
1279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_lock_eq(struct wl_priv *wl);
1289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_unlock_eq(struct wl_priv *wl);
1299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_init_eq_lock(struct wl_priv *wl);
1309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_init_eloop_handler(struct wl_event_loop *el);
1319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct wl_event_q *wl_deq_event(struct wl_priv *wl);
1329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_enq_event(struct wl_priv *wl, uint32 type, const wl_event_msg_t *msg, void *data);
1339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_put_event(struct wl_event_q *e);
1349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_wakeup_event(struct wl_priv *wl);
1359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
1369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data);
1379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
1389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data);
1399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
1409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data);
1419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
1429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data);
1439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
1449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data);
1459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
1469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data);
1479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
1499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** register/deregister sdio function
1509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
1519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct sdio_func *wl_sdio_func(void);
1529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_clear_sdio_func(void);
1539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
1559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** ioctl utilites
1569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
1579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dev_bufvar_get(struct net_device *dev, int8 *name, int8 *buf, int32 buf_len);
1589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic __used int32 wl_dev_bufvar_set(struct net_device *dev, int8 *name, int8 *buf, int32 len);
1599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dev_intvar_set(struct net_device *dev, int8 *name, int32 val);
1609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dev_intvar_get(struct net_device *dev, int8 *name, int32 *retval);
1619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dev_ioctl(struct net_device *dev, uint32 cmd, void *arg, uint32 len);
1629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
1659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** cfg80211 set_wiphy_params utilities
1669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
1679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_set_frag(struct net_device *dev, uint32 frag_threshold);
1689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_set_rts(struct net_device *dev, uint32 frag_threshold);
1699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_set_retry(struct net_device *dev, uint32 retry, bool l);
1709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
1729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** wl profile utilities
1739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
1749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, int32 item);
1759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void * wl_read_prof(struct wl_priv *wl, int32 item);
1769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_init_prof(struct wl_profile *prof);
1779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
1809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** cfg80211 connect utilites
1819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
1829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme);
1839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme);
1849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme);
1859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme);
1869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme);
1879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_get_assoc_ies(struct wl_priv *wl);
1889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
1919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** information element utilities
1929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
1939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_rst_ie(struct wl_priv *wl);
1949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_add_ie(struct wl_priv *wl, uint8 t, uint8 l, uint8 *v);
1959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_mrg_ie(struct wl_priv *wl, uint8 *ie_stream, uint16 ie_size);
1969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_cp_ie(struct wl_priv *wl, uint8 *dst, uint16 dst_size);
1979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic uint32 wl_get_ielen(struct wl_priv *wl);
1989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
1999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_mode_to_nl80211_iftype(int32 mode);
2019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct wireless_dev *wl_alloc_wdev(int32 sizeof_iface, struct device *dev);
2039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_free_wdev(struct wl_priv *wl);
2049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_inform_bss(struct wl_priv *wl);
2069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
2079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_update_bss_info(struct wl_priv *wl);
2089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
2109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     uint8 key_idx, const uint8 *mac_addr, struct key_params *params);
2119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
2149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** key indianess swap utilities
2159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
2169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void swap_key_from_BE(struct wl_wsec_key *key);
2179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void swap_key_to_BE(struct wl_wsec_key *key);
2189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
2219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** wl_priv memory init/deinit utilities
2229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
2239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_init_priv_mem(struct wl_priv *wl);
2249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_deinit_priv_mem(struct wl_priv *wl);
2259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_delay(uint32 ms);
2279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
2299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** store/restore cfg80211 instance data
2309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
2319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_set_drvdata(struct wl_dev *dev, void *data);
2329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void *wl_get_drvdata(struct wl_dev *dev);
2339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
2359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** ibss mode utilities
2369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
2379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic bool wl_is_ibssmode(struct wl_priv *wl);
2389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic bool wl_is_ibssstarter(struct wl_priv *wl);
2399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
2419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** dongle up/down , default configuration utilities
2429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
2439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
2449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
2459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_link_up(struct wl_priv *wl);
2469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_link_down(struct wl_priv *wl);
2479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_mode(struct net_device *ndev, int32 iftype);
2489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 __wl_cfg80211_up(struct wl_priv *wl);
2499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 __wl_cfg80211_down(struct wl_priv *wl);
2509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_probecap(struct wl_priv *wl);
2519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_init_conf(struct wl_conf *conf);
2529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
2549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** dongle configuration utilities
2559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
2569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifndef EMBEDDED_PLATFORM
2579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_mode(struct net_device *ndev, int32 iftype);
2589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_country(struct net_device *ndev, uint8 ccode);
2599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_up(struct net_device *ndev, uint32 up);
2609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_power(struct net_device *ndev, uint32 power_mode);
2619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_glom(struct net_device *ndev, uint32 glom, uint32 dongle_align);
2629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_roam(struct net_device *ndev, uint32 roamvar, uint32 bcn_timeout);
2639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_eventmsg(struct net_device *ndev);
2649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_scantime(struct net_device *ndev, int32 scan_assoc_time,
2659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 scan_unassoc_time);
2669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_offload(struct net_device *ndev, int32 arpoe, int32 arp_ol);
2679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_pattern_atoh(int8 *src, int8 *dst);
2689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dongle_filter(struct net_device *ndev, uint32 filter_mode);
2699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_update_wiphybands(struct wl_priv *wl);
2709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* !EMBEDDED_PLATFORM */
2719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
2729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
2749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** iscan handler
2759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
2769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_iscan_timer(ulong data);
2779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_term_iscan(struct wl_priv *wl);
2789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_init_iscan(struct wl_priv *wl);
2799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_iscan_thread(void *data);
2809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dev_iovar_setbuf(struct net_device *dev, int8 *iovar, void *param,
2819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 paramlen, void *bufptr, int32 buflen);
2829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_dev_iovar_getbuf(struct net_device *dev, int8 *iovar, void *param,
2839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 paramlen, void *bufptr, int32 buflen);
2849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, uint16 action);
2859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_do_iscan(struct wl_priv *wl);
2869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
2879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_invoke_iscan(struct wl_priv *wl);
2889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status,
2899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_scan_results **bss_list);
2909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted);
2919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_init_iscan_eloop(struct wl_iscan_eloop *el);
2929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_iscan_done(struct wl_priv *wl);
2939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_iscan_pending(struct wl_priv *wl);
2949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_iscan_inprogress(struct wl_priv *wl);
2959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32 wl_iscan_aborted(struct wl_priv *wl);
2969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
2979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
2989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** fw/nvram downloading handler
2999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
3009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void wl_init_fw(struct wl_fw_ctrl *fw);
3019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
3039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt* find most significant bit set
3049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
3059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic __used uint32 wl_find_msb(uint16 bit16);
3069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
3089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt* update pmklist to dongle
3099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
3109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic __used int32 wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
3119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err);
3129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define WL_PRIV_GET() 										\
3159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	({											\
3169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		struct wl_iface *ci;								\
3179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(!(wl_cfg80211_dev && (ci = wl_get_drvdata(wl_cfg80211_dev))))) {	\
3189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("wl_cfg80211_dev is unavailable\n"));				\
3199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			BUG();									\
3209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} 									\
3219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ci_to_wl(ci);							\
3229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	})
3239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define CHECK_SYS_UP()							\
3259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	do {										\
3269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		struct wl_priv *wl = wiphy_to_wl(wiphy);	\
3279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) {	\
3289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_INFO(("device is not ready : status (%d)\n", (int)wl->status));	\
3299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -EIO;	\
3309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}	\
3319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} while (0)
3329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtextern int dhd_wait_pend8021x(struct net_device *dev);
3359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (WL_DBG_LEVEL > 0)
3379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define WL_DBG_ESTR_MAX	32
3389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
3399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
3409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
3419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
3429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
3439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
3449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
3459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND", "PFN_NET_LOST",
3469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START", "IBSS_ASSOC",
3479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"RADIO", "PSM_WATCHDOG",
3489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"PROBREQ_MSG",
3499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED", "EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
3509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
3519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"IF",
3529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt"RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
3539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
3549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif	/* WL_DBG_LEVEL */
3559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define CHAN2G(_channel, _freq, _flags) {			\
3579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.band			= IEEE80211_BAND_2GHZ,		\
3589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.center_freq		= (_freq),			\
3599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.hw_value		= (_channel),			\
3609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.flags			= (_flags),			\
3619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.max_antenna_gain	= 0,				\
3629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.max_power		= 30,				\
3639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
3649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define CHAN5G(_channel, _flags) {				\
3669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.band			= IEEE80211_BAND_5GHZ,		\
3679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.center_freq		= 5000 + (5 * (_channel)),	\
3689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.hw_value		= (_channel),			\
3699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.flags			= (_flags),			\
3709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.max_antenna_gain	= 0,				\
3719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.max_power		= 30,				\
3729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
3739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
3759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define RATETAB_ENT(_rateid, _flags) \
3769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	{                                                               \
3779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
3789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		.hw_value       = (_rateid),                            \
3799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		.flags          = (_flags),                             \
3809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
3819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct ieee80211_rate __wl_rates[] = {
3839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_1M, 0),
3849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
3859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
3869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
3879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_6M, 0),
3889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_9M, 0),
3899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_12M, 0),
3909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_18M, 0),
3919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_24M, 0),
3929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_36M, 0),
3939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_48M, 0),
3949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	RATETAB_ENT(WLC_RATE_54M, 0),
3959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
3969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
3979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define wl_a_rates		(__wl_rates + 4)
3989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define wl_a_rates_size	8
3999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define wl_g_rates		(__wl_rates + 0)
4009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define wl_g_rates_size	12
4019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
4029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct ieee80211_channel __wl_2ghz_channels[] = {
4039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(1, 2412, 0),
4049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(2, 2417, 0),
4059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(3, 2422, 0),
4069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(4, 2427, 0),
4079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(5, 2432, 0),
4089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(6, 2437, 0),
4099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(7, 2442, 0),
4109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(8, 2447, 0),
4119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(9, 2452, 0),
4129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(10, 2457, 0),
4139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(11, 2462, 0),
4149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(12, 2467, 0),
4159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(13, 2472, 0),
4169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN2G(14, 2484, 0),
4179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
4189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
4199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct ieee80211_channel __wl_5ghz_a_channels[] = {
4209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(34, 0),		CHAN5G(36, 0),
4219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(38, 0),		CHAN5G(40, 0),
4229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(42, 0),		CHAN5G(44, 0),
4239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(46, 0),		CHAN5G(48, 0),
4249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(52, 0),		CHAN5G(56, 0),
4259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(60, 0),		CHAN5G(64, 0),
4269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(100, 0),		CHAN5G(104, 0),
4279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(108, 0),		CHAN5G(112, 0),
4289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(116, 0),		CHAN5G(120, 0),
4299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(124, 0),		CHAN5G(128, 0),
4309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(132, 0),		CHAN5G(136, 0),
4319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(140, 0),		CHAN5G(149, 0),
4329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(153, 0),		CHAN5G(157, 0),
4339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(161, 0),		CHAN5G(165, 0),
4349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(184, 0),		CHAN5G(188, 0),
4359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(192, 0),		CHAN5G(196, 0),
4369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(200, 0),		CHAN5G(204, 0),
4379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(208, 0),		CHAN5G(212, 0),
4389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(216, 0),
4399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
4409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
4419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct ieee80211_channel __wl_5ghz_n_channels[] = {
4429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(32, 0),		CHAN5G(34, 0),
4439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(36, 0),		CHAN5G(38, 0),
4449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(40, 0),		CHAN5G(42, 0),
4459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(44, 0),		CHAN5G(46, 0),
4469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(48, 0),		CHAN5G(50, 0),
4479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(52, 0),		CHAN5G(54, 0),
4489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(56, 0),		CHAN5G(58, 0),
4499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(60, 0),		CHAN5G(62, 0),
4509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(64, 0),		CHAN5G(66, 0),
4519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(68, 0),		CHAN5G(70, 0),
4529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(72, 0),		CHAN5G(74, 0),
4539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(76, 0),		CHAN5G(78, 0),
4549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(80, 0),		CHAN5G(82, 0),
4559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(84, 0),		CHAN5G(86, 0),
4569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(88, 0),		CHAN5G(90, 0),
4579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(92, 0),		CHAN5G(94, 0),
4589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(96, 0),		CHAN5G(98, 0),
4599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(100, 0),		CHAN5G(102, 0),
4609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(104, 0),		CHAN5G(106, 0),
4619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(108, 0),		CHAN5G(110, 0),
4629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(112, 0),		CHAN5G(114, 0),
4639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(116, 0),		CHAN5G(118, 0),
4649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(120, 0),		CHAN5G(122, 0),
4659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(124, 0),		CHAN5G(126, 0),
4669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(128, 0),		CHAN5G(130, 0),
4679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(132, 0),		CHAN5G(134, 0),
4689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(136, 0),		CHAN5G(138, 0),
4699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(140, 0),		CHAN5G(142, 0),
4709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(144, 0),		CHAN5G(145, 0),
4719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(146, 0),		CHAN5G(147, 0),
4729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(148, 0),		CHAN5G(149, 0),
4739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(150, 0),		CHAN5G(151, 0),
4749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(152, 0),		CHAN5G(153, 0),
4759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(154, 0),		CHAN5G(155, 0),
4769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(156, 0),		CHAN5G(157, 0),
4779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(158, 0),		CHAN5G(159, 0),
4789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(160, 0),		CHAN5G(161, 0),
4799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(162, 0),		CHAN5G(163, 0),
4809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(164, 0),		CHAN5G(165, 0),
4819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(166, 0),		CHAN5G(168, 0),
4829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(170, 0),		CHAN5G(172, 0),
4839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(174, 0),		CHAN5G(176, 0),
4849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(178, 0),		CHAN5G(180, 0),
4859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(182, 0),		CHAN5G(184, 0),
4869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(186, 0),		CHAN5G(188, 0),
4879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(190, 0),		CHAN5G(192, 0),
4889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(194, 0),		CHAN5G(196, 0),
4899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(198, 0),		CHAN5G(200, 0),
4909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(202, 0),		CHAN5G(204, 0),
4919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(206, 0),		CHAN5G(208, 0),
4929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(210, 0),		CHAN5G(212, 0),
4939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(214, 0),		CHAN5G(216, 0),
4949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(218, 0),		CHAN5G(220, 0),
4959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(222, 0),		CHAN5G(224, 0),
4969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHAN5G(226, 0),		CHAN5G(228, 0),
4979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
4989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
4999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct ieee80211_supported_band __wl_band_2ghz = {
5009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.band    	= IEEE80211_BAND_2GHZ,
5019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.channels 	= __wl_2ghz_channels,
5029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.n_channels = ARRAY_SIZE(__wl_2ghz_channels),
5039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.bitrates 	= wl_g_rates,
5049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.n_bitrates = wl_g_rates_size,
5059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
5069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct ieee80211_supported_band __wl_band_5ghz_a = {
5089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.band		= IEEE80211_BAND_5GHZ,
5099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.channels 	= __wl_5ghz_a_channels,
5109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
5119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.bitrates 	= wl_a_rates,
5129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.n_bitrates = wl_a_rates_size,
5139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
5149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct ieee80211_supported_band __wl_band_5ghz_n = {
5169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.band   	= IEEE80211_BAND_5GHZ,
5179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.channels	= __wl_5ghz_n_channels,
5189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.n_channels	= ARRAY_SIZE(__wl_5ghz_n_channels),
5199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.bitrates 	= wl_a_rates,
5209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.n_bitrates = wl_a_rates_size,
5219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
5229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic const uint32 __wl_cipher_suites[] = {
5249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WLAN_CIPHER_SUITE_WEP40,
5259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WLAN_CIPHER_SUITE_WEP104,
5269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WLAN_CIPHER_SUITE_TKIP,
5279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WLAN_CIPHER_SUITE_CCMP,
5289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WLAN_CIPHER_SUITE_AES_CMAC,
5299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
5309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
5329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtswap_key_from_BE(struct wl_wsec_key *key)
5339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
5349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->index = htod32(key->index);
5359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->len = htod32(key->len);
5369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->algo = htod32(key->algo);
5379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->flags = htod32(key->flags);
5389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->rxiv.hi = htod32(key->rxiv.hi);
5399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->rxiv.lo = htod16(key->rxiv.lo);
5409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->iv_initialized = htod32(key->iv_initialized);
5419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
5429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
5449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtswap_key_to_BE(struct wl_wsec_key *key)
5459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
5469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->index = dtoh32(key->index);
5479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->len = dtoh32(key->len);
5489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->algo = dtoh32(key->algo);
5499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->flags = dtoh32(key->flags);
5509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->rxiv.hi = dtoh32(key->rxiv.hi);
5519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->rxiv.lo = dtoh16(key->rxiv.lo);
5529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key->iv_initialized = dtoh32(key->iv_initialized);
5539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
5549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
5569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dev_ioctl(struct net_device *dev, uint32 cmd, void *arg, uint32 len)
5579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
5589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct ifreq ifr;
5599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_ioctl ioc;
5609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mm_segment_t fs;
5619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
5629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
5649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In : cmd (%d)\n", cmd));
5659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
5669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&ioc, 0, sizeof(ioc));
5679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ioc.cmd = cmd;
5689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ioc.buf = arg;
5699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ioc.len = len;
5709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	strcpy(ifr.ifr_name, dev->name);
5719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ifr.ifr_data = (caddr_t) &ioc;
5729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	fs = get_fs();
5759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_fs(get_ds());
5769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
5779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_fs(fs);
5789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
5799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
5809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
5819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
5839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
5849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
5869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
5879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	enum nl80211_iftype type, uint32 *flags, struct vif_params *params)
5889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
5899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
5909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wireless_dev *wdev;
5919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 infra = 0;
5929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 ap = 0;
5939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
5949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
5959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
5969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
5979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
5989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
5999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (type) {
6009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_IFTYPE_MONITOR:
6019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_IFTYPE_WDS:
6029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("type (%d) : currently we do not support this type\n", type));
6039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EOPNOTSUPP;
6049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_IFTYPE_ADHOC:
6059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->conf->mode = WL_MODE_IBSS;
6069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
6079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_IFTYPE_STATION:
6089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->conf->mode = WL_MODE_BSS;
6099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		infra = 1;
6109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
6119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	default:
6129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EINVAL;
6139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
6149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	infra = htod32(infra);
6159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ap = htod32(ap);
6169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev = ndev->ieee80211_ptr;
6179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->iftype = type;
6189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra));
6199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)))) ||
6209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		unlikely((err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap))))) {
6219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Error (%d)\n", err));
6229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
6239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
6249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
6259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
6269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
6279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* -EINPROGRESS: Call commit handler */
6289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return -EINPROGRESS;
6299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
6309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
6329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
6339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
6349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
6359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->bss_type = DOT11_BSSTYPE_ANY;
6369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->scan_type = 0;
6379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->nprobes = -1;
6389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->active_time = -1;
6399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->passive_time = -1;
6409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->home_time = -1;
6419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->channel_num = 0;
6429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->nprobes = htod32(params->nprobes);
6449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->active_time = htod32(params->active_time);
6459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->passive_time = htod32(params->passive_time);
6469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->home_time = htod32(params->home_time);
6479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (ssid && ssid->SSID_len)
6489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
6499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
6519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
6539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dev_iovar_setbuf(struct net_device *dev, int8 *iovar, void *param,
6549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 paramlen, void *bufptr, int32 buflen)
6559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
6569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 iolen;
6579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
6599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	BUG_ON(unlikely(!iolen));
6609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen);
6629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
6639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
6659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dev_iovar_getbuf(struct net_device *dev, int8 *iovar, void *param,
6669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 paramlen, void *bufptr, int32 buflen)
6679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
6689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 iolen;
6699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen);
6719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	BUG_ON(unlikely(!iolen));
6729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen);
6749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
6759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
6779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, uint16 action)
6789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
6799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_iscan_params_t, params));
6809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_params *params;
6819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
6829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
6849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
6859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
6869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (ssid && ssid->SSID_len)
6879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		params_size += sizeof(struct wlc_ssid);
6889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
6899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!params))
6909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOMEM;
6919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(params, 0, params_size);
6929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
6939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_iscan_prep(&params->params, ssid);
6959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
6969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->version = htod32(ISCAN_REQ_VERSION);
6979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->action = htod16(action);
6989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params->scan_duration = htod16(0);
6999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* params_size += OFFSETOF(wl_iscan_params_t, params); */
7019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
7029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->ioctl_buf, WLC_IOCTL_SMLEN)))) {
7039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -EBUSY) {
7049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_INFO(("system busy : iscan canceled\n"));
7059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
7069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("error (%d)\n", err));
7079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
7089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
7099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	kfree(params);
7109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
7119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
7129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
7139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
7149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
7159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
7189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_do_iscan(struct wl_priv *wl)
7199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
7209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
7219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wlc_ssid ssid;
7229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
7239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
7259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
7269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
7279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Broadcast scan by default */
7289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&ssid, 0, sizeof(ssid));
7299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iscan->state = WL_ISCAN_STATE_SCANING;
7319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->active_scan) {
7339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		int32 passive_scan = 0;
7349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* make it active scan */
7359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
7369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			&passive_scan, sizeof(passive_scan))))) {
7379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("error (%d)\n", err));
7389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
7399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
7409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
7419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->iscan_kickstart = TRUE;
7429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
7439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000);
7449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iscan->timer_on = 1;
7459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
7479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
7489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
7499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
7519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
7529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
7559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt__wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
7569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_scan_request *request,  struct cfg80211_ssid *this_ssid)
7579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
7589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(ndev);
7599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_ssid *ssids;
7609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_scan_req *sr = wl_to_sr(wl);
7619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 n_ssids;
7629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bool iscan_req;
7639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bool spec_scan;
7649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
7659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
7679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
7689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
7699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) {
7709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
7719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EAGAIN;
7729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
7739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) {
7749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Scanning being aborted : status (%d)\n", (int)wl->status));
7759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EAGAIN;
7769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
7779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
7789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iscan_req = FALSE;
7799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	spec_scan = FALSE;
7809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (request) {	/* scan bss */
7819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ssids = request->ssids;
7829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		n_ssids = min(request->n_ssids, WL_NUM_SCAN_MAX);
7839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (wl->iscan_on && n_ssids && !ssids->ssid_len) { /* for specific scan,
7849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								* ssids->ssid_len has
7859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								* non-zero(ssid string) length.
7869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								* Otherwise this is 0.
7879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								* we do not iscan for
7889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								* specific scan request
7899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								*/
7909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			iscan_req = TRUE;
7919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
7929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {	/* scan in ibss */
7939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* we don't do iscan in ibss */
7949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ssids = this_ssid;
7959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		n_ssids = 1;
7969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
7979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->scan_request = request;
7989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_bit(WL_STATUS_SCANNING, &wl->status);
7999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (iscan_req) {
8009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (likely(!(err = wl_do_iscan(wl))))
8019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
8029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		else
8039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			goto scan_out;
8049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
8059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("n_ssid (%d), ssid \"%s\", ssid_len (%d)\n",
8069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		n_ssids, ssids->ssid, ssids->ssid_len));
8079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memset(&sr->ssid, 0, sizeof(sr->ssid));
8089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (n_ssids) {
8099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			sr->ssid.SSID_len = MIN(sizeof(sr->ssid.SSID), ssids->ssid_len);
8109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (sr->ssid.SSID_len) {
8119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
8129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
8139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_DBG(("Specific scan ssid=\"%s\" len=%d\n", sr->ssid.SSID,
8149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				sr->ssid.SSID_len));
8159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				spec_scan = TRUE;
8169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			} else {
8179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_DBG(("Broadcast scan\n"));
8189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
8199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
8209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			/* broadcast scan */
8219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("Broadcast scan\n"));
8229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
8239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
8249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (wl->active_scan) {
8259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			int32 pssive_scan = 0;
8269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			/* make it active scan */
8279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (unlikely((err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
8289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				&pssive_scan, sizeof(pssive_scan))))) {
8299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
8309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				goto scan_out;
8319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
8329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
8339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if ((err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid, sizeof(sr->ssid)))) {
8349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (err == -EBUSY) {
8359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_INFO(("system busy : scan for \"%s\" canceled\n",
8369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				sr->ssid.SSID));
8379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			} else {
8389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_ERR(("WLC_SCAN error (%d)\n", err));
8399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
8409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			goto scan_out;
8419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
8429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
8439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
8449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
8459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
8469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return 0;
8489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtscan_out:
8509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	clear_bit(WL_STATUS_SCANNING, &wl->status);
8519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->scan_request = NULL;
8529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
8539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
8549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
8579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
8589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_scan_request *request)
8599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
8609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
8619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
8639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
8649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
8659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
8669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = __wl_cfg80211_scan(wiphy, ndev, request, NULL)))) {
8679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("scan error (%d)\n", err));
8689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
8699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
8709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
8719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
8729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
8739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
8759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
8769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
8789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dev_intvar_set(struct net_device *dev, int8 *name, int32 val)
8799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
8809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 buf[WLC_IOCTL_SMLEN];
8819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 len;
8829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
8839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	val = htod32(val);
8859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf));
8869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	BUG_ON(unlikely(!len));
8879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len)))) {
8899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("error (%d)\n", err));
8909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
8919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
8939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
8949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
8959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
8969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dev_intvar_get(struct net_device *dev, int8 *name, int32 *retval)
8979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
8989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	union {
8999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		int8 buf[WLC_IOCTL_SMLEN];
9009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		int32 val;
9019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} var;
9029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 len;
9039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 data_null;
9049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
9059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	len = bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf));
9079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	BUG_ON(unlikely(!len));
9089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len)))) {
9099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("error (%d)\n", err));
9109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
9119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*retval = dtoh32(var.val);
9129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
9149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
9159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
9179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_rts(struct net_device *dev, uint32 rts_threshold)
9189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
9199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
9209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
9229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
9239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
9249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold)))) {
9259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Error (%d)\n", err));
9269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
9279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
9289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
9299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
9309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
9319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
9329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
9339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
9359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_frag(struct net_device *dev, uint32 frag_threshold)
9369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
9379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
9389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
9409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
9419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
9429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold)))) {
9439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Error (%d)\n", err));
9449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
9459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
9469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
9479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
9489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
9499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
9509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
9519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
9539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_retry(struct net_device *dev, uint32 retry, bool l)
9549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
9559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
9569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL);
9579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
9599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
9609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
9619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	retry = htod32(retry);
9629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry))))) {
9639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("cmd (%d) , error (%d)\n", cmd, err));
9649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
9659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
9669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
9679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
9689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
9699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
9709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
9719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
9739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_set_wiphy_params(struct wiphy *wiphy, uint32 changed)
9749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
9759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
9769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct net_device *ndev = wl_to_ndev(wl);
9779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
9789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
9799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
9809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
9819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
9829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
9839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
9849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		(wl->conf->rts_threshold != wiphy->rts_threshold)) {
9859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->conf->rts_threshold = wiphy->rts_threshold;
9869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (!(err = wl_set_rts(ndev, wl->conf->rts_threshold))) {
9879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
9889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
9899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
9909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
9919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		(wl->conf->frag_threshold != wiphy->frag_threshold)) {
9929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->conf->frag_threshold = wiphy->frag_threshold;
9939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (!(err = wl_set_frag(ndev, wl->conf->frag_threshold))) {
9949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
9959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
9969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
9979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (changed & WIPHY_PARAM_RETRY_LONG && (wl->conf->retry_long != wiphy->retry_long)) {
9989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->conf->retry_long = wiphy->retry_long;
9999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (!(err = wl_set_retry(ndev, wl->conf->retry_long, TRUE))) {
10009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
10019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
10029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
10039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (changed & WIPHY_PARAM_RETRY_SHORT && (wl->conf->retry_short != wiphy->retry_short)) {
10049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->conf->retry_short = wiphy->retry_short;
10059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (!(err = wl_set_retry(ndev, wl->conf->retry_short, FALSE))) {
10069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
10079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
10089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
10099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
10109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
10119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
10129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
10139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
10149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
10159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
10169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
10179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
10189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_ibss_params *params)
10199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
10209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
10219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_bss *bss;
10229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct ieee80211_channel *chan;
10239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_join_params join_params;
10249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_ssid ssid;
10259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 scan_retry = 0;
10269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
10279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
10289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
10299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In \n"));
10309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
10319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
10329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (params->bssid) {
10339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Invalid bssid\n"));
10349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EOPNOTSUPP;
10359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
10369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
10379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (!bss) {
10389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(ssid.ssid, params->ssid, params->ssid_len);
10399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ssid.ssid_len = params->ssid_len;
10409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		do {
10419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (unlikely(__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) == -EBUSY)) {
10429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				wl_delay(150);
10439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			} else {
10449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
10459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
10469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} while (++scan_retry < WL_SCAN_RETRY_MAX);
10479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rtnl_unlock();	/* to allow scan_inform to paropagate to cfg80211 plane */
10489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		schedule_timeout_interruptible(4 * HZ);	/* wait 4 secons till scan done.... */
10499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rtnl_lock();
10509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		bss = cfg80211_get_ibss(wiphy, NULL,
10519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			params->ssid, params->ssid_len);
10529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
10539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (bss) {
10549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->ibss_starter = FALSE;
10559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Found IBSS\n"));
10569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
10579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->ibss_starter = TRUE;
10589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
10599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((chan = params->channel)) {
10609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
10619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
10629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/*
10639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	** Join with specific BSSID and cached SSID
10649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	** If SSID is zero join based on BSSID only
10659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*/
10669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&join_params, 0, sizeof(join_params));
10679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy((void *)join_params.ssid.SSID, (void *)params->ssid, params->ssid_len);
10689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	join_params.ssid.SSID_len = htod32(params->ssid_len);
10699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (params->bssid)
10709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(&join_params.params.bssid, params->bssid, ETHER_ADDR_LEN);
10719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	else
10729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN);
10739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
10749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, sizeof(join_params))))) {
10759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Error (%d)\n", err));
10769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
10779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
10789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
10799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
10809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
10819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
10829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
10839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
10849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
10859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
10869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
10879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
10889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
10899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
10909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
10919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
10929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
10939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
10949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_link_down(wl);
10959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
10969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
10979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
10989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
10999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
11009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
11019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
11029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
11039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
11049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
11059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(dev);
11069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_security *sec;
11079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 val = 0;
11089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
11099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
11109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
11119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
11129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
11139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
11149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
11159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
11169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
11179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	else
11189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		val = WPA_AUTH_DISABLED;
11199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("setting wpa_auth to 0x%0x\n", val));
11209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_set(dev, "wpa_auth", val)))) {
11219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("set wpa_auth failed (%d)\n", err));
11229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
11239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
11249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec = wl_read_prof(wl, WL_PROF_SEC);
11259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec->wpa_versions = sme->crypto.wpa_versions;
11269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
11279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
11289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
11299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
11309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
11319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
11329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
11339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
11349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
11359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(dev);
11369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_security *sec;
11379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 val = 0;
11389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
11399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
11409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
11419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
11429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
11439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (sme->auth_type) {
11449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_AUTHTYPE_OPEN_SYSTEM:
11459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		val = 0;
11469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("open system\n"));
11479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
11489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_AUTHTYPE_SHARED_KEY:
11499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		val = 1;
11509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("shared key\n"));
11519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
11529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_AUTHTYPE_AUTOMATIC:
11539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		val = 2;
11549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("automatic\n"));
11559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
11569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_AUTHTYPE_NETWORK_EAP:
11579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("network eap\n"));
11589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	default :
11599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		val = 2;
11609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("invalid auth type (%d)\n", sme->auth_type));
11619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
11629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
11639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
11649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_set(dev, "auth", val)))) {
11659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("set auth failed (%d)\n", err));
11669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
11679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
11689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec = wl_read_prof(wl, WL_PROF_SEC);
11699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec->auth_type = sme->auth_type;
11709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
11719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
11729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
11739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
11749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
11759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
11769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
11779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
11789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
11799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
11809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(dev);
11819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_security *sec;
11829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 pval = 0;
11839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 gval = 0;
11849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
11859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
11869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
11879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
11889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
11899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (sme->crypto.n_ciphers_pairwise) {
11909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		switch (sme->crypto.ciphers_pairwise[0]) {
11919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_WEP40:
11929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_WEP104:
11939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			pval =	WEP_ENABLED;
11949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
11959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_TKIP:
11969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			pval = TKIP_ENABLED;
11979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
11989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_CCMP:
11999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			pval = AES_ENABLED;
12009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
12019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_AES_CMAC:
12029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			pval = AES_ENABLED;
12039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
12049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		default:
12059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("invalid cipher pairwise (%d)\n",
12069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			sme->crypto.ciphers_pairwise[0]));
12079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -EINVAL;
12089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
12099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
12109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (sme->crypto.cipher_group) {
12119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		switch (sme->crypto.cipher_group) {
12129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_WEP40:
12139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_WEP104:
12149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			gval =	WEP_ENABLED;
12159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
12169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_TKIP:
12179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			gval = TKIP_ENABLED;
12189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
12199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_CCMP:
12209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			gval = AES_ENABLED;
12219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
12229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_AES_CMAC:
12239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			gval = AES_ENABLED;
12249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
12259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		default:
12269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("invalid cipher group (%d)\n", sme->crypto.cipher_group));
12279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -EINVAL;
12289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
12299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
12309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
12319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("pval (%d) gval (%d)\n", pval, gval));
12329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_set(dev, "wsec", pval|gval)))) {
12339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("error (%d)\n", err));
12349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
12359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
12369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
12379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec = wl_read_prof(wl, WL_PROF_SEC);
12389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
12399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec->cipher_group = sme->crypto.cipher_group;
12409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
12419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
12429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
12439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
12449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
12459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
12469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
12479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
12489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
12499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
12509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(dev);
12519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_security *sec;
12529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 val = 0;
12539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
12549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
12559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
12569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
12579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
12589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
12599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (sme->crypto.n_akm_suites) {
12609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_dev_intvar_get(dev, "wpa_auth", &val)))) {
12619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("could not get wpa_auth (%d)\n", err));
12629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
12639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
12649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
12659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			switch (sme->crypto.akm_suites[0]) {
12669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			case WLAN_AKM_SUITE_8021X:
12679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				val = WPA_AUTH_UNSPECIFIED;
12689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
12699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			case WLAN_AKM_SUITE_PSK:
12709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				val = WPA_AUTH_PSK;
12719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
12729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			default :
12739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_ERR(("invalid cipher group (%d)\n",
12749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				sme->crypto.cipher_group));
12759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				return -EINVAL;
12769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
12779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
12789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			switch (sme->crypto.akm_suites[0]) {
12799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			case WLAN_AKM_SUITE_8021X:
12809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				val = WPA2_AUTH_UNSPECIFIED;
12819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
12829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			case WLAN_AKM_SUITE_PSK:
12839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				val = WPA2_AUTH_PSK;
12849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
12859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			default :
12869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_ERR(("invalid cipher group (%d)\n",
12879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				sme->crypto.cipher_group));
12889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				return -EINVAL;
12899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
12909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
12919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
12929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("setting wpa_auth to %d\n", val));
12939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_dev_intvar_set(dev, "wpa_auth", val)))) {
12949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("could not set wpa_auth (%d)\n", err));
12959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
12969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
12979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
12989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec = wl_read_prof(wl, WL_PROF_SEC);
12999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sec->wpa_auth = sme->crypto.akm_suites[0];
13009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
13019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
13029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
13039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
13049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
13059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
13069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
13079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
13089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme)
13099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
13109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(dev);
13119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_security *sec;
13129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_wsec_key key;
13139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 val;
13149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
13159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
13169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
13179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
13189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
13199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("key len (%d)\n", sme->key_len));
13209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (sme->key_len) {
13219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sec = wl_read_prof(wl, WL_PROF_SEC);
13229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n", sec->wpa_versions,
13239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			sec->cipher_pairwise));
13249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) &&
13259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			(sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
13269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WLAN_CIPHER_SUITE_WEP104))) {
13279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memset(&key, 0, sizeof(key));
13289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.len = (uint32)sme->key_len;
13299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.index = (uint32)sme->key_idx;
13309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (unlikely(key.len > sizeof(key.data))) {
13319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_ERR(("Too long key length (%u)\n", key.len));
13329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				return -EINVAL;
13339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
13349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memcpy(key.data, sme->key, key.len);
13359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.flags = WL_PRIMARY_KEY;
13369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			switch (sec->cipher_pairwise) {
13379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			case WLAN_CIPHER_SUITE_WEP40:
13389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				key.algo = CRYPTO_ALGO_WEP1;
13399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
13409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			case WLAN_CIPHER_SUITE_WEP104:
13419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				key.algo = CRYPTO_ALGO_WEP128;
13429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
13439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			default :
13449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_ERR(("Invalid algorithm (%d)\n",
13459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				sme->crypto.ciphers_pairwise[0]));
13469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				return -EINVAL;
13479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
13489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			/* Set the new key/index */
13499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("key length (%d) key index (%d) algo (%d)\n", key.len,
13509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				key.index, key.algo));
13519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("key \"%s\"\n", key.data));
13529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			swap_key_from_BE(&key);
13539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
13549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_ERR(("WLC_SET_KEY error (%d)\n", err));
13559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				return err;
13569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
13579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
13589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_DBG(("set auth_type to shared key\n"));
13599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				val = 1;	/* shared key */
13609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				if (unlikely((err = wl_dev_intvar_set(dev, "auth", val)))) {
13619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt					WL_ERR(("set auth failed (%d)\n", err));
13629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt					return err;
13639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				}
13649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
13659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
13669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
13679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
13689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
13699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
13709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
13719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
13729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
13739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
13749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
13759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_connect_params *sme)
13769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
13779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
13789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct ieee80211_channel *chan = sme->channel;
13799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wlc_ssid ssid;
13809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
13819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
13829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
13839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In \n"));
13849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
13859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
13869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!sme->ssid)) {
13879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Invalid ssid\n"));
13889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EOPNOTSUPP;
13899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
13909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (chan) {
13919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
13929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("channel (%d), center_req (%d) \n", wl->channel, chan->center_freq));
13939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
13949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("ie (%p), ie_len (%d)\n", sme->ie, sme->ie_len));
13959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_set_wpa_version(dev, sme)))) {
13969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
13979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
13989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_set_auth_type(dev, sme)))) {
13999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
14009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
14019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_set_set_cipher(dev, sme)))) {
14029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
14039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
14049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_set_key_mgmt(dev, sme)))) {
14059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
14069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
14079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_set_set_sharedkey(dev, sme)))) {
14089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
14099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
14109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID);
14119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/*
14129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	**  Join with specific BSSID and cached SSID
14139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	**  If SSID is zero join based on BSSID only
14149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	 */
14159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&ssid, 0, sizeof(ssid));
14169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ssid.SSID_len = MIN(sizeof(ssid.SSID), sme->ssid_len);
14179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(ssid.SSID, sme->ssid, ssid.SSID_len);
14189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ssid.SSID_len = htod32(ssid.SSID_len);
14199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_update_prof(wl, NULL, &ssid, WL_PROF_SSID);
14209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
14219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("ssid \"%s\", len (%d)\n", ssid.SSID, ssid.SSID_len));
14229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
14239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid))))) {
14249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("error (%d)\n", err));
14259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
14269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
14279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_bit(WL_STATUS_CONNECTING, &wl->status);
14289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
14299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
14309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
14319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
14329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
14339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
14349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
14359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
14369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
14379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint16 reason_code)
14389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
14399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
14409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	scb_val_t scbval;
14419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bool act = FALSE;
14429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
14439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
14449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
14459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
14469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
14479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Reason %d\n", reason_code));
14489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
14499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (likely((act = *(bool *)wl_read_prof(wl, WL_PROF_ACT)))) {
14509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		scbval.val = reason_code;
14519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
14529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		scbval.val = htod32(scbval.val);
14539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
14549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			sizeof(scb_val_t))))) {
14559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("error (%d)\n", err));
14569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
14579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
14589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
14599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
14609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
14619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
14629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
14639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
14649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
14659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
14669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
14679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type, int32 dbm)
14689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
14699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
14709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
14719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct net_device *ndev = wl_to_ndev(wl);
14729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint16 txpwrmw;
14739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err  = 0;
14749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 disable = 0;
14759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
14769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
14779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
14789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
14799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
14809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (type) {
14819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case TX_POWER_AUTOMATIC:
14829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
14839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case TX_POWER_LIMITED:
14849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (dbm < 0) {
14859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n"));
14869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -EINVAL;
14879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
14889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
14899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case TX_POWER_FIXED:
14909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (dbm < 0) {
14919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("TX_POWER_FIXED - dbm is negative..\n"));
14929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -EINVAL;
14939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
14949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
14959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
14969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Make sure radio is off or on as far as software is concerned */
14979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	disable = WL_RADIO_SW_DISABLE << 16;
14989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	disable = htod32(disable);
14999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable))))) {
15009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_SET_RADIO error (%d)\n", err));
15019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
15029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
15039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (dbm > 0xffff)
15059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		txpwrmw = 0xffff;
15069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	else
15079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		txpwrmw = (uint16)dbm;
15089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_set(ndev, "qtxpower",
15099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		(int32)(bcm_mw_to_qdbm(txpwrmw)))))) {
15109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("qtxpower error (%d)\n", err));
15119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
15129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
15139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->conf->tx_power = dbm;
15149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
15159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
15169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
15179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
15199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
15209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
15229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_get_tx_power(struct wiphy *wiphy, int32 *dbm)
15239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
15249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
15259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct net_device *ndev = wl_to_ndev(wl);
15269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 txpwrdbm;
15279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint8 result;
15289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
15299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
15319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
15329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
15339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
15349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm)))) {
15359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("error (%d)\n", err));
15369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
15379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
15389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	result = (uint8)(txpwrdbm & ~WL_TXPWR_OVERRIDE);
15399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*dbm = (int32)bcm_qdbm_to_mw(result);
15409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
15419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
15429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
15439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
15459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
15469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
15489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, uint8 key_idx)
15499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
15509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 index;
15519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 wsec;
15529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
15539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
15559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
15569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
15579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("key index (%d)\n", key_idx));
15589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
15599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
15619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
15629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
15639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
15649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wsec = dtoh32(wsec);
15659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wsec & WEP_ENABLED) {
15669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* Just select a new current key */
15679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		index = (uint32)key_idx;
15689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		index = htod32(index);
15699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY,
15709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			&index, sizeof(index))))) {
15719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("error (%d)\n", err));
15729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
15739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
15749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
15759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
15769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
15779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
15789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
15799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
15819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
15829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     uint8 key_idx, const uint8 *mac_addr, struct key_params *params)
15839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
15849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_wsec_key key;
15859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
15869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
15879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
15889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
15899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
15909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&key, 0, sizeof(key));
15919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.index = (uint32)key_idx;
15929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Instead of bcast for ea address for default wep keys, driver needs it to be Null */
15939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (!ETHER_ISMULTI(mac_addr))
15949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN);
15959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.len = (uint32)params->key_len;
15969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* check for key index change */
15979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (key.len == 0) {
15989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* key delete */
15999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		swap_key_from_BE(&key);
16009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
16019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("key delete error (%d)\n", err));
16029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
16039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
16049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
16059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (key.len > sizeof(key.data)) {
16069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Invalid key length (%d)\n", key.len));
16079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -EINVAL;
16089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
16099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Setting the key index %d\n", key.index));
16119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(key.data, params->key, key.len);
16129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
16149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			uint8 keybuf[8];
16159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memcpy(keybuf, &key.data[24], sizeof(keybuf));
16169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
16179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memcpy(&key.data[16], keybuf, sizeof(keybuf));
16189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
16199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* if IW_ENCODE_EXT_RX_SEQ_VALID set */
16219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (params->seq && params->seq_len == 6) {
16229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			/* rx iv */
16239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			uint8 *ivptr;
16249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			ivptr = (uint8 *)params->seq;
16259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
16269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				(ivptr[3] << 8) | ivptr[2];
16279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
16289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.iv_initialized = TRUE;
16299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
16309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		switch (params->cipher) {
16329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_WEP40:
16339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.algo = CRYPTO_ALGO_WEP1;
16349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
16359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
16369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_WEP104:
16379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.algo = CRYPTO_ALGO_WEP128;
16389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
16399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
16409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_TKIP:
16419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.algo = CRYPTO_ALGO_TKIP;
16429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
16439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
16449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_AES_CMAC:
16459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.algo = CRYPTO_ALGO_AES_CCM;
16469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
16479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
16489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		case WLAN_CIPHER_SUITE_CCMP:
16499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			key.algo = CRYPTO_ALGO_AES_CCM;
16509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
16519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
16529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		default:
16539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
16549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -EINVAL;
16559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
16569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		swap_key_from_BE(&key);
16579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		dhd_wait_pend8021x(dev);
16599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
16609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("WLC_SET_KEY error (%d)\n", err));
16619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
16629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
16639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
16649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
16659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
16669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
16679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
16689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
16699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
16719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
16729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     uint8 key_idx, const uint8 *mac_addr, struct key_params *params)
16739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
16749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_wsec_key key;
16759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 val;
16769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 wsec;
16779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
16789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
16809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
16819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
16829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("key index (%d)\n", key_idx));
16839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
16849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (mac_addr)
16869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
16879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&key, 0, sizeof(key));
16889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.len = (uint32)params->key_len;
16909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.index = (uint32)key_idx;
16919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(key.len > sizeof(key.data))) {
16939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Too long key length (%u)\n", key.len));
16949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EINVAL;
16959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
16969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(key.data, params->key, key.len);
16979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
16989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.flags = WL_PRIMARY_KEY;
16999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (params->cipher) {
17009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WLAN_CIPHER_SUITE_WEP40:
17019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		key.algo = CRYPTO_ALGO_WEP1;
17029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
17039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
17049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WLAN_CIPHER_SUITE_WEP104:
17059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		key.algo = CRYPTO_ALGO_WEP128;
17069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
17079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
17089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WLAN_CIPHER_SUITE_TKIP:
17099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		key.algo = CRYPTO_ALGO_TKIP;
17109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
17119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
17129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WLAN_CIPHER_SUITE_AES_CMAC:
17139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		key.algo = CRYPTO_ALGO_AES_CCM;
17149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
17159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
17169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WLAN_CIPHER_SUITE_CCMP:
17179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		key.algo = CRYPTO_ALGO_AES_CCM;
17189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
17199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
17209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	default:
17219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
17229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EINVAL;
17239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
17249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
17259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Set the new key/index */
17269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	swap_key_from_BE(&key);
17279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
17289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_SET_KEY error (%d)\n", err));
17299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
17309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
17319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
17329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	val = WEP_ENABLED;
17339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_get(dev, "wsec", &wsec)))) {
17349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("get wsec error (%d)\n", err));
17359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
17369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
17379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wsec  &= ~(WEP_ENABLED);
17389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wsec |= val;
17399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_set(dev, "wsec", wsec)))) {
17409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("set wsec error (%d)\n", err));
17419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
17429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
17439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
17449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	val = 1;	/* assume shared key. otherwise 0 */
17459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	val = htod32(val);
17469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))) {
17479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
17489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
17499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
17509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
17519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
17529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
17539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
17549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
17559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
17569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
17579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
17589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     uint8 key_idx, const uint8 *mac_addr)
17599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
17609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_wsec_key key;
17619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
17629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 val;
17639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 wsec;
17649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
17659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
17669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
17679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
17689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
17699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&key, 0, sizeof(key));
17709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
17719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.index = (uint32)key_idx;
17729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.flags = WL_PRIMARY_KEY;
17739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.algo = CRYPTO_ALGO_OFF;
17749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
17759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("key index (%d)\n", key_idx));
17769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Set the new key/index */
17779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	swap_key_from_BE(&key);
17789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key))))) {
17799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -EINVAL) {
17809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
17819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				/* we ignore this key index in this case */
17829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				WL_DBG(("invalid key index (%d)\n", key_idx));
17839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
17849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
17859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("WLC_SET_KEY error (%d)\n", err));
17869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
17879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
17889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
17899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
17909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	val = 0;
17919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_get(dev, "wsec", &wsec)))) {
17929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("get wsec error (%d)\n", err));
17939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
17949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
17959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wsec  &= ~(WEP_ENABLED);
17969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wsec |= val;
17979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_intvar_set(dev, "wsec", wsec)))) {
17989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("set wsec error (%d)\n", err));
17999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
18009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
18019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	val = 0;	/* assume open key. otherwise 1 */
18039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	val = htod32(val);
18049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val))))) {
18059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_SET_AUTH error (%d)\n", err));
18069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
18079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
18089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
18099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
18109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
18119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
18129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
18139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
18159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
18169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     uint8 key_idx, const uint8 *mac_addr, void *cookie,
18179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     void (*callback)(void *cookie, struct key_params *params))
18189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
18199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct key_params params;
18209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_wsec_key key;
18219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
18229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_security *sec;
18239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 wsec;
18249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
18259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
18279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
18289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
18299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("key index (%d)\n", key_idx));
18309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
18319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&key, 0, sizeof(key));
18339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	key.index = key_idx;
18349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	swap_key_to_BE(&key);
18359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&params, 0, sizeof(params));
18369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	params.key_len = (uint8)MIN(DOT11_MAX_KEY_SIZE, key.len);
18379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(params.key, key.data, params.key_len);
18389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)))) {
18409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
18419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
18429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
18439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wsec = dtoh32(wsec);
18449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (wsec) {
18459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WEP_ENABLED:
18469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sec = wl_read_prof(wl, WL_PROF_SEC);
18479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
18489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			params.cipher = WLAN_CIPHER_SUITE_WEP40;
18499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n"));
18509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
18519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			params.cipher = WLAN_CIPHER_SUITE_WEP104;
18529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n"));
18539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
18549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
18559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case TKIP_ENABLED:
18569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		params.cipher = WLAN_CIPHER_SUITE_TKIP;
18579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n"));
18589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
18599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case AES_ENABLED:
18609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
18619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
18629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
18639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	default:
18649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Invalid algo (0x%x)\n", wsec));
18659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EINVAL;
18669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
18679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	callback(cookie, &params);
18699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
18709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
18719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
18729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
18739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
18749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
18769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
18779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt     struct net_device *dev, uint8 key_idx)
18789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
18799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_INFO(("Not supported\n"));
18809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
18819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return -EOPNOTSUPP;
18829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
18839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
18859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint8 *mac, struct station_info *sinfo)
18879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
18899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
18909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	scb_val_t scb_val;
18919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int rssi;
18929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 rate;
18939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
18949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
18959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
18969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
18979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
18989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
18999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
19009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Wrong Mac address\n"));
19019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOENT;
19029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
19039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Report the current tx rate */
19059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)))) {
19069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Could not get rate (%d)\n", err));
19079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
19089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rate = dtoh32(rate);
19099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sinfo->filled |= STATION_INFO_TX_BITRATE;
19109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sinfo->txrate.legacy = rate * 5;
19119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Rate %d Mbps\n", (rate/2)));
19129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
19139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
19159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		scb_val.val = 0;
19169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)))) {
19179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Could not get rssi (%d)\n", err));
19189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
19199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
19209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rssi = dtoh32(scb_val.val);
19219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sinfo->filled |= STATION_INFO_SIGNAL;
19229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sinfo->signal = rssi;
19239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("RSSI %d dBm\n", rssi));
19249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
19259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
19269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
19279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
19289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
19309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
19319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
19339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
19349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt       bool enabled, int32 timeout)
19359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
19369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 pm;
19379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
19389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
19409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
19419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
19429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
19439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pm = enabled ? PM_FAST : PM_OFF;
19449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pm = htod32(pm);
19459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
19469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm))))) {
19479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -ENODEV) {
19489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("net_device is not ready yet\n"));
19499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
19509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("error (%d)\n", err));
19519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
19529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
19539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
19549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
19559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
19569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
19579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
19589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
19599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic __used uint32
19619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_find_msb(uint16 bit16)
19629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
19639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 ret = 0;
19649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (bit16 & 0xff00) {
19669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ret += 8;
19679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		bit16 >>= 8;
19689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
19699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (bit16 & 0xf0) {
19719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ret += 4;
19729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		bit16 >>= 4;
19739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
19749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (bit16 & 0xc) {
19769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ret += 2;
19779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		bit16 >>= 2;
19789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
19799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (bit16 & 2)
19819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ret += bit16 & 2;
19829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	else if (bit16)
19839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ret += bit16;
19849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return ret;
19869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
19879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
19889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \
19899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	defined(CHROMIUMOS_COMPAT_WIRELESS)
19909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
19919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
19929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const uint8 *addr, const struct cfg80211_bitrate_mask *mask)
19939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
19949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_rateset rateset;
19959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 rate;
19969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 val;
19979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err_bg;
19989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err_a;
19999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 legacy;
20009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
20019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
20039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
20049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
20059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
20069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* addr param is always NULL. ignore it */
20079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Get current rateset */
20089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
20099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sizeof(rateset))))) {
20109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("could not get current rateset (%d)\n", err));
20119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
20129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
20139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rateset.count = dtoh32(rateset.count);
20159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (!(legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy)))
20179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
20189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	val = wl_g_rates[legacy-1].bitrate * 100000;
20209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (val < rateset.count) {
20229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* Select rate by rateset index */
20239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rate = rateset.rates[val] & 0x7f;
20249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
20259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* Specified rate in bps */
20269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rate = val / 500000;
20279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
20289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("rate %d mbps\n", (rate/2)));
20309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/*
20329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*
20339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*	Set rate override,
20349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*	Since the is a/b/g-blind, both a/bg_rate are enforced.
20359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*/
20369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
20379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err_a = wl_dev_intvar_set(dev, "a_rate", rate);
20389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err_bg && err_a)) {
20399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
20409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return (err_bg | err_a);
20419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
20429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
20449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
20459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
20469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
20489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
20499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
20509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
20519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
20529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const uint8 *addr, const struct cfg80211_bitrate_mask *mask)
20539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
20549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_rateset rateset;
20559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 rate;
20569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 val;
20579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err_bg;
20589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err_a;
20599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
20609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int i;
20619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
20639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
20649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
20659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
20669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* addr param is always NULL. ignore it */
20679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Get current rateset */
20689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
20699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sizeof(rateset))))) {
20709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("could not get current rateset (%d)\n", err));
20719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
20729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
20739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rateset.count = dtoh32(rateset.count);
20759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (mask->fixed || mask->maxrate) {
20779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		val = mask->fixed ? (mask->fixed * 1000) : (mask->maxrate * 1000);
20789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (val < rateset.count) {
20799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			/* Select rate by rateset index */
20809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			rate = rateset.rates[val] & 0x7f;
20819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
20829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			/* Specified rate in bps */
20839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			rate = val / 500000;
20849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
20859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
20869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* Select maximum rate */
20879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rate = rateset.rates[rateset.count - 1] & 0x7f;
20889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
20899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
20909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (mask->fixed) {
20919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/*
20929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			Set rate override,
20939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			Since the is a/b/g-blind, both a/bg_rate are enforced.
20949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		*/
20959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
20969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err_a = wl_dev_intvar_set(dev, "a_rate", rate);
20979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err_bg && err_a)) {
20989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
20999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return (err_bg | err_a);
21009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
21019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
21029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/*
21039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			clear rate override
21049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			Since the is a/b/g-blind, both a/bg_rate are enforced.
21059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		*/
21069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* 0 is for clearing rate override */
21079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err_bg = wl_dev_intvar_set(dev, "bg_rate", 0);
21089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* 0 is for clearing rate override */
21099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err_a = wl_dev_intvar_set(dev, "a_rate", 0);
21109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err_bg && err_a)) {
21129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("could not set max rate (%d) (%d)\n", err_bg, err_a));
21139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return (err_bg | err_a);
21149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
21159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* Remove rates above selected rate */
21179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		for (i = 0; i < rateset.count; i++)
21189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if ((rateset.rates[i] & 0x7f) > rate)
21199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
21209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rateset.count = htod32(i);
21219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		/* Set current rateset */
21239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_dev_ioctl(dev, WLC_SET_RATESET, &rateset,
21249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			sizeof(rateset))))) {
21259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("error (%d)\n", err));
21269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
21279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
21289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
21299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
21309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
21319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
21329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
21349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
21359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */
21369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
21389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_resume(struct wiphy *wiphy)
21399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
21409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
21419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
21439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
21449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
21459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
21469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_invoke_iscan(wiphy_to_wl(wiphy));
21479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
21489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
21499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
21509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
21529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
21539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
21559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_suspend(struct wiphy *wiphy)
21569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
21579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
21589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
21599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
21619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
21629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
21639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
21649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
21669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_term_iscan(wl);
21679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->scan_request) {
21689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE means abort */
21699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->scan_request = NULL;
21709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
21719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	clear_bit(WL_STATUS_SCANNING, &wl->status);
21729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
21739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
21759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
21769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
21779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
21799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
21809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic __used int32
21829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, int32 err)
21839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
21849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 eabuf[ETHER_ADDR_STR_LEN];
21859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int i, j;
21869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(eabuf, 0, ETHER_ADDR_STR_LEN);
21889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
21899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid));
21909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
21919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("PMKID[%d]: %s =\n", i,
21929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			bcm_ether_ntoa(&pmk_list->pmkids.pmkid[i].BSSID,
21939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			eabuf)));
21949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		for (j = 0; j < WPA2_PMKID_LEN; j++) {
21959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]));
21969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
21979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
21989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (likely(!err)) {
21999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
22009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			sizeof(*pmk_list));
22019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
22029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
22049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
22059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \
22079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	defined(CHROMIUMOS_COMPAT_WIRELESS)
22089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
22099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
22109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_pmksa *pmksa)
22119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
22129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
22139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 eabuf[ETHER_ADDR_STR_LEN];
22149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
22159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int i;
22169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
22179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
22189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
22199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
22219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(eabuf, 0, ETHER_ADDR_STR_LEN);
22229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
22239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
22249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			ETHER_ADDR_LEN))
22259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				break;
22269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (i < WL_NUM_PMKIDS_MAX) {
22279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
22289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
22299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (i == wl->pmk_list->pmkids.npmkid)
22309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			wl->pmk_list->pmkids.npmkid++;
22319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
22329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -EINVAL;
22339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
22349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %s =\n",
22359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		bcm_ether_ntoa(&wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID,
22369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		eabuf)));
22379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	for (i = 0; i < WPA2_PMKID_LEN; i++) {
22389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("%02x\n",
22399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].PMKID[i]));
22409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
22419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err = wl_update_pmklist(dev, wl->pmk_list, err);
22439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
22459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
22469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
22479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
22499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
22509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
22529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
22539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_pmksa *pmksa)
22549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
22559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
22569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 eabuf[ETHER_ADDR_STR_LEN];
22579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct _pmkid_list pmkid;
22589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
22599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int i;
22609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
22629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
22639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
22649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
22669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(eabuf, 0, ETHER_ADDR_STR_LEN);
22679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
22689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
22699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %s =\n",
22719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		bcm_ether_ntoa(&pmkid.pmkid[0].BSSID, eabuf)));
22729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	for (i = 0; i < WPA2_PMKID_LEN; i++) {
22739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i]));
22749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
22759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
22779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN))
22789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
22799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((wl->pmk_list->pmkids.npmkid > 0) && (i < wl->pmk_list->pmkids.npmkid)) {
22819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t));
22829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) {
22839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID,
22849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				&wl->pmk_list->pmkids.pmkid[i+1].BSSID, ETHER_ADDR_LEN);
22859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID,
22869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				&wl->pmk_list->pmkids.pmkid[i+1].PMKID, WPA2_PMKID_LEN);
22879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
22889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->pmk_list->pmkids.npmkid--;
22899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
22909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	else {
22919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -EINVAL;
22929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
22939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err = wl_update_pmklist(dev, wl->pmk_list, err);
22959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
22969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
22979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
22989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
22999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
23009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
23029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
23049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
23059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
23069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = wiphy_to_wl(wiphy);
23079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
23089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
23109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
23119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
23129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	CHECK_SYS_UP();
23139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
23149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err = wl_update_pmklist(dev, wl->pmk_list, err);
23159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
23169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
23179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
23189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
23199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
23219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */
23229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct cfg80211_ops wl_cfg80211_ops = {
23249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.change_virtual_intf = wl_cfg80211_change_iface,
23259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.scan = wl_cfg80211_scan,
23269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.set_wiphy_params = wl_cfg80211_set_wiphy_params,
23279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.join_ibss = wl_cfg80211_join_ibss,
23289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.leave_ibss = wl_cfg80211_leave_ibss,
23299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.get_station = wl_cfg80211_get_station,
23309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.set_tx_power = wl_cfg80211_set_tx_power,
23319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.get_tx_power = wl_cfg80211_get_tx_power,
23329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.add_key = wl_cfg80211_add_key,
23339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.del_key = wl_cfg80211_del_key,
23349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.get_key = wl_cfg80211_get_key,
23359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.set_default_key = wl_cfg80211_config_default_key,
23369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
23379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.set_power_mgmt = wl_cfg80211_set_power_mgmt,
23389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
23399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.connect = wl_cfg80211_connect,
23409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.disconnect = wl_cfg80211_disconnect,
23419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.suspend = wl_cfg80211_suspend,
23429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.resume = wl_cfg80211_resume,
23439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \
23449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	defined(CHROMIUMOS_COMPAT_WIRELESS)
23459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.set_pmksa = wl_cfg80211_set_pmksa,
23469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.del_pmksa = wl_cfg80211_del_pmksa,
23479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	.flush_pmksa = wl_cfg80211_flush_pmksa
23489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
23499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt};
23509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
23529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_mode_to_nl80211_iftype(int32 mode)
23539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
23549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
23559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
23579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
23589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
23599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (mode) {
23609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_MODE_BSS:
23619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return NL80211_IFTYPE_STATION;
23629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_MODE_IBSS:
23639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return NL80211_IFTYPE_ADHOC;
23649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	default:
23659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return NL80211_IFTYPE_UNSPECIFIED;
23669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
23679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
23689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
23699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
23709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
23729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
23739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct wireless_dev *
23759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_alloc_wdev(int32 sizeof_iface, struct device *dev)
23769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
23779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wireless_dev *wdev;
23789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
23799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
23809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
23819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
23829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
23839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
23849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wdev)) {
23859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Could not allocate wireless device\n"));
23869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return ERR_PTR(-ENOMEM);
23879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
23889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface);
23899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wdev->wiphy)) {
23909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Couldn not allocate wiphy device\n"));
23919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -ENOMEM;
23929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto wiphy_new_out;
23939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
23949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_wiphy_dev(wdev->wiphy, dev);
23959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
23969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \
23979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	defined(CHROMIUMOS_COMPAT_WIRELESS)
23989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
23999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
24009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)| BIT(NL80211_IFTYPE_ADHOC);
24019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
24029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;	/* Set it as 11a by default.
24039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								** This will be updated with
24049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								** 11n phy tables in "ifconfig up"
24059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								** if phy has 11n capability
24069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt								*/
24079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
24089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->cipher_suites = __wl_cipher_suites;
24099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
24109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifndef WL_POWERSAVE_DISABLED
24119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \
24129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	defined(CHROMIUMOS_COMPAT_WIRELESS)
24139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
24149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt							* save mode by default
24159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt							*/
24169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
24179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->ps_default = TRUE;	/* enable power save mode by default */
24189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
24199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
24209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \
24219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	defined(CHROMIUMOS_COMPAT_WIRELESS)
24229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
24239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
24249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->wiphy->ps_default = FALSE;
24259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
24269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* !WL_POWERSAVE_DISABLED */
24279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(((err = wiphy_register(wdev->wiphy)) < 0))) {
24289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Couldn not register wiphy device (%d)\n", err));
24299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto wiphy_register_out;
24309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
24319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return wdev;
24329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwiphy_register_out:
24349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wiphy_free(wdev->wiphy);
24359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwiphy_new_out:
24379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	kfree(wdev);
24389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
24409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
24419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
24429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return ERR_PTR(err);
24449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
24459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
24479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_free_wdev(struct wl_priv *wl)
24489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
24499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wireless_dev *wdev = wl_to_wdev(wl);
24509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
24529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
24539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
24549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wdev)) {
24559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("wdev is invalid\n"));
24569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return;
24579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
24589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wiphy_unregister(wdev->wiphy);
24599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wiphy_free(wdev->wiphy);
24609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	kfree(wdev);
24619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_to_wdev(wl) = NULL;
24629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
24639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
24649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
24659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
24669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
24689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_inform_bss(struct wl_priv *wl)
24699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
24709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_scan_results *bss_list;
24719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_bss_info *bi = NULL;	/* must be initialized */
24729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
24739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int i;
24749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bss_list = wl->bss_list;
24779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
24789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n", bss_list->version));
24799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -EOPNOTSUPP;
24809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
24819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("scanned AP count (%d)\n", bss_list->count));
24829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bi = next_bss(bss_list, bi);
24839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	for_each_bss(bss_list, bi, i) {
24849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err = wl_inform_single_bss(wl, bi)))
24859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			break;
24869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
24879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
24889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
24899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
24909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
24919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
24929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
24939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wiphy *wiphy = wl_to_wiphy(wl);
24949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct ieee80211_mgmt *mgmt;
24959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct ieee80211_channel *channel;
24969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct ieee80211_supported_band *band;
24979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_cfg80211_bss_info *notif_bss_info;
24989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_scan_req *sr = wl_to_sr(wl);
24999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 signal;
25009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 freq;
25019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
25029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) {
25049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Beacon size is larger than allocated buffer. Discard it!!\n"));
25059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
25069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
25079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(uint8) +
25089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_BSS_INFO_MAX, GFP_KERNEL);
25099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!notif_bss_info)) {
25109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("notif_bss_info alloc failed\n"));
25119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOMEM;
25129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
25139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
25149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	notif_bss_info->channel = CHSPEC_CHANNEL(bi->chanspec);
25159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
25169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		band = wiphy->bands[IEEE80211_BAND_2GHZ];
25179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	else
25189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		band = wiphy->bands[IEEE80211_BAND_5GHZ];
25199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	notif_bss_info->rssi = bi->RSSI;
25209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(mgmt->bssid, &bi->BSSID,  ETHER_ADDR_LEN);
25219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
25229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
25239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			IEEE80211_STYPE_PROBE_RESP);
25249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
25259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mgmt->u.probe_resp.timestamp = 0;
25269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mgmt->u.probe_resp.beacon_int = cpu_to_le16(bi->beacon_period);
25279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mgmt->u.probe_resp.capab_info = cpu_to_le16(bi->capability);
25289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_rst_ie(wl);
25299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
25309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count, bi->rateset.rates);
25319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_mrg_ie(wl, ((uint8 *)bi) + bi->ie_offset, bi->ie_length);
25329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_cp_ie(wl, mgmt->u.probe_resp.variable, WL_BSS_INFO_MAX -
25339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		offsetof(struct wl_cfg80211_bss_info, frame_buf));
25349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt, u.probe_resp.variable) +
25359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_get_ielen(wl);
25369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
25379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	channel = ieee80211_get_channel(wiphy, freq);
25389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("SSID : \"%s\", rssi (%d), capability : 0x04%x\n", bi->SSID, notif_bss_info->rssi,
25409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		mgmt->u.probe_resp.capab_info));
25419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	signal = notif_bss_info->rssi * 100;
25439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
25449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL))) {
25459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("cfg80211_inform_bss_frame error\n"));
25469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(notif_bss_info);
25479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EINVAL;
25489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
25499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	kfree(notif_bss_info);
25509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
25529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
25539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic bool
25559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
25569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
25579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 event = ntoh32(e->event_type);
25589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint16 flags =	ntoh16(e->flags);
25599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (event == WLC_E_JOIN || event == WLC_E_ASSOC_IND || event == WLC_E_REASSOC_IND) {
25619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return TRUE;
25629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else if (event == WLC_E_LINK) {
25639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (flags & WLC_EVENT_MSG_LINK) {
25649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			if (wl_is_ibssmode(wl)) {
25659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				if (wl_is_ibssstarter(wl)) {
25669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt				}
25679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			} else {
25689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			}
25709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
25719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
25729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return FALSE;
25749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
25759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic bool
25779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e)
25789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
25799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 event = ntoh32(e->event_type);
25809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint16 flags =	ntoh16(e->flags);
25819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
25839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return TRUE;
25849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else if (event == WLC_E_LINK) {
25859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (!(flags & WLC_EVENT_MSG_LINK)) {
25869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return TRUE;
25879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
25889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
25899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return FALSE;
25919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
25929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
25939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
25949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
25959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data)
25969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
25979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bool act;
25989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
25999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
26019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
26029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
26039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl_is_linkup(wl, e)) {
26049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_link_up(wl);
26059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (wl_is_ibssmode(wl)) {
26069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			cfg80211_ibss_joined(ndev, (int8 *)&e->addr, GFP_KERNEL);
26079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("joined in IBSS network\n"));
26089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
26099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			wl_bss_connect_done(wl, ndev, e, data);
26109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("joined in BSS network \"%s\"\n",
26119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			((struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID))->SSID));
26129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
26139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		act = TRUE;
26149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_update_prof(wl, e, &act, WL_PROF_ACT);
26159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else if (wl_is_linkdown(wl, e)) {
26169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
26179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		clear_bit(WL_STATUS_CONNECTED, &wl->status);
26189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_link_down(wl);
26199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_init_prof(wl->profile);
26209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
26219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
26229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
26239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
26249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
26269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
26279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
26299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
26309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data)
26319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
26329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bool act;
26339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
26349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
26369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
26379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
26389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_bss_roaming_done(wl, ndev, e, data);
26399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	act = TRUE;
26409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_update_prof(wl, e, &act, WL_PROF_ACT);
26419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
26429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
26439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
26449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
26469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
26479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic __used int32
26499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dev_bufvar_set(struct net_device *dev, int8 *name, int8 *buf, int32 len)
26509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
26519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(dev);
26529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 buflen;
26539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
26559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	BUG_ON(unlikely(!buflen));
26569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return (wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen));
26589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
26599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
26619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dev_bufvar_get(struct net_device *dev, int8 *name, int8 *buf, int32 buf_len)
26629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
26639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(dev);
26649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 len;
26659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
26669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
26689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	BUG_ON(unlikely(!len));
26699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf,
26709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_IOCTL_LEN_MAX)))) {
26719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("error (%d)\n", err));
26729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
26739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
26749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(buf, wl->ioctl_buf, buf_len);
26759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
26779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
26789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
26809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_get_assoc_ies(struct wl_priv *wl)
26819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
26829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct net_device *ndev = wl_to_ndev(wl);
26839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_assoc_ielen *assoc_info;
26849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_connect_info *conn_info = wl_to_conn(wl);
26859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 req_len;
26869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 resp_len;
26879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
26889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
26899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
26909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ASSOC_INFO_MAX))) {
26919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("could not get assoc info (%d)\n", err));
26929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
26939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
26949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	assoc_info = (struct wl_assoc_ielen *)wl->extra_buf;
26959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	req_len = assoc_info->req_len;
26969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	resp_len = assoc_info->resp_len;
26979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (req_len) {
26989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
26999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ASSOC_INFO_MAX))) {
27009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("could not get assoc req (%d)\n", err));
27019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
27029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
27039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->req_ie_len = req_len;
27049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->req_ie = kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
27059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
27069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->req_ie_len = 0;
27079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->req_ie = NULL;
27089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
27099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (resp_len) {
27109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
27119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ASSOC_INFO_MAX))) {
27129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("could not get assoc resp (%d)\n", err));
27139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return err;
27149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
27159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->resp_ie_len = resp_len;
27169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->resp_ie = kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
27179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
27189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->resp_ie_len = 0;
27199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->resp_ie = NULL;
27209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
27219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len, conn_info->resp_ie_len));
27229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
27249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
27259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
27279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_update_bss_info(struct wl_priv *wl)
27289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
27299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct cfg80211_bss *bss;
27309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_bss_info *bi;
27319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wlc_ssid *ssid;
27329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
27339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
27369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
27379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
27389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl_is_ibssmode(wl))
27399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
27409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
27429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bss = cfg80211_get_bss(wl_to_wiphy(wl), NULL, (int8 *)&wl->bssid, ssid->SSID,
27439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ssid->SSID_len, WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
27449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_lock();
27469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!bss)) {
27479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Could not find the AP\n"));
27489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		*(uint32*)wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
27499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, wl->extra_buf,
27509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_EXTRA_BUF_MAX))) {
27519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Could not get bss info %d\n", err));
27529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			goto update_bss_info_out;
27539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
27549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		bi = (struct wl_bss_info *)(wl->extra_buf + 4);
27559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) {
27569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			err = -EIO;
27579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			goto update_bss_info_out;
27589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
27599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_inform_single_bss(wl, bi))))
27609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			goto update_bss_info_out;
27619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
27629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Found the AP in the list - BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
27639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			bss->bssid[0], bss->bssid[1], bss->bssid[2], bss->bssid[3],
27649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			bss->bssid[4], bss->bssid[5]));
27659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cfg80211_put_bss(bss);
27669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
27679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
27689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
27699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
27709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtupdate_bss_info_out:
27729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_unlock();
27739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
27749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
27759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
27779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
27789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data)
27799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
27809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_connect_info *conn_info = wl_to_conn(wl);
27819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
27829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
27849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
27859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
27869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_get_assoc_ies(wl);
27879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(&wl->bssid, &e->addr,  ETHER_ADDR_LEN);
27889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_update_bss_info(wl);
27899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	cfg80211_roamed(ndev,
27909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		(uint8 *)&wl->bssid,
27919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->req_ie, conn_info->req_ie_len,
27929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->resp_ie, conn_info->resp_ie_len,
27939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		GFP_KERNEL);
27949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Report roaming result\n"));
27959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
27969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_bit(WL_STATUS_CONNECTED, &wl->status);
27979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
27989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
27999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
28009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
28029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
28039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
28059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
28069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data)
28079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
28089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_connect_info *conn_info = wl_to_conn(wl);
28099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
28109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
28129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
28139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
28149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_get_assoc_ies(wl);
28159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(&wl->bssid, &e->addr,  ETHER_ADDR_LEN);
28169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_update_bss_info(wl);
28179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
28189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cfg80211_connect_result(ndev,
28199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			(uint8 *)&wl->bssid,
28209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			conn_info->req_ie, conn_info->req_ie_len,
28219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			conn_info->resp_ie, conn_info->resp_ie_len,
28229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WLAN_STATUS_SUCCESS,
28239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			GFP_KERNEL);
28249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Report connect result\n"));
28259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
28269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cfg80211_roamed(ndev,
28279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			(uint8 *)&wl->bssid,
28289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			conn_info->req_ie, conn_info->req_ie_len,
28299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			conn_info->resp_ie, conn_info->resp_ie_len,
28309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			GFP_KERNEL);
28319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		 WL_DBG(("Report roaming result\n"));
28329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
28339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_bit(WL_STATUS_CONNECTED, &wl->status);
28349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
28359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
28369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
28379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
28399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
28409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
28429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
28439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data)
28449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
28459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint16 flags =	ntoh16(e->flags);
28469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	enum nl80211_key_type key_type;
28479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
28499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
28509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
28519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_lock();
28539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (flags & WLC_EVENT_MSG_GROUP)
28549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		key_type = NL80211_KEYTYPE_GROUP;
28559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	else
28569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		key_type = NL80211_KEYTYPE_PAIRWISE;
28579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	cfg80211_michael_mic_failure(ndev, (uint8 *)&e->addr, key_type, -1, NULL, GFP_KERNEL);
28599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_unlock();
28609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
28629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
28639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
28649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return 0;
28659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
28669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
28689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
28699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const wl_event_msg_t *e, void* data)
28709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
28719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct channel_info channel_inform;
28729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_scan_results *bss_list;
28739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 len = WL_SCAN_BUF_MAX;
28749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
28759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
28779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
28789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
28799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->iscan_on && wl->iscan_kickstart)
28819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return wl_wakeup_iscan(wl_to_iscan(wl));
28829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
28849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Scan complete while device not scanning\n"));
28859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -EINVAL;
28869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
28879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->scan_request)) {
28889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
28899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_lock();
28909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
28919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sizeof(channel_inform))))) {
28929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("scan busy (%d)\n", err));
28939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto scan_done_out;
28949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
28959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	channel_inform.scan_channel = dtoh32(channel_inform.scan_channel);
28969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(channel_inform.scan_channel)) {
28979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
28989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("channel_inform.scan_channel (%d)\n", channel_inform.scan_channel));
28999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->bss_list = wl->scan_results;
29019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bss_list = wl->bss_list;
29029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(bss_list, 0, len);
29039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bss_list->buflen = htod32(len);
29049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len)))) {
29059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err));
29069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -EINVAL;
29079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto scan_done_out;
29089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bss_list->buflen = dtoh32(bss_list->buflen);
29109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bss_list->version = dtoh32(bss_list->version);
29119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bss_list->count = dtoh32(bss_list->count);
29129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
29139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((err = wl_inform_bss(wl))) {
29149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto scan_done_out;
29159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
29179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtscan_done_out :
29189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->scan_request) {
29199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cfg80211_scan_done(wl->scan_request, FALSE);
29209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->scan_request = NULL;
29219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
29239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
29249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
29259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_unlock();
29269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
29279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
29289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
29299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
29309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_conf(struct wl_conf *conf)
29319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
29329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	conf->mode = (uint32)-1;
29339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	conf->frag_threshold = (uint32)-1;
29349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	conf->rts_threshold = (uint32)-1;
29359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	conf->retry_short = (uint32)-1;
29369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	conf->retry_long = (uint32)-1;
29379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	conf->tx_power = -1;
29389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
29399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
29409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
29419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_prof(struct wl_profile *prof)
29429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
29439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(prof, 0, sizeof(*prof));
29449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
29459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
29469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
29479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_eloop_handler(struct wl_event_loop *el)
29489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
29499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(el, 0, sizeof(*el));
29509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
29519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_JOIN] = wl_notify_connect_status;
29529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_LINK] = wl_notify_connect_status;
29539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
29549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
29559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
29569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
29579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
29589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
29599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
29609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
29619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
29629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_priv_mem(struct wl_priv *wl)
29639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
29649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
29659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->scan_results)) {
29669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Scan results alloc failed\n"));
29679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
29689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL);
29709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->conf)) {
29719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("wl_conf alloc failed\n"));
29729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
29739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL);
29759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->profile)) {
29769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("wl_profile alloc failed\n"));
29779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
29789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
29809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->bss_info)) {
29819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Bss information alloc failed\n"));
29829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
29839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->scan_req_int = (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL);
29859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->scan_req_int)) {
29869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Scan req alloc failed\n"));
29879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
29889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
29909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->ioctl_buf)) {
29919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Ioctl buf alloc failed\n"));
29929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
29939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
29959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->extra_buf)) {
29969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Extra buf alloc failed\n"));
29979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
29989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
29999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL);
30009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->iscan)) {
30019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Iscan buf alloc failed\n"));
30029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
30039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL);
30059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->fw)) {
30069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("fw object alloc failed\n"));
30079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
30089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL);
30109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl->pmk_list)) {
30119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("pmk list alloc failed\n"));
30129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto init_priv_mem_out;
30139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return 0;
30169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtinit_priv_mem_out:
30189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_deinit_priv_mem(wl);
30199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return -ENOMEM;
30219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
30229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
30249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_deinit_priv_mem(struct wl_priv *wl)
30259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
30269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->scan_results) {
30279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->scan_results);
30289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->scan_results = NULL;
30299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->bss_info) {
30319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->bss_info);
30329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->bss_info = NULL;
30339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->conf) {
30359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->conf);
30369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->conf = NULL;
30379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->profile) {
30399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->profile);
30409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->profile = NULL;
30419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->scan_req_int) {
30439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->scan_req_int);
30449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->scan_req_int = NULL;
30459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->ioctl_buf) {
30479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->ioctl_buf);
30489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->ioctl_buf = NULL;
30499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->extra_buf) {
30519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->extra_buf);
30529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->extra_buf = NULL;
30539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->iscan) {
30559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->iscan);
30569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->iscan = NULL;
30579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->fw) {
30599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->fw);
30609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->fw = NULL;
30619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->pmk_list) {
30639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(wl->pmk_list);
30649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->pmk_list = NULL;
30659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
30679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
30709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_create_event_handler(struct wl_priv *wl)
30719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
30729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sema_init(&wl->event_sync, 0);
30739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	init_completion(&wl->event_exit);
30749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(((wl->event_pid = kernel_thread(wl_event_handler, wl, 0)) < 0))) {
30759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("failed to create event thread\n"));
30769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOMEM;
30779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("pid %d\n", wl->event_pid));
30799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return 0;
30809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
30819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
30839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_destroy_event_handler(struct wl_priv *wl)
30849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
30859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->event_pid >= 0) {
30869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		KILL_PROC(wl->event_pid, SIGTERM);
30879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wait_for_completion(&wl->event_exit);
30889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
30899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
30909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
30929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_term_iscan(struct wl_priv *wl)
30939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
30949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
30959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
30969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->iscan_on && iscan->pid >= 0) {
30979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->state = WL_ISCAN_STATE_IDLE;
30989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		KILL_PROC(iscan->pid, SIGTERM);
30999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wait_for_completion(&iscan->exited);
31009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->pid = -1;
31019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
31029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
31039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
31059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
31069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
31079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = iscan_to_wl(iscan);
31089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
31109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
31119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
31129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
31139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Scan complete while device not scanning\n"));
31149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return;
31159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
31169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (likely(wl->scan_request)) {
31179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cfg80211_scan_done(wl->scan_request, aborted);
31189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->scan_request = NULL;
31199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
31209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->iscan_kickstart = FALSE;
31219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
31229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
31239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
31249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
31259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
31279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
31289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
31299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
31309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("wake up iscan\n"));
31319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		up(&iscan->sync);
31329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return 0;
31339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
31349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return -EIO;
31369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
31379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
31399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_get_iscan_results(struct wl_iscan_ctrl *iscan, uint32 *status, struct wl_scan_results **bss_list)
31409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
31419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_results list;
31429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_scan_results *results;
31439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_results *list_buf;
31449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
31459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
31479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	list_buf = (struct wl_iscan_results *)iscan->scan_buf;
31489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	results = &list_buf->results;
31499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
31509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	results->version = 0;
31519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	results->count = 0;
31529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(&list, 0, sizeof(list));
31549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	list.results.buflen = htod32(WL_ISCAN_BUF_MAX);
31559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dev_iovar_getbuf(
31569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->dev,
31579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		"iscanresults",
31589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		&list,
31599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ISCAN_RESULTS_FIXED_SIZE,
31609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->scan_buf,
31619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ISCAN_BUF_MAX)))) {
31629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("error (%d)\n", err));
31639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
31649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
31659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	results->buflen = dtoh32(results->buflen);
31669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	results->version = dtoh32(results->version);
31679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	results->count = dtoh32(results->count);
31689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("results->count = %d\n", results->count));
31699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("results->buflen = %d\n", results->buflen));
31709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*status = dtoh32(list_buf->status);
31719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*bss_list = results;
31729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
31749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
31759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
31779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_iscan_done(struct wl_priv *wl)
31789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
31799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = wl->iscan;
31809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
31819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
31839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
31849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
31859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iscan->state = WL_ISCAN_STATE_IDLE;
31869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_lock();
31879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_inform_bss(wl);
31889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_notify_iscan_complete(iscan, FALSE);
31899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_unlock();
31909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
31919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
31929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
31939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
31959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
31969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
31979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
31989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_iscan_pending(struct wl_priv *wl)
31999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
32009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = wl->iscan;
32019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
32029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
32049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
32059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
32069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Reschedule the timer */
32079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000);
32089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iscan->timer_on = 1;
32099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
32109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
32119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
32129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
32149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
32159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
32179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_iscan_inprogress(struct wl_priv *wl)
32189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
32199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = wl->iscan;
32209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
32219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
32239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
32249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
32259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_lock();
32269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_inform_bss(wl);
32279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE);
32289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_unlock();
32299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Reschedule the timer */
32309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mod_timer(&iscan->timer, jiffies + iscan->timer_ms*HZ/1000);
32319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iscan->timer_on = 1;
32329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
32339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
32349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
32359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
32379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
32389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
32409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_iscan_aborted(struct wl_priv *wl)
32419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
32429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = wl->iscan;
32439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
32449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
32469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
32479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
32489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	iscan->state = WL_ISCAN_STATE_IDLE;
32499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_lock();
32509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_notify_iscan_complete(iscan, TRUE);
32519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	rtnl_unlock();
32529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
32539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
32549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
32559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
32579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
32589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
32609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_iscan_thread(void *data)
32619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
32629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
32639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
32649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = iscan_to_wl(iscan);
32659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_eloop *el = &iscan->el;
32669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 status;
32679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int err = 0;
32689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
32709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
32719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
32729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sched_setscheduler(current, SCHED_FIFO, &param);
32739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	status = WL_SCAN_RESULTS_PARTIAL;
32749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	while (likely(!down_interruptible(&iscan->sync))) {
32759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (iscan->timer_on) {
32769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			del_timer_sync(&iscan->timer);
32779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			iscan->timer_on = 0;
32789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
32799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rtnl_lock();
32809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely((err = wl_get_iscan_results(iscan, &status, &wl->bss_list)))) {
32819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			status = WL_SCAN_RESULTS_ABORTED;
32829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Abort iscan\n"));
32839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
32849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rtnl_unlock();
32859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		el->handler[status](wl);
32869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
32879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (iscan->timer_on) {
32889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		del_timer_sync(&iscan->timer);
32899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->timer_on = 0;
32909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
32919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	complete_and_exit(&iscan->exited, 0);
32929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
32939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
32949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
32959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return 0;
32979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
32989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
32999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
33009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_iscan_timer(ulong data)
33019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
33029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
33039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (iscan) {
33059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->timer_on = 0;
33069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("timer expired\n"));
33079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_wakeup_iscan(iscan);
33089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
33099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
33109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
33129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_invoke_iscan(struct wl_priv *wl)
33139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
33149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
33159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int err = 0;
33169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->iscan_on && iscan->pid < 0) {
33189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->state = WL_ISCAN_STATE_IDLE;
33199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sema_init(&iscan->sync, 0);
33209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		init_completion(&iscan->exited);
33219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0);
33229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(iscan->pid < 0)) {
33239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Could not create iscan thread\n"));
33249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -ENOMEM;
33259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
33269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
33279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
33299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
33309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
33329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_iscan_eloop(struct wl_iscan_eloop *el)
33339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
33349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memset(el, 0, sizeof(*el));
33359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done;
33369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress;
33379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending;
33389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted;
33399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted;
33409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
33419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
33439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_iscan(struct wl_priv *wl)
33449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
33459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
33469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int err = 0;
33479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->iscan_on) {
33499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->dev = wl_to_ndev(wl);
33509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->state = WL_ISCAN_STATE_IDLE;
33519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_init_iscan_eloop(&iscan->el);
33529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
33539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		init_timer(&iscan->timer);
33549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->timer.data = (ulong)iscan;
33559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->timer.function = wl_iscan_timer;
33569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sema_init(&iscan->sync, 0);
33579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		init_completion(&iscan->exited);
33589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->pid = kernel_thread(wl_iscan_thread, iscan, 0);
33599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(iscan->pid < 0)) {
33609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Could not create iscan thread\n"));
33619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			return -ENOMEM;
33629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
33639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		iscan->data = wl;
33649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
33659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
33679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
33689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
33709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_fw(struct wl_fw_ctrl *fw)
33719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
33729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	fw->status = 0;	/* init fw loading status. 0 means nothing was loaded yet */
33739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
33749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
33769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_priv(struct wl_priv *wl)
33779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
33789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wiphy *wiphy = wl_to_wiphy(wl);
33799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
33809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
33819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
33829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
33839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
33849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->scan_request = NULL;
33859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) || \
33869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	defined(CHROMIUMOS_COMPAT_WIRELESS)
33879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT);
33889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
33899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->pwr_save = wiphy->ps_default;
33909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
33919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifndef WL_ISCAN_DISABLED
33929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->iscan_on = TRUE;	/* iscan on & off switch. we enable iscan per default */
33939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
33949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->iscan_on = FALSE;
33959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* WL_ISCAN_DISABLED */
33969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifndef WL_ROAM_DISABLED
33979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->roam_on = TRUE;	/* roam on & off switch. we enable roam per default */
33989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
33999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->roam_on = FALSE;
34009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* WL_ROAM_DISABLED */
34019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->iscan_kickstart = FALSE;
34039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->active_scan = TRUE;	/* we do active scan for specific scan per default */
34049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->dongle_up = FALSE;	/* dongle is not up yet */
34059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_init_eq(wl);
34069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_init_priv_mem(wl))))
34079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
34089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(wl_create_event_handler(wl)))
34099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOMEM;
34109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_init_eloop_handler(&wl->el);
34119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mutex_init(&wl->usr_sync);
34129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_init_iscan(wl))))
34139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
34149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_init_fw(wl->fw);
34159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_init_conf(wl->conf);
34169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_init_prof(wl->profile);
34179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_link_down(wl);
34189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
34199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
34209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
34219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
34239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
34249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
34269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_deinit_priv(struct wl_priv *wl)
34279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
34289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
34299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
34309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
34319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_destroy_event_handler(wl);
34329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->dongle_up = FALSE;	/* dongle down */
34339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_flush_eq(wl);
34349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_link_down(wl);
34359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_term_iscan(wl);
34369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_deinit_priv_mem(wl);
34379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
34389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
34399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
34409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
34419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtint32
34439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_attach(struct net_device *ndev, void *data)
34449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
34459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wireless_dev *wdev;
34469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
34479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_iface *ci;
34489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
34499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
34519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
34529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
34539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!ndev)) {
34549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("ndev is invaild\n"));
34559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENODEV;
34569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
34579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
34589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!wl_cfg80211_dev)) {
34599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("wl_cfg80211_dev is invalid\n"));
34609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOMEM;
34619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
34629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("func %p\n", wl_sdio_func()));
34639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifndef WL_CFG80211_LOCALTEST
34649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_sdio_func()->dev);
34659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#else
34669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev = wl_alloc_wdev(sizeof(struct wl_iface), NULL);
34679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
34689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(IS_ERR(wdev)))
34699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOMEM;
34709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
34729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = wdev_to_wl(wdev);
34739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->wdev = wdev;
34749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->pub = data;
34759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ci = (struct wl_iface *)wl_to_ci(wl);
34769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ci->wl = wl;
34779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ndev->ieee80211_ptr = wdev;
34789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
34799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev->netdev = ndev;
34809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_init_priv(wl)))) {
34819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Failed to init iwm_priv (%d)\n", err));
34829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto cfg80211_attach_out;
34839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
34849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_set_drvdata(wl_cfg80211_dev, ci);
34859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_bit(WL_STATUS_READY, &wl->status);
34869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
34879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
34889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
34899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
34919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtcfg80211_attach_out:
34939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_free_wdev(wl);
34949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
34959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
34969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
34979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtvoid
34989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_detach(void)
34999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
35009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
35019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
35039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
35049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
35059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = WL_PRIV_GET();
35069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_deinit_priv(wl);
35089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_free_wdev(wl);
35099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_set_drvdata(wl_cfg80211_dev, NULL);
35109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	kfree(wl_cfg80211_dev);
35119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_cfg80211_dev = NULL;
35129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_clear_sdio_func();
35139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
35149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
35159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
35169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
35179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
35199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_wakeup_event(struct wl_priv *wl)
35209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
35219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	up(&wl->event_sync);
35229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
35239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
35259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_event_handler(void *data)
35269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
35279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = (struct wl_priv *)data;
35289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
35299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_event_q *e;
35309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
35329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
35339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
35349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	sched_setscheduler(current, SCHED_FIFO, &param);
35359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	while (likely(!down_interruptible(&wl->event_sync))) {
35369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(!(e = wl_deq_event(wl)))) {
35379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("eqeue empty..\n"));
35389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			BUG();
35399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
35409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("event type (%d)\n", e->etype));
35419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (wl->el.handler[e->etype]) {
35429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			wl->el.handler[e->etype](wl, wl_to_ndev(wl), &e->emsg, e->edata);
35439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} 	else {
35449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
35459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
35469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_put_event(e);
35479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
35489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	complete_and_exit(&wl->event_exit, 0);
35499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
35509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
35519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
35529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
35539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtvoid
35559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e, void* data)
35569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
35579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32 event_type = ntoh32(e->event_type);
35589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl = ndev_to_wl(ndev);
35599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#if (WL_DBG_LEVEL > 0)
35609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 *estr = (event_type <= sizeof(wl_dbg_estr)/WL_DBG_ESTR_MAX-1) ?
35619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_dbg_estr[event_type] : (int8 *)"Unknown";
35629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* (WL_DBG_LEVEL > 0) */
35639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("event_type (%d):""WLC_E_""%s\n", event_type, estr));
35649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (likely(!wl_enq_event(wl, event_type, e, data)))
35659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl_wakeup_event(wl);
35669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
35679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
35699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_eq(struct wl_priv *wl)
35709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
35719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_init_eq_lock(wl);
35729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	INIT_LIST_HEAD(&wl->eq_list);
35739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
35749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
35769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_flush_eq(struct wl_priv *wl)
35779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
35789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_event_q *e;
35799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_lock_eq(wl);
35819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	while (!list_empty(&wl->eq_list)) {
35829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
35839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		list_del(&e->eq_list);
35849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(e);
35859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
35869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_unlock_eq(wl);
35879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
35889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
35909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt* retrieve first queued event from head
35919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
35929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct wl_event_q *
35949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_deq_event(struct wl_priv *wl)
35959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
35969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_event_q *e = NULL;
35979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
35989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_lock_eq(wl);
35999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (likely(!list_empty(&wl->eq_list))) {
36009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list);
36019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		list_del(&e->eq_list);
36029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
36039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_unlock_eq(wl);
36049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return e;
36069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
36079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/*
36099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt** push event to tail of the queue
36109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt*/
36119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
36139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_enq_event(struct wl_priv *wl, uint32 event, const wl_event_msg_t *msg, void *data)
36149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
36159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_event_q *e;
36169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
36179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(!(e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL)))) {
36199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("event alloc failed\n"));
36209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOMEM;
36219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
36229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	e->etype = event;
36249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(&e->emsg, msg, sizeof(wl_event_msg_t));
36259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (data) {
36269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
36279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_lock_eq(wl);
36289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	list_add_tail(&e->eq_list, &wl->eq_list);
36299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_unlock_eq(wl);
36309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
36329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
36339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
36359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_put_event(struct wl_event_q *e)
36369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
36379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	kfree(e);
36389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
36399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtvoid
36419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_sdio_func(void *func)
36429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
36439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	cfg80211_sdio_func = (struct sdio_func *)func;
36449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
36459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
36479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_clear_sdio_func(void)
36489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
36499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	cfg80211_sdio_func = NULL;
36509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
36519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic struct sdio_func  *
36549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_sdio_func(void)
36559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
36569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return cfg80211_sdio_func;
36579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
36589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
36609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_mode(struct net_device *ndev, int32 iftype)
36619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
36629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 infra = 0;
36639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 ap = 0;
36649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
36659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (iftype) {
36679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_IFTYPE_MONITOR:
36689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_IFTYPE_WDS:
36699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("type (%d) : currently we do not support this mode\n", iftype));
36709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -EINVAL;
36719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
36729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_IFTYPE_ADHOC:
36739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
36749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case NL80211_IFTYPE_STATION:
36759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		infra = 1;
36769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
36779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	default:
36789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -EINVAL;
36799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("invalid type (%d)\n", iftype));
36809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
36819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
36829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	infra = htod32(infra);
36839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ap = htod32(ap);
36849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra));
36859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra))) ||
36869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		unlikely(err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap)))) {
36879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_SET_INFRA error (%d)\n", err));
36889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
36899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
36909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return -EINPROGRESS;
36929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
36939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifndef EMBEDDED_PLATFORM
36959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
36969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_country(struct net_device *ndev, uint8 ccode)
36979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
36989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
36999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
37009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
37039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
37049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
37069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_up(struct net_device *ndev, uint32 up)
37079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
37089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
37099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
37119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
37129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
37139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err =  wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up)))) {
37149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_UP error (%d)\n", err));
37159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
37169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
37179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
37189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
37199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
37209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
37219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
37239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_power(struct net_device *ndev, uint32 power_mode)
37249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
37259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
37269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err =  wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode)))) {
37289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("WLC_SET_PM error (%d)\n", err));
37299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
37309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
37319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
37329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
37349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_glom(struct net_device *ndev, uint32 glom, uint32 dongle_align)
37359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
37369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
37379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
37389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Match Host and Dongle rx alignment */
37409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf));
37419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err =  wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
37429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("txglomalign error (%d)\n", err));
37439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_glom_out;
37449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
37459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* disable glom option per default */
37469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
37479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err =  wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
37489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("txglom error (%d)\n", err));
37499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_glom_out;
37509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
37519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtdongle_glom_out :
37529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
37539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
37549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
37569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_roam(struct net_device *ndev, uint32 roamvar, uint32 bcn_timeout)
37579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
37589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
37599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
37609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Setup timeout if Beacons are lost and roam is off to report link down */
37629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (roamvar) {
37639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
37649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err =  wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
37659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("bcn_timeout error (%d)\n", err));
37669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			goto dongle_rom_out;
37679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
37689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
37699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
37709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
37719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err =  wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
37729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("roam_off error (%d)\n", err));
37739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_rom_out;
37749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
37759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtdongle_rom_out :
37769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
37779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
37789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
37809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_eventmsg(struct net_device *ndev)
37819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
37829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
37849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 eventmask[WL_EVENTING_MASK_LEN];
37859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
37869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Setup event_msgs */
37889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
37899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err =  wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf)))) {
37909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Get event_msgs error (%d)\n", err));
37919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_eventmsg_out;
37929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
37939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
37949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
37959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_SET_SSID);
37969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_PRUNE);
37979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_AUTH);
37989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_REASSOC);
37999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_REASSOC_IND);
38009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_DEAUTH_IND);
38019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_DISASSOC_IND);
38029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_DISASSOC);
38039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_JOIN);
38049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_ASSOC_IND);
38059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_PSK_SUP);
38069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_LINK);
38079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_NDIS_LINK);
38089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_MIC_ERROR);
38099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_PMKID_CACHE);
38109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_TXFAIL);
38119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_JOIN_START);
38129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	setbit(eventmask, WLC_E_SCAN_COMPLETE);
38139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf));
38159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err =  wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
38169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Set event_msgs error (%d)\n", err));
38179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_eventmsg_out;
38189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
38199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtdongle_eventmsg_out :
38219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
38229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
38239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
38259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_scantime(struct net_device *ndev, int32 scan_assoc_time, int32 scan_unassoc_time)
38269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
38279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
38289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((err =  wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
38309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sizeof(scan_assoc_time)))) {
38319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -EOPNOTSUPP) {
38329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_INFO(("Scan assoc time is not supported\n"));
38339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
38349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Scan assoc time error (%d)\n", err));
38359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
38369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_scantime_out;
38379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
38389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((err =  wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
38399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sizeof(scan_unassoc_time)))) {
38409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -EOPNOTSUPP) {
38419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_INFO(("Scan unassoc time is not supported\n"));
38429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
38439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Scan unassoc time error (%d)\n", err));
38449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
38459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_scantime_out;
38469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
38479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtdongle_scantime_out :
38499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
38509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
38519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
38539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_offload(struct net_device *ndev, int32 arpoe, int32 arp_ol)
38549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
38559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
38569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
38579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Set ARP offload */
38599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
38609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((err =  wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
38619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -EOPNOTSUPP) {
38629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_INFO(("arpoe is not supported\n"));
38639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
38649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("arpoe error (%d)\n", err));
38659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
38669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_offload_out;
38679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
38689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
38699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((err =  wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
38709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -EOPNOTSUPP) {
38719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_INFO(("arp_ol is not supported\n"));
38729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
38739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("arp_ol error (%d)\n", err));
38749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
38759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_offload_out;
38769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
38779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtdongle_offload_out :
38799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
38809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
38819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
38829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
38839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_pattern_atoh(int8 *src, int8 *dst)
38849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
38859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
38869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int i;
38879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (strncmp(src, "0x", 2) != 0 &&
38889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	    strncmp(src, "0X", 2) != 0) {
38899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
38909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -1;
38919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
38929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	src = src + 2; /* Skip past 0x */
38939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (strlen(src) % 2 != 0) {
38949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Mask invalid format. Needs to be of even length\n"));
38959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -1;
38969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
38979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	for (i = 0; *src != '\0'; i++) {
38989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		char num[3];
38999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		strncpy(num, src, 2);
39009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		num[2] = '\0';
39019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		dst[i] = (uint8)strtoul(num, NULL, 16);
39029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		src += 2;
39039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
39049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return i;
39059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
39069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
39089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_filter(struct net_device *ndev, uint32 filter_mode)
39099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
39109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
39119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const int8 				*str;
39129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_pkt_filter		pkt_filter;
39139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_pkt_filter		*pkt_filterp;
39149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32						buf_len;
39159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32						str_len;
39169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32					mask_size;
39179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	uint32					pattern_size;
39189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 buf[256];
39199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
39209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt/* add a default packet filter pattern */
39229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	str = "pkt_filter_add";
39239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	str_len = strlen(str);
39249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	strncpy(buf, str, str_len);
39259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	buf[ str_len ] = '\0';
39269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	buf_len = str_len + 1;
39279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pkt_filterp = (struct wl_pkt_filter *) (buf + str_len + 1);
39299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Parse packet filter id. */
39319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pkt_filter.id = htod32(100);
39329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Parse filter polarity. */
39349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pkt_filter.negate_match = htod32(0);
39359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Parse filter type. */
39379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pkt_filter.type = htod32(0);
39389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Parse pattern filter offset. */
39409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pkt_filter.u.pattern.offset = htod32(0);
39419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Parse pattern filter mask. */
39439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mask_size =	htod32(wl_pattern_atoh("0xff",
39449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		(char *) pkt_filterp->u.pattern.mask_and_pattern));
39459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Parse pattern filter pattern. */
39479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pattern_size = htod32(wl_pattern_atoh("0x00",
39489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		(char *) &pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
39499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (mask_size != pattern_size) {
39519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("Mask and pattern not the same size\n"));
39529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -EINVAL;
39539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_filter_out;
39549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
39559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	pkt_filter.u.pattern.size_bytes = mask_size;
39579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	buf_len += WL_PKT_FILTER_FIXED_LEN;
39589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
39599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Keep-alive attributes are set in local	variable (keep_alive_pkt), and
39619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	** then memcpy'ed into buffer (keep_alive_pktp) since there is no
39629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	** guarantee that the buffer is properly aligned.
39639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	*/
39649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy((char *)pkt_filterp, &pkt_filter,
39659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
39669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((err =  wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len))) {
39689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -EOPNOTSUPP) {
39699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_INFO(("filter not supported\n"));
39709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
39719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("filter (%d)\n", err));
39729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
39739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_filter_out;
39749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
39759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* set mode to allow pattern */
39779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf, sizeof(iovbuf));
39789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if ((err =  wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)))) {
39799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (err == -EOPNOTSUPP) {
39809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_INFO(("filter_mode not supported\n"));
39819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		} else {
39829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("filter_mode (%d)\n", err));
39839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
39849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto dongle_filter_out;
39859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
39869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtdongle_filter_out :
39889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
39899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
39909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* !EMBEDDED_PLATFORM */
39919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
39929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtint32
39939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_config_dongle(struct wl_priv *wl, bool need_lock)
39949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
39959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifndef DHD_SDALIGN
39969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#define DHD_SDALIGN	32
39979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
39989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct net_device *ndev;
39999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wireless_dev *wdev;
40009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
40019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
40039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
40049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
40059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->dongle_up)
40069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
40079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ndev = wl_to_ndev(wl);
40109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wdev = ndev->ieee80211_ptr;
40119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (need_lock)
40129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rtnl_lock();
40139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifndef EMBEDDED_PLATFORM
40159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dongle_up(ndev, 0))))
40169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto default_conf_out;
40179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dongle_country(ndev, 0))))
40189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto default_conf_out;
40199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dongle_power(ndev, PM_FAST))))
40209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto default_conf_out;
40219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dongle_glom(ndev, 0, DHD_SDALIGN))))
40229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto default_conf_out;
40239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3))))
40249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto default_conf_out;
40259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dongle_eventmsg(ndev))))
40269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto default_conf_out;
40279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_dongle_scantime(ndev, 40, 80);
40299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_dongle_offload(ndev, 1, 0xf);
40309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_dongle_filter(ndev, 1);
40319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif /* !EMBEDDED_PLATFORM */
40329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err = wl_dongle_mode(ndev, wdev->iftype);
40349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err && err != -EINPROGRESS))
40359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto default_conf_out;
40369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_dongle_probecap(wl))))
40379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		goto default_conf_out;
40389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
40409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
40419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
40429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* -EINPROGRESS: Call commit handler */
40439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtdefault_conf_out :
40459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (need_lock)
40469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		rtnl_unlock();
40479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->dongle_up = TRUE;
40499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
40519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
40539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
40559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_update_wiphybands(struct wl_priv *wl)
40569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
40579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wiphy *wiphy;
40589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 phy_list;
40599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int8 phy;
40609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
40619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
40639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
40649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
40659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err =  wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list,
40669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		sizeof(phy_list)))) {
40679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("error (%d)\n", err));
40689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
40699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
40709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	phy = ((char *)&phy_list)[1];
40729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("%c phy\n", phy));
40739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (phy == 'n' || phy == 'a') {
40749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wiphy = wl_to_wiphy(wl);
40759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
40769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
40779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
40789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
40799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
40809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
40829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
40839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
40859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt__wl_cfg80211_up(struct wl_priv *wl)
40869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
40879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
40889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err = wl_config_dongle(wl, FALSE)))
40909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
40919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_invoke_iscan(wl);
40939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_bit(WL_STATUS_READY, &wl->status);
40949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
40959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
40969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
40979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
40989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt__wl_cfg80211_down(struct wl_priv *wl)
40999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
41009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
41019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	/* Check if cfg80211 interface is already down */
41039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (!test_bit(WL_STATUS_READY, &wl->status))
41049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;	   /* it is even not ready */
41059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
41079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_term_iscan(wl);
41089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (wl->scan_request) {
41099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cfg80211_scan_done(wl->scan_request, TRUE); /* TRUE means abort */
41109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->scan_request = NULL;
41119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
41129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	clear_bit(WL_STATUS_READY, &wl->status);
41139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	clear_bit(WL_STATUS_SCANNING, &wl->status);
41149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
41159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	clear_bit(WL_STATUS_CONNECTED, &wl->status);
41169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
41189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
41199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtint32
41219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_up(void)
41229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
41239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
41249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
41259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
41279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
41289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
41299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = WL_PRIV_GET();
41309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mutex_lock(&wl->usr_sync);
41319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err = __wl_cfg80211_up(wl);
41329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mutex_unlock(&wl->usr_sync);
41339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
41349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
41359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
41369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
41389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
41399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtint32
41419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_down(void)
41429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
41439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
41449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
41459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
41479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
41489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
41499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = WL_PRIV_GET();
41509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mutex_lock(&wl->usr_sync);
41519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	err = __wl_cfg80211_down(wl);
41529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	mutex_unlock(&wl->usr_sync);
41539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
41549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
41559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
41569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
41589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
41599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
41619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_dongle_probecap(struct wl_priv *wl)
41629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
41639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
41649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely((err = wl_update_wiphybands(wl))))
41669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return err;
41679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
41699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
41709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void *
41729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_read_prof(struct wl_priv *wl, int32 item)
41739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
41749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (item) {
41759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_PROF_SEC:
41769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return &wl->profile->sec;
41779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_PROF_ACT:
41789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return &wl->profile->active;
41799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_PROF_BSSID:
41809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return &wl->profile->bssid;
41819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_PROF_SSID:
41829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return &wl->profile->ssid;
41839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
41849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_ERR(("invalid item (%d)\n", item));
41859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return NULL;
41869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
41879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
41899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, int32 item)
41909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
41919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
41929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wlc_ssid *ssid;
41939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
41949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	switch (item) {
41959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_PROF_SSID:
41969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		ssid = (wlc_ssid_t *)data;
41979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memset(wl->profile->ssid.SSID, 0, sizeof(wl->profile->ssid.SSID));
41989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len);
41999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->profile->ssid.SSID_len = ssid->SSID_len;
42009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
42019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_PROF_BSSID:
42029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (data)
42039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN);
42049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		else
42059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			memset(wl->profile->bssid, 0, ETHER_ADDR_LEN);
42069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
42079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_PROF_SEC:
42089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
42099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
42109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	case WL_PROF_ACT:
42119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		wl->profile->active = *(bool *)data;
42129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
42139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	default :
42149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("unsupported item (%d)\n", item));
42159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -EOPNOTSUPP;
42169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		break;
42179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
42189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
42209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
42219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtvoid
42239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_dbg_level(uint32 level)
42249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
42259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl_dbg_level = level;
42269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
42279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic bool
42299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_is_ibssmode(struct wl_priv *wl)
42309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
42319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return (wl->conf->mode == WL_MODE_IBSS);
42329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
42339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic bool
42359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_is_ibssstarter(struct wl_priv *wl)
42369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
42379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return wl->ibss_starter;
42389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
42399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
42419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_rst_ie(struct wl_priv *wl)
42429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
42439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_ie *ie = wl_to_ie(wl);
42449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ie->offset = 0;
42469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
42479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
42499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_add_ie(struct wl_priv *wl, uint8 t, uint8 l, uint8 *v)
42509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
42519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_ie *ie = wl_to_ie(wl);
42529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
42539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
42559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("ei crosses buffer boundary\n"));
42569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOSPC;
42579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
42589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ie->buf[ie->offset] = t;
42599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ie->buf[ie->offset+1] = l;
42609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(&ie->buf[ie->offset+2], v, l);
42619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ie->offset += l+2;
42629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
42649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
42659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
42679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_mrg_ie(struct wl_priv *wl, uint8 *ie_stream, uint16 ie_size)
42689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
42699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_ie *ie = wl_to_ie(wl);
42709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
42719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
42739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("ei_stream crosses buffer boundary\n"));
42749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOSPC;
42759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
42769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(&ie->buf[ie->offset], ie_stream,  ie_size);
42779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	ie->offset += ie_size;
42789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
42809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
42819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic int32
42839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cp_ie(struct wl_priv *wl, uint8 *dst, uint16 dst_size)
42849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
42859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_ie *ie = wl_to_ie(wl);
42869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
42879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(ie->offset > dst_size)) {
42899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_ERR(("dst_size is not enough\n"));
42909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return -ENOSPC;
42919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
42929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(dst, &ie->buf[0], ie->offset);
42939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return err;
42959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
42969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
42979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic uint32
42989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_get_ielen(struct wl_priv *wl)
42999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_ie *ie = wl_to_ie(wl);
43019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return ie->offset;
43039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
43069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_link_up(struct wl_priv *wl)
43079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->link_up = TRUE;
43099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
43129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_link_down(struct wl_priv *wl)
43139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_connect_info *conn_info = wl_to_conn(wl);
43159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->link_up = FALSE;
43179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (conn_info->req_ie) {
43189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(conn_info->req_ie);
43199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->req_ie = NULL;
43209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
43219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	conn_info->req_ie_len = 0;
43229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (conn_info->resp_ie) {
43239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		kfree(conn_info->resp_ie);
43249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		conn_info->resp_ie = NULL;
43259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
43269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	conn_info->resp_ie_len = 0;
43279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
43309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_lock_eq(struct wl_priv *wl)
43319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	spin_lock_irq(&wl->eq_lock);
43339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
43369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_unlock_eq(struct wl_priv *wl)
43379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	spin_unlock_irq(&wl->eq_lock);
43399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
43429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_init_eq_lock(struct wl_priv *wl)
43439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	spin_lock_init(&wl->eq_lock);
43459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
43489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_delay(uint32 ms)
43499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (ms < 1000 / HZ) {
43519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		cond_resched();
43529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		mdelay(ms);
43539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
43549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		msleep(ms);
43559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
43569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void
43599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_set_drvdata(struct wl_dev *dev, void *data)
43609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	dev->driver_data = data;
43629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtstatic void *
43659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_get_drvdata(struct wl_dev *dev)
43669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return dev->driver_data;
43689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtint32
43719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_read_fw(int8 *buf, uint32 size)
43729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const struct firmware *fw_entry;
43749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
43759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
43779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In : size (%d)\n", size));
43789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
43799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = WL_PRIV_GET();
43809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	fw_entry = wl->fw->fw_entry;
43829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (fw_entry->size < wl->fw->ptr + size) {
43849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		size = fw_entry->size - wl->fw->ptr;
43859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
43869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	memcpy(buf, &fw_entry->data[wl->fw->ptr], size);
43879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->fw->ptr += size;
43889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
43899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out : size (%d)\n", size));
43909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
43919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return size;
43929984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
43939984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43949984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtvoid
43959984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_release_fw(void)
43969984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
43979984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
43989984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
43999984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
44009984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
44019984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
44029984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = WL_PRIV_GET();
44039984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	release_firmware(wl->fw->fw_entry);
44049984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->fw->ptr = 0;
44059984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
44069984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
44079984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
44089984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
44099984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
44109984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtvoid *
44119984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_request_fw(int8 *file_name)
44129984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
44139984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
44149984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	const struct firmware *fw_entry = NULL;
44159984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	int32 err = 0;
44169984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
44179984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
44189984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
44199984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
44209984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("file name : \"%s\"\n", file_name));
44219984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = WL_PRIV_GET();
44229984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
44239984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
44249984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err = request_firmware(&wl->fw->fw_entry, file_name,
44259984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			&wl_sdio_func()->dev))) {
44269984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Could not download fw (%d)\n", err));
44279984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			goto req_fw_out;
44289984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
44299984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
44309984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		fw_entry = wl->fw->fw_entry;
44319984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (fw_entry) {
44329984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("fw size (%d), data (%p)\n", fw_entry->size, fw_entry->data));
44339984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
44349984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
44359984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (unlikely(err = request_firmware(&wl->fw->fw_entry, file_name,
44369984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			&wl_sdio_func()->dev))) {
44379984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_ERR(("Could not download nvram (%d)\n", err));
44389984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			goto req_fw_out;
44399984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
44409984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
44419984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		fw_entry = wl->fw->fw_entry;
44429984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		if (fw_entry) {
44439984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt			WL_DBG(("nvram size (%d), data (%p)\n", fw_entry->size, fw_entry->data));
44449984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		}
44459984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	} else {
44469984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		WL_DBG(("Downloading already done. Nothing to do more\n"));
44479984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		err = -EPERM;
44489984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
44499984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
44509984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
44519984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
44529984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
44539984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtreq_fw_out:
44549984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	if (unlikely(err)) {
44559984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt		return NULL;
44569984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	}
44579984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl->fw->ptr = 0;
44589984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return (void *)fw_entry->data;
44599984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
44609984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
44619984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtint8 *
44629984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_get_fwname(void)
44639984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
44649984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
44659984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
44669984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
44679984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
44689984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
44699984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = WL_PRIV_GET();
44709984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
44719984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
44729984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
44739984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
44749984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return wl->fw->fw_name;
44759984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
44769984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
44779984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtint8 *
44789984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidtwl_cfg80211_get_nvramname(void)
44799984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt{
44809984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	struct wl_priv *wl;
44819984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt
44829984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
44839984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("In\n"));
44849984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
44859984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	wl = WL_PRIV_GET();
44869984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
44879984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#ifdef WL_CFG80211_BACKTRACE
44889984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	WL_DBG(("Out\n"));
44899984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt#endif
44909984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt	return wl->fw->nvram_name;
44919984c42af1f24da360515edd81441ef5dfe23da4Dmitry Shmidt}
4492