| 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
|
|
|