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(¶ms->bssid, ðer_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(¶ms->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(¶ms->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(¶ms, 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, ¶ms); 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, ¶m); 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, ¶m); 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