Index: chromeos/drivers/ath6kl/os/linux/ar6000_drv.c |
diff --git a/chromeos/drivers/ath6kl/os/linux/ar6000_drv.c b/chromeos/drivers/ath6kl/os/linux/ar6000_drv.c |
index ae67aed11d9f12997733b6a5b5553871d73fb372..daba6e4cb9d8bf6a13f8f9294964d868190eef9f 100644 |
--- a/chromeos/drivers/ath6kl/os/linux/ar6000_drv.c |
+++ b/chromeos/drivers/ath6kl/os/linux/ar6000_drv.c |
@@ -1,21 +1,25 @@ |
-/* |
- * |
- * Copyright (c) 2004-2010 Atheros Communications Inc. |
- * All rights reserved. |
- * |
- * |
-// This program is free software; you can redistribute it and/or modify |
-// it under the terms of the GNU General Public License version 2 as |
-// published by the Free Software Foundation; |
+//------------------------------------------------------------------------------ |
+// Copyright (c) 2004-2010 Atheros Communications Inc. |
+// All rights reserved. |
// |
-// Software distributed under the License is distributed on an "AS |
-// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
-// implied. See the License for the specific language governing |
-// rights and limitations under the License. |
+// |
// |
+// Permission to use, copy, modify, and/or distribute this software for any |
+// purpose with or without fee is hereby granted, provided that the above |
+// copyright notice and this permission notice appear in all copies. |
// |
- * |
- */ |
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
+// |
+// |
+// |
+// Author(s): ="Atheros" |
+//------------------------------------------------------------------------------ |
/* |
* This driver is a pseudo ethernet driver to access the Atheros AR6000 |
@@ -31,6 +35,8 @@ |
#include "epping_test.h" |
#include "wlan_config.h" |
#include "ar3kconfig.h" |
+#include "ar6k_pal.h" |
+#include "AR6002/addrs.h" |
/* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux behavior. When |
@@ -63,7 +69,6 @@ static ATH_DEBUG_MASK_DESCRIPTION driver_debug_desc[] = { |
{ ATH_DEBUG_HTC_RAW , "HTC Raw IF tracing"}, |
{ ATH_DEBUG_HCI_BRIDGE , "HCI Bridge Setup"}, |
{ ATH_DEBUG_HCI_RECV , "HCI Recv tracing"}, |
- { ATH_DEBUG_HCI_SEND , "HCI Send tracing"}, |
{ ATH_DEBUG_HCI_DUMP , "HCI Packet dumps"}, |
}; |
@@ -85,7 +90,7 @@ ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver, |
MODULE_AUTHOR("Atheros Communications, Inc."); |
MODULE_DESCRIPTION(DESCRIPTION); |
-MODULE_LICENSE("GPL and additional rights"); |
+MODULE_LICENSE("Dual BSD/GPL"); |
#ifndef REORG_APTC_HEURISTICS |
#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL |
@@ -115,9 +120,7 @@ HCI_TRANSPORT_CALLBACKS ar6kHciTransCallbacks = { NULL }; |
unsigned int processDot11Hdr = 0; |
int bmienable = BMIENABLE_DEFAULT; |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
char ifname[IFNAMSIZ] = {0,}; |
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */ |
int wlaninitmode = WLAN_INIT_MODE_DEFAULT; |
unsigned int bypasswmi = 0; |
@@ -145,6 +148,7 @@ unsigned int panic_on_assert = 1; |
unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT; |
unsigned int setuphci = SETUPHCI_DEFAULT; |
+unsigned int setuphcipal = SETUPHCIPAL_DEFAULT; |
unsigned int loghci = 0; |
unsigned int setupbtdev = SETUPBTDEV_DEFAULT; |
#ifndef EXPORT_HCI_BRIDGE_INTERFACE |
@@ -158,7 +162,6 @@ unsigned int csumOffloadTest=0; |
#endif |
unsigned int eppingtest=0; |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
module_param_string(ifname, ifname, sizeof(ifname), 0644); |
module_param(wlaninitmode, int, 0644); |
module_param(bmienable, int, 0644); |
@@ -189,6 +192,7 @@ module_param(irqprocmode, uint, 0644); |
module_param(nohifscattersupport, uint, 0644); |
module_param(panic_on_assert, uint, 0644); |
module_param(setuphci, uint, 0644); |
+module_param(setuphcipal, uint, 0644); |
module_param(loghci, uint, 0644); |
module_param(setupbtdev, uint, 0644); |
#ifndef EXPORT_HCI_BRIDGE_INTERFACE |
@@ -197,48 +201,10 @@ module_param(hciuartscale, uint, 0644); |
module_param(hciuartstep, uint, 0644); |
#endif |
module_param(eppingtest, uint, 0644); |
-#else |
-#define __user |
-/* for linux 2.4 and lower */ |
-MODULE_PARM(bmienable,"i"); |
-MODULE_PARM(wlaninitmode,"i"); |
-MODULE_PARM(bypasswmi,"i"); |
-MODULE_PARM(debuglevel, "i"); |
-MODULE_PARM(onebitmode,"i"); |
-MODULE_PARM(busspeedlow, "i"); |
-MODULE_PARM(skipflash, "i"); |
-MODULE_PARM(wmitimeout, "i"); |
-MODULE_PARM(wlanNodeCaching, "i"); |
-MODULE_PARM(enableuartprint,"i"); |
-MODULE_PARM(logWmiRawMsgs, "i"); |
-MODULE_PARM(enabletimerwar,"i"); |
-MODULE_PARM(fwmode,"i"); |
-MODULE_PARM(mbox_yield_limit,"i"); |
-MODULE_PARM(reduce_credit_dribble,"i"); |
-MODULE_PARM(allow_trace_signal,"i"); |
-MODULE_PARM(enablerssicompensation,"i"); |
-MODULE_PARM(processDot11Hdr,"i"); |
-#ifdef CONFIG_CHECKSUM_OFFLOAD |
-MODULE_PARM(csumOffload,"i"); |
-#endif |
-#ifdef CONFIG_HOST_TCMD_SUPPORT |
-MODULE_PARM(testmode, "i"); |
-#endif |
-MODULE_PARM(irqprocmode, "i"); |
-MODULE_PARM(nohifscattersupport, "i"); |
-MODULE_PARM(panic_on_assert, "i"); |
-MODULE_PARM(setuphci, "i"); |
-MODULE_PARM(loghci, "i"); |
-#endif |
- |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) |
/* in 2.6.10 and later this is now a pointer to a uint */ |
unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX; |
#define mboxnum &_mboxnum |
-#else |
-unsigned int mboxnum = HTC_MAILBOX_NUM_MAX; |
-#endif |
#ifdef DEBUG |
A_UINT32 g_dbg_flags = DBG_DEFAULTS; |
@@ -251,7 +217,6 @@ unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0}; |
unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0}; |
unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0}; |
unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0}; |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
module_param(debugflags, uint, 0644); |
module_param(debugdriver, int, 0644); |
module_param(debughtc, uint, 0644); |
@@ -261,18 +226,6 @@ module_param_array(txcreditsavailable, uint, mboxnum, 0644); |
module_param_array(txcreditsconsumed, uint, mboxnum, 0644); |
module_param_array(txcreditintrenable, uint, mboxnum, 0644); |
module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644); |
-#else |
-/* linux 2.4 and lower */ |
-MODULE_PARM(debugflags,"i"); |
-MODULE_PARM(debugdriver, "i"); |
-MODULE_PARM(debughtc, "i"); |
-MODULE_PARM(debugbmi, "i"); |
-MODULE_PARM(debughif, "i"); |
-MODULE_PARM(txcreditsavailable, "0-3i"); |
-MODULE_PARM(txcreditsconsumed, "0-3i"); |
-MODULE_PARM(txcreditintrenable, "0-3i"); |
-MODULE_PARM(txcreditintrenableaggregate, "0-3i"); |
-#endif |
#endif /* DEBUG */ |
@@ -285,7 +238,6 @@ unsigned int war23838_disabled = 0; |
#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL |
unsigned int enableAPTCHeuristics = 1; |
#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
module_param_array(tx_attempt, uint, mboxnum, 0644); |
module_param_array(tx_post, uint, mboxnum, 0644); |
module_param_array(tx_complete, uint, mboxnum, 0644); |
@@ -295,25 +247,10 @@ module_param(resetok, uint, 0644); |
#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL |
module_param(enableAPTCHeuristics, uint, 0644); |
#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ |
-#else |
-MODULE_PARM(tx_attempt, "0-3i"); |
-MODULE_PARM(tx_post, "0-3i"); |
-MODULE_PARM(tx_complete, "0-3i"); |
-MODULE_PARM(hifBusRequestNumMax, "i"); |
-MODULE_PARM(war23838_disabled, "i"); |
-MODULE_PARM(resetok, "i"); |
-#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL |
-MODULE_PARM(enableAPTCHeuristics, "i"); |
-#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ |
-#endif |
#ifdef BLOCK_TX_PATH_FLAG |
int blocktx = 0; |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
module_param(blocktx, int, 0644); |
-#else |
-MODULE_PARM(blocktx, "i"); |
-#endif |
#endif /* BLOCK_TX_PATH_FLAG */ |
typedef struct user_rssi_compensation_t { |
@@ -335,6 +272,7 @@ static USER_RSSI_CPENSATION rssi_compensation_param; |
static A_INT16 rssi_compensation_table[96]; |
int reconnect_flag = 0; |
+static ar6k_pal_config_t ar6k_pal_config_g; |
/* Function declarations */ |
static int ar6000_init_module(void); |
@@ -361,11 +299,8 @@ void read_rssi_compensation_param(AR_SOFTC_T *ar); |
/* !!!! Interim android support to make it easier to patch the default driver for |
* android use. You must define an external source file ar6000_android.c that handles the following |
* APIs */ |
-extern A_STATUS android_ar6k_start(AR_SOFTC_T *ar); |
extern void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks); |
extern void android_module_exit(void); |
-extern A_BOOL android_ar6k_endpoint_is_stop(AR_SOFTC_T *ar); |
-extern void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, A_BOOL isEvent); |
#endif |
/* |
* HTC service connection handlers |
@@ -376,8 +311,6 @@ static A_STATUS ar6000_unavail_ev(void *context, void *hif_handle); |
A_STATUS ar6000_configure_target(AR_SOFTC_T *ar); |
-void ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile); |
- |
static void ar6000_target_failure(void *Instance, A_STATUS Status); |
static void ar6000_rx(void *Context, HTC_PACKET *pPacket); |
@@ -401,16 +334,22 @@ static void ar6000_refill_amsdu_rxbufs(AR_SOFTC_T *ar, int Count); |
static void ar6000_cleanup_amsdu_rxbufs(AR_SOFTC_T *ar); |
static ssize_t |
-ar6000_sysfs_bmi_read(struct kobject *kobj, struct bin_attribute *bin_attr, |
+ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, |
+ struct bin_attribute *bin_attr, |
char *buf, loff_t pos, size_t count); |
static ssize_t |
-ar6000_sysfs_bmi_write(struct kobject *kobj, struct bin_attribute *bin_attr, |
+ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, |
+ struct bin_attribute *bin_attr, |
char *buf, loff_t pos, size_t count); |
static A_STATUS |
ar6000_sysfs_bmi_init(AR_SOFTC_T *ar); |
+/* HCI PAL callback function declarations */ |
+A_STATUS ar6k_setup_hci_pal(AR_SOFTC_T *ar); |
+void ar6k_cleanup_hci_pal(AR_SOFTC_T *ar); |
+ |
static void |
ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar); |
@@ -422,6 +361,7 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode); |
*/ |
struct net_device *ar6000_devices[MAX_AR6000]; |
+static int is_netdev_registered; |
extern struct iw_handler_def ath_iw_handler_def; |
DECLARE_WAIT_QUEUE_HEAD(arEvent); |
static void ar6000_cookie_init(AR_SOFTC_T *ar); |
@@ -433,16 +373,17 @@ static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar); |
static A_STATUS ar6000_reinstall_keys(AR_SOFTC_T *ar,A_UINT8 key_op_ctrl); |
#endif |
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT |
+struct net_device *arApNetDev; |
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ |
static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM]; |
#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \ |
- (((ar)->arTargetType == TARGET_TYPE_AR6001) ? AR6001_HOST_INTEREST_ITEM_ADDRESS(item) : \ |
(((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \ |
- (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))) |
+ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)) |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) |
static struct net_device_ops ar6000_netdev_ops = { |
.ndo_init = NULL, |
.ndo_open = ar6000_open, |
@@ -452,7 +393,6 @@ static struct net_device_ops ar6000_netdev_ops = { |
.ndo_start_xmit = ar6000_data_tx, |
.ndo_set_multicast_list = ar6000_set_multicast_list, |
}; |
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) */ |
/* Debug log support */ |
@@ -582,8 +522,7 @@ dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len) |
int |
ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) |
{ |
- struct dbglog_hdr_s debug_hdr; |
- struct dbglog_buf_s debug_buf; |
+ A_UINT32 data[8]; /* Should be able to accomodate struct dbglog_buf_s */ |
A_UINT32 address; |
A_UINT32 length; |
A_UINT32 dropped; |
@@ -611,20 +550,20 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) |
/* Get the contents of the ring buffer */ |
if (debug_hdr_ptr) { |
address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr); |
- length = sizeof(struct dbglog_hdr_s); |
- ar6000_ReadDataDiag(ar->arHifDevice, address, |
- (A_UCHAR *)&debug_hdr, length); |
- address = TARG_VTOP(ar->arTargetType, (A_UINT32)debug_hdr.dbuf); |
+ length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */; |
+ A_MEMZERO(data, sizeof(data)); |
+ ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)data, length); |
+ address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */); |
firstbuf = address; |
- dropped = debug_hdr.dropped; |
- length = sizeof(struct dbglog_buf_s); |
- ar6000_ReadDataDiag(ar->arHifDevice, address, |
- (A_UCHAR *)&debug_buf, length); |
+ dropped = data[1]; /* dropped */ |
+ length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */; |
+ A_MEMZERO(data, sizeof(data)); |
+ ar6000_ReadDataDiag(ar->arHifDevice, address, (A_UCHAR *)&data, length); |
do { |
- address = TARG_VTOP(ar->arTargetType, (A_UINT32)debug_buf.buffer); |
- length = debug_buf.length; |
- if ((length) && (debug_buf.length <= debug_buf.bufsize)) { |
+ address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/); |
+ length = data[3]; /* length */ |
+ if ((length) && (length <= data[2] /* bufsize*/)) { |
/* Rewind the index if it is about to overrun the buffer */ |
if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) { |
ar->log_cnt = 0; |
@@ -638,13 +577,14 @@ ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar) |
ar->log_cnt += length; |
} else { |
AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n", |
- debug_buf.length, debug_buf.bufsize)); |
+ data[3], data[2])); |
} |
- address = TARG_VTOP(ar->arTargetType, (A_UINT32)debug_buf.next); |
- length = sizeof(struct dbglog_buf_s); |
+ address = TARG_VTOP(ar->arTargetType, data[0] /* next */); |
+ length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */; |
+ A_MEMZERO(data, sizeof(data)); |
if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address, |
- (A_UCHAR *)&debug_buf, length)) |
+ (A_UCHAR *)&data, length)) |
{ |
break; |
} |
@@ -720,6 +660,13 @@ ar6000_init_module(void) |
A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks)); |
osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev; |
osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev; |
+#ifdef CONFIG_PM |
+ osdrvCallbacks.deviceSuspendHandler = ar6000_suspend_ev; |
+ osdrvCallbacks.deviceResumeHandler = ar6000_resume_ev; |
+ osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev; |
+#endif |
+ |
+ ar6000_pm_init(); |
#ifdef ANDROID_ENV |
android_module_init(&osdrvCallbacks); |
@@ -778,10 +725,12 @@ ar6000_cleanup_module(void) |
a_module_debug_support_cleanup(); |
+ ar6000_pm_exit(); |
+ |
#ifdef ANDROID_ENV |
android_module_exit(); |
#endif |
- |
+ |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n")); |
} |
@@ -850,14 +799,15 @@ static struct bin_attribute bmi_attr = { |
}; |
static ssize_t |
-ar6000_sysfs_bmi_read(struct kobject *kobj, struct bin_attribute *bin_attr, |
+ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, |
+ struct bin_attribute *bin_attr, |
char *buf, loff_t pos, size_t count) |
{ |
int index; |
AR_SOFTC_T *ar; |
HIF_DEVICE_OS_DEVICE_INFO *osDevInfo; |
- AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", count)); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (A_UINT32)count)); |
for (index=0; index < MAX_AR6000; index++) { |
ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]); |
osDevInfo = &ar->osDevInfo; |
@@ -876,14 +826,15 @@ ar6000_sysfs_bmi_read(struct kobject *kobj, struct bin_attribute *bin_attr, |
} |
static ssize_t |
-ar6000_sysfs_bmi_write(struct kobject *kobj, struct bin_attribute *bin_attr, |
+ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, |
+ struct bin_attribute *bin_attr, |
char *buf, loff_t pos, size_t count) |
{ |
int index; |
AR_SOFTC_T *ar; |
HIF_DEVICE_OS_DEVICE_INFO *osDevInfo; |
- AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", count)); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (A_UINT32)count)); |
for (index=0; index < MAX_AR6000; index++) { |
ar = (AR_SOFTC_T *)ar6k_priv(ar6000_devices[index]); |
osDevInfo = &ar->osDevInfo; |
@@ -948,7 +899,6 @@ ar6000_sysfs_bmi_deinit(AR_SOFTC_T *ar) |
#ifdef INIT_MODE_DRV_ENABLED |
#ifdef SOFTMAC_FILE_USED |
-#define AR6001_MAC_ADDRESS_OFFSET 0x06 |
#define AR6002_MAC_ADDRESS_OFFSET 0x0A |
#define AR6003_MAC_ADDRESS_OFFSET 0x16 |
static |
@@ -999,9 +949,6 @@ ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) |
const struct firmware *softmac_entry; |
A_UCHAR *ptr_mac; |
switch (ar->arTargetType) { |
- case TARGET_TYPE_AR6001: |
- ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6001_MAC_ADDRESS_OFFSET); |
- break; |
case TARGET_TYPE_AR6002: |
ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET); |
break; |
@@ -1009,12 +956,10 @@ ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) |
ptr_mac = (A_UINT8 *)((A_UCHAR *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET); |
break; |
default: |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Target Type \n")); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n")); |
return; |
} |
- printk("MAC from EEPROM %02X:%02X:%02X:%02X:%02X:%02X\n", |
- ptr_mac[0], ptr_mac[1], ptr_mac[2], |
- ptr_mac[3], ptr_mac[4], ptr_mac[5]); |
+ printk(KERN_DEBUG "MAC from EEPROM %pM\n", ptr_mac); |
/* create a random MAC in case we cannot read file from system */ |
ptr_mac[0] = 0; |
@@ -1043,9 +988,7 @@ ar6000_softmac_update(AR_SOFTC_T *ar, A_UCHAR *eeprom_data, size_t size) |
} |
A_RELEASE_FIRMWARE(softmac_entry); |
} |
- printk("MAC from %s %02X:%02X:%02X:%02X:%02X:%02X\n", source, |
- ptr_mac[0], ptr_mac[1], ptr_mac[2], |
- ptr_mac[3], ptr_mac[4], ptr_mac[5]); |
+ printk(KERN_DEBUG "MAC from %s %pM\n", source, ptr_mac); |
calculate_crc(ar->arTargetType, eeprom_data); |
} |
#endif /* SOFTMAC_FILE_USED */ |
@@ -1056,6 +999,7 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A |
A_STATUS status; |
const char *filename; |
const struct firmware *fw_entry; |
+ A_UINT32 fw_entry_size; |
switch (file) { |
case AR6K_OTP_FILE: |
@@ -1159,10 +1103,48 @@ ar6000_transfer_bin_file(AR_SOFTC_T *ar, AR6K_BIN_FILE file, A_UINT32 address, A |
} |
#endif |
+ |
+ fw_entry_size = fw_entry->size; |
+ |
+ /* Load extended board data for AR6003 */ |
+ if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) { |
+ A_UINT32 board_ext_address; |
+ A_UINT32 board_ext_data_size; |
+ A_UINT32 board_data_size; |
+ |
+ board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \ |
+ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0)); |
+ |
+ board_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_DATA_SZ : \ |
+ (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0)); |
+ |
+ /* Determine where in Target RAM to write Board Data */ |
+ bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (A_UCHAR *)&board_ext_address, 4)); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address)); |
+ |
+ /* check whether the target has allocated memory for extended board data and file contains extended board data */ |
+ if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) { |
+ A_UINT32 param; |
+ |
+ status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (A_UCHAR *)(((A_UINT32)fw_entry->data) + board_data_size), board_ext_data_size); |
+ |
+ if (status != A_OK) { |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); |
+ A_RELEASE_FIRMWARE(fw_entry); |
+ return A_ERROR; |
+ } |
+ |
+ /* Record the fact that extended board Data IS initialized */ |
+ param = 1; |
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_initialized), (A_UCHAR *)¶m, 4)); |
+ } |
+ fw_entry_size = board_data_size; |
+ } |
+ |
if (compressed) { |
- status = BMIFastDownload(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry->size); |
+ status = BMIFastDownload(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size); |
} else { |
- status = BMIWriteMemory(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry->size); |
+ status = BMIWriteMemory(ar->arHifDevice, address, (A_UCHAR *)fw_entry->data, fw_entry_size); |
} |
if (status != A_OK) { |
@@ -1241,6 +1223,8 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", options, sleep)); |
if (ar->arTargetType == TARGET_TYPE_AR6003) { |
+ /* Program analog PLL register */ |
+ bmifn(BMIWriteSOCRegister(ar->arHifDevice, ANALOG_INTF_BASE_ADDRESS + 0x284, 0xF9104001)); |
/* Run at 80/88MHz by default */ |
param = CPU_CLOCK_STANDARD_SET(1); |
} else { |
@@ -1350,8 +1334,8 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) |
/* Reserve 5.5K of RAM */ |
param = 5632; |
} else { /* AR6003_REV2_VERSION */ |
- /* Reserve 6K of RAM */ |
- param = 6144; |
+ /* Reserve 6.5K of RAM */ |
+ param = 6656; |
} |
bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_end_RAM_reserve_sz), (A_UCHAR *)¶m, 4)); |
} |
@@ -1363,8 +1347,6 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) |
address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS; |
param = options | 0x20; |
bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); |
- /* Get the device address for BT if enabled */ |
- ar6000_update_bdaddr(ar); |
if (ar->arTargetType == TARGET_TYPE_AR6003) { |
/* Configure GPIO AR6003 UART */ |
@@ -1385,20 +1367,32 @@ ar6000_sysfs_bmi_get_config(AR_SOFTC_T *ar, A_UINT32 mode) |
/* Configure GPIO for BT Reset */ |
#ifdef ATH6KL_CONFIG_GPIO_BT_RESET |
+#define CONFIG_AR600x_BT_RESET_PIN 0x16 |
param = CONFIG_AR600x_BT_RESET_PIN; |
bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (A_UCHAR *)¶m, 4)); |
#endif /* ATH6KL_CONFIG_GPIO_BT_RESET */ |
+ |
+ /* Configure UART flow control polarity */ |
+#ifndef CONFIG_ATH6KL_BT_UART_FC_POLARITY |
+#define CONFIG_ATH6KL_BT_UART_FC_POLARITY 0 |
+#endif |
+ |
+#if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1) |
+ if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { |
+ param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2); |
+ bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (A_UCHAR *)¶m, 4)); |
+ } |
+#endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */ |
} |
+ |
#ifdef HTC_RAW_INTERFACE |
if (!eppingtest && bypasswmi) { |
/* Don't run BMIDone for ART mode and force resetok=0 */ |
resetok = 0; |
msleep(1000); |
- return A_OK; |
} |
#endif /* HTC_RAW_INTERFACE */ |
- /* Tell Target to execute loaded firmware */ |
- bmifn(BMIDone(ar->arHifDevice)); |
+ |
#endif /* INIT_MODE_DRV_ENABLED */ |
} |
@@ -1490,32 +1484,6 @@ ar6000_configure_target(AR_SOFTC_T *ar) |
} |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n")); |
} |
-#if 0 /* HOST_INTEREST is no longer used to configure dot11 processing rule */ |
- if (processDot11Hdr) { |
- A_UINT32 param; |
- |
- if (BMIReadMemory(ar->arHifDevice, |
- HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), |
- (A_UCHAR *)¶m, |
- 4)!= A_OK) |
- { |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for processDot11Hdr failed \n")); |
- return A_ERROR; |
- } |
- |
- param |= HI_OPTION_RELAY_DOT11_HDR; |
- |
- if (BMIWriteMemory(ar->arHifDevice, |
- HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), |
- (A_UCHAR *)¶m, |
- 4) != A_OK) |
- { |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for processDot11Hdr failed \n")); |
- return A_ERROR; |
- } |
- AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("processDot11Hdr enabled\n")); |
- } |
-#endif |
#ifdef ATH6KL_DISABLE_TARGET_DBGLOGS |
{ |
@@ -1544,15 +1512,22 @@ ar6000_configure_target(AR_SOFTC_T *ar) |
} |
#endif /* ATH6KL_DISABLE_TARGET_DBGLOGS */ |
- // No need to reserve RAM space for patch as AR6001 is flash based |
- if (ar->arTargetType == TARGET_TYPE_AR6001) { |
- param = 0; |
+ /* |
+ * Hardcode the address use for the extended board data |
+ * Ideally this should be pre-allocate by the OS at boot time |
+ * But since it is a new feature and board data is loaded |
+ * at init time, we have to workaround this from host. |
+ * It is difficult to patch the firmware boot code, |
+ * but possible in theory. |
+ */ |
+ if (ar->arTargetType == TARGET_TYPE_AR6003) { |
+ param = AR6003_BOARD_EXT_DATA_ADDRESS; |
if (BMIWriteMemory(ar->arHifDevice, |
- HOST_INTEREST_ITEM_ADDRESS(ar, hi_end_RAM_reserve_sz), |
+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), |
(A_UCHAR *)¶m, |
4) != A_OK) |
{ |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for hi_end_RAM_reserve_sz failed \n")); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for hi_board_ext_data failed \n")); |
return A_ERROR; |
} |
} |
@@ -1579,6 +1554,44 @@ ar6000_configure_target(AR_SOFTC_T *ar) |
return A_OK; |
} |
+static void |
+init_netdev(struct net_device *dev, char *name) |
+{ |
+ dev->netdev_ops = &ar6000_netdev_ops; |
+ dev->watchdog_timeo = AR6000_TX_TIMEOUT; |
+ dev->wireless_handlers = &ath_iw_handler_def; |
+ |
+ ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */ |
+ |
+ /* |
+ * We need the OS to provide us with more headroom in order to |
+ * perform dix to 802.3, WMI header encap, and the HTC header |
+ */ |
+ if (processDot11Hdr) { |
+ dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR; |
+ } else { |
+ dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) + |
+ sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR; |
+ } |
+ |
+ if (name[0]) |
+ { |
+ strcpy(dev->name, name); |
+ } |
+ |
+#ifdef SET_MODULE_OWNER |
+ SET_MODULE_OWNER(dev); |
+#endif |
+ |
+#ifdef CONFIG_CHECKSUM_OFFLOAD |
+ if(csumOffload){ |
+ dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/ |
+ } |
+#endif |
+ |
+ return; |
+} |
+ |
/* |
* HTC Event handlers |
*/ |
@@ -1655,16 +1668,7 @@ ar6000_avail_ev(void *context, void *hif_handle) |
ar->arNetworkType = INFRA_NETWORK; |
#endif /* ATH6K_CONFIG_CFG80211 */ |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
- if (ifname[0]) |
- { |
- strcpy(dev->name, ifname); |
- } |
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */ |
- |
-#ifdef SET_MODULE_OWNER |
- SET_MODULE_OWNER(dev); |
-#endif |
+ init_netdev(dev, ifname); |
#ifdef SET_NETDEV_DEV |
if (ar_netif) { |
@@ -1682,6 +1686,17 @@ ar6000_avail_ev(void *context, void *hif_handle) |
ar->arWlanState = WLAN_ENABLED; |
ar->arDeviceIndex = device_index; |
+ ar->arWlanPowerState = WLAN_POWER_STATE_ON; |
+ ar->arWlanOff = FALSE; /* We are in ON state */ |
+#ifdef CONFIG_PM |
+ ar->arWowState = WLAN_WOW_STATE_NONE; |
+ ar->arBTOff = TRUE; /* BT chip assumed to be OFF */ |
+ ar->arBTSharing = WLAN_CONFIG_BT_SHARING; |
+ ar->arWlanOffConfig = WLAN_CONFIG_WLAN_OFF; |
+ ar->arSuspendConfig = WLAN_CONFIG_PM_SUSPEND; |
+ ar->arWow2Config = WLAN_CONFIG_PM_WOW2; |
+#endif /* CONFIG_PM */ |
+ |
A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev); |
ar->arHBChallengeResp.seqNum = 0; |
ar->arHBChallengeResp.outstanding = FALSE; |
@@ -1702,19 +1717,6 @@ ar6000_avail_ev(void *context, void *hif_handle) |
A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev); |
- /* |
- * If requested, perform some magic which requires no cooperation from |
- * the Target. It causes the Target to ignore flash and execute to the |
- * OS from ROM. |
- * |
- * This is intended to support recovery from a corrupted flash on Targets |
- * that support flash. |
- */ |
- if (skipflash) |
- { |
- //ar6000_reset_device_skipflash(ar->arHifDevice); |
- } |
- |
BMIInit(); |
if (bmienable) { |
@@ -1764,44 +1766,13 @@ ar6000_avail_ev(void *context, void *hif_handle) |
ar->arWapiEnable = 0; |
#endif |
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) |
- dev->open = &ar6000_open; |
- dev->stop = &ar6000_close; |
- dev->hard_start_xmit = &ar6000_data_tx; |
- dev->get_stats = &ar6000_get_stats; |
- /* dev->tx_timeout = ar6000_tx_timeout; */ |
- dev->do_ioctl = &ar6000_ioctl; |
- dev->set_multicast_list = &ar6000_set_multicast_list; |
-#else |
- dev->netdev_ops = &ar6000_netdev_ops; |
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ |
- dev->watchdog_timeo = AR6000_TX_TIMEOUT; |
- dev->wireless_handlers = &ath_iw_handler_def; |
- |
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) |
- dev->get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */ |
-#else |
- ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */ |
-#endif |
#ifdef CONFIG_CHECKSUM_OFFLOAD |
if(csumOffload){ |
- |
- dev->features |= NETIF_F_IP_CSUM;/*advertise kernel capability |
- to do TCP/UDP CSUM offload for IPV4*/ |
- ar->rxMetaVersion=WMI_META_VERSION_2;/*if external frame work is also needed, change and use an extended rxMetaVerion*/ |
+ /*if external frame work is also needed, change and use an extended rxMetaVerion*/ |
+ ar->rxMetaVersion=WMI_META_VERSION_2; |
} |
#endif |
- if (processDot11Hdr) { |
- dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR; |
- } else { |
- /* |
- * We need the OS to provide us with more headroom in order to |
- * perform dix to 802.3, WMI header encap, and the HTC header |
- */ |
- dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) + |
- sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR; |
- } |
#ifdef ATH_AR6K_11N_SUPPORT |
if((ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs)) == NULL) { |
@@ -1822,11 +1793,7 @@ ar6000_avail_ev(void *context, void *hif_handle) |
/* Don't install the init function if BMI is requested */ |
if (!bmienable) { |
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) |
- dev->init = ar6000_init; |
-#else |
ar6000_netdev_ops.ndo_init = ar6000_init; |
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ |
} else { |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode)); |
if ((wlaninitmode == WLAN_INIT_MODE_UDEV) || |
@@ -1840,12 +1807,7 @@ ar6000_avail_ev(void *context, void *hif_handle) |
break; |
} |
#ifdef HTC_RAW_INTERFACE |
- if (bypasswmi) { |
- A_UINT32 param = 1; |
- status = BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), |
- (A_UCHAR *)¶m, 4); |
- break; |
- } |
+ break; /* Don't call ar6000_init for ART */ |
#endif |
rtnl_lock(); |
status = (ar6000_init(dev)==0) ? A_OK : A_ERROR; |
@@ -1869,9 +1831,14 @@ ar6000_avail_ev(void *context, void *hif_handle) |
return A_ERROR; |
} |
- AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%x, dev=0x%x (%d), ar=0x%x\n", |
- dev->name, (A_UINT32)ar->arHifDevice, (A_UINT32)dev, device_index, |
- (A_UINT32)ar)); |
+ is_netdev_registered = 1; |
+ |
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT |
+ arApNetDev = NULL; |
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ |
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%lx, dev=0x%lx (%d), ar=0x%lx\n", |
+ dev->name, (unsigned long)ar->arHifDevice, (unsigned long)dev, device_index, |
+ (unsigned long)ar)); |
avail_ev_failed : |
if (A_FAILED(init_status)) { |
@@ -1930,7 +1897,42 @@ ar6000_unavail_ev(void *context, void *hif_handle) |
} |
void |
-ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile) |
+ar6000_restart_endpoint(struct net_device *dev) |
+{ |
+ A_STATUS status = A_OK; |
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); |
+ |
+ BMIInit(); |
+ do { |
+ if ( (status=ar6000_configure_target(ar))!=A_OK) |
+ break; |
+ if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != A_OK) |
+ { |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n")); |
+ break; |
+ } |
+ rtnl_lock(); |
+ status = (ar6000_init(dev)==0) ? A_OK : A_ERROR; |
+ rtnl_unlock(); |
+ |
+ if (status!=A_OK) { |
+ break; |
+ } |
+ if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) { |
+ ar6000_connect_to_ap(ar); |
+ } |
+ } while (0); |
+ |
+ if (status==A_OK) { |
+ return; |
+ } |
+ |
+ ar6000_devices[ar->arDeviceIndex] = NULL; |
+ ar6000_destroy(ar->arNetDev, 1); |
+} |
+ |
+void |
+ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile, A_BOOL getdbglogs) |
{ |
AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); |
@@ -1945,32 +1947,42 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile) |
if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) |
{ |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Disconnect\n", __func__)); |
-#ifdef ANDROID_ENV |
- if (keepprofile) { |
- wmi_disconnect_cmd(ar->arWmi); |
- } else |
-#endif /* ANDROID_ENV */ |
- { |
+ if (!keepprofile) { |
AR6000_SPIN_LOCK(&ar->arLock, 0); |
ar6000_init_profile_info(ar); |
AR6000_SPIN_UNLOCK(&ar->arLock, 0); |
- wmi_disconnect_cmd(ar->arWmi); |
} |
+ wmi_disconnect_cmd(ar->arWmi); |
} |
+ |
A_UNTIMEOUT(&ar->disconnect_timer); |
+ |
+ if (getdbglogs) { |
+ ar6000_dbglog_get_debug_logs(ar); |
+ } |
+ |
ar->arWmiReady = FALSE; |
- ar->arConnected = FALSE; |
- ar->arConnectPending = FALSE; |
wmi_shutdown(ar->arWmi); |
ar->arWmiEnabled = FALSE; |
ar->arWmi = NULL; |
-#ifdef ANDROID_ENV |
- if (!keepprofile) { |
- ar->arWlanState = WLAN_ENABLED; |
+ /* |
+ * After wmi_shudown all WMI events will be dropped. |
+ * We need to cleanup the buffers allocated in AP mode |
+ * and give disconnect notification to stack, which usually |
+ * happens in the disconnect_event. |
+ * Simulate the disconnect_event by calling the function directly. |
+ * Sometimes disconnect_event will be received when the debug logs |
+ * are collected. |
+ */ |
+ if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { |
+ if(ar->arNetworkType & AP_NETWORK) { |
+ ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0); |
+ } else { |
+ ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0); |
+ } |
+ ar->arConnected = FALSE; |
+ ar->arConnectPending = FALSE; |
} |
-#else |
- ar->arWlanState = WLAN_ENABLED; |
-#endif /* ANDROID_ENV */ |
#ifdef USER_KEYS |
ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; |
ar->user_key_ctrl = 0; |
@@ -1981,8 +1993,8 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile) |
} |
else |
{ |
- AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%08x 0x%08x\n", |
- __func__, (unsigned int) ar, (unsigned int) ar->arWmi)); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%lx 0x%lx\n", |
+ __func__, (unsigned long) ar, (unsigned long) ar->arWmi)); |
/* Shut down WMI if we have started it */ |
if(ar->arWmiEnabled == TRUE) |
@@ -2013,7 +2025,17 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile) |
} |
} |
// END workaround |
- ar6000_cleanup_hci(ar); |
+ if (setuphci) |
+ ar6000_cleanup_hci(ar); |
+#endif |
+#ifdef EXPORT_HCI_PAL_INTERFACE |
+ if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.cleanupTransport)) { |
+ ar6kHciPalCallbacks_g.cleanupTransport(ar); |
+ } |
+#else |
+ /* cleanup hci pal driver data structures */ |
+ if(setuphcipal) |
+ ar6k_cleanup_hci_pal(ar); |
#endif |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n")); |
/* stop HTC */ |
@@ -2026,10 +2048,7 @@ ar6000_stop_endpoint(struct net_device *dev, A_BOOL keepprofile) |
* a debug session */ |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n")); |
if (ar->arHifDevice != NULL) { |
- A_BOOL coldReset = FALSE; |
-#ifdef CONFIG_MMC_SDHCI_S3C |
- coldReset = TRUE; |
-#endif |
+ A_BOOL coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? TRUE: FALSE; |
ar6000_reset_device(ar->arHifDevice, ar->arTargetType, TRUE, coldReset); |
} |
} else { |
@@ -2058,7 +2077,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) |
AR_SOFTC_T *ar; |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n")); |
- |
+ |
if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL)) |
{ |
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n", __func__)); |
@@ -2071,17 +2090,16 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) |
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__)); |
return; |
} |
- if (ar->arWmiReady && !bypasswmi) { |
- ar6000_dbglog_get_debug_logs(ar); |
- } |
-#ifdef ANDROID_ENV |
- if (!android_ar6k_endpoint_is_stop(ar)) { |
-#else |
- if (1) { |
-#endif |
+ |
+ if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) { |
/* only stop endpoint if we are not stop it in suspend_ev */ |
- ar6000_stop_endpoint(dev, FALSE); |
+ ar6000_stop_endpoint(dev, FALSE, TRUE); |
+ } else { |
+ /* clear up the platform power state before rmmod */ |
+ plat_setup_power(1,0); |
} |
+ |
+ ar->arWlanState = WLAN_DISABLED; |
if (ar->arHtcTarget != NULL) { |
/* destroy HTC */ |
HTCDestroy(ar->arHtcTarget); |
@@ -2107,7 +2125,7 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) |
} |
/* Cleanup BMI */ |
- BMIInit(); |
+ BMICleanup(); |
/* Clear the tx counters */ |
memset(tx_attempt, 0, sizeof(tx_attempt)); |
@@ -2121,8 +2139,10 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) |
} |
#endif |
/* Free up the device data structure */ |
- if( unregister ) |
+ if (unregister && is_netdev_registered) { |
unregister_netdev(dev); |
+ is_netdev_registered = 0; |
+ } |
#ifndef free_netdev |
kfree(dev); |
#else |
@@ -2133,6 +2153,10 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) |
ar6k_cfg80211_deinit(ar); |
#endif /* ATH6K_CONFIG_CFG80211 */ |
+#ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT |
+ ar6000_remove_ap_interface(); |
+#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ |
+ |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n")); |
} |
@@ -2276,11 +2300,11 @@ ar6000_open(struct net_device *dev) |
spin_lock_irqsave(&ar->arLock, flags); |
-#ifndef ANDROID_ENV |
+#ifdef ATH6K_CONFIG_CFG80211 |
if(ar->arWlanState == WLAN_DISABLED) { |
ar->arWlanState = WLAN_ENABLED; |
} |
-#endif |
+#endif /* ATH6K_CONFIG_CFG80211 */ |
if( ar->arConnected || bypasswmi) { |
netif_carrier_on(dev); |
@@ -2297,12 +2321,12 @@ ar6000_open(struct net_device *dev) |
static int |
ar6000_close(struct net_device *dev) |
{ |
+#ifdef ATH6K_CONFIG_CFG80211 |
AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); |
+#endif /* ATH6K_CONFIG_CFG80211 */ |
netif_stop_queue(dev); |
-#ifdef ANDROID_ENV |
- (void)ar; /* do nothing. Android SDK will handle it */ |
-#else |
+#ifdef ATH6K_CONFIG_CFG80211 |
AR6000_SPIN_LOCK(&ar->arLock, 0); |
if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { |
AR6000_SPIN_UNLOCK(&ar->arLock, 0); |
@@ -2318,7 +2342,8 @@ ar6000_close(struct net_device *dev) |
} |
ar->arWlanState = WLAN_DISABLED; |
} |
-#endif |
+#endif /* ATH6K_CONFIG_CFG80211 */ |
+ |
return 0; |
} |
@@ -2423,26 +2448,28 @@ int ar6000_init(struct net_device *dev) |
if((ar = ar6k_priv(dev)) == NULL) |
{ |
- ret = -EIO; |
- goto ar6000_init_done; |
+ return -EIO; |
} |
- if (wlaninitmode == WLAN_INIT_MODE_USR) |
+ if (wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) { |
+ |
ar6000_update_bdaddr(ar); |
+ if (enablerssicompensation) { |
+ ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType); |
+ read_rssi_compensation_param(ar); |
+ for (i=-95; i<=0; i++) { |
+ rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i); |
+ } |
+ } |
+ } |
+ |
dev_hold(dev); |
rtnl_unlock(); |
- if (enablerssicompensation) { |
- ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType); |
- read_rssi_compensation_param(ar); |
- for (i=-95; i<=0; i++) { |
- rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i); |
- } |
- } |
- |
/* Do we need to finish the BMI phase */ |
- if ((wlaninitmode == WLAN_INIT_MODE_USR) && (BMIDone(ar->arHifDevice) != A_OK)) |
+ if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) && |
+ (BMIDone(ar->arHifDevice) != A_OK)) |
{ |
ret = -EIO; |
goto ar6000_init_done; |
@@ -2467,8 +2494,8 @@ int ar6000_init(struct net_device *dev) |
goto ar6000_init_done; |
} |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%08x.\n", __func__, |
- (unsigned int) ar->arWmi)); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%lx.\n", __func__, |
+ (unsigned long) ar->arWmi)); |
} |
do { |
@@ -2603,6 +2630,13 @@ int ar6000_init(struct net_device *dev) |
status = ar6000_setup_hci(ar); |
} |
#endif |
+#ifdef EXPORT_HCI_PAL_INTERFACE |
+ if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.setupTransport)) |
+ status = ar6kHciPalCallbacks_g.setupTransport(ar); |
+#else |
+ if(setuphcipal) |
+ status = ar6k_setup_hci_pal(ar); |
+#endif |
} while (FALSE); |
@@ -2733,10 +2767,6 @@ int ar6000_init(struct net_device *dev) |
dev->dev_addr[5] = 0xCC; |
} |
-#ifdef ANDROID_ENV |
- android_ar6k_start(ar); |
-#endif |
- |
ar6000_init_done: |
rtnl_lock(); |
dev_put(dev); |
@@ -2846,7 +2876,7 @@ static void ar6000_dump_skb(struct sk_buff *skb) |
{ |
u_char *ch; |
for (ch = A_NETBUF_DATA(skb); |
- (A_UINT32)ch < ((A_UINT32)A_NETBUF_DATA(skb) + |
+ (unsigned long)ch < ((unsigned long)A_NETBUF_DATA(skb) + |
A_NETBUF_LEN(skb)); ch++) |
{ |
AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch)); |
@@ -2873,17 +2903,14 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) |
HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG; |
A_UINT8 dot11Hdr = processDot11Hdr; |
#ifdef CONFIG_PM |
- if (ar->arWowState) { |
+ if (ar->arWowState != WLAN_WOW_STATE_NONE) { |
A_NETBUF_FREE(skb); |
return 0; |
} |
#endif /* CONFIG_PM */ |
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) |
- skb->list = NULL; |
-#endif |
- AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%x, data=0x%x, len=0x%x\n", |
- (A_UINT32)skb, (A_UINT32)A_NETBUF_DATA(skb), |
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%lx, data=0x%lx, len=0x%x\n", |
+ (unsigned long)skb, (unsigned long)A_NETBUF_DATA(skb), |
A_NETBUF_LEN(skb))); |
/* If target is not associated */ |
@@ -3154,7 +3181,7 @@ ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) |
AR6000_SPIN_UNLOCK(&ar->arLock, 0); |
if (cookie != NULL) { |
- cookie->arc_bp[0] = (A_UINT32)skb; |
+ cookie->arc_bp[0] = (unsigned long)skb; |
cookie->arc_bp[1] = mapNo; |
SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, |
cookie, |
@@ -3209,7 +3236,7 @@ ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev) |
AR6000_SPIN_UNLOCK(&ar->arLock, 0); |
if (cookie != NULL) { |
- cookie->arc_bp[0] = (A_UINT32)skb; |
+ cookie->arc_bp[0] = (unsigned long)skb; |
cookie->arc_bp[1] = 0; |
SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, |
cookie, |
@@ -3408,8 +3435,8 @@ ar6000_tx_complete(void *Context, HTC_PACKET_QUEUE *pPacketQueue) |
A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb)); |
} |
- AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%x data=0x%x len=0x%x eid=%d ", |
- (A_UINT32)pktSkb, (A_UINT32)pPacket->pBuffer, |
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%lx data=0x%lx len=0x%x eid=%d ", |
+ (unsigned long)pktSkb, (unsigned long)pPacket->pBuffer, |
pPacket->ActualLength, |
eid)); |
@@ -3560,8 +3587,8 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) |
A_ASSERT((status != A_OK) || |
(pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN))); |
- AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%x eid=%d, skb=0x%x, data=0x%x, len=0x%x status:%d", |
- (A_UINT32)ar, ept, (A_UINT32)skb, (A_UINT32)pPacket->pBuffer, |
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d", |
+ (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer, |
pPacket->ActualLength, status)); |
if (status != A_OK) { |
if (status != A_ECANCELED) { |
@@ -3602,17 +3629,17 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) |
/* |
* this is a wmi control msg |
*/ |
-#ifdef ANDROID_ENV |
- android_ar6k_check_wow_status(ar, skb, TRUE); |
-#endif /* ANDROID_ENV */ |
+#ifdef CONFIG_PM |
+ ar6000_check_wow_status(ar, skb, TRUE); |
+#endif /* CONFIG_PM */ |
wmi_control_rx(ar->arWmi, skb); |
} else { |
WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb); |
A_UINT8 is_amsdu, tid, is_acl_data_frame; |
is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL; |
-#ifdef ANDROID_ENV |
- android_ar6k_check_wow_status(ar, NULL, FALSE); |
-#endif /* ANDROID_ENV */ |
+#ifdef CONFIG_PM |
+ ar6000_check_wow_status(ar, NULL, FALSE); |
+#endif /* CONFIG_PM */ |
/* |
* this is a wmi data packet |
*/ |
@@ -3779,16 +3806,13 @@ ar6000_rx(void *Context, HTC_PACKET *pPacket) |
if (is_acl_data_frame) { |
A_NETBUF_PUSH(skb, sizeof(int)); |
*((short *)A_NETBUF_DATA(skb)) = WMI_ACL_DATA_EVENTID; |
+ /* send the data packet to PAL driver */ |
+ if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) { |
+ if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, skb) == TRUE) |
+ goto rx_done; |
+ } |
} |
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) |
- /* |
- * extra push and memcpy, for eth_type_trans() of 2.4 kernel |
- * will pull out hard_header_len bytes of the skb. |
- */ |
- A_NETBUF_PUSH(skb, sizeof(WMI_DATA_HDR) + sizeof(ATH_LLC_SNAP_HDR) + HTC_HEADER_LEN); |
- A_MEMCPY(A_NETBUF_DATA(skb), A_NETBUF_DATA(skb) + sizeof(WMI_DATA_HDR) + |
- sizeof(ATH_LLC_SNAP_HDR) + HTC_HEADER_LEN, sizeof(ATH_MAC_HDR)); |
-#endif |
+ |
if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) { |
if (ar->arNetworkType == AP_NETWORK) { |
struct sk_buff *skb1 = NULL; |
@@ -3848,9 +3872,9 @@ ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf) |
if(skb) { |
skb->dev = dev; |
if ((skb->dev->flags & IFF_UP) == IFF_UP) { |
-#ifdef ANDROID_ENV |
- android_ar6k_check_wow_status((AR_SOFTC_T *)ar6k_priv(dev), skb, FALSE); |
-#endif |
+#ifdef CONFIG_PM |
+ ar6000_check_wow_status((AR_SOFTC_T *)ar6k_priv(dev), skb, FALSE); |
+#endif /* CONFIG_PM */ |
skb->protocol = eth_type_trans(skb, skb->dev); |
/* |
* If this routine is called on a ISR (Hard IRQ) or DSR (Soft IRQ) |
@@ -4043,39 +4067,7 @@ static HTC_PACKET *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpo |
static void |
ar6000_set_multicast_list(struct net_device *dev) |
{ |
- int i; |
- AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); |
- if (ar->arWmiReady == FALSE || ar->arWlanState == WLAN_DISABLED) |
- return; |
- |
- for (i=0; i<MAC_MAX_FILTERS_PER_LIST; ++i) { |
- A_UINT8 *filter = ar->mcast_filters[i]; |
- if (filter[0] || filter[1] || filter[2] || filter[3] ) { |
- wmi_del_mcast_filter_cmd(ar->arWmi, filter[0], filter[1], filter[2], filter[3]); |
- } |
- } |
- A_MEMZERO(ar->mcast_filters, sizeof(ar->mcast_filters)); |
- |
- if ((dev->flags & IFF_PROMISC) || |
- (dev->flags & IFF_ALLMULTI) || dev->mc_count > MAC_MAX_FILTERS_PER_LIST) { |
- wmi_mcast_filter_cmd(ar->arWmi, TRUE); |
- return; |
- } |
- |
- if (dev->flags & IFF_MULTICAST && dev->mc_count > 0) { |
- struct dev_mc_list *mc; |
- for (mc = dev->mc_list, i=0; mc; mc = mc->next, ++i) { |
- u8 *mac = mc->dmi_addr; |
- if (mac[2] || mac[3] || mac[4] || mac[5]) { |
- A_MEMCPY(ar->mcast_filters[i], &mac[2], sizeof(ar->mcast_filters[i])); |
- wmi_set_mcast_filter_cmd(ar->arWmi, mac[2], mac[3], mac[4] , mac[5]); |
- } |
- } |
- wmi_mcast_filter_cmd(ar->arWmi, TRUE); |
- } else { |
- /* target drop multicast packets if fitler disable and fitler list is zero */ |
- wmi_mcast_filter_cmd(ar->arWmi, FALSE); |
- } |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n")); |
} |
static struct net_device_stats * |
@@ -4104,7 +4096,7 @@ ar6000_get_iwstats(struct net_device * dev) |
pIwStats->miss.beacon =0; |
return pIwStats; |
} |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) |
+ |
/* |
* The in_atomic function is used to determine if the scheduling is |
* allowed in the current context or not. This was introduced in 2.6 |
@@ -4125,13 +4117,9 @@ ar6000_get_iwstats(struct net_device * dev) |
pIwStats->miss.beacon = pStats->cs_bmiss_cnt; |
return pIwStats; |
} |
-#endif /* LINUX_VERSION_CODE */ |
+ |
dev_hold(dev); |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) |
rtnllocked = rtnl_is_locked(); |
-#else |
- rtnllocked = TRUE; |
-#endif |
if (rtnllocked) { |
rtnl_unlock(); |
} |
@@ -4182,8 +4170,6 @@ ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, |
AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; |
struct net_device *dev = ar->arNetDev; |
- ar->arWmiReady = TRUE; |
- wake_up(&arEvent); |
A_MEMCPY(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN); |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", |
dev->dev_addr[0], dev->dev_addr[1], |
@@ -4194,6 +4180,10 @@ ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, |
ar->arVersion.wlan_ver = sw_ver; |
ar->arVersion.abi_ver = abi_ver; |
+ /* Indicate to the waiting thread that the ready event was received */ |
+ ar->arWmiReady = TRUE; |
+ wake_up(&arEvent); |
+ |
#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN |
wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN); |
#endif |
@@ -4201,27 +4191,31 @@ ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap, A_UINT32 sw_ver, |
wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP); |
#endif |
wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL); |
+#if WLAN_CONFIG_DISABLE_11N |
+ { |
+ WMI_SET_HT_CAP_CMD htCap; |
+ |
+ A_MEMZERO(&htCap, sizeof(WMI_SET_HT_CAP_CMD)); |
+ htCap.band = 0; |
+ wmi_set_ht_cap_cmd(ar->arWmi, &htCap); |
+ |
+ htCap.band = 1; |
+ wmi_set_ht_cap_cmd(ar->arWmi, &htCap); |
+ } |
+#endif /* WLAN_CONFIG_DISABLE_11N */ |
+ |
+#ifdef ATH6K_CONFIG_OTA_MODE |
+ wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER); |
+#endif |
+ wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT); |
} |
-A_UINT8 |
+void |
add_new_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 aid, A_UINT8 *wpaie, |
A_UINT8 ielen, A_UINT8 keymgmt, A_UINT8 ucipher, A_UINT8 auth) |
{ |
- A_INT8 free_slot=-1, i; |
- |
- for(i=0; i < AP_MAX_NUM_STA; i++) { |
- if(A_MEMCMP(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) { |
- /* it is already available */ |
- return 0; |
- } |
- |
- if(!((1 << i) & ar->sta_list_index)) { |
- free_slot = i; |
- break; |
- } |
- } |
+ A_UINT8 free_slot=aid-1; |
- if(free_slot >= 0) { |
A_MEMCPY(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN); |
A_MEMCPY(ar->sta_list[free_slot].wpa_ie, wpaie, ielen); |
ar->sta_list[free_slot].aid = aid; |
@@ -4229,10 +4223,7 @@ add_new_sta(AR_SOFTC_T *ar, A_UINT8 *mac, A_UINT16 aid, A_UINT8 *wpaie, |
ar->sta_list[free_slot].ucipher = ucipher; |
ar->sta_list[free_slot].auth = auth; |
ar->sta_list_index = ar->sta_list_index | (1 << free_slot); |
- ar->arAPStats.sta[aid-1].aid = aid; |
- return 1; |
- } |
- return 0; /* not added */ |
+ ar->arAPStats.sta[free_slot].aid = aid; |
} |
void |
@@ -4477,6 +4468,8 @@ skip_key: |
netif_wake_queue(ar->arNetDev); |
+ /* For CFG80211 the key configuration and the default key comes in after connect so no point in plumbing invalid keys */ |
+#ifndef ATH6K_CONFIG_CFG80211 |
if ((networkType & ADHOC_NETWORK) && |
(OPEN_AUTH == ar->arDot11AuthMode) && |
(NONE_AUTH == ar->arAuthMode) && |
@@ -4493,6 +4486,7 @@ skip_key: |
NO_SYNC_WMIFLAG); |
} |
} |
+#endif /* ATH6K_CONFIG_CFG80211 */ |
/* Update connect & link status atomically */ |
spin_lock_irqsave(&ar->arLock, flags); |
@@ -4588,6 +4582,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, |
{ |
A_UINT8 i; |
unsigned long flags; |
+ union iwreq_data wrqu; |
if(ar->arNetworkType & AP_NETWORK) { |
union iwreq_data wrqu; |
@@ -4607,7 +4602,9 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, |
A_MUTEX_UNLOCK(&ar->mcastpsqLock); |
/* Clear the LSB of the BitMapCtl field of the TIM IE */ |
- wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0); |
+ if (ar->arWmiReady) { |
+ wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0); |
+ } |
} |
if(!IS_MAC_BCAST(bssid)) { |
@@ -4625,17 +4622,12 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, |
protocolReasonStatus); |
#endif /* ATH6K_CONFIG_CFG80211 */ |
- if (NO_NETWORK_AVAIL != reason) |
- { |
- union iwreq_data wrqu; |
- A_MEMZERO(&wrqu, sizeof(wrqu)); |
- wrqu.addr.sa_family = ARPHRD_ETHER; |
+ /* Send disconnect event to supplicant */ |
+ A_MEMZERO(&wrqu, sizeof(wrqu)); |
+ wrqu.addr.sa_family = ARPHRD_ETHER; |
+ wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL); |
- /* Send disconnect event to supplicant */ |
- wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL); |
- } |
/* it is necessary to clear the host-side rx aggregation state */ |
- |
aggr_reset_state(ar->aggr_cntxt); |
A_UNTIMEOUT(&ar->disconnect_timer); |
@@ -4666,7 +4658,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, |
if( reason == DISCONNECT_CMD) |
{ |
ar->arConnectPending = FALSE; |
- if (!ar->arUserBssFilter) { |
+ if ((!ar->arUserBssFilter) && (ar->arWmiReady)) { |
wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); |
} |
} else { |
@@ -4678,7 +4670,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, |
} |
} |
- if (reason == NO_NETWORK_AVAIL) |
+ if ((reason == NO_NETWORK_AVAIL) && (ar->arWmiReady)) |
{ |
bss_t *pWmiSsidnode = NULL; |
@@ -4702,33 +4694,7 @@ ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid, |
wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr); |
} |
- }while (pWmiSsidnode); |
- |
-#if 0 |
- /* |
- * Issuing a disconnect cmd prevent the firmware from |
- * continuing the scan and connect to the AP, if the AP |
- * cannot be found in 10 seconds. The user has to issue |
- * the iwconfig command again to connect to the AP. |
- * This change came in CL#575412 (EV# 59469) has to |
- * be fixed in a different way |
- */ |
- ar6000_init_profile_info(ar); |
- wmi_disconnect_cmd(ar->arWmi); |
-#else |
- { /* FIXME, This code is necessary if don't invoke |
- * wmi_disconnect_cmd. FIXME if you has fixed above |
- * EV# 59469 |
- */ |
- union iwreq_data wrqu; |
- A_MEMZERO(&wrqu, sizeof(wrqu)); |
- wrqu.addr.sa_family = ARPHRD_ETHER; |
- |
- /* Send disconnect event to supplicant */ |
- wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL); |
- } |
- |
-#endif |
+ } while (pWmiSsidnode); |
} |
/* Update connect & link status atomically */ |
@@ -4788,6 +4754,11 @@ ar6000_aggr_rcv_delba_req_evt(AR_SOFTC_T *ar, WMI_DELBA_EVENT *evt) |
} |
#endif |
+void register_pal_cb(ar6k_pal_config_t *palConfig_p) |
+{ |
+ ar6k_pal_config_g = *palConfig_p; |
+} |
+ |
void |
ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) |
{ |
@@ -4813,6 +4784,12 @@ ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) |
buf += sizeof(int); |
A_MEMCPY(buf, cmd->buf, cmd->evt_buf_sz); |
+ if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) |
+ { |
+ /* pass the cmd packet to PAL driver */ |
+ if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, osbuf) == TRUE) |
+ return; |
+ } |
ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf); |
if(loghci) { |
A_PRINTF_LOG("HCI Event From PAL <-- \n"); |
@@ -5100,13 +5077,13 @@ ar6000_hbChallengeResp_event(AR_SOFTC_T *ar, A_UINT32 cookie, A_UINT32 source) |
void |
ar6000_reportError_event(AR_SOFTC_T *ar, WMI_TARGET_ERROR_VAL errorVal) |
{ |
- char *errString[] = { |
- [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL", |
- [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND", |
- [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR", |
- [WMI_TARGET_BMISS] "WMI_TARGET_BMISS", |
- [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN" |
- }; |
+ static const char * const errString[] = { |
+ [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL", |
+ [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND", |
+ [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR", |
+ [WMI_TARGET_BMISS] "WMI_TARGET_BMISS", |
+ [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN" |
+ }; |
A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal); |
@@ -5283,11 +5260,7 @@ ar6000_bssInfo_event_rx(AR_SOFTC_T *ar, A_UINT8 *datap, int len) |
A_NETBUF_PUT(skb, len); |
A_MEMCPY(A_NETBUF_DATA(skb), datap, len); |
skb->dev = ar->arNetDev; |
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) |
A_MEMCPY(skb_mac_header(skb), A_NETBUF_DATA(skb), 6); |
-#else |
- skb->mac.raw = A_NETBUF_DATA(skb); |
-#endif |
skb->ip_summed = CHECKSUM_NONE; |
skb->pkt_type = PACKET_OTHERHOST; |
skb->protocol = __constant_htons(0x0019); |
@@ -5305,7 +5278,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) |
struct ar_cookie *cookie = NULL; |
int i; |
#ifdef CONFIG_PM |
- if (ar->arWowState) { |
+ if (ar->arWowState != WLAN_WOW_STATE_NONE) { |
A_NETBUF_FREE(osbuf); |
return A_EACCES; |
} |
@@ -5315,15 +5288,15 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) |
do { |
- AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%x, len=0x%x eid =%d\n", |
- (A_UINT32)osbuf, A_NETBUF_LEN(osbuf), eid)); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%lx, len=0x%x eid =%d\n", |
+ (unsigned long)osbuf, A_NETBUF_LEN(osbuf), eid)); |
if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) { |
/* control endpoint is full, don't allocate resources, we |
* are just going to drop this packet */ |
cookie = NULL; |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%X, len:%d \n", |
- (A_UINT32)osbuf, A_NETBUF_LEN(osbuf))); |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%lX, len:%d \n", |
+ (unsigned long)osbuf, A_NETBUF_LEN(osbuf))); |
} else { |
cookie = ar6000_alloc_cookie(ar); |
} |
@@ -5356,7 +5329,7 @@ ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) |
AR6000_SPIN_UNLOCK(&ar->arLock, 0); |
if (cookie != NULL) { |
- cookie->arc_bp[0] = (A_UINT32)osbuf; |
+ cookie->arc_bp[0] = (unsigned long)osbuf; |
cookie->arc_bp[1] = 0; |
SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, |
cookie, |
@@ -6132,7 +6105,6 @@ ar6000_ap_mode_profile_commit(struct ar6_softc *ar) |
return 0; |
} |
- |
A_STATUS |
ar6000_connect_to_ap(struct ar6_softc *ar) |
{ |
@@ -6170,10 +6142,10 @@ ar6000_connect_to_ap(struct ar6_softc *ar) |
ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, |
ar->arGroupCrypto, ar->arGroupCryptoLen)); |
reconnect_flag = 0; |
- /* Set the listen interval into 1000TUs. This value will be indicated to Ap in the conn. |
+ /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn. |
later set it back locally at the STA to 100/1000 TUs depending on the power mode */ |
if ((ar->arNetworkType == INFRA_NETWORK)) { |
- wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0); |
+ wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (A_UINT16)A_MAX_WOW_LISTEN_INTERVAL), 0); |
} |
status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType, |
ar->arDot11AuthMode, ar->arAuthMode, |
@@ -6204,117 +6176,6 @@ ar6000_connect_to_ap(struct ar6_softc *ar) |
return A_ERROR; |
} |
-A_STATUS |
-ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) |
-{ |
- A_STATUS status = A_OK; |
- AR6000_WLAN_STATE oldstate = ar->arWlanState; |
- if (ar->arWmiReady == FALSE || |
- (state!=WLAN_DISABLED && state!=WLAN_ENABLED)) { |
- return A_ERROR; |
- } |
- if (state == ar->arWlanState) { |
- return A_OK; |
- } |
- |
- if (down_interruptible(&ar->arSem)) { |
- return -ERESTARTSYS; |
- } |
- |
- if (ar->bIsDestroyProgress) { |
- up(&ar->arSem); |
- return -EBUSY; |
- } |
- |
- ar->arWlanState = state; |
- do { |
- if (ar->arWlanState == WLAN_ENABLED) { |
- A_UINT16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; |
- WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = { TRUE, FALSE}; |
- WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent ; |
- |
- wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE; |
- if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != A_OK) { |
- break; |
- } |
- ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)&wmiSleepEvent, |
- sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); |
- /* Enable foreground scanning */ |
- if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period, |
- ar->scParams.fg_end_period, |
- ar->scParams.bg_period, |
- ar->scParams.minact_chdwell_time, |
- ar->scParams.maxact_chdwell_time, |
- ar->scParams.pas_chdwell_time, |
- ar->scParams.shortScanRatio, |
- ar->scParams.scanCtrlFlags, |
- ar->scParams.max_dfsch_act_time, |
- ar->scParams.maxact_scan_per_ssid)) != A_OK) { |
- break; |
- } |
- if (ar->arSsidLen) { |
- if (ar6000_connect_to_ap(ar) != A_OK) { |
- /* no need to report error if connection failed */ |
- break; |
- } |
- } |
- } else { |
- WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = FALSE }; |
- |
- WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode; |
- WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent; |
- |
- wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP; |
- /* make sure we disable wow for deep sleep */ |
- if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!=A_OK) { |
- break; |
- } |
- |
- ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (A_UINT8*)&wmiSleepEvent, |
- sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); |
- |
- /* Disconnect from the AP and disable foreground scanning */ |
- AR6000_SPIN_LOCK(&ar->arLock, 0); |
- if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { |
- AR6000_SPIN_UNLOCK(&ar->arLock, 0); |
- wmi_disconnect_cmd(ar->arWmi); |
- } else { |
- AR6000_SPIN_UNLOCK(&ar->arLock, 0); |
- } |
- |
- ar->scan_triggered = 0; |
- |
- if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != A_OK) { |
- break; |
- } |
- ar6000_TxDataCleanup(ar); |
-#ifndef ATH6K_CONFIG_OTA_MODE |
- wmi_powermode_cmd(ar->arWmi, REC_POWER); |
-#endif |
- hostSleepMode.awake = FALSE; |
- hostSleepMode.asleep = TRUE; |
- if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!=A_OK) { |
- break; |
- } |
- if (ar->arTxPending[ar->arControlEp]) { |
- long timeleft = wait_event_interruptible_timeout(arEvent, |
- ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ); |
- if (!timeleft || signal_pending(current)) { |
- status = A_ERROR; |
- break; |
- } |
- } |
- } |
- } while (0); |
- if (status!=A_OK) { |
- AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState)); |
- ar->arWlanState = oldstate; |
- } |
- up(&ar->arSem); |
- |
- return status; |
-} |
- |
A_STATUS |
ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie) |
{ |
@@ -6444,7 +6305,7 @@ static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, st |
} |
A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb)); |
- cookie->arc_bp[0] = (A_UINT32)new_skb; |
+ cookie->arc_bp[0] = (unsigned long)new_skb; |
cookie->arc_bp[1] = MapNo; |
SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, |
cookie, |
@@ -6474,9 +6335,117 @@ static void DoHTCSendPktsTest(AR_SOFTC_T *ar, int MapNo, HTC_ENDPOINT_ID eid, st |
HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue); |
} |
+#endif |
+ |
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT |
+/* |
+ * Add support for adding and removing a virtual adapter for soft AP. |
+ * Some OS requires different adapters names for station and soft AP mode. |
+ * To support these requirement, create and destory a netdevice instance |
+ * when the AP mode is operational. A full fledged support for virual device |
+ * is not implemented. Rather a virtual interface is created and is linked |
+ * with the existing physical device instance during the operation of the |
+ * AP mode. |
+ */ |
+ |
+A_STATUS ar6000_start_ap_interface(AR_SOFTC_T *ar) |
+{ |
+ AR_VIRTUAL_INTERFACE_T *arApDev; |
+ |
+ /* Change net_device to point to AP instance */ |
+ arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev; |
+ ar->arNetDev = arApDev->arNetDev; |
+ |
+ return A_OK; |
+} |
+ |
+A_STATUS ar6000_stop_ap_interface(AR_SOFTC_T *ar) |
+{ |
+ AR_VIRTUAL_INTERFACE_T *arApDev; |
+ |
+ /* Change net_device to point to sta instance */ |
+ arApDev = (AR_VIRTUAL_INTERFACE_T *)ar->arApDev; |
+ if (arApDev) { |
+ ar->arNetDev = arApDev->arStaNetDev; |
+ } |
+ |
+ return A_OK; |
+} |
+ |
+ |
+A_STATUS ar6000_create_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) |
+{ |
+ struct net_device *dev; |
+ AR_VIRTUAL_INTERFACE_T *arApDev; |
+ |
+ dev = alloc_etherdev(sizeof(AR_VIRTUAL_INTERFACE_T)); |
+ if (dev == NULL) { |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n")); |
+ return A_ERROR; |
+ } |
+ |
+ ether_setup(dev); |
+ init_netdev(dev, ap_ifname); |
+ |
+ if (register_netdev(dev)) { |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n")); |
+ return A_ERROR; |
+ } |
+ |
+ arApDev = netdev_priv(dev); |
+ arApDev->arDev = ar; |
+ arApDev->arNetDev = dev; |
+ arApDev->arStaNetDev = ar->arNetDev; |
+ |
+ ar->arApDev = arApDev; |
+ arApNetDev = dev; |
+ /* Copy the MAC address */ |
+ A_MEMCPY(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN); |
+ |
+ return A_OK; |
+} |
+ |
+A_STATUS ar6000_add_ap_interface(AR_SOFTC_T *ar, char *ap_ifname) |
+{ |
+ /* Interface already added, need not proceed further */ |
+ if (ar->arApDev != NULL) { |
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n")); |
+ return A_OK; |
+ } |
+ |
+ if (ar6000_create_ap_interface(ar, ap_ifname) != A_OK) { |
+ return A_ERROR; |
+ } |
+ |
+ A_PRINTF("Add AP interface %s \n",ap_ifname); |
+ |
+ return ar6000_start_ap_interface(ar); |
+} |
+ |
+A_STATUS ar6000_remove_ap_interface(AR_SOFTC_T *ar) |
+{ |
+ if (arApNetDev) { |
+ ar6000_stop_ap_interface(ar); |
+ |
+ unregister_netdev(arApNetDev); |
+#ifndef free_netdev |
+ kfree(arApNetDev); |
+#else |
+ free_netdev(apApNetDev); |
#endif |
+ A_PRINTF("Remove AP interface\n"); |
+ } |
+ ar->arApDev = NULL; |
+ arApNetDev = NULL; |
+ |
+ |
+ return A_OK; |
+} |
+#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ |
+ |
+ |
#ifdef EXPORT_HCI_BRIDGE_INTERFACE |
EXPORT_SYMBOL(setupbtdev); |
#endif |