r2540 - in developers/nbd: . ar6k ar6k/ar6000 ar6k/bmi ar6k/hif ar6k/htc ar6k/include ar6k/include/app ar6k/include/hw ar6k/wlan ar6k/wmi patches-2.6.22

nbd at sita.openmoko.org nbd at sita.openmoko.org
Fri Jul 27 20:59:04 CEST 2007


Author: nbd
Date: 2007-07-27 20:59:01 +0200 (Fri, 27 Jul 2007)
New Revision: 2540

Added:
   developers/nbd/ar6k/
   developers/nbd/ar6k/Makefile
   developers/nbd/ar6k/ar6000/
   developers/nbd/ar6k/ar6000/ar6000_drv.c
   developers/nbd/ar6k/ar6000/ar6000_drv.h
   developers/nbd/ar6k/bmi/
   developers/nbd/ar6k/bmi/Makefile
   developers/nbd/ar6k/bmi/bmi.c
   developers/nbd/ar6k/bmi/bmi_internal.h
   developers/nbd/ar6k/hif/
   developers/nbd/ar6k/hif/Makefile
   developers/nbd/ar6k/hif/hif.c
   developers/nbd/ar6k/hif/hif_internal.h
   developers/nbd/ar6k/htc/
   developers/nbd/ar6k/htc/Makefile
   developers/nbd/ar6k/htc/htc.c
   developers/nbd/ar6k/htc/htc_events.c
   developers/nbd/ar6k/htc/htc_internal.h
   developers/nbd/ar6k/htc/htc_recv.c
   developers/nbd/ar6k/htc/htc_send.c
   developers/nbd/ar6k/htc/htc_utils.c
   developers/nbd/ar6k/include/
   developers/nbd/ar6k/include/AR6000_bmi.h
   developers/nbd/ar6k/include/AR6000_gpio.h
   developers/nbd/ar6k/include/AR6000_version.h
   developers/nbd/ar6k/include/app/
   developers/nbd/ar6k/include/app/dset.h
   developers/nbd/ar6k/include/ar6000_api.h
   developers/nbd/ar6k/include/athdefs.h
   developers/nbd/ar6k/include/athdrv.h
   developers/nbd/ar6k/include/athtypes.h
   developers/nbd/ar6k/include/bmi.h
   developers/nbd/ar6k/include/dset_api.h
   developers/nbd/ar6k/include/gpio_api.h
   developers/nbd/ar6k/include/hif.h
   developers/nbd/ar6k/include/host_version.h
   developers/nbd/ar6k/include/htc.h
   developers/nbd/ar6k/include/hw/
   developers/nbd/ar6k/include/hw/mbox_host_reg.h
   developers/nbd/ar6k/include/hw/mbox_reg.h
   developers/nbd/ar6k/include/hw/mc_reg.h
   developers/nbd/ar6k/include/hw/rtc_reg.h
   developers/nbd/ar6k/include/ieee80211.h
   developers/nbd/ar6k/include/ieee80211_ioctl.h
   developers/nbd/ar6k/include/ieee80211_node.h
   developers/nbd/ar6k/include/osapi.h
   developers/nbd/ar6k/include/osapi_linux.h
   developers/nbd/ar6k/include/queue.h
   developers/nbd/ar6k/include/wlan_api.h
   developers/nbd/ar6k/include/wmi.h
   developers/nbd/ar6k/include/wmi_api.h
   developers/nbd/ar6k/include/wmi_host.h
   developers/nbd/ar6k/include/wmix.h
   developers/nbd/ar6k/wlan/
   developers/nbd/ar6k/wlan/Makefile
   developers/nbd/ar6k/wlan/wlan_node.c
   developers/nbd/ar6k/wlan/wlan_recv_beacon.c
   developers/nbd/ar6k/wlan/wlan_utils.c
   developers/nbd/ar6k/wmi/
   developers/nbd/ar6k/wmi/wmi.c
   developers/nbd/patches-2.6.22/
   developers/nbd/patches-2.6.22/100-asoc.patch
   developers/nbd/patches-2.6.22/110-asoc-asm_hardware_h.patch
   developers/nbd/patches-2.6.22/120-asoc-platform-hw_init-pcm_emulation-fix.patch
   developers/nbd/patches-2.6.22/130-i2c-permit_invalid_addrs.patch
   developers/nbd/patches-2.6.22/140-pm-debug_less_verbose.patch
   developers/nbd/patches-2.6.22/150-g_ether-highpower.patch
   developers/nbd/patches-2.6.22/160-g_ether-vendor_product.patch
   developers/nbd/patches-2.6.22/170-s3c2410_serial-nodebug.patch
   developers/nbd/patches-2.6.22/180-s3c2410_udc.patch
   developers/nbd/patches-2.6.22/190-s3c2410_touchscreen.patch
   developers/nbd/patches-2.6.22/200-s3c2410-bbt.patch
   developers/nbd/patches-2.6.22/210-udc-nomodule-misccr.patch
   developers/nbd/patches-2.6.22/220-s3c2410_udc-vbus_draw_pdata.patch
   developers/nbd/patches-2.6.22/280-qt2410-base.patch
   developers/nbd/patches-2.6.22/290-qt2410-cs8900.patch
   developers/nbd/patches-2.6.22/300-qt2410-s3c_mci-pdata.patch
   developers/nbd/patches-2.6.22/310-gta01-pcf50606.patch
   developers/nbd/patches-2.6.22/320-gta01-core.patch
   developers/nbd/patches-2.6.22/330-gta01-jbt6k74.patch
   developers/nbd/patches-2.6.22/340-gta01-backlight.patch
   developers/nbd/patches-2.6.22/350-gta01-vibrator.patch
   developers/nbd/patches-2.6.22/360-gta01-inputdevice.patch
   developers/nbd/patches-2.6.22/370-gta01-power_control.patch
   developers/nbd/patches-2.6.22/380-gta01-no_nand_partitions.patch
   developers/nbd/patches-2.6.22/390-input-nots-mousedev.patch
   developers/nbd/patches-2.6.22/400-ts0710.patch
   developers/nbd/patches-2.6.22/410-s3c2410-qt2410-buttons.patch
   developers/nbd/patches-2.6.22/420-config-nr-tty-devices.patch
   developers/nbd/patches-2.6.22/430-hxd8-core.patch
   developers/nbd/patches-2.6.22/440-s3c2410_fb-truecolor.patch
   developers/nbd/patches-2.6.22/450-s3c2440-nand-disable-hwecc.patch
   developers/nbd/patches-2.6.22/460-hxd8-tsl256x.patch
   developers/nbd/patches-2.6.22/470-pcf50633.patch
   developers/nbd/patches-2.6.22/480-smedia-glamo.patch
   developers/nbd/patches-2.6.22/490-s3c24xx-nand-largepage.patch
   developers/nbd/patches-2.6.22/500-gta02-core.patch
   developers/nbd/patches-2.6.22/800-sdio_merge.patch
   developers/nbd/patches-2.6.22/810-s3c_mci.patch
   developers/nbd/patches-2.6.22/820-s3cmci_dbg.patch
   developers/nbd/patches-2.6.22/830-s3cmci-dma-free.patch
   developers/nbd/patches-2.6.22/840-s3cmci-stop-fix.patch
   developers/nbd/patches-2.6.22/850-s3c_mci_platform.patch
   developers/nbd/patches-2.6.22/860-missing_defs.patch
   developers/nbd/patches-2.6.22/870-missing_export.patch
   developers/nbd/patches-2.6.22/880-sdio_ops.patch
   developers/nbd/patches-2.6.22/900-pcf50606_fix.patch
   developers/nbd/patches-2.6.22/901-pcf50633_fix.patch
   developers/nbd/patches-2.6.22/902-qt2410_lcd.patch
   developers/nbd/patches-2.6.22/903-qt2410_nand.patch
   developers/nbd/patches-2.6.22/904-partitions.patch
Log:
add my WiP ar6k tree and kernel patches

Added: developers/nbd/ar6k/Makefile
===================================================================
--- developers/nbd/ar6k/Makefile	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/Makefile	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,29 @@
+#
+#  AR6K Kernel Module makefile.
+#
+REV ?= 2
+
+
+EXTRA_CFLAGS += -DLINUX -DDEBUG -D__KERNEL__ -DHTC_RAW_INTERFACE \
+ 	-DSEND_EVENT_TO_APP#\
+ 	-DMULTIPLE_FRAMES_PER_INTERRUPT -DAR6000REV$(REV) \
+ 	-DBLOCK_TX_PATH_FLAG \
+
+EXTRA_CFLAGS += -DKERNEL_2_6
+
+obj-dir		:= /bmi /htc /hif
+
+obj-m += ar6000.o
+ar6000-objs += htc/htc.o		\
+ 	htc/htc_send.o			\
+ 	htc/htc_recv.o			\
+ 	htc/htc_utils.o			\
+ 	htc/htc_events.o		\
+ 	bmi/bmi.o			\
+	hif/hif.o			\
+ 	ar6000/ar6000_drv.o		\
+ 	wmi/wmi.o			\
+ 	wlan/wlan_node.o		\
+ 	wlan/wlan_recv_beacon.o		\
+ 	wlan/wlan_utils.o
+

Added: developers/nbd/ar6k/ar6000/ar6000_drv.c
===================================================================
--- developers/nbd/ar6k/ar6000/ar6000_drv.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/ar6000/ar6000_drv.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,5761 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+
+/*
+ * This driver is a pseudo ethernet driver to access the Atheros AR6000
+ * WLAN Device
+ */
+static const char athId[] __attribute__ ((unused)) = "$Id: //depot/sw/releases/etnaGPL1.1/host/os/linux/ar6000_drv.c#2 $";
+
+#include <linux/module.h>
+#include <linux/autoconf.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/if_ether.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <net/iw_handler.h>
+#include <linux/if_arp.h>
+#include <linux/ip.h>
+#include <linux/rtnetlink.h>
+#include <linux/netdevice.h>
+#include <asm/semaphore.h>
+#include <linux/wireless.h>
+
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/osapi.h"
+#include "../include/htc.h"
+#include "../include/wmi.h"
+#include "../include/athdrv.h"
+#include "ar6000_drv.h"
+#include "../include/bmi.h"
+#include "../include/ieee80211.h"
+#include "../include/ieee80211_ioctl.h"
+#include "../include/wlan_api.h"
+#include "../include/wmi_api.h"
+#include "../include/dset_api.h"
+#include "../include/app/dset.h"
+#include "../include/gpio_api.h"
+#include "../include/AR6000_gpio.h"
+#include "../include/host_version.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#include <asm/uaccess.h>
+#include <linux/rtnetlink.h>
+#endif
+#include "../include/hw/mbox_host_reg.h"
+#include "../include/hw/mc_reg.h"
+#include "../include/hw/mbox_reg.h"
+#include "../include/hw/rtc_reg.h"
+
+MODULE_LICENSE("Dual BSD/GPL");
+
+#if defined (SPI)
+#define CONTROL_PADCONF_AA12 0x00E8
+unsigned int awake_gpio = 17;
+unsigned int awake_gpio_pad_conf_offset = CONTROL_PADCONF_AA12;
+unsigned int awake_gpio_pad_conf_byte = 1;
+unsigned int awake_gpio_pad_mode_value = 0x3;
+#endif
+
+int bmienable = 0;
+unsigned int bypasswmi = 0;
+unsigned int debuglevel = 0;
+int tspecCompliance = CCX_V4_COMPLIANCE;
+unsigned int busspeedlow = 0;
+unsigned int onebitmode = 0;
+unsigned int skipflash = 0;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+module_param(bmienable, int, 0644);
+module_param(bypasswmi, int, 0644);
+module_param(debuglevel, int, 0644);
+module_param(tspecCompliance, int, 0644);
+module_param(onebitmode, int, 0644);
+module_param(busspeedlow, int, 0644);
+module_param(skipflash, int, 0644);
+
+#else
+
+#define __user
+/* for linux 2.4 and lower */
+MODULE_PARM(bmienable,"i");
+MODULE_PARM(bypasswmi,"i");
+MODULE_PARM(debuglevel, "i");
+MODULE_PARM(onebitmode,"i");
+MODULE_PARM(busspeedlow, "i");
+MODULE_PARM(skipflash, "i");
+
+#if defined SPI
+MODULE_PARM(awake_gpio, "i");
+MODULE_PARM_DESC(awake_gpio, "Awake GPIO pin");
+MODULE_PARM(awake_gpio_pad_conf_offset, "i");
+MODULE_PARM_DESC(awake_gpio_pad_conf_offset,
+                 "Awake GPIO pin pad config offset");
+MODULE_PARM(awake_gpio_pad_conf_byte, "i");
+MODULE_PARM_DESC(awake_gpio_pad_conf_byte,
+                 "Awake GPIO pin pad byte number");
+MODULE_PARM(awake_gpio_pad_mode_value, "i");
+MODULE_PARM_DESC(awake_gpio_pad_mode_value,
+                 "Awake GPIO pin mode value");
+#endif
+#endif
+
+#define MAX_ALLOWED_TXQ_DEPTH   (HTC_DATA_REQUEST_RING_BUFFER_SIZE - 2)
+static int txFlowCtrlThresh[HTC_MAILBOX_NUM_MAX]
+        = {0 * (MAX_ALLOWED_TXQ_DEPTH - 1),
+           1 * (MAX_ALLOWED_TXQ_DEPTH - 1),
+           2 * (MAX_ALLOWED_TXQ_DEPTH - 1),
+           3 * (MAX_ALLOWED_TXQ_DEPTH - 1)};
+
+#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
+int debugdriver = 1;
+unsigned int debughtc = 128;
+unsigned int debugbmi = 1;
+unsigned int debughif = 1;
+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(debugdriver, int, 0644);
+module_param(debughtc, int, 0644);
+module_param(debugbmi, int, 0644);
+module_param(debughif, int, 0644);
+module_param_array(txcreditsavailable, int, mboxnum, 0644);
+module_param_array(txcreditsconsumed, int, mboxnum, 0644);
+module_param_array(txcreditintrenable, int, mboxnum, 0644);
+module_param_array(txcreditintrenableaggregate, int, mboxnum, 0644);
+#else
+/* linux 2.4 and lower */
+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 */
+
+unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0};
+unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0};
+unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0};
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+module_param_array(tx_attempt, int, mboxnum, 0644);
+module_param_array(tx_post, int, mboxnum, 0644);
+module_param_array(tx_complete, int, mboxnum, 0644);
+#else
+MODULE_PARM(tx_attempt, "0-3i");
+MODULE_PARM(tx_post, "0-3i");
+MODULE_PARM(tx_complete, "0-3i");
+#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 */
+
+#ifdef DEBUG
+#define AR_DEBUG_PRINTF(args...)        if (debugdriver) printk(args);
+#define AR_DEBUG2_PRINTF(args...)        if (debugdriver >= 2) printk(args);
+#else
+#define AR_DEBUG_PRINTF(args...)
+#define AR_DEBUG2_PRINTF(args...)
+#endif
+
+/* Function declarations */
+static int ar6000_init_module(void);
+static void ar6000_cleanup_module(void);
+
+static int ar6000_init(struct net_device *dev);
+static int ar6000_open(struct net_device *dev);
+static int ar6000_close(struct net_device *dev);
+static void ar6000_init_control_info(AR_SOFTC_T *ar);
+static void ar6000_init_profile_info(AR_SOFTC_T *ar);
+static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev);
+static int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void ar6000_destroy(struct net_device *dev);
+static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
+static void ar6000_ioctl_iwsetup(struct iw_handler_def *def);
+static int ar6000_ioctl_set_channelParams(struct net_device *dev,
+                                          struct ifreq *rq);
+static int ar6000_ioctl_set_probedSsid(struct net_device *dev,
+                                       struct ifreq *rq);
+static int ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_set_link_threshold(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_set_access_params(struct net_device *dev,
+                                          struct ifreq *rq);
+static int ar6000_ioctl_set_disconnect_timeout(struct net_device *dev,
+                                               struct ifreq *rq);
+static int ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata);
+static int ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata);
+static int ar6000_ioctl_get_roam_tbl(struct net_device *dev,
+                                               struct ifreq *rq);
+static int ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata);
+static int ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata);
+static int ar6000_ioctl_get_power_mode(struct net_device *dev,
+                                       struct ifreq *rq);
+
+#ifdef HTC_RAW_INTERFACE
+static void ar6000_htc_raw_read_cb(HTC_TARGET *htcTarget,
+                                   HTC_ENDPOINT_ID endPointId,
+                                   HTC_EVENT_ID evId,
+                                   HTC_EVENT_INFO *evInfo,
+                                   void *arg);
+static void ar6000_htc_raw_unread_cb(HTC_TARGET *htcTarget,
+                                     HTC_ENDPOINT_ID endPointId,
+                                     HTC_EVENT_ID evId,
+                                     HTC_EVENT_INFO *evInfo,
+                                     void *arg);
+static void ar6000_htc_raw_write_cb(HTC_TARGET *htcTarget,
+                                    HTC_ENDPOINT_ID endPointId,
+                                    HTC_EVENT_ID evId,
+                                    HTC_EVENT_INFO *evInfo,
+                                    void *arg);
+static int ar6000_htc_raw_open(HTC_TARGET *htcTarget);
+static int ar6000_htc_raw_close(HTC_TARGET *htcTarget);
+static ssize_t ar6000_htc_raw_read(HTC_TARGET *htcTarget,
+                                   HTC_ENDPOINT_ID endPointId,
+                                   char __user *buffer, size_t count);
+static ssize_t ar6000_htc_raw_write(HTC_TARGET *htcTarget,
+                                    HTC_ENDPOINT_ID endPointId,
+                                    char __user *buffer, size_t count);
+#endif /* HTC_RAW_INTERFACE */
+static void ar6000_install_static_wep_keys(AR_SOFTC_T *ar);
+static int ar6000_ioctl_addpmkid(struct net_device *dev,
+                                 struct iw_request_info *info, void *w, char *extra);
+
+#if CONFIG_HOST_DSET_SUPPORT
+static void ar6000_dset_init(void);
+static int ar6000_ioctl_wait_dset_req(struct net_device *dev, struct ifreq *rq);
+static int ar6000_ioctl_dset_open_reply(struct net_device *dev,
+                                        struct ifreq *rq);
+static int ar6000_ioctl_dset_data_reply(struct net_device *dev,
+                                        struct ifreq *rq);
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+#if CONFIG_HOST_GPIO_SUPPORT
+static void ar6000_gpio_init(void);
+A_STATUS ar6000_gpio_output_set(struct net_device *dev,
+                                A_UINT32 set_mask,
+                                A_UINT32 clear_mask,
+                                A_UINT32 enable_mask,
+                                A_UINT32 disable_mask);
+static A_STATUS ar6000_gpio_input_get(struct net_device *dev);
+static A_STATUS ar6000_gpio_register_set(struct net_device *dev,
+                                         A_UINT32 gpioreg_id,
+                                         A_UINT32 value);
+static A_STATUS ar6000_gpio_register_get(struct net_device *dev,
+                                         A_UINT32 gpioreg_id);
+static A_STATUS ar6000_gpio_intr_ack(struct net_device *dev,
+                                     A_UINT32 ack_mask);
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+/*
+ * HTC event handlers
+ */
+static void ar6000_avail_ev(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                            HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);
+
+static void ar6000_unavail_ev(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                            HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);
+
+static void ar6000_rx(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                      HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);
+
+static void ar6000_rx_refill(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                      HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);
+
+static void ar6000_tx_complete(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                      HTC_EVENT_ID id, HTC_EVENT_INFO *evInfo, void *arg);
+
+/*
+ * Static variables
+ */
+static struct net_device *ar6000_devices[MAX_AR6000];
+static struct iw_handler_def ath_iw_handler_def;
+static DECLARE_WAIT_QUEUE_HEAD(arEvent);
+static A_UINT8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+static A_UINT8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+
+#if CONFIG_HOST_GPIO_SUPPORT
+struct ar6000_gpio_intr_wait_cmd_s  gpio_intr_results;
+/* gpio_reg_results and gpio_data_available are protected by arSem */
+static struct ar6000_gpio_register_cmd_s gpio_reg_results;
+static A_BOOL gpio_data_available; /* Requested GPIO data available */
+static A_BOOL gpio_intr_available; /* GPIO interrupt info available */
+static A_BOOL gpio_ack_received;   /* GPIO ack was received */
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+#if 0
+static struct iw_statistics * ar6000_get_iwstats(struct net_device *dev);
+#endif
+
+/*
+ * adhoc PS support
+ */
+static void ar6000_cookie_init(AR_SOFTC_T *ar);
+static void ar6000_cookie_cleanup(AR_SOFTC_T *ar);
+static void ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie);
+static struct ar_cookie *ar6000_alloc_cookie(AR_SOFTC_T *ar);
+
+static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM];
+
+static int __init
+ar6000_init_module(void)
+{
+    static int probed = 0;
+    A_STATUS status;
+
+    if (probed) {
+        return -ENODEV;
+    }
+    probed++;
+
+#if CONFIG_HOST_DSET_SUPPORT
+    ar6000_dset_init();
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+#if CONFIG_HOST_GPIO_SUPPORT
+    ar6000_gpio_init();
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+    status = HTCInit();
+    if(status != A_OK)
+        return -ENODEV;
+
+    HTCEventReg(NULL, ENDPOINT_UNUSED, HTC_TARGET_AVAILABLE,
+                ar6000_avail_ev, NULL);
+    HTCEventReg(NULL, ENDPOINT_UNUSED, HTC_TARGET_UNAVAILABLE,
+                ar6000_unavail_ev, NULL);
+
+    return 0;
+}
+
+static void __exit
+ar6000_cleanup_module(void)
+{
+    int i = 0;
+    struct net_device *ar6000_netdev;
+
+    for (i=0; i < MAX_AR6000; i++) {
+        if (ar6000_devices[i] != NULL) {
+            ar6000_netdev = ar6000_devices[i];
+            ar6000_devices[i] = NULL;
+            ar6000_destroy(ar6000_netdev);
+        }
+    }
+
+    /* This will unregister with the SDIO bus driver */
+    HTCShutDown(NULL);
+
+    AR_DEBUG_PRINTF("ar6000_cleanup: success\n");
+}
+
+/*
+ * Write to the AR6000 through its diagnostic window.
+ * No cooperation from the Target is required for this.
+ */
+A_STATUS
+ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data)
+{
+    HIF_REQUEST request;
+    A_STATUS status;
+
+    HIF_FRAME_REQUEST(&request,
+                      HIF_WRITE,
+                      HIF_EXTENDED_IO,
+                      HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS,
+                      HIF_INCREMENTAL_ADDRESS);
+
+    status = HIFReadWrite(hifDevice,
+                          WINDOW_DATA_ADDRESS,
+                          (A_UCHAR *)data,
+                          sizeof(A_UINT32),
+                          &request,
+                          NULL);
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data);
+        return status;
+    }
+
+    status = HIFReadWrite(hifDevice,
+                          WINDOW_WRITE_ADDR_ADDRESS+1,
+                          ((A_UCHAR *)(address))+1,
+                          sizeof(A_UINT32)-1,
+                          &request,
+                          NULL);
+
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Cannot write initial bytes of 0x%x to WINDOW_WRITE_ADDR_ADDRESS\n", *address);
+        return status;
+    }
+
+    status = HIFReadWrite(hifDevice,
+                          WINDOW_WRITE_ADDR_ADDRESS,
+                          (A_UCHAR *)address,
+                          sizeof(A_UINT8),
+                          &request,
+                          NULL);
+
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Cannot write 0x%x to WINDOW_WRITE_ADDR_ADDRESS\n", *address);
+        return status;
+    }
+
+    return status;
+}
+
+/*
+ * HTC Event handlers
+ */
+static void
+ar6000_avail_ev(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid, HTC_EVENT_ID event,
+                HTC_EVENT_INFO *evInfo,
+                void *arg)
+{
+    int i;
+    struct net_device *dev;
+    AR_SOFTC_T *ar;
+    int device_index = 0;
+
+    AR_DEBUG_PRINTF("ar6000_available\n");
+
+    for (i=0; i < MAX_AR6000; i++) {
+        if (ar6000_devices[i] == NULL) {
+            break;
+        }
+    }
+
+    if (i == MAX_AR6000) {
+        AR_DEBUG_PRINTF("ar6000_available: max devices reached\n");
+        return;
+    }
+
+    /* Save this. It gives a bit better readability especially since */
+    /* we use another local "i" variable below.                      */
+    device_index = i;
+
+    A_ASSERT(htcTarget != NULL);
+    A_ASSERT(event == HTC_TARGET_AVAILABLE);
+
+    dev = alloc_etherdev(sizeof(AR_SOFTC_T));
+    if (dev == NULL) {
+        AR_DEBUG_PRINTF("ar6000_available: can't alloc etherdev\n");
+        return;
+    }
+    SET_MODULE_OWNER(dev);
+
+    ether_setup(dev);
+
+    if (dev->priv == NULL) {
+        printk(KERN_CRIT "ar6000_available: Could not allocate memory\n");
+        return;
+    }
+
+    A_MEMZERO(dev->priv, sizeof(AR_SOFTC_T));
+
+    ar                       = (AR_SOFTC_T *)dev->priv;
+    ar->arNetDev             = dev;
+    ar->arHtcTarget          = htcTarget;
+    ar->arHifDevice          = evInfo->buffer;
+    ar->arWlanState          = WLAN_ENABLED;
+
+    ar6000_init_control_info(ar);
+    init_waitqueue_head(&arEvent);
+    sema_init(&ar->arSem, 1);
+
+    /*
+     * If requested, perform some magic which requires no cooperation from
+     * the Target.  It causes the Target to ignore flash and execute the
+     * OS from ROM.
+     *
+     * This code uses the Diagnostic Window to remap instructions at
+     * the start of ROM in such a way that on the next CPU reset, the
+     * ROM code avoids using flash.  Then it uses the Diagnostic
+     * Window to force a CPU Warm Reset.
+     *
+     * This is intended to support recovery from a corrupted flash.
+     */
+    if (skipflash)
+    {
+        int i;
+
+        static struct {
+                A_UINT32 addr;
+                A_UINT32 data;
+        } ForceROM[] = {
+                /* NB: This is ROM-version dependent. */
+                {0x00001ff0, 0x175b0027}, /* jump instruction at 0xa0001ff0 */
+                {0x00001ff4, 0x00000000}, /* nop instruction at 0xa0001ff4 */
+
+                {MC_REMAP_TARGET_ADDRESS, 0x00001ff0}, /* remap to 0xa0001ff0 */
+                {MC_REMAP_COMPARE_ADDRESS, 0x01000040},/* ...from 0xbfc00040 */
+                {MC_REMAP_SIZE_ADDRESS, 0x00000000},   /* ...1 cache line */
+                {MC_REMAP_VALID_ADDRESS, 0x00000001},  /* ...remap is valid */
+
+                {LOCAL_COUNT_ADDRESS+0x10, 0}, /* clear BMI credit counter */
+
+                {RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK},
+        };
+
+        AR_DEBUG_PRINTF("Force Target to execute from ROM....\n");
+        for (i=0; i<sizeof(ForceROM)/sizeof(*ForceROM); i++) {
+            if (ar6000_WriteRegDiag(ar->arHifDevice,
+                &ForceROM[i].addr,
+                &ForceROM[i].data) != A_OK)
+            {
+                AR_DEBUG_PRINTF("Cannot force Target to execute ROM!\n");
+                break;
+            }
+        }
+    }
+
+    BMIInit();
+    if ((BMIGetTargetId(ar->arHifDevice, &ar->arVersion.target_ver)) != A_OK) {
+        return;
+    }
+
+    spin_lock_init(&ar->arLock);
+
+    /* Don't install the init function if BMI is requested */
+    if(!bmienable)
+    {
+        dev->init = ar6000_init;
+    }
+    dev->open = &ar6000_open;
+    dev->stop = &ar6000_close;
+    dev->hard_start_xmit = &ar6000_data_tx;
+    dev->get_stats = &ar6000_get_stats;
+#if 0
+    dev->get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */
+#endif
+    /* dev->tx_timeout = ar6000_tx_timeout; */
+    dev->do_ioctl = &ar6000_ioctl;
+    dev->watchdog_timeo = AR6000_TX_TIMEOUT;
+    ar6000_ioctl_iwsetup(&ath_iw_handler_def);
+    dev->wireless_handlers = &ath_iw_handler_def;
+
+    /*
+     * 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;
+
+    /* This runs the init function */
+    if (register_netdev(dev)) {
+        AR_DEBUG_PRINTF("ar6000_avail: register_netdev failed\n");
+        ar6000_destroy(dev);
+        return;
+    }
+
+    /* We only register the device in the global list if we succeed. */
+    /* If the device is in the global list, it will be destroyed     */
+    /* when the module is unloaded.                                  */
+    ar6000_devices[device_index] = dev;
+
+    AR_DEBUG_PRINTF("ar6000_avail: name=%s htcTarget=0x%x, dev=0x%x (%d), ar=0x%x\n",
+                    dev->name, (A_UINT32)htcTarget, (A_UINT32)dev, device_index,
+                    (A_UINT32)ar);
+}
+
+static void
+ar6000_unavail_ev(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                  HTC_EVENT_ID event, HTC_EVENT_INFO *evInfo, void *arg)
+{
+    int i;
+    AR_SOFTC_T *ar;
+    struct net_device *ar6000_netdev;
+
+    for (i=0; i < MAX_AR6000; i++) {
+        if (ar6000_devices[i] != NULL) {
+            ar = (AR_SOFTC_T *)ar6000_devices[i]->priv;
+            if (ar && ar->arHtcTarget == htcTarget) {
+                ar6000_netdev = ar6000_devices[i];
+                ar6000_devices[i] = NULL;
+                ar6000_destroy(ar6000_netdev);
+            }
+        }
+    }
+}
+
+static void
+ar6000_destroy(struct net_device *dev)
+{
+    AR_SOFTC_T *ar;
+
+    if((dev == NULL) || ((ar = netdev_priv(dev)) == NULL))
+    {
+        AR_DEBUG_PRINTF("%s(): Failed to get device structure.\n", __func__);
+        return;
+    }
+
+    /* Stop the transmit queues */
+    netif_stop_queue(dev);
+
+    /* Disable the target and the interrupts associated with it */
+    if (ar->arWmiReady == TRUE)
+    {
+        if (!bypasswmi)
+        {
+            if (ar->arConnected == TRUE || ar->arConnectPending == TRUE)
+            {
+                AR_DEBUG_PRINTF("%s(): Disconnect\n", __func__);
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                ar6000_init_profile_info(ar);
+                wmi_disconnect_cmd(ar->arWmi);
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            }
+
+            /* It's necessary to wait for the tx pending cleaning */
+            wait_event_interruptible(arEvent,
+                ar->arTxPending[WMI_CONTROL_MBOX]==0);
+
+            ar->arWmiReady  = FALSE;
+            ar->arConnected = FALSE;
+            ar->arConnectPending = FALSE;
+            wmi_shutdown(ar->arWmi);
+            ar->arWmiEnabled = FALSE;
+            ar->arWmi = NULL;
+            ar->arWlanState = WLAN_ENABLED;
+        }
+
+        /* It's necessary to wait for the tx pending cleaning */
+        wait_event_interruptible(arEvent,
+            ar->arTxPending[WMI_CONTROL_MBOX]==0);
+
+        HTCStop(ar->arHtcTarget);
+
+        /* It's necessary to wait for the tx pending cleaning */
+        wait_event_interruptible(arEvent,
+            ar->arTxPending[WMI_CONTROL_MBOX]==0);
+
+        AR_DEBUG_PRINTF("%s(): WMI and HTC stopped\n", __func__);
+    }
+    else
+    {
+        AR_DEBUG_PRINTF("%s(): WMI not ready 0x%08x 0x%08x\n",
+            __func__, (unsigned int) ar, (unsigned int) ar->arWmi);
+
+        /* Shut down WMI if we have started it */
+        if(ar->arWmiEnabled == TRUE)
+        {
+            AR_DEBUG_PRINTF("%s(): Shut down WMI\n", __func__);
+            wmi_shutdown(ar->arWmi);
+            ar->arWmiEnabled = FALSE;
+            ar->arWmi = NULL;
+        }
+
+        /* It's necessary to wait for the tx pending cleaning */
+        wait_event_interruptible(arEvent,
+            ar->arTxPending[WMI_CONTROL_MBOX]==0);
+
+        HTCStop(ar->arHtcTarget);
+
+        /* It's necessary to wait for the tx pending cleaning */
+        wait_event_interruptible(arEvent,
+            ar->arTxPending[WMI_CONTROL_MBOX]==0);
+    }
+
+    BMIInit();
+
+    /* Done with cookies */
+    ar6000_cookie_cleanup(ar);
+
+    /* Free up the device data structure */
+    HTCShutDown(ar->arHtcTarget);
+
+    unregister_netdev(dev);
+#ifdef mvlcee31_2_4_20_omap2420_gsm_gprs
+    kfree(dev);
+#else
+    free_netdev(dev);
+#endif
+}
+
+static void
+ar6000_init_profile_info(AR_SOFTC_T *ar)
+{
+    ar->arSsidLen            = 0;
+    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+    ar->arNetworkType        = INFRA_NETWORK;
+    ar->arDot11AuthMode      = OPEN_AUTH;
+    ar->arAuthMode           = NONE_AUTH;
+    ar->arPairwiseCrypto     = NONE_CRYPT;
+    ar->arPairwiseCryptoLen  = 0;
+    ar->arGroupCrypto        = NONE_CRYPT;
+    ar->arGroupCryptoLen     = 0;
+    A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
+    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+    A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
+    ar->arBssChannel = 0;
+}
+
+static void
+ar6000_init_control_info(AR_SOFTC_T *ar)
+{
+    ar->arWmiEnabled         = FALSE;
+    ar6000_init_profile_info(ar);
+    ar->arDefTxKeyIndex      = 0;
+    A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList));
+    ar->arChannelHint        = 0;
+    ar->arListenInterval     = MAX_LISTEN_INTERVAL;
+    ar->arVersion.host_ver   = AR6000_SW_VERSION;
+    ar->arRssi               = 0;
+    ar->arTxPwr              = 0;
+    ar->arTxPwrSet           = FALSE;
+    ar->arBitRate            = 0;
+    ar->arMaxRetries         = 0;
+}
+
+static int
+ar6000_open(struct net_device *dev)
+{
+    /* Wake up the queues */
+    netif_wake_queue(dev);
+
+    return 0;
+}
+
+static int
+ar6000_close(struct net_device *dev)
+{
+    netif_stop_queue(dev);
+
+    return 0;
+}
+
+/* This function does one time initialization for the lifetime of the device */
+static int
+ar6000_init(struct net_device *dev)
+{
+    int i;
+    AR_SOFTC_T *ar;
+    int endpoint[] = { ENDPOINT1, ENDPOINT2, ENDPOINT3, ENDPOINT4 };
+    A_STATUS    status;
+    A_INT32     timeleft;
+
+    if((ar = netdev_priv(dev)) == NULL)
+    {
+        return(-EIO);
+    }
+
+    /* Do we need to finish the BMI phase */
+    if(BMIDone(ar->arHifDevice) != A_OK)
+    {
+        return -EIO;
+    }
+
+    if (!bypasswmi)
+    {
+        if (ar->arVersion.host_ver != ar->arVersion.target_ver) {
+            A_PRINTF("WARNING: Host version 0x%x does not match Target "
+                    " version 0x%x!\n",
+                    ar->arVersion.host_ver, ar->arVersion.target_ver);
+        }
+
+        /* Indicate that WMI is enabled (although not ready yet) */
+        ar->arWmiEnabled = TRUE;
+        if ((ar->arWmi = wmi_init((void *) ar)) == NULL)
+        {
+            AR_DEBUG_PRINTF("%s() Failed to initialize WMI.\n", __func__);
+            return(-EIO);
+        }
+
+        AR_DEBUG_PRINTF("%s() Got WMI @ 0x%08x.\n", __func__,
+            (unsigned int) ar->arWmi);
+    }
+
+    /* Install event handlers for each end point */
+    for(i = 0; i < (sizeof(endpoint) / sizeof(int)); i++)
+    {
+        if(HTCEventReg(ar->arHtcTarget, endpoint[i], HTC_BUFFER_RECEIVED,
+            ar6000_rx, ar) != A_OK)
+        {
+            return(-EIO);
+        }
+
+        if(HTCEventReg(ar->arHtcTarget, endpoint[i], HTC_DATA_AVAILABLE,
+            ar6000_rx_refill, ar) != A_OK)
+        {
+            return(-EIO);
+        }
+
+        if(HTCEventReg(ar->arHtcTarget, endpoint[i], HTC_BUFFER_SENT,
+            ar6000_tx_complete, ar) != A_OK)
+        {
+            return(-EIO);
+        }
+    }
+
+    /*
+     * Provide HTC with receive buffers
+     */
+    ar6000_rx_refill(ar->arHtcTarget, ENDPOINT1, HTC_DATA_AVAILABLE,
+                     NULL, ar);
+
+    ar6000_rx_refill(ar->arHtcTarget, ENDPOINT2, HTC_DATA_AVAILABLE,
+                     NULL, ar);
+
+    /*
+     * We will post the receive buffers only for SPE testing and so we are
+     * making it conditional on the 'bypasswmi' flag.
+     */
+    if (bypasswmi) {
+        ar6000_rx_refill(ar->arHtcTarget, ENDPOINT3, HTC_DATA_AVAILABLE,
+                         NULL, ar);
+
+        ar6000_rx_refill(ar->arHtcTarget, ENDPOINT4, HTC_DATA_AVAILABLE,
+                         NULL, ar);
+    }
+
+    /* Since cookies are used for HTC transports, they should be */
+    /* initialized prior to enabling HTC.                        */
+    ar6000_cookie_init(ar);
+
+    /* Enable the target and the interrupts associated with it */
+    status = HTCStart(ar->arHtcTarget);
+
+    if (status != A_OK) {
+        if (ar->arWmiEnabled == TRUE) {
+            wmi_shutdown(ar->arWmi);
+            ar->arWmiEnabled = FALSE;
+            ar->arWmi = NULL;
+        }
+        ar6000_cookie_cleanup(ar);
+        return -EIO;
+    }
+
+    if (!bypasswmi) {
+        /*Wait for Wmi event to be ready  */
+        timeleft = wait_event_interruptible_timeout(arEvent,
+            (ar->arWmiReady == TRUE), 1 * HZ);
+
+        if(!timeleft || signal_pending(current))
+        {
+            AR_DEBUG_PRINTF("WMI is not ready or wait was interrupted\n");
+            return -EIO;
+        }
+
+        AR_DEBUG_PRINTF("%s() WMI is ready\n", __func__);
+    }
+
+    ar->arNumDataEndPts = 1;
+
+    return(0);
+}
+
+/* This would basically hold all the private ioctls that are not related to
+   WLAN operation */
+static int
+ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    HIF_DEVICE *hifDevice = ar->arHifDevice;
+    HTC_TARGET *htcTarget = ar->arHtcTarget;
+    int ret, param;
+    unsigned int address = 0;
+    unsigned int length = 0;
+    unsigned char *buffer;
+    char *userdata;
+#ifdef HTC_RAW_INTERFACE
+    HTC_ENDPOINT_ID endPointId = 0;
+    static A_BOOL rawIfInit = FALSE;
+#endif /* HTC_RAW_INTERFACE */
+    static WMI_SCAN_PARAMS_CMD scParams = {0, 0, 0, 0, 0,
+                                           WMI_SHORTSCANRATIO_DEFAULT };
+
+    if (cmd == AR6000_IOCTL_EXTENDED)
+    {
+        /*
+         * This allows for many more wireless ioctls than would otherwise
+         * be available.  Applications embed the actual ioctl command in
+         * the first word of the parameter block, and use the command
+         * AR6000_IOCTL_EXTENDED_CMD on the ioctl call.
+         */
+        get_user(cmd, (int *)rq->ifr_data);
+        userdata = (char *)(((unsigned int *)rq->ifr_data)+1);
+    }
+    else
+    {
+        userdata = (char *)rq->ifr_data;
+    }
+
+    if ((ar->arWlanState == WLAN_DISABLED) &&
+        (cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE))
+    {
+        return -EIO;
+    }
+
+    ret = 0;
+    switch(cmd)
+    {
+        case AR6000_XIOCTL_BMI_DONE:
+            if(bmienable)
+            {
+				ret = ar6000_init(dev);
+            }
+            else
+            {
+           	    ret = BMIDone(hifDevice);
+            }
+            break;
+
+        case AR6000_XIOCTL_BMI_READ_MEMORY:
+            get_user(address, (unsigned int *)userdata);
+            get_user(length, (unsigned int *)userdata + 1);
+            AR_DEBUG_PRINTF("Read Memory (address: 0x%x, length: %d)\n",
+                             address, length);
+            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
+                A_MEMZERO(buffer, length);
+                ret = BMIReadMemory(hifDevice, address, buffer, length);
+                if (copy_to_user(rq->ifr_data, buffer, length)) {
+                    ret = -EFAULT;
+                }
+                A_FREE(buffer);
+            } else {
+                ret = -ENOMEM;
+            }
+            break;
+
+        case AR6000_XIOCTL_BMI_WRITE_MEMORY:
+            get_user(address, (unsigned int *)userdata);
+            get_user(length, (unsigned int *)userdata + 1);
+            AR_DEBUG_PRINTF("Write Memory (address: 0x%x, length: %d)\n",
+                             address, length);
+            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
+                A_MEMZERO(buffer, length);
+                if (copy_from_user(buffer, &userdata[sizeof(address) +
+                                   sizeof(length)], length))
+                {
+                    ret = -EFAULT;
+                } else {
+                    ret = BMIWriteMemory(hifDevice, address, buffer, length);
+                }
+                A_FREE(buffer);
+            } else {
+                ret = -ENOMEM;
+            }
+            break;
+
+        case AR6000_XIOCTL_BMI_TEST:
+           AR_DEBUG_PRINTF("No longer supported\n");
+           ret = -EOPNOTSUPP;
+           break;
+
+        case AR6000_XIOCTL_BMI_EXECUTE:
+            get_user(address, (unsigned int *)userdata);
+            get_user(param, (unsigned int *)userdata + 1);
+            AR_DEBUG_PRINTF("Execute (address: 0x%x, param: %d)\n",
+                             address, param);
+            ret = BMIExecute(hifDevice, address, &param);
+            put_user(param, (unsigned int *)rq->ifr_data); /* return value */
+            break;
+
+        case AR6000_XIOCTL_BMI_SET_APP_START:
+            get_user(address, (unsigned int *)userdata);
+            AR_DEBUG_PRINTF("Set App Start (address: 0x%x)\n", address);
+            ret = BMISetAppStart(hifDevice, address);
+            break;
+
+        case AR6000_XIOCTL_BMI_READ_SOC_REGISTER:
+            get_user(address, (unsigned int *)userdata);
+            ret = BMIReadSOCRegister(hifDevice, address, &param);
+            put_user(param, (unsigned int *)rq->ifr_data); /* return value */
+            break;
+
+        case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER:
+            get_user(address, (unsigned int *)userdata);
+            get_user(param, (unsigned int *)userdata + 1);
+            ret = BMIWriteSOCRegister(hifDevice, address, param);
+            break;
+
+#ifdef HTC_RAW_INTERFACE
+        case AR6000_XIOCTL_HTC_RAW_OPEN:
+            ret = A_OK;
+            if (!rawIfInit) {
+                /* Terminate the BMI phase */
+                ret = BMIDone(hifDevice);
+                if (ret == A_OK) {
+                    ret = ar6000_htc_raw_open(htcTarget);
+                }
+                if (ret == A_OK) {
+                    rawIfInit = TRUE;
+                }
+            }
+            break;
+
+        case AR6000_XIOCTL_HTC_RAW_CLOSE:
+            if (rawIfInit) {
+                ret = ar6000_htc_raw_close(htcTarget);
+                rawIfInit = FALSE;
+            } else {
+                ret = A_ERROR;
+            }
+            break;
+
+        case AR6000_XIOCTL_HTC_RAW_READ:
+            if (rawIfInit) {
+                get_user(endPointId, (unsigned int *)userdata);
+                get_user(length, (unsigned int *)userdata + 1);
+                buffer = rq->ifr_data + sizeof(length);
+                ret = ar6000_htc_raw_read(htcTarget, endPointId,
+                                          buffer, length);
+                put_user(ret, (unsigned int *)rq->ifr_data);
+            } else {
+                ret = A_ERROR;
+            }
+            break;
+
+        case AR6000_XIOCTL_HTC_RAW_WRITE:
+            if (rawIfInit) {
+                get_user(endPointId, (unsigned int *)userdata);
+                get_user(length, (unsigned int *)userdata + 1);
+                buffer = userdata + sizeof(endPointId) + sizeof(length);
+                ret = ar6000_htc_raw_write(htcTarget, endPointId,
+                                           buffer, length);
+                put_user(ret, (unsigned int *)rq->ifr_data);
+            } else {
+                ret = A_ERROR;
+            }
+            break;
+#endif /* HTC_RAW_INTERFACE */
+
+        case AR6000_IOCTL_WMI_GETREV:
+        {
+            if (copy_to_user(rq->ifr_data, &ar->arVersion,
+                             sizeof(ar->arVersion)))
+            {
+                ret = -EFAULT;
+            }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SETPWR:
+        {
+            WMI_POWER_MODE_CMD pwrModeCmd;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&pwrModeCmd, userdata,
+                                   sizeof(pwrModeCmd)))
+            {
+                ret = -EFAULT;
+            } else {
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode)
+                       != A_OK)
+                {
+                    ret = -EIO;
+                }
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS:
+        {
+            WMI_IBSS_PM_CAPS_CMD ibssPmCaps;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&ibssPmCaps, userdata,
+                                   sizeof(ibssPmCaps)))
+            {
+                ret = -EFAULT;
+            } else {
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl,
+                    ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != A_OK)
+                {
+                    ret = -EIO;
+                }
+                ar->arIbssPsEnable = ibssPmCaps.power_saving;
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_PMPARAMS:
+        {
+            WMI_POWER_PARAMS_CMD pmParams;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&pmParams, userdata,
+                                      sizeof(pmParams)))
+            {
+                ret = -EFAULT;
+            } else {
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period,
+                                     pmParams.pspoll_number,
+                                     pmParams.dtim_policy) != A_OK)
+                {
+                    ret = -EIO;
+                }
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SETSCAN:
+        {
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&scParams, userdata,
+                                      sizeof(scParams)))
+            {
+                ret = -EFAULT;
+            } else {
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                if (wmi_scanparams_cmd(ar->arWmi, scParams.fg_start_period,
+                                       scParams.fg_end_period,
+                                       scParams.bg_period,
+                                       scParams.act_chdwell_time,
+                                       scParams.pas_chdwell_time,
+                                       scParams.shortScanRatio) != A_OK)
+                {
+                    ret = -EIO;
+                }
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SETLISTENINT:
+        {
+            WMI_LISTEN_INT_CMD listenCmd;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&listenCmd, userdata,
+                                      sizeof(listenCmd)))
+            {
+                ret = -EFAULT;
+            } else {
+                    AR6000_SPIN_LOCK(&ar->arLock, 0);
+                    if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != A_OK) {
+                        ret = -EIO;
+                    } else {
+                        ar->arListenInterval = param;
+                    }
+                    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+                }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_BMISS_TIME:
+        {
+            WMI_BMISS_TIME_CMD bmissCmd;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&bmissCmd, userdata,
+                                      sizeof(bmissCmd)))
+            {
+                ret = -EFAULT;
+            } else {
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != A_OK) {
+                    ret = -EIO;
+                }
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SETBSSFILTER:
+        {
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else {
+                get_user(param, (unsigned int *)userdata);
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                if (wmi_bssfilter_cmd(ar->arWmi, param) != A_OK) {
+                    ret = -EIO;
+                }
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_LINKTHRESHOLD:
+        {
+            ret = ar6000_ioctl_set_link_threshold(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_CHANNELPARAMS:
+        {
+            ret = ar6000_ioctl_set_channelParams(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_PROBEDSSID:
+        {
+            ret = ar6000_ioctl_set_probedSsid(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_BADAP:
+        {
+            ret = ar6000_ioctl_set_badAp(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_CREATE_QOS:
+        {
+            ret = ar6000_ioctl_create_qos(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_DELETE_QOS:
+        {
+            ret = ar6000_ioctl_delete_qos(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_GET_QOS_QUEUE:
+        {
+            ret = ar6000_ioctl_get_qos_queue(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_GET_TARGET_STATS:
+        {
+            ret = ar6000_ioctl_get_target_stats(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK:
+        {
+            ret = ar6000_ioctl_set_error_report_bitmask(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_ASSOC_INFO:
+        {
+            WMI_SET_ASSOC_INFO_CMD cmd;
+            A_UINT8 assocInfo[WMI_MAX_ASSOC_INFO_LEN];
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else {
+                get_user(cmd.ieType, userdata);
+                if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) {
+                    ret = -EIO;
+                } else {
+                    get_user(cmd.bufferSize, userdata + 1);
+                    if (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) {
+                        ret = -EFAULT;
+                        break;
+                    }
+                    if (copy_from_user(assocInfo, userdata + 2,
+                                       cmd.bufferSize))
+                    {
+                        ret = -EFAULT;
+                    } else {
+                        AR6000_SPIN_LOCK(&ar->arLock, 0);
+                        if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType,
+                                                 cmd.bufferSize,
+                                                 assocInfo) != A_OK)
+                        {
+                            ret = -EIO;
+                        }
+                        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+                    }
+                }
+            }
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS:
+        {
+            ret = ar6000_ioctl_set_access_params(dev, rq);
+            break;
+        }
+        case AR6000_IOCTL_WMI_SET_DISC_TIMEOUT:
+        {
+            ret = ar6000_ioctl_set_disconnect_timeout(dev, rq);
+            break;
+        }
+#if CONFIG_HOST_DSET_SUPPORT
+        case AR6000_XIOCTL_WMI_DSET_WAIT_REQ:
+        {
+            ar6000_ioctl_wait_dset_req(dev, rq);
+            break;
+        }
+        case AR6000_XIOCTL_WMI_DSET_OPEN_REPLY:
+        {
+            AR6000_SPIN_LOCK(&ar->arLock, 0);
+            ar6000_ioctl_dset_open_reply(dev, rq);
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            break;
+        }
+        case AR6000_XIOCTL_WMI_DSET_DATA_REPLY:
+        {
+            AR6000_SPIN_LOCK(&ar->arLock, 0);
+            ar6000_ioctl_dset_data_reply(dev, rq);
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            break;
+        }
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+        case AR6000_XIOCTL_FORCE_TARGET_RESET:
+        {
+            if (htcTarget)
+            {
+//                HTCForceReset(htcTarget);
+            }
+            else
+            {
+                AR_DEBUG_PRINTF("ar6000_ioctl cannot attempt reset.\n");
+            }
+            break;
+        }
+        case AR6000_XIOCTL_CHECK_TARGET_READY:
+        {
+            /* If we made it to here, then the Target exists and is ready. */
+            break;
+        }
+#if CONFIG_HOST_GPIO_SUPPORT
+        case AR6000_XIOCTL_GPIO_OUTPUT_SET:
+        {
+            struct ar6000_gpio_output_set_cmd_s gpio_output_set_cmd;
+
+            if (ar->arWmiReady == FALSE) {
+                return -EIO;
+            }
+            if (down_interruptible(&ar->arSem)) {
+                return -ERESTARTSYS;
+            }
+
+            if (copy_from_user(&gpio_output_set_cmd, userdata,
+                                sizeof(gpio_output_set_cmd)))
+            {
+                ret = -EFAULT;
+            } else {
+                ret = ar6000_gpio_output_set(dev,
+                                             gpio_output_set_cmd.set_mask,
+                                             gpio_output_set_cmd.clear_mask,
+                                             gpio_output_set_cmd.enable_mask,
+                                             gpio_output_set_cmd.disable_mask);
+                if (ret != A_OK) {
+                    ret = EIO;
+                }
+            }
+            up(&ar->arSem);
+            break;
+        }
+        case AR6000_XIOCTL_GPIO_INPUT_GET:
+        {
+            if (ar->arWmiReady == FALSE) {
+                return -EIO;
+            }
+            if (down_interruptible(&ar->arSem)) {
+                return -ERESTARTSYS;
+            }
+
+            ret = ar6000_gpio_input_get(dev);
+            if (ret != A_OK) {
+                up(&ar->arSem);
+                return -EIO;
+            }
+
+            /* Wait for Target to respond. */
+            wait_event_interruptible(arEvent, gpio_data_available);
+            if (signal_pending(current)) {
+                ret = -EINTR;
+            } else {
+                A_ASSERT(gpio_reg_results.gpioreg_id == GPIO_ID_NONE);
+
+                if (copy_to_user(userdata, &gpio_reg_results.value,
+                                 sizeof(gpio_reg_results.value)))
+                {
+                    ret = -EFAULT;
+                }
+            }
+            up(&ar->arSem);
+            break;
+        }
+        case AR6000_XIOCTL_GPIO_REGISTER_SET:
+        {
+            struct ar6000_gpio_register_cmd_s gpio_register_cmd;
+
+            if (ar->arWmiReady == FALSE) {
+                return -EIO;
+            }
+            if (down_interruptible(&ar->arSem)) {
+                return -ERESTARTSYS;
+            }
+
+            if (copy_from_user(&gpio_register_cmd, userdata,
+                                sizeof(gpio_register_cmd)))
+            {
+                ret = -EFAULT;
+            } else {
+                ret = ar6000_gpio_register_set(dev,
+                                               gpio_register_cmd.gpioreg_id,
+                                               gpio_register_cmd.value);
+                if (ret != A_OK) {
+                    ret = EIO;
+                }
+
+                /* Wait for acknowledgement from Target */
+                wait_event_interruptible(arEvent, gpio_ack_received);
+                if (signal_pending(current)) {
+                    ret = -EINTR;
+                }
+            }
+            up(&ar->arSem);
+            break;
+        }
+        case AR6000_XIOCTL_GPIO_REGISTER_GET:
+        {
+            struct ar6000_gpio_register_cmd_s gpio_register_cmd;
+
+            if (ar->arWmiReady == FALSE) {
+                return -EIO;
+            }
+            if (down_interruptible(&ar->arSem)) {
+                return -ERESTARTSYS;
+            }
+
+            if (copy_from_user(&gpio_register_cmd, userdata,
+                                sizeof(gpio_register_cmd)))
+            {
+                ret = -EFAULT;
+            } else {
+                ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id);
+                if (ret != A_OK) {
+                    up(&ar->arSem);
+                    return -EIO;
+                }
+
+                /* Wait for Target to respond. */
+                wait_event_interruptible(arEvent, gpio_data_available);
+                if (signal_pending(current)) {
+                    ret = -EINTR;
+                } else {
+                    A_ASSERT(gpio_register_cmd.gpioreg_id == gpio_reg_results.gpioreg_id);
+                    if (copy_to_user(userdata, &gpio_reg_results,
+                                     sizeof(gpio_reg_results)))
+                    {
+                        ret = -EFAULT;
+                    }
+                }
+            }
+            up(&ar->arSem);
+            break;
+        }
+        case AR6000_XIOCTL_GPIO_INTR_ACK:
+        {
+            struct ar6000_gpio_intr_ack_cmd_s gpio_intr_ack_cmd;
+
+            if (ar->arWmiReady == FALSE) {
+                return -EIO;
+            }
+            if (down_interruptible(&ar->arSem)) {
+                return -ERESTARTSYS;
+            }
+
+            if (copy_from_user(&gpio_intr_ack_cmd, userdata,
+                                sizeof(gpio_intr_ack_cmd)))
+            {
+                ret = -EFAULT;
+            } else {
+                ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask);
+                if (ret != A_OK) {
+                    ret = EIO;
+                }
+            }
+            up(&ar->arSem);
+            break;
+        }
+        case AR6000_XIOCTL_GPIO_INTR_WAIT:
+        {
+            /* Wait for Target to report an interrupt. */
+            dev_hold(dev);
+            rtnl_unlock();
+            wait_event_interruptible(arEvent, gpio_intr_available);
+            rtnl_lock();
+            dev_put(dev);
+
+            if (signal_pending(current)) {
+                ret = -EINTR;
+            } else {
+                if (copy_to_user(userdata, &gpio_intr_results,
+                                 sizeof(gpio_intr_results)))
+                {
+                    ret = -EFAULT;
+                }
+            }
+            break;
+        }
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+        case AR6000_XIOCTL_SET_ADHOC_BSSID:
+        {
+            WMI_SET_ADHOC_BSSID_CMD adhocBssid;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&adhocBssid, userdata,
+                                      sizeof(adhocBssid)))
+            {
+                ret = -EFAULT;
+            } else if (A_MEMCMP(adhocBssid.bssid, bcast_mac,
+                                AR6000_ETH_ADDR_LEN) == 0)
+            {
+                ret = -EFAULT;
+            } else {
+
+                A_MEMCPY(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid));
+        }
+            break;
+        }
+
+        case AR6000_XIOCTL_SET_OPT_MODE:
+        {
+        WMI_SET_OPT_MODE_CMD optModeCmd;
+            AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&optModeCmd, userdata,
+                                      sizeof(optModeCmd)))
+            {
+                ret = -EFAULT;
+            } else if (ar->arConnected && optModeCmd.optMode == SPECIAL_ON) {
+                ret = -EFAULT;
+
+            } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode)
+                       != A_OK)
+            {
+                ret = -EIO;
+            }
+            break;
+        }
+
+        case AR6000_XIOCTL_OPT_SEND_FRAME:
+        {
+        WMI_OPT_TX_FRAME_CMD optTxFrmCmd;
+            A_UINT8 data[MAX_OPT_DATA_LEN];
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&optTxFrmCmd, userdata,
+                                      sizeof(optTxFrmCmd)))
+            {
+                ret = -EFAULT;
+            } else if (copy_from_user(data,
+                                      optTxFrmCmd.optIEData,
+                                      optTxFrmCmd.optIEDataLen))
+            {
+                ret = -EFAULT;
+            } else {
+                ret = wmi_opt_tx_frame_cmd(ar->arWmi,
+                                           optTxFrmCmd.frmType,
+                                           optTxFrmCmd.dstAddr,
+                                           optTxFrmCmd.bssid,
+                                           optTxFrmCmd.optIEDataLen,
+                                           data);
+            }
+
+            break;
+        }
+
+        case AR6000_XIOCTL_SET_ADHOC_BEACON_INTVAL:
+        {
+            WMI_BEACON_INT_CMD bIntvlCmd;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&bIntvlCmd, userdata,
+                       sizeof(bIntvlCmd)))
+            {
+                ret = -EFAULT;
+            } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconInterval)
+                        != A_OK)
+            {
+                ret = -EIO;
+            }
+            break;
+        }
+        case IEEE80211_IOCTL_SETAUTHALG:
+        {
+            AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+            struct ieee80211req_authalg req;
+
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+            } else if (copy_from_user(&req, userdata,
+                       sizeof(struct ieee80211req_authalg)))
+            {
+                ret = -EFAULT;
+            } else if (req.auth_alg == AUTH_ALG_OPEN_SYSTEM) {
+                ar->arDot11AuthMode  = OPEN_AUTH;
+                ar->arPairwiseCrypto  = NONE_CRYPT;
+                ar->arGroupCrypto     = NONE_CRYPT;
+            } else if (req.auth_alg == AUTH_ALG_LEAP) {
+                ar->arDot11AuthMode   = LEAP_AUTH;
+            } else {
+                ret = -EIO;
+            }
+            break;
+        }
+
+        case AR6000_XIOCTL_SET_VOICE_PKT_SIZE:
+            ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata);
+            break;
+
+        case AR6000_XIOCTL_SET_MAX_SP:
+            ret = ar6000_xioctl_set_max_sp_len(dev, userdata);
+            break;
+
+        case AR6000_XIOCTL_WMI_GET_ROAM_TBL:
+            ret = ar6000_ioctl_get_roam_tbl(dev, rq);
+            break;
+        case AR6000_XIOCTL_WMI_SET_ROAM_CTRL:
+            ret = ar6000_ioctl_set_roam_ctrl(dev, userdata);
+            break;
+        case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS:
+            ret = ar6000_ioctl_set_powersave_timers(dev, userdata);
+            break;
+        case AR6000_XIOCTRL_WMI_GET_POWER_MODE:
+            ret = ar6000_ioctl_get_power_mode(dev, rq);
+            break;
+        case AR6000_XIOCTRL_WMI_SET_WLAN_STATE:
+            get_user(ar->arWlanState, (unsigned int *)userdata);
+            if (ar->arWmiReady == FALSE) {
+                ret = -EIO;
+                break;
+            }
+
+            if (ar->arWlanState == WLAN_ENABLED) {
+                /* Enable foreground scanning */
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                if (wmi_scanparams_cmd(ar->arWmi, scParams.fg_start_period,
+                                       scParams.fg_end_period,
+                                       scParams.bg_period,
+                                       scParams.act_chdwell_time,
+                                       scParams.pas_chdwell_time,
+                                       scParams.shortScanRatio) != A_OK)
+                {
+                    ret = -EIO;
+                }
+                if (ar->arSsidLen) {
+                    if (wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
+                                        ar->arDot11AuthMode, ar->arAuthMode,
+                                        ar->arPairwiseCrypto,
+                                        ar->arPairwiseCryptoLen,
+                                        ar->arGroupCrypto, ar->arGroupCryptoLen,
+                                        ar->arSsidLen, ar->arSsid,
+                                        ar->arReqBssid, ar->arChannelHint) != A_OK)
+                    {
+                        ret = -EIO;
+                    }
+                    else
+                    {
+                        ar->arConnectPending = TRUE;
+                    }
+                }
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            } else {
+                /* Disconnect from the AP and disable foreground scanning */
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) {
+                    wmi_disconnect_cmd(ar->arWmi);
+                }
+                if (wmi_scanparams_cmd(ar->arWmi, 65535, 0, 0, 0, 0, 0) != A_OK)
+                {
+                    ret = -EIO;
+                }
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            }
+            break;
+        case AR6000_XIOCTL_WMI_GET_ROAM_DATA:
+            ret = ar6000_ioctl_get_roam_data(dev, rq);
+            break;
+        default:
+            ret = -EOPNOTSUPP;
+    }
+    return ret;
+}
+
+void
+ar6000_bitrate_rx(void *devt, A_INT32 rateKbps)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+    ar->arBitRate = rateKbps;
+    wake_up(&arEvent);
+}
+
+void
+ar6000_txPwr_rx(void *devt, A_UINT8 txPwr)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+    ar->arTxPwr = txPwr;
+    wake_up(&arEvent);
+}
+
+static int
+ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_CHANNEL_PARAMS_CMD cmd, *cmdp;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    if (cmd.numChannels > 1) {
+        cmdp = A_MALLOC(128);
+        if (copy_from_user(cmdp, rq->ifr_data,
+                           sizeof (*cmdp) +
+                           ((cmd.numChannels - 1) * sizeof(A_UINT16))))
+        {
+            kfree(cmdp);
+            return -EFAULT;
+        }
+    } else {
+        cmdp = &cmd;
+    }
+
+    if ((ar->arPhyCapability == WMI_11G_CAPABILITY) &&
+        ((cmdp->phyMode == WMI_11A_MODE) || (cmdp->phyMode == WMI_11AG_MODE)))
+    {
+        ret = -EINVAL;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (!ret &&
+        (wmi_set_channelParams_cmd(ar->arWmi, cmdp->phyMode, cmdp->numChannels,
+                                  cmdp->channelList) != A_OK))
+    {
+        ret = -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    if (cmd.numChannels > 1) {
+        kfree(cmdp);
+    }
+
+    return ret;
+}
+
+static int
+ar6000_ioctl_set_link_threshold(struct net_device *dev, struct ifreq *rq)
+{
+
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if( wmi_set_link_threshold_params(ar->arWmi,
+                            cmd.highThreshold_upperVal,
+                            cmd.highThreshold_lowerVal,
+                            cmd.lowThreshold_upperVal,
+                            cmd.lowThreshold_lowerVal,
+                            cmd.pollTime) != A_OK ) {
+        ret = -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return ret;
+}
+
+void
+ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+    A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (A_UINT16));
+    ar->arNumChannels = numChan;
+
+    wake_up(&arEvent);
+}
+
+static int
+ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_PROBED_SSID_CMD cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength,
+                                  cmd.ssid) != A_OK)
+    {
+        ret = -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return ret;
+}
+
+static int
+ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_ADD_BAD_AP_CMD cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    if (cmd.badApIndex > WMI_MAX_BAD_AP_INDEX) {
+        return -EIO;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (A_MEMCMP(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) {
+        /*
+         * This is a delete badAP.
+         */
+        if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != A_OK) {
+            ret = -EIO;
+        }
+    } else {
+        if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != A_OK) {
+            ret = -EIO;
+        }
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return ret;
+}
+
+static int
+ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_CREATE_PSTREAM_CMD cmd;
+    A_STATUS ret;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    cmd.rxQueueNum = 0xFF;
+    ret = wmi_verify_tspec_params(&cmd, tspecCompliance);
+    if (ret == A_OK)
+        ret = wmi_create_pstream_cmd(ar->arWmi, &cmd);
+
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+    switch (ret) {
+        case A_OK:
+            return 0;
+        case A_EBUSY :
+            return -EBUSY;
+        case A_NO_MEMORY:
+            return -ENOMEM;
+        case A_EINVAL:
+        default:
+            return -EFAULT;
+    }
+}
+
+static int
+ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_DELETE_PSTREAM_CMD cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.txQueueNumber,
+                                 cmd.rxQueueNumber, cmd.trafficDirection);
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+    switch (ret) {
+        case A_OK:
+            return 0;
+        case A_EBUSY :
+            return -EBUSY;
+        case A_NO_MEMORY:
+            return -ENOMEM;
+        case A_EINVAL:
+        default:
+            return -EFAULT;
+    }
+}
+
+static int
+ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    struct ar6000_queuereq qreq;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    copy_from_user(&qreq, rq->ifr_data,
+                  sizeof(struct ar6000_queuereq));
+
+    qreq.queueNumber = wmi_get_mapped_qos_queue(ar->arWmi,
+                               qreq.trafficDirection,
+                               qreq.trafficClass);
+
+    if (copy_to_user(rq->ifr_data, &qreq,
+                 sizeof(struct ar6000_queuereq)))
+    {
+        ret = -EFAULT;
+    }
+    return ret;
+}
+
+#ifdef HTC_RAW_INTERFACE
+#define RAW_HTC_READ_BUFFERS_NUM                     16
+#define RAW_HTC_WRITE_BUFFERS_NUM                    16
+typedef struct {
+    int currPtr;
+    int length;
+    unsigned char data[AR6000_BUFFER_SIZE];
+} raw_htc_buffer;
+
+static struct semaphore raw_htc_read_sem[HTC_MAILBOX_NUM_MAX];
+static struct semaphore raw_htc_write_sem[HTC_MAILBOX_NUM_MAX];
+static wait_queue_head_t raw_htc_read_queue[HTC_MAILBOX_NUM_MAX];
+static wait_queue_head_t raw_htc_write_queue[HTC_MAILBOX_NUM_MAX];
+static raw_htc_buffer raw_htc_read_buffer[HTC_MAILBOX_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM];
+static raw_htc_buffer raw_htc_write_buffer[HTC_MAILBOX_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM];
+static A_BOOL write_buffer_available[HTC_MAILBOX_NUM_MAX];
+static A_BOOL read_buffer_available[HTC_MAILBOX_NUM_MAX];
+
+static void
+ar6000_htc_raw_read_cb(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId,
+                       HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg)
+{
+    HTC_TARGET *target;
+    raw_htc_buffer *busy;
+
+    target = (HTC_TARGET *)arg;
+    A_ASSERT(target != NULL);
+    busy = (raw_htc_buffer *)evInfo->cookie;
+    A_ASSERT(busy != NULL);
+
+    if (evInfo->status == A_ECANCELED) {
+        /*
+         * HTC provides A_ECANCELED status when it doesn't want to be refilled
+         * (probably due to a shutdown)
+         */
+        memset(busy, 0, sizeof(raw_htc_buffer));
+        return;
+    }
+
+#ifdef CF
+   if (down_trylock(&raw_htc_read_sem[endPointId])) {
+#else
+    if (down_interruptible(&raw_htc_read_sem[endPointId])) {
+#endif /* CF */
+        AR_DEBUG2_PRINTF("Unable to down the semaphore\n");
+    }
+
+    A_ASSERT(evId == HTC_BUFFER_RECEIVED);
+    A_ASSERT((evInfo->status != A_OK) ||
+             (evInfo->buffer == (busy->data + HTC_HEADER_LEN)));
+
+    busy->length = evInfo->actualLength + HTC_HEADER_LEN;
+    busy->currPtr = HTC_HEADER_LEN;
+    read_buffer_available[endPointId] = TRUE;
+    up(&raw_htc_read_sem[endPointId]);
+
+    /* Signal the waiting process */
+    AR_DEBUG2_PRINTF("Waking up the endpoint(%d) read process\n", endPointId);
+    wake_up_interruptible(&raw_htc_read_queue[endPointId]);
+}
+
+static void
+ar6000_htc_raw_write_cb(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId,
+                        HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg)
+{
+    HTC_TARGET *target;
+    raw_htc_buffer *free;
+
+    target = (HTC_TARGET *)arg;
+    A_ASSERT(target != NULL);
+    free = (raw_htc_buffer *)evInfo->cookie;
+    A_ASSERT(free != NULL);
+
+    if (evInfo->status == A_ECANCELED) {
+        /*
+         * HTC provides A_ECANCELED status when it doesn't want to be refilled
+         * (probably due to a shutdown)
+         */
+        memset(free, 0, sizeof(raw_htc_buffer));
+        return;
+    }
+
+#ifdef CF
+    if (down_trylock(&raw_htc_write_sem[endPointId])) {
+#else
+    if (down_interruptible(&raw_htc_write_sem[endPointId])) {
+#endif /* CF */
+        AR_DEBUG2_PRINTF("Unable to down the semaphore\n");
+    }
+
+    A_ASSERT(evId == HTC_BUFFER_SENT);
+    A_ASSERT(evInfo->buffer == (free->data + HTC_HEADER_LEN));
+
+    free->length = 0;
+    write_buffer_available[endPointId] = TRUE;
+    up(&raw_htc_write_sem[endPointId]);
+
+    /* Signal the waiting process */
+    AR_DEBUG2_PRINTF("Waking up the endpoint(%d) write process\n", endPointId);
+    wake_up_interruptible(&raw_htc_write_queue[endPointId]);
+}
+
+static void
+ar6000_htc_raw_unread_cb(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                         HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg)
+{
+    HTC_TARGET *target;
+
+    target = (HTC_TARGET *)arg;
+    A_ASSERT(target != NULL);
+
+    AR_DEBUG_PRINTF("Not implemented\n");
+}
+
+static int
+ar6000_htc_raw_open(HTC_TARGET *htcTarget)
+{
+    A_STATUS status;
+    int count1, count2;
+    raw_htc_buffer *buffer;
+
+    for (count1 = 0; count1 < HTC_MAILBOX_NUM_MAX; count1 ++) {
+        /* Initialize the data structures */
+        init_MUTEX(&raw_htc_read_sem[count1]);
+        init_MUTEX(&raw_htc_write_sem[count1]);
+        init_waitqueue_head(&raw_htc_read_queue[count1]);
+        init_waitqueue_head(&raw_htc_write_queue[count1]);
+
+        /* Register the event handlers */
+        if ((status = HTCEventReg(htcTarget, count1, HTC_BUFFER_RECEIVED,
+                                  ar6000_htc_raw_read_cb, htcTarget)) != A_OK)
+        {
+            BMIInit();
+            return -EIO;
+        }
+        if ((status = HTCEventReg(htcTarget, count1, HTC_DATA_AVAILABLE,
+                                  ar6000_htc_raw_unread_cb, htcTarget)) != A_OK)
+        {
+            BMIInit();
+            return -EIO;
+        }
+        if ((status = HTCEventReg(htcTarget, count1, HTC_BUFFER_SENT,
+                                  ar6000_htc_raw_write_cb, htcTarget)) != A_OK)
+        {
+            BMIInit();
+            return -EIO;
+        }
+
+        for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
+            /* Initialize the receive buffers */
+            buffer = &raw_htc_write_buffer[count1][count2];
+            memset(buffer, 0, sizeof(raw_htc_buffer));
+            buffer = &raw_htc_read_buffer[count1][count2];
+            memset(buffer, 0, sizeof(raw_htc_buffer));
+
+            /* Queue buffers to HTC for receive */
+            if ((status = HTCBufferReceive(htcTarget, count1, buffer->data,
+                                           AR6000_BUFFER_SIZE, buffer)) != A_OK)
+            {
+                BMIInit();
+                return -EIO;
+            }
+        }
+
+        for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
+            /* Initialize the receive buffers */
+            buffer = &raw_htc_write_buffer[count1][count2];
+            memset(buffer, 0, sizeof(raw_htc_buffer));
+        }
+
+        read_buffer_available[count1] = FALSE;
+        write_buffer_available[count1] = TRUE;
+    }
+
+    /* Start the HTC component */
+    if ((status = HTCStart(htcTarget)) != A_OK) {
+        BMIInit();
+        return -EIO;
+    }
+
+    return 0;
+}
+
+static int
+ar6000_htc_raw_close(HTC_TARGET *htcTarget)
+{
+    int count;
+    A_STATUS status;
+
+    /* Stop the HTC */
+    HTCStop(htcTarget);
+
+    /* Unregister the event handlers */
+    for (count = 0; count < HTC_MAILBOX_NUM_MAX; count ++) {
+        status = HTCEventReg(htcTarget, count, HTC_BUFFER_RECEIVED,
+                             NULL, htcTarget);
+
+        status = HTCEventReg(htcTarget, count, HTC_DATA_AVAILABLE,
+                             NULL, htcTarget);
+
+        status = HTCEventReg(htcTarget, count, HTC_BUFFER_SENT,
+                             NULL, htcTarget);
+    }
+
+    /* Initialize the BMI component */
+    BMIInit();
+
+    return 0;
+}
+
+raw_htc_buffer *
+get_filled_buffer(HTC_ENDPOINT_ID endPointId)
+{
+    int count;
+    raw_htc_buffer *busy;
+
+    /* Check for data */
+    for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
+        busy = &raw_htc_read_buffer[endPointId][count];
+        if (busy->length) {
+            break;
+        }
+    }
+    if (busy->length) {
+        read_buffer_available[endPointId] = TRUE;
+    } else {
+        read_buffer_available[endPointId] = FALSE;
+    }
+
+    return busy;
+}
+
+static ssize_t
+ar6000_htc_raw_read(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId,
+                    char __user *buffer, size_t length)
+{
+    int readPtr;
+    raw_htc_buffer *busy;
+
+    if (down_interruptible(&raw_htc_read_sem[endPointId])) {
+        return -ERESTARTSYS;
+    }
+
+    busy = get_filled_buffer(endPointId);
+    while (!read_buffer_available[endPointId]) {
+        up(&raw_htc_read_sem[endPointId]);
+
+        /* Wait for the data */
+        AR_DEBUG2_PRINTF("Sleeping endpoint(%d) read process\n", endPointId);
+        if (wait_event_interruptible(raw_htc_read_queue[endPointId],
+                                     read_buffer_available[endPointId]))
+        {
+            return -EINTR;
+        }
+        if (down_interruptible(&raw_htc_read_sem[endPointId])) {
+            return -ERESTARTSYS;
+        }
+        busy = get_filled_buffer(endPointId);
+    }
+
+    /* Read the data */
+    readPtr = busy->currPtr;
+    if (length > busy->length - HTC_HEADER_LEN) {
+        length = busy->length - HTC_HEADER_LEN;
+    }
+    if (copy_to_user(buffer, &busy->data[readPtr], length)) {
+        up(&raw_htc_read_sem[endPointId]);
+        return -EFAULT;
+    }
+
+    busy->currPtr += length;
+    if (busy->currPtr == busy->length)
+    {
+        /* Packet has been completely read. Queue it with HTC */
+        memset(busy, 0, sizeof(raw_htc_buffer));
+        HTCBufferReceive(htcTarget, endPointId, busy->data,
+                         AR6000_BUFFER_SIZE, busy);
+    }
+    read_buffer_available[endPointId] = FALSE;
+    up(&raw_htc_read_sem[endPointId]);
+
+    return length;
+}
+
+raw_htc_buffer *
+get_free_buffer(HTC_ENDPOINT_ID endPointId)
+{
+    int count;
+    raw_htc_buffer *free;
+
+    free = NULL;
+    for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
+        free = &raw_htc_write_buffer[endPointId][count];
+        if (free->length == 0) {
+            break;
+        }
+    }
+    if (!free->length) {
+        write_buffer_available[endPointId] = TRUE;
+    } else {
+        write_buffer_available[endPointId] = FALSE;
+    }
+
+    return free;
+}
+
+static ssize_t
+ar6000_htc_raw_write(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId,
+                     char __user *buffer, size_t length)
+{
+    int writePtr;
+    raw_htc_buffer *free;
+
+    if (down_interruptible(&raw_htc_write_sem[endPointId])) {
+        return -ERESTARTSYS;
+    }
+
+    /* Search for a free buffer */
+    free = get_free_buffer(endPointId);
+
+    /* Check if there is space to write else wait */
+    while (!write_buffer_available[endPointId]) {
+        up(&raw_htc_write_sem[endPointId]);
+
+        /* Wait for buffer to become free */
+        AR_DEBUG2_PRINTF("Sleeping endpoint(%d) write process\n", endPointId);
+        if (wait_event_interruptible(raw_htc_write_queue[endPointId],
+                                     write_buffer_available[endPointId]))
+        {
+            return -EINTR;
+        }
+        if (down_interruptible(&raw_htc_write_sem[endPointId])) {
+            return -ERESTARTSYS;
+        }
+        free = get_free_buffer(endPointId);
+    }
+
+    /* Send the data */
+    writePtr = HTC_HEADER_LEN;
+    if (length > (AR6000_BUFFER_SIZE - HTC_HEADER_LEN)) {
+        length = AR6000_BUFFER_SIZE - HTC_HEADER_LEN;
+    }
+
+    if (copy_from_user(&free->data[writePtr], buffer, length)) {
+        up(&raw_htc_read_sem[endPointId]);
+        return -EFAULT;
+    }
+
+    free->length = length;
+    HTCBufferSend(htcTarget, endPointId, &free->data[writePtr], length, free);
+    write_buffer_available[endPointId] = FALSE;
+    up(&raw_htc_write_sem[endPointId]);
+
+    return length;
+}
+#endif /* HTC_RAW_INTERFACE */
+
+/*
+ * As soon as the DataSet Server application waits for a request,
+ * we know that the server is operational, and we try to process
+ * requests.  If the Target sends any requests before the server
+ * has started, we reject the request.  The model we use is that
+ * once started, the server must continue to service requests as
+ * long as they may arrive, and the server ought to be started
+ * before WMI is started (before the network interface is brought
+ * up.
+ */
+static A_BOOL dset_server_alive;
+
+#if CONFIG_HOST_DSET_SUPPORT
+/*
+ * For now, we allow for just one outstanding (unhandled) request
+ * at a time.  The current Target doesn't need any more than that.
+ * If we ever need to handle many simultaneous requests, this
+ * pending_dset_request and pending_dset_request_valid mechanism
+ * can get more complicated.  The use of dset_request_lock is
+ * also very simple; it assumes that a single well-behaved thread
+ * serves all requests.
+ */
+static A_BOOL pending_dset_request_valid;
+static dset_request_t pending_dset_request;
+
+static spinlock_t dset_request_lock;
+static DECLARE_WAIT_QUEUE_HEAD(dset_request);
+
+static int
+ar6000_ioctl_wait_dset_req(struct net_device *dev, struct ifreq *rq)
+{
+    int ret = 0;
+
+    dset_server_alive = TRUE;
+
+    /* Wait for a DataSet Request to arrive. */
+    dev_hold(dev);
+    rtnl_unlock();
+    wait_event_interruptible(dset_request, pending_dset_request_valid);
+    rtnl_lock();
+    dev_put(dev);
+
+    if (signal_pending(current)) {
+        ret = -EINTR;
+    } else {
+        if (copy_to_user(rq->ifr_data,
+                         &pending_dset_request,
+                         sizeof(pending_dset_request))) {
+            ret = -EFAULT;
+        }
+
+        /* pending_dset_request is now available for use */
+        pending_dset_request_valid = FALSE;
+        spin_unlock(&dset_request_lock);
+    }
+
+    return ret;
+}
+
+static int
+ar6000_ioctl_dset_open_reply(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    int ret = 0;
+    dset_open_reply_t dset_reply;
+
+    if (copy_from_user(&dset_reply, rq->ifr_data, sizeof(dset_reply))) {
+        ret = -EFAULT;
+    } else {
+        A_ASSERT(dset_reply.cmd == AR6000_XIOCTL_WMI_DSET_OPEN_REPLY);
+        ret = wmi_dset_open_reply(ar->arWmi,
+                                  dset_reply.status,
+                                  dset_reply.access_cookie,
+                                  dset_reply.size,
+                                  dset_reply.version,
+                                  dset_reply.targ_handle,
+                                  dset_reply.targ_reply_fn,
+                                  dset_reply.targ_reply_arg);
+
+        if (ret == A_NO_MEMORY) {
+            ret = -ENOMEM;
+        } else if (ret == A_ERROR) {
+            ret = -EFAULT;
+        }
+    }
+
+    return ret;
+}
+
+static int
+ar6000_ioctl_dset_data_reply(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    int ret = 0;
+    dset_data_reply_t dset_reply;
+
+    if (copy_from_user(&dset_reply, rq->ifr_data, sizeof(dset_reply))) {
+        ret = -EFAULT;
+    } else {
+        A_ASSERT(dset_reply.cmd == AR6000_XIOCTL_WMI_DSET_DATA_REPLY);
+        ret = wmi_dset_data_reply(ar->arWmi,
+                                  dset_reply.status,
+                                  dset_reply.buf,
+                                  dset_reply.length,
+                                  dset_reply.targ_buf,
+                                  dset_reply.targ_reply_fn,
+                                  dset_reply.targ_reply_arg);
+
+        if (ret == A_NO_MEMORY) {
+            ret = -ENOMEM;
+        } else if (ret == A_ERROR) {
+            ret = -EFAULT;
+        }
+    }
+
+    return ret;
+}
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+A_UINT8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, A_UINT32 * mapNo)
+{
+    AR_SOFTC_T      *ar = (AR_SOFTC_T *)dev->priv;
+    A_UINT8         *datap;
+    ATH_MAC_HDR     *macHdr;
+    A_UINT32         i, emptMap;
+
+    (*mapNo) = 0;
+    datap = a_netbuf_to_data(skb);
+    macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR));
+    if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) {
+        return ENDPOINT3;
+    }
+
+    emptMap = -1;
+    for (i = 0; i < ar->arNodeNum; i ++) {
+        if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) {
+            (*mapNo) = i + 1;
+            ar->arNodeMap[i].txPending ++;
+            return ar->arNodeMap[i].epId;
+        }
+
+        if ((emptMap == -1) && !ar->arNodeMap[i].txPending) {
+            emptMap = i;
+        }
+    }
+
+    if (emptMap == -1) {
+        emptMap = ar->arNodeNum;
+        ar->arNodeNum ++;
+        A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM);
+    }
+
+    A_MEMCPY(ar->arNodeMap[emptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN);
+
+    for (i = ENDPOINT2; i <= ENDPOINT4; i ++) {
+        if (!ar->arTxPending[i]) {
+            ar->arNodeMap[emptMap].epId = i;
+            break;
+        }
+    }
+
+    if (i > ENDPOINT4) {
+        ar->arNodeMap[emptMap].epId = ar->arNexEpId;
+        ar->arNexEpId ++;
+        if (ar->arNexEpId > ENDPOINT4) {
+            ar->arNexEpId = ENDPOINT2;
+        }
+    }
+
+    (*mapNo) = emptMap + 1;
+    ar->arNodeMap[emptMap].txPending ++;
+
+    return ar->arNodeMap[ar->arNodeNum - 1].epId;
+}
+
+static int
+ar6000_data_tx(struct sk_buff *skb, struct net_device *dev)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    HTC_ENDPOINT_ID endPointId;
+    A_UINT32        mapNo = 0;
+    struct iphdr    *ipHdr;
+    struct sk_buff  *newbuf;
+    int len;
+    struct ar_cookie *cookie;
+
+    if (ar->arWmiReady == FALSE && bypasswmi == 0) {
+        a_netbuf_free(skb);
+        return 0;
+    }
+
+#ifdef BLOCK_TX_PATH_FLAG
+    if (blocktx) {
+        a_netbuf_free(skb);
+        return 0;
+    }
+#endif /* BLOCK_TX_PATH_FLAG */
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    /* If all data queues are full, notify upper layer to stop. */
+    if (ar->arTotalTxDataPending >= (txFlowCtrlThresh[ar->arNumDataEndPts])) {
+        netif_stop_queue(ar->arNetDev);
+    }
+
+    AR_DEBUG2_PRINTF("ar6000_data_tx start - skb=0x%x, data=0x%x, len=0x%x\n",
+                     (A_UINT32)skb, (A_UINT32)a_netbuf_to_data(skb),
+                     a_netbuf_to_len(skb));
+
+    if (ar->arWmiEnabled == TRUE) {
+        if (a_netbuf_headroom(skb) < dev->hard_header_len) {
+            /*
+             * We really should have gotten enough headroom but sometimes
+             * we still get packets with not enough headroom.  Copy the packet.
+             */
+            len = a_netbuf_to_len(skb);
+            newbuf = a_netbuf_alloc(len);
+            if (newbuf == NULL) {
+                a_netbuf_free(skb);
+                AR6000_STAT_INC(ar, tx_dropped);
+                AR6000_STAT_INC(ar, tx_aborted_errors);
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+                return A_NO_MEMORY;
+            }
+            a_netbuf_put(newbuf, len);
+            A_MEMCPY(a_netbuf_to_data(newbuf), a_netbuf_to_data(skb), len);
+            a_netbuf_free(skb);
+            skb = newbuf;
+        }
+        if (wmi_dix_2_dot3(ar->arWmi, skb) != A_OK) {
+            AR_DEBUG_PRINTF("ar6000_data_tx - wmi_dix_2_dot3 failed\n");
+            AR6000_STAT_INC(ar, tx_dropped);
+            AR6000_STAT_INC(ar, tx_aborted_errors);
+            a_netbuf_free(skb);
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            return 0;
+        }
+
+        if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE) != A_OK) {
+            AR_DEBUG_PRINTF("ar6000_data_tx - wmi_data_hdr_add failed\n");
+            AR6000_STAT_INC(ar, tx_dropped);
+            AR6000_STAT_INC(ar, tx_aborted_errors);
+            a_netbuf_free(skb);
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            return 0;
+        }
+
+        if ((ar->arNetworkType == ADHOC_NETWORK) &&
+            ar->arIbssPsEnable && ar->arConnected)
+        {
+            endPointId = ar6000_ibss_map_epid(skb, dev, &mapNo);
+        } else {
+            /* Extract the end point information */
+            endPointId = wmi_get_endpoint(ar->arWmi,
+                              wmi_implicit_create_pstream(ar->arWmi, skb, UPLINK_TRAFFIC));
+        }
+    } else {
+        /*
+         * the endpoint is directly based on the TOS field in the IP
+         * header
+         */
+        ipHdr = a_netbuf_to_data(skb) + sizeof(ATH_MAC_HDR);
+        endPointId = ((ipHdr->tos >> 1) & 0x03);
+    }
+
+    AR_DEBUG2_PRINTF("ar6000_data_tx - ep=%d skb=0x%x, data=0x%x, len=0x%x\n",
+                    endPointId, (A_UINT32)skb, (A_UINT32)a_netbuf_to_data(skb),
+                    a_netbuf_to_len(skb));
+
+#ifdef DEBUG
+    if (debugdriver >= 3) {
+        u_char *ch;
+
+       for (ch = a_netbuf_to_data(skb);
+            (A_UINT32)ch < ((A_UINT32)a_netbuf_to_data(skb) +
+            a_netbuf_to_len(skb)); ch++)
+        {
+             AR_DEBUG_PRINTF("%2.2x ", *ch);
+        }
+        AR_DEBUG_PRINTF("\n");
+    }
+#endif /* DEBUG */
+    ar->arTxPending[endPointId]++;
+    ar->arTotalTxDataPending++;
+
+    /* If the particular data queue is full, silently drop the pkt. */
+    if (ar->arTxPending[endPointId] > MAX_ALLOWED_TXQ_DEPTH) {
+        ar->arTxPending[endPointId]--;
+        ar->arTotalTxDataPending--;
+        a_netbuf_free(skb);
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        return 0;
+    }
+
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    cookie = ar6000_alloc_cookie(ar);
+    if (cookie == NULL) {
+        AR6000_SPIN_LOCK(&ar->arLock, 0);
+        ar->arTxPending[endPointId]--;
+        ar->arTotalTxDataPending--;
+        a_netbuf_free(skb);
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        return 0;
+    }
+
+    cookie->arc_bp[0] = (A_UINT32)skb;
+    cookie->arc_bp[1] = mapNo;
+
+    if (HTCBufferSend(ar->arHtcTarget, endPointId, a_netbuf_to_data(skb),
+                      a_netbuf_to_len(skb), cookie) != A_OK)
+    {
+        AR6000_SPIN_LOCK(&ar->arLock, 0);
+        ar->arTxPending[endPointId]--;
+        ar->arTotalTxDataPending--;
+        AR_DEBUG_PRINTF("Dropping the frame\n");
+        ar6000_free_cookie(ar, cookie);
+        a_netbuf_free(skb);
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+    }
+
+    return 0;
+}
+
+static void
+ar6000_tx_complete(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                      HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg)
+{
+    AR_SOFTC_T     *ar = (AR_SOFTC_T *)arg;
+    void           *cookie = (void *)evInfo->cookie;
+    struct sk_buff *skb = NULL;
+    A_UINT32        mapNo = 0;
+
+    if (ar->arWmiReady == TRUE || bypasswmi != 0)
+    {
+        struct ar_cookie * ar_cookie = (struct ar_cookie *)cookie;
+        skb = (struct sk_buff *)ar_cookie->arc_bp[0];
+        mapNo = ar_cookie->arc_bp[1];
+    } else {
+        skb = (struct sk_buff *)cookie;
+        AR_DEBUG_PRINTF("%s() WARNING Wierd cookie\n", __func__);
+    }
+
+    A_ASSERT(skb);
+    A_ASSERT(evId == HTC_BUFFER_SENT);
+    A_ASSERT(evInfo->buffer == a_netbuf_to_data(skb));
+    if (evInfo->status != A_ECANCELED) {
+        A_ASSERT(evInfo->actualLength == a_netbuf_to_len(skb));
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    ar->arTxPending[eid]--;
+    if (eid != WMI_CONTROL_MBOX || bypasswmi) {
+        ar->arTotalTxDataPending--;
+    }
+    AR_DEBUG2_PRINTF("ar6000_tx_complete skb=0x%x data=0x%x len=0x%x mbox=%d ",
+                     (A_UINT32)skb, (A_UINT32)evInfo->buffer,
+                     evInfo->actualLength,
+                     eid);
+
+    if ((eid == WMI_CONTROL_MBOX) &&
+        (ar->arTxPending[WMI_CONTROL_MBOX] == 0))
+    {
+        wake_up(&arEvent);
+    }
+
+
+    if (evInfo->status != A_OK) {
+        AR_DEBUG_PRINTF("%s() -TX ERROR\n", __func__);
+        AR6000_STAT_INC(ar, tx_errors);
+    } else {
+        AR_DEBUG2_PRINTF("OK\n");
+        AR6000_STAT_INC(ar, tx_packets);
+        ar->arNetStats.tx_bytes += a_netbuf_to_len(skb);
+    }
+
+    if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable
+        && (eid != WMI_CONTROL_MBOX) && mapNo)
+    {
+        mapNo --;
+        ar->arNodeMap[mapNo].txPending --;
+
+        if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {
+            A_UINT32 i;
+            for (i = ar->arNodeNum; i > 0; i --) {
+                if (!ar->arNodeMap[i - 1].txPending) {
+                    A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));
+                    ar->arNodeNum --;
+                } else {
+                    break;
+                }
+            }
+        }
+    }
+
+    /* Freeing a cookie should not be contingent on either of */
+    /* these flags, just if we have a cookie or not.           */
+    /* Can we even get here without a cookie? Fix later.       */
+    if (ar->arWmiReady == TRUE || (bypasswmi))
+    {
+        ar6000_free_cookie(ar, cookie);
+    }
+
+    a_netbuf_free(skb);
+
+    if ((ar->arConnected == TRUE) || (bypasswmi)) {
+        netif_wake_queue(ar->arNetDev);
+    }
+
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+}
+
+/*
+ * Receive event handler.  This is called by HTC when a packet is received
+ */
+int pktcount;
+static void
+ar6000_rx(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                      HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)arg;
+    struct sk_buff *skb = (struct sk_buff *)evInfo->cookie;
+    int minHdrLen;
+
+    A_ASSERT(evId == HTC_BUFFER_RECEIVED);
+    A_ASSERT((evInfo->status != A_OK) || (evInfo->buffer == (a_netbuf_to_data(skb) + HTC_HEADER_LEN)));
+
+#ifdef DEBUG
+    AR_DEBUG2_PRINTF("ar6000_rx ar=0x%x ep=%d, skb=0x%x, data=0x%x, len=0x%x ",
+                    (A_UINT32)ar, eid, (A_UINT32)skb, (A_UINT32)evInfo->buffer,
+                    evInfo->actualLength);
+    if (evInfo->status != A_OK) {
+        AR_DEBUG2_PRINTF("ERR\n");
+    } else {
+        AR_DEBUG2_PRINTF("OK\n");
+    }
+#endif /* DEBUG */
+
+    ar->arRxBuffers[eid]--;
+    AR6000_STAT_INC(ar, rx_packets);
+    ar->arNetStats.rx_bytes += evInfo->actualLength;
+
+    a_netbuf_put(skb, evInfo->actualLength +  HTC_HEADER_LEN);
+
+    a_netbuf_pull(skb, HTC_HEADER_LEN);
+
+#ifdef DEBUG
+    if (debugdriver >= 2) {
+        u_char *ch;
+
+        for (ch = a_netbuf_to_data(skb);
+            (A_UINT32)ch < ((A_UINT32)a_netbuf_to_data(skb) +
+            a_netbuf_to_len(skb)); ch++)
+        {
+            AR_DEBUG_PRINTF("%2.2x ", *ch);
+        }
+        AR_DEBUG_PRINTF("\n");
+    }
+#endif /* DEBUG */
+
+    if (evInfo->status != A_OK) {
+        AR6000_STAT_INC(ar, rx_errors);
+        a_netbuf_free(skb);
+    } else if (ar->arWmiEnabled == TRUE) {
+        if (eid == WMI_CONTROL_MBOX) {
+           /*
+            * this is a wmi control msg
+            */
+            AR6000_SPIN_LOCK(&ar->arLock, 0);
+            wmi_control_rx(ar->arWmi, skb);
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        } else {
+            WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)a_netbuf_to_data(skb);
+            if (WMI_DATA_HDR_IS_MSG_TYPE(dhdr, CNTL_MSGTYPE)) {
+                /*
+                 * this is a wmi control msg
+                 */
+                /* strip off WMI hdr */
+                wmi_data_hdr_remove(ar->arWmi, skb);
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                wmi_control_rx(ar->arWmi, skb);
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            } else {
+                /*
+                 * this is a wmi data packet
+                 */
+                minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) +
+                            sizeof(ATH_LLC_SNAP_HDR);
+
+                if ((evInfo->actualLength < minHdrLen) ||
+                    (evInfo->actualLength > AR6000_BUFFER_SIZE))
+                {
+                    /*
+                     * packet is too short or too long
+                     */
+                    AR_DEBUG_PRINTF("TOO SHORT or TOO LONG\n");
+                    AR6000_STAT_INC(ar, rx_errors);
+                    AR6000_STAT_INC(ar, rx_length_errors);
+                    a_netbuf_free(skb);
+                } else {
+                    AR6000_SPIN_LOCK(&ar->arLock, 0);
+                    wmi_implicit_create_pstream(ar->arWmi, skb, DNLINK_TRAFFIC);
+                    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+#if 0
+                    /* Access RSSI values here */
+                    AR_DEBUG_PRINTF("RSSI %d\n",
+                        ((WMI_DATA_HDR *) a_netbuf_to_data(skb))->rssi);
+#endif
+                    wmi_data_hdr_remove(ar->arWmi, skb);
+                    wmi_dot3_2_dix(ar->arWmi, skb);
+
+#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_to_data(skb), a_netbuf_to_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)
+                    {
+                        skb->dev = ar->arNetDev;
+                        skb->protocol = eth_type_trans(skb, ar->arNetDev);
+                        netif_rx(skb);
+                    }
+                    else
+                    {
+                        a_netbuf_free(skb);
+                    }
+                }
+            }
+        }
+    } else {
+        if ((ar->arNetDev->flags & IFF_UP) == IFF_UP)
+        {
+            skb->dev = ar->arNetDev;
+            skb->protocol = eth_type_trans(skb, ar->arNetDev);
+            netif_rx(skb);
+        }
+        else
+        {
+            a_netbuf_free(skb);
+        }
+    }
+
+    if (evInfo->status != A_ECANCELED) {
+        /*
+         * HTC provides A_ECANCELED status when it doesn't want to be refilled
+         * (probably due to a shutdown)
+         */
+        ar6000_rx_refill(htcTarget, eid, HTC_DATA_AVAILABLE, NULL, ar);
+    }
+}
+
+static void
+ar6000_rx_refill(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID eid,
+                      HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)arg;
+    void *osBuf;
+    int arRxBuffers;
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    arRxBuffers = ar->arRxBuffers[eid];
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    AR_DEBUG2_PRINTF("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n",
+                    AR6000_MAX_RX_BUFFERS - arRxBuffers, eid);
+    while (arRxBuffers < AR6000_MAX_RX_BUFFERS) {
+        osBuf = a_netbuf_alloc(AR6000_BUFFER_SIZE);
+        HTCBufferReceive(htcTarget, eid, a_netbuf_to_data(osBuf),
+                         AR6000_BUFFER_SIZE, osBuf);
+        arRxBuffers++;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    ar->arRxBuffers[eid] = arRxBuffers;
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+}
+
+static struct net_device_stats *
+ar6000_get_stats(struct net_device *dev)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    return &ar->arNetStats;
+}
+#if 0
+static struct iw_statistics *
+ar6000_get_iwstats(struct net_device * dev)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    TARGET_STATS *pStats = &ar->arTargetStats;
+    struct iw_statistics * pIwStats = &ar->arIwStats;
+
+    if (ar->arWmiReady == FALSE) {
+        pIwStats->status = 0;
+        pIwStats->qual.qual = 0;
+        pIwStats->qual.level =0;
+        pIwStats->qual.noise = 0;
+        pIwStats->discard.code =0;
+        pIwStats->discard.retries=0;
+        pIwStats->miss.beacon =0;
+        return pIwStats;
+    }
+    if (down_interruptible(&ar->arSem)) {
+        pIwStats->status = 0;
+        return pIwStats;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    ar->statsUpdatePending = TRUE;
+
+    if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        up(&ar->arSem);
+        pIwStats->status = 0;
+        return pIwStats;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    wait_event_interruptible(arEvent, ar->statsUpdatePending == FALSE);
+
+    if (signal_pending(current)) {
+        pIwStats->status = 0;
+        return pIwStats;
+    }
+    pIwStats->status = 1 ;
+    pIwStats->qual.qual = pStats->cs_aveBeacon_rssi;
+    pIwStats->qual.level =pStats->cs_aveBeacon_rssi + 161;  /* noise is -95 dBm */
+    pIwStats->qual.noise = pStats->noise_floor_calibation;
+    pIwStats->discard.code = pStats->rx_decrypt_err;
+    pIwStats->discard.retries = pStats->tx_retry_cnt;
+    pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
+    up(&ar->arSem);
+    return pIwStats;
+}
+#endif
+
+void
+ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap)
+{
+    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("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+        dev->dev_addr[0], dev->dev_addr[1],
+        dev->dev_addr[2], dev->dev_addr[3],
+        dev->dev_addr[4], dev->dev_addr[5]);
+
+    ar->arPhyCapability = phyCap;
+}
+
+A_UINT8
+ar6000_iptos_to_userPriority(A_UINT8 *pkt)
+{
+    struct iphdr *ipHdr = (struct iphdr *)pkt;
+    A_UINT8 userPriority;
+
+    /*
+     * IP Tos format :
+     *      (Refer Pg 57 WMM-test-plan-v1.2)
+     * IP-TOS - 8bits
+     *          : DSCP(6-bits) ECN(2-bits)
+     *          : DSCP - P2 P1 P0 X X X
+     *              where (P2 P1 P0) form 802.1D
+     */
+    userPriority = ipHdr->tos >> 5;
+    return (userPriority & 0x7);
+}
+
+void
+ar6000_connect_event(AR_SOFTC_T *ar, A_UINT16 channel, A_UINT8 *bssid,
+                     A_UINT16 listenInterval, A_UINT8 beaconIeLen,
+                     A_UINT8 assocReqLen, A_UINT8 assocRespLen,
+                     A_UINT8 *assocInfo)
+{
+    union iwreq_data wrqu;
+    int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos;
+    static const char *tag1 = "ASSOCINFO(ReqIEs=";
+    static const char *tag2 = "ASSOCRESPIE=";
+    static const char *beaconIetag = "BEACONIE=";
+    char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + sizeof(tag1)];
+    char *pos;
+
+    A_MEMCPY(ar->arBssid, bssid, sizeof(ar->arBssid));
+    ar->arBssChannel = channel;
+
+    A_PRINTF("AR6000 connected event on freq %d ", channel);
+    A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
+            " listenInterval=%d, beaconIeLen = %d assocReqLen=%d"
+            " assocRespLen =%d\n",
+             bssid[0], bssid[1], bssid[2],
+             bssid[3], bssid[4], bssid[5],
+             listenInterval,
+             beaconIeLen, assocReqLen, assocRespLen);
+
+    if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) {
+        AR_DEBUG_PRINTF("\nBeaconIEs= ");
+
+        beacon_ie_pos = 0;
+        A_MEMZERO(buf, sizeof(buf));
+        sprintf(buf, "%s", beaconIetag);
+        pos = buf + 9;
+        for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) {
+            AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]);
+            sprintf(pos, "%2.2x", assocInfo[i]);
+            pos += 2;
+        }
+        AR_DEBUG_PRINTF("\n");
+
+        A_MEMZERO(&wrqu, sizeof(wrqu));
+        wrqu.data.length = strlen(buf);
+        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+    }
+
+    if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2))))
+    {
+        assoc_resp_ie_pos = beaconIeLen + assocReqLen +
+                            sizeof(A_UINT16)  +  /* capinfo*/
+                            sizeof(A_UINT16)  +  /* status Code */
+                            sizeof(A_UINT16)  ;  /* associd */
+        A_MEMZERO(buf, sizeof(buf));
+        sprintf(buf, "%s", tag2);
+        pos = buf + 12;
+        AR_DEBUG_PRINTF("\nAssocRespIEs= ");
+        /*
+         * The Association Response Frame w.o. the WLAN header is delivered to
+         * the host, so skip over to the IEs
+         */
+        for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen; i++)
+        {
+            AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]);
+            sprintf(pos, "%2.2x", assocInfo[i]);
+            pos += 2;
+        }
+        AR_DEBUG_PRINTF("\n");
+
+        A_MEMZERO(&wrqu, sizeof(wrqu));
+        wrqu.data.length = strlen(buf);
+        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+    }
+
+    if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) {
+        /*
+         * assoc Request includes capability and listen interval. Skip these.
+         */
+        assoc_req_ie_pos =  beaconIeLen +
+                            sizeof(A_UINT16)  +  /* capinfo*/
+                            sizeof(A_UINT16);    /* listen interval */
+
+        A_MEMZERO(buf, sizeof(buf));
+        sprintf(buf, "%s", tag1);
+        pos = buf + 17;
+        AR_DEBUG_PRINTF("AssocReqIEs= ");
+        for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen; i++) {
+            AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]);
+            sprintf(pos, "%2.2x", assocInfo[i]);
+            pos += 2;;
+        }
+        AR_DEBUG_PRINTF("\n");
+
+        A_MEMZERO(&wrqu, sizeof(wrqu));
+        wrqu.data.length = strlen(buf);
+        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+    }
+
+    if (ar->arTotalTxDataPending < txFlowCtrlThresh[ar->arNumDataEndPts]) {
+        netif_wake_queue(ar->arNetDev);
+    }
+
+    if ((OPEN_AUTH == ar->arDot11AuthMode) &&
+        (NONE_AUTH == ar->arAuthMode)      &&
+        (WEP_CRYPT == ar->arPairwiseCrypto))
+    {
+        if (!ar->arConnected) {
+            ar6000_install_static_wep_keys(ar);
+        }
+    }
+
+    ar->arConnected  = TRUE;
+    ar->arConnectPending = FALSE;
+
+    A_MEMZERO(&wrqu, sizeof(wrqu));
+    A_MEMCPY(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN);
+    wrqu.addr.sa_family = ARPHRD_ETHER;
+    wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL);
+
+    if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) {
+        A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap));
+        ar->arNodeNum = 0;
+        ar->arNexEpId = ENDPOINT2;
+    }
+}
+
+void ar6000_set_numdataendpts(AR_SOFTC_T *ar, A_UINT32 num)
+{
+    A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1));
+    ar->arNumDataEndPts = num;
+}
+
+void
+ar6000_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason, A_UINT8 *bssid,
+                        A_UINT8 assocRespLen, A_UINT8 *assocInfo)
+{
+    A_UINT8 i;
+
+    A_PRINTF("AR6000 disconnected");
+    if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) {
+        A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
+                 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
+    }
+
+    AR_DEBUG_PRINTF("\nAssocResp Frame = %s",
+                    assocRespLen ? " " : "NULL");
+    for (i = 0; i < assocRespLen; i++) {
+        if (!(i % 0x10)) {
+            AR_DEBUG_PRINTF("\n");
+        }
+        AR_DEBUG_PRINTF("%2.2x ", assocInfo[i]);
+    }
+    AR_DEBUG_PRINTF("\n");
+    /*
+     * If the event is due to disconnect cmd from the host, only they the target
+     * would stop trying to connect. Under any other condition, target would
+     * keep trying to connect.
+     *
+     */
+    if( reason == DISCONNECT_CMD)
+    {
+        ar->arConnectPending = FALSE;
+    }
+    ar->arConnected = FALSE;
+
+    netif_stop_queue(ar->arNetDev);
+    A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
+    ar->arBssChannel = 0;
+}
+
+void
+ar6000_regDomain_event(AR_SOFTC_T *ar, A_UINT32 regCode)
+{
+    A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode);
+    ar->arRegCode = regCode;
+}
+
+void
+ar6000_neighborReport_event(AR_SOFTC_T *ar, int numAps, WMI_NEIGHBOR_INFO *info)
+{
+    static const char *tag = "PRE-AUTH";
+    char buf[128];
+    union iwreq_data wrqu;
+    int i;
+
+    A_PRINTF("AR6000 Neighbor Report Event\n");
+    for (i=0; i < numAps; info++, i++) {
+        A_PRINTF("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",
+            info->bssid[0], info->bssid[1], info->bssid[2],
+            info->bssid[3], info->bssid[4], info->bssid[5]);
+        if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) {
+            A_PRINTF("preauth-cap");
+        }
+        if (info->bssFlags & WMI_PMKID_VALID_BSS) {
+            A_PRINTF(" pmkid-valid\n");
+            continue;           /* we skip bss if the pmkid is already valid */
+        }
+        A_PRINTF("\n");
+        snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
+                 tag,
+                 info->bssid[0], info->bssid[1], info->bssid[2],
+                 info->bssid[3], info->bssid[4], info->bssid[5],
+                 i, info->bssFlags);
+        A_MEMZERO(&wrqu, sizeof(wrqu));
+        wrqu.data.length = strlen(buf);
+        wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+    }
+}
+
+void
+ar6000_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
+{
+    static const char *tag = "MLME-MICHAELMICFAILURE.indication";
+    char buf[128];
+    union iwreq_data wrqu;
+
+    A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
+             keyid, ismcast ? "multi": "uni");
+    snprintf(buf, sizeof(buf), "%s(keyid=%d %scat)", tag, keyid,
+             ismcast ? "multi" : "uni");
+    memset(&wrqu, 0, sizeof(wrqu));
+    wrqu.data.length = strlen(buf);
+    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
+}
+
+void
+ar6000_scanComplete_event(AR_SOFTC_T *ar)
+{
+    A_PRINTF("AR6000 scan complete\n");
+}
+
+void
+ar6000_targetStats_event(AR_SOFTC_T *ar,  WMI_TARGET_STATS *pTarget)
+{
+    TARGET_STATS *pStats = &ar->arTargetStats;
+    A_UINT8 ac;
+
+    A_PRINTF("AR6000 updating target stats\n");
+    pStats->tx_packets          += pTarget->txrxStats.tx_stats.tx_packets;
+    pStats->tx_bytes            += pTarget->txrxStats.tx_stats.tx_bytes;
+    pStats->tx_unicast_pkts     += pTarget->txrxStats.tx_stats.tx_unicast_pkts;
+    pStats->tx_unicast_bytes    += pTarget->txrxStats.tx_stats.tx_unicast_bytes;
+    pStats->tx_multicast_pkts   += pTarget->txrxStats.tx_stats.tx_multicast_pkts;
+    pStats->tx_multicast_bytes  += pTarget->txrxStats.tx_stats.tx_multicast_bytes;
+    pStats->tx_broadcast_pkts   += pTarget->txrxStats.tx_stats.tx_broadcast_pkts;
+    pStats->tx_broadcast_bytes  += pTarget->txrxStats.tx_stats.tx_broadcast_bytes;
+    pStats->tx_rts_success_cnt  += pTarget->txrxStats.tx_stats.tx_rts_success_cnt;
+    for(ac = 0; ac < WMM_NUM_AC; ac++)
+        pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac];
+    pStats->tx_errors           += pTarget->txrxStats.tx_stats.tx_errors;
+    pStats->tx_failed_cnt       += pTarget->txrxStats.tx_stats.tx_failed_cnt;
+    pStats->tx_retry_cnt        += pTarget->txrxStats.tx_stats.tx_retry_cnt;
+    pStats->tx_rts_fail_cnt     += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt;
+
+    pStats->rx_packets          += pTarget->txrxStats.rx_stats.rx_packets;
+    pStats->rx_bytes            += pTarget->txrxStats.rx_stats.rx_bytes;
+    pStats->rx_unicast_pkts     += pTarget->txrxStats.rx_stats.rx_unicast_pkts;
+    pStats->rx_unicast_bytes    += pTarget->txrxStats.rx_stats.rx_unicast_bytes;
+    pStats->rx_multicast_pkts   += pTarget->txrxStats.rx_stats.rx_multicast_pkts;
+    pStats->rx_multicast_bytes  += pTarget->txrxStats.rx_stats.rx_multicast_bytes;
+    pStats->rx_broadcast_pkts   += pTarget->txrxStats.rx_stats.rx_broadcast_pkts;
+    pStats->rx_broadcast_bytes  += pTarget->txrxStats.rx_stats.rx_broadcast_bytes;
+    pStats->rx_fragment_pkt     += pTarget->txrxStats.rx_stats.rx_fragment_pkt;
+    pStats->rx_errors           += pTarget->txrxStats.rx_stats.rx_errors;
+    pStats->rx_crcerr           += pTarget->txrxStats.rx_stats.rx_crcerr;
+    pStats->rx_key_cache_miss   += pTarget->txrxStats.rx_stats.rx_key_cache_miss;
+    pStats->rx_decrypt_err      += pTarget->txrxStats.rx_stats.rx_decrypt_err;
+    pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames;
+
+
+    pStats->tkip_local_mic_failure
+                                += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure;
+    pStats->tkip_counter_measures_invoked
+                                += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked;
+    pStats->tkip_replays        += pTarget->txrxStats.tkipCcmpStats.tkip_replays;
+    pStats->tkip_format_errors  += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors;
+    pStats->ccmp_format_errors  += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors;
+    pStats->ccmp_replays        += pTarget->txrxStats.tkipCcmpStats.ccmp_replays;
+
+
+    pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt;
+    pStats->noise_floor_calibation = pTarget->noise_floor_calibation;
+
+    pStats->cs_bmiss_cnt        += pTarget->cservStats.cs_bmiss_cnt;
+    pStats->cs_lowRssi_cnt      += pTarget->cservStats.cs_lowRssi_cnt;
+    pStats->cs_connect_cnt      += pTarget->cservStats.cs_connect_cnt;
+    pStats->cs_disconnect_cnt   += pTarget->cservStats.cs_disconnect_cnt;
+    pStats->cs_aveBeacon_rssi   = pTarget->cservStats.cs_aveBeacon_rssi;
+    pStats->cs_lastRoam_msec    = pTarget->cservStats.cs_lastRoam_msec;
+
+    ar->statsUpdatePending = FALSE;
+    wake_up(&arEvent);
+}
+
+
+void
+ar6000_rssiThreshold_event(AR_SOFTC_T *ar,  WMI_RSSI_THRESHOLD_VAL newThreshold)
+{
+    A_PRINTF("AR6000 Threshold val = %d \n", newThreshold);
+}
+
+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"
+                };
+
+    A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal);
+
+    /* One error is reported at a time, and errorval is a bitmask */
+    if(errorVal & (errorVal - 1))
+       return;
+
+    A_PRINTF("AR6000 Error type = ");
+    switch(errorVal)
+    {
+        case WMI_TARGET_PM_ERR_FAIL:
+        case WMI_TARGET_KEY_NOT_FOUND:
+        case WMI_TARGET_DECRYPTION_ERR:
+        case WMI_TARGET_BMISS:
+        case WMI_PSDISABLE_NODE_JOIN:
+            A_PRINTF("%s\n", errString[errorVal]);
+            break;
+        default:
+            A_PRINTF("INVALID\n");
+            break;
+    }
+
+}
+
+
+void
+ar6000_cac_event(AR_SOFTC_T *ar, A_UINT8 ac, A_UINT8 cacIndication,
+                 A_UINT8 statusCode, A_UINT8 *tspecSuggestion)
+{
+    WMM_TSPEC_IE    *tspecIe;
+
+    /*
+     * This is the TSPEC IE suggestion from AP.
+     * Suggestion provided by AP under some error
+     * cases, could be helpful for the host app.
+     * Check documentation.
+     */
+    tspecIe = (WMM_TSPEC_IE *)tspecSuggestion;
+
+    /*
+     * What do we do, if we get TSPEC rejection? One thought
+     * that comes to mind is implictly delete the pstream...
+     */
+    A_PRINTF("AR6000 CAC notification. "
+                "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n",
+                 ac, cacIndication, statusCode);
+}
+
+#define AR6000_PRINT_BSSID(_pBss)  do {     \
+        A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\
+                 (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\
+                 (_pBss)[4],(_pBss)[5]);  \
+} while(0)
+
+void
+ar6000_roam_tbl_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_TBL *pTbl)
+{
+    A_UINT8 i;
+
+    A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n",
+              pTbl->numEntries, pTbl->roamMode);
+    for (i= 0; i < pTbl->numEntries; i++) {
+        A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i,
+            pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1],
+            pTbl->bssRoamInfo[i].bssid[2],
+            pTbl->bssRoamInfo[i].bssid[3],
+            pTbl->bssRoamInfo[i].bssid[4],
+            pTbl->bssRoamInfo[i].bssid[5]);
+        A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d"
+                 " BIAS %d\n",
+            pTbl->bssRoamInfo[i].rssi,
+            pTbl->bssRoamInfo[i].rssidt,
+            pTbl->bssRoamInfo[i].last_rssi,
+            pTbl->bssRoamInfo[i].util,
+            pTbl->bssRoamInfo[i].roam_util,
+            pTbl->bssRoamInfo[i].bias);
+    }
+}
+
+/*
+ * Report the Roaming related data collected on the target
+ */
+void
+ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p)
+{
+    A_PRINTF("Disconnect Data : BSSID: ");
+    AR6000_PRINT_BSSID(p->disassoc_bssid);
+    A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n",
+             p->disassoc_bss_rssi,p->disassoc_time,
+             p->no_txrx_time);
+    A_PRINTF("Connect Data: BSSID: ");
+    AR6000_PRINT_BSSID(p->assoc_bssid);
+    A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n",
+             p->assoc_bss_rssi,p->assoc_time,
+             p->allow_txrx_time);
+    A_PRINTF("Last Data Tx Time (b4 Disassoc) %d "\
+             "First Data Tx Time (after Assoc) %d\n",
+             p->last_data_txrx_time, p->first_data_txrx_time);
+}
+
+void
+ar6000_roam_data_event(AR_SOFTC_T *ar, WMI_TARGET_ROAM_DATA *p)
+{
+    switch (p->roamDataType) {
+        case ROAM_DATA_TIME:
+            ar6000_display_roam_time(&p->u.roamTime);
+            break;
+        default:
+            break;
+    }
+}
+
+static int
+ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_TARGET_ERROR_REPORT_BITMASK cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    ret = wmi_set_error_report_bitmask(ar->arWmi, cmd.bitmask);
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return  (ret==0 ? ret : -EINVAL);
+}
+
+
+static int
+ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    TARGET_STATS *pStats = &ar->arTargetStats;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+    if (down_interruptible(&ar->arSem)) {
+        return -ERESTARTSYS;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    ar->statsUpdatePending = TRUE;
+
+    if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        up(&ar->arSem);
+        return -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    wait_event_interruptible(arEvent, ar->statsUpdatePending == FALSE);
+
+    if (signal_pending(current)) {
+        ret = -EINTR;
+    }
+
+    if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
+        ret = -EFAULT;
+    }
+
+    up(&ar->arSem);
+
+    return ret;
+}
+
+static int
+ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_SET_ACCESS_PARAMS_CMD cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (wmi_set_access_params_cmd(ar->arWmi, cmd.txop, cmd.eCWmin, cmd.eCWmax,
+                                  cmd.aifsn) == A_OK)
+    {
+        ret = 0;
+    } else {
+        ret = -EINVAL;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return (ret);
+}
+
+static int
+ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_DISC_TIMEOUT_CMD cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == A_OK)
+    {
+        ret = 0;
+    } else {
+        ret = -EINVAL;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return (ret);
+}
+
+static int
+ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_SET_VOICE_PKT_SIZE_CMD cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == A_OK)
+    {
+        ret = 0;
+    } else {
+        ret = -EINVAL;
+    }
+
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return (ret);
+}
+
+static int
+ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_SET_MAX_SP_LEN_CMD cmd;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == A_OK)
+    {
+        ret = 0;
+    } else {
+        ret = -EINVAL;
+    }
+
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return (ret);
+}
+
+A_STATUS
+ar6000_control_tx(void *devt, void *osbuf, int endPt)
+{
+    AR_SOFTC_T       *ar = (AR_SOFTC_T *)devt;
+    A_STATUS         status;
+    struct ar_cookie *cookie;
+    WMI_DATA_HDR *dhdr;
+
+    A_ASSERT((endPt == WMI_CONTROL_MBOX) || (endPt == WMI_LOW_PRIORITY_MBOX) ||
+        (endPt == WMI_HIGH_PRIORITY_MBOX) || (endPt == WMI_BEST_EFFORT_MBOX));
+
+    ar->arTxPending[endPt]++;
+    if (endPt != WMI_CONTROL_MBOX) {
+        ar->arTotalTxDataPending++;
+    }
+
+    AR_DEBUG2_PRINTF("ar_control_tx: skb=0x%x, len=0x%x, mbox=%d\n",
+                     (A_UINT32)osbuf, a_netbuf_to_len(osbuf), endPt);
+
+    cookie = ar6000_alloc_cookie(ar);
+
+    /* If the particular data queue is full, silently drop the pkt. */
+    dhdr = (WMI_DATA_HDR *)a_netbuf_to_data(osbuf);
+    if ((cookie == NULL) ||
+        ((ar->arTxPending[endPt] > MAX_ALLOWED_TXQ_DEPTH) &&
+         (!WMI_DATA_HDR_IS_MSG_TYPE(dhdr, SYNC_MSGTYPE))))
+    {
+        ar->arTxPending[endPt]--;
+        if (endPt != WMI_CONTROL_MBOX) {
+            ar->arTotalTxDataPending--;
+        }
+        a_netbuf_free(osbuf);
+        if (cookie != NULL) {
+            ar6000_free_cookie(ar, cookie);
+        }
+        return A_NO_MEMORY;
+    }
+
+    cookie->arc_bp[0] = (A_UINT32)osbuf;
+    cookie->arc_bp[1] = 0;
+    status = HTCBufferSend(ar->arHtcTarget, endPt, a_netbuf_to_data(osbuf),
+                  a_netbuf_to_len(osbuf), cookie);
+    if (status != A_OK) {
+        /*
+         * XXX This is an error that requires us to reset chip
+         */
+        ar->arTxPending[endPt]--;
+        if (endPt != WMI_CONTROL_MBOX) {
+            ar->arTotalTxDataPending--;
+        }
+        AR_DEBUG_PRINTF("Dropping control frame!!\n");
+        ar6000_free_cookie(ar, cookie);
+        a_netbuf_free(osbuf);
+        return (status);
+    }
+
+    return A_OK;
+}
+
+module_init(ar6000_init_module);
+module_exit(ar6000_cleanup_module);
+
+/*
+ * SIOCGIWNAME
+ */
+int
+ar6000_ioctl_giwname(struct net_device *dev,
+           struct iw_request_info *info,
+           char *name, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    switch (ar->arPhyCapability) {
+    case (WMI_11A_CAPABILITY):
+        strncpy(name, "AR6000 802.11a", IFNAMSIZ);
+        break;
+    case (WMI_11G_CAPABILITY):
+        strncpy(name, "AR6000 802.11g", IFNAMSIZ);
+        break;
+    case (WMI_11AG_CAPABILITY):
+        strncpy(name, "AR6000 802.11ag", IFNAMSIZ);
+        break;
+    default:
+        strncpy(name, "AR6000 802.11", IFNAMSIZ);
+        break;
+    }
+
+    return 0;
+}
+
+/*
+ * SIOCSIWFREQ
+ */
+int
+ar6000_ioctl_siwfreq(struct net_device *dev,
+            struct iw_request_info *info,
+            struct iw_freq *freq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    /*
+     * We support limiting the channels via wmiconfig.
+     *
+     * We use this command to configure the channel hint for the connect cmd
+     * so it is possible the target will end up connecting to a different
+     * channel.
+     */
+    if (freq->e > 1) {
+        return -EINVAL;
+    } else if (freq->e == 1) {
+        ar->arChannelHint = freq->m / 100000;
+    } else {
+        ar->arChannelHint = wlan_ieee2freq(freq->m);
+    }
+
+    A_PRINTF("channel hint set to %d\n", ar->arChannelHint);
+    return 0;
+}
+
+/*
+ * SIOCGIWFREQ
+ */
+int
+ar6000_ioctl_giwfreq(struct net_device *dev,
+                struct iw_request_info *info,
+                struct iw_freq *freq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (ar->arConnected != TRUE) {
+        return -EINVAL;
+    }
+
+    freq->m = ar->arBssChannel * 100000;
+    freq->e = 1;
+
+    return 0;
+}
+
+/*
+ * SIOCSIWMODE
+ */
+int
+ar6000_ioctl_siwmode(struct net_device *dev,
+            struct iw_request_info *info,
+            __u32 *mode, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    switch (*mode) {
+    case IW_MODE_INFRA:
+        ar->arNetworkType = INFRA_NETWORK;
+        break;
+    case IW_MODE_ADHOC:
+        ar->arNetworkType = ADHOC_NETWORK;
+        break;
+    default:
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+/*
+ * SIOCGIWMODE
+ */
+int
+ar6000_ioctl_giwmode(struct net_device *dev,
+            struct iw_request_info *info,
+            __u32 *mode, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    switch (ar->arNetworkType) {
+    case INFRA_NETWORK:
+        *mode = IW_MODE_INFRA;
+        break;
+    case ADHOC_NETWORK:
+        *mode = IW_MODE_ADHOC;
+        break;
+    default:
+        return -EIO;
+    }
+    return 0;
+}
+
+/*
+ * SIOCSIWSENS
+ */
+int
+ar6000_ioctl_siwsens(struct net_device *dev,
+            struct iw_request_info *info,
+            struct iw_param *sens, char *extra)
+{
+    return 0;
+}
+
+/*
+ * SIOCGIWSENS
+ */
+int
+ar6000_ioctl_giwsens(struct net_device *dev,
+            struct iw_request_info *info,
+            struct iw_param *sens, char *extra)
+{
+    sens->value = 0;
+    sens->fixed = 1;
+
+    return 0;
+}
+
+/*
+ * SIOCGIWRANGE
+ */
+int
+ar6000_ioctl_giwrange(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *data, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    struct iw_range *range = (struct iw_range *) extra;
+    int i, ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (down_interruptible(&ar->arSem)) {
+        return -ERESTARTSYS;
+    }
+    ar->arNumChannels = -1;
+    A_MEMZERO(ar->arChannelList, sizeof (ar->arChannelList));
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (wmi_get_channelList_cmd(ar->arWmi) != A_OK) {
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        up(&ar->arSem);
+        return -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    wait_event_interruptible(arEvent, ar->arNumChannels != -1);
+
+    if (signal_pending(current)) {
+        up(&ar->arSem);
+        return -EINTR;
+    }
+
+    data->length = sizeof(struct iw_range);
+    A_MEMZERO(range, sizeof(struct iw_range));
+
+    range->txpower_capa = 0;
+
+    range->min_pmp = 1 * 1024;
+    range->max_pmp = 65535 * 1024;
+    range->min_pmt = 1 * 1024;
+    range->max_pmt = 1000 * 1024;
+    range->pmp_flags = IW_POWER_PERIOD;
+    range->pmt_flags = IW_POWER_TIMEOUT;
+    range->pm_capa = 0;
+
+    range->we_version_compiled = WIRELESS_EXT;
+    range->we_version_source = 13;
+
+    range->retry_capa = IW_RETRY_LIMIT;
+    range->retry_flags = IW_RETRY_LIMIT;
+    range->min_retry = 0;
+    range->max_retry = 255;
+
+    range->num_frequency = range->num_channels = ar->arNumChannels;
+    for (i = 0; i < ar->arNumChannels; i++) {
+        range->freq[i].i = wlan_freq2ieee(ar->arChannelList[i]);
+        range->freq[i].m = ar->arChannelList[i] * 100000;
+        range->freq[i].e = 1;
+    }
+
+    /* Max quality is max field value minus noise floor */
+    range->max_qual.qual  = 0xff - 161;
+
+    /*
+     * In order to use dBm measurements, 'level' must be lower
+     * than any possible measurement (see iw_print_stats() in
+     * wireless tools).  It's unclear how this is meant to be
+     * done, but setting zero in these values forces dBm and
+     * the actual numbers are not used.
+     */
+    range->max_qual.level = 0;
+    range->max_qual.noise = 0;
+
+    range->sensitivity = 3;
+
+    range->max_encoding_tokens = 4;
+    /* XXX query driver to find out supported key sizes */
+    range->num_encoding_sizes = 3;
+    range->encoding_size[0] = 5;        /* 40-bit */
+    range->encoding_size[1] = 13;       /* 104-bit */
+    range->encoding_size[2] = 16;       /* 128-bit */
+
+    range->num_bitrates = 0;
+
+    /* estimated maximum TCP throughput values (bps) */
+    range->throughput = 22000000;
+
+    range->min_rts = 0;
+    range->max_rts = 2347;
+    range->min_frag = 256;
+    range->max_frag = 2346;
+
+    up(&ar->arSem);
+
+    return ret;
+}
+
+/*
+ * SIOCSIWAP
+ * This ioctl is used to set the desired bssid for the connect command.
+ */
+int
+ar6000_ioctl_siwap(struct net_device *dev,
+              struct iw_request_info *info,
+              struct sockaddr *ap_addr, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (ap_addr->sa_family != ARPHRD_ETHER) {
+        return -EIO;
+    }
+
+    if (A_MEMCMP(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) {
+        A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+    } else {
+        A_MEMCPY(ar->arReqBssid, &ap_addr->sa_data,  sizeof(ar->arReqBssid));
+    }
+
+    return 0;
+}
+
+/*
+ * SIOCGIWAP
+ */
+int
+ar6000_ioctl_giwap(struct net_device *dev,
+              struct iw_request_info *info,
+              struct sockaddr *ap_addr, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (ar->arConnected != TRUE) {
+        return -EINVAL;
+    }
+
+    A_MEMCPY(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid));
+    ap_addr->sa_family = ARPHRD_ETHER;
+
+    return 0;
+}
+
+/*
+ * SIOCGIWAPLIST
+ */
+int
+ar6000_ioctl_iwaplist(struct net_device *dev,
+            struct iw_request_info *info,
+            struct iw_point *data, char *extra)
+{
+    return -EIO;            /* for now */
+}
+
+/*
+ * SIOCGIWSCAN
+ */
+int
+ar6000_ioctl_siwscan(struct net_device *dev,
+                     struct iw_request_info *info,
+                     struct iw_point *data, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN) != A_OK) {
+        ret = -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return ret;
+}
+
+#if WIRELESS_EXT > 14
+/*
+ * Encode a WPA or RSN information element as a custom
+ * element using the hostap format.
+ */
+static u_int
+encode_ie(void *buf, size_t bufsize,
+    const u_int8_t *ie, size_t ielen,
+    const char *leader, size_t leader_len)
+{
+    u_int8_t *p;
+    int i;
+
+    if (bufsize < leader_len)
+        return 0;
+    p = buf;
+    memcpy(p, leader, leader_len);
+    bufsize -= leader_len;
+    p += leader_len;
+    for (i = 0; i < ielen && bufsize > 2; i++)
+        p += sprintf(p, "%02x", ie[i]);
+    return (i == ielen ? p - (u_int8_t *)buf : 0);
+}
+#endif /* WIRELESS_EXT > 14 */
+/*
+ * Units are in db above the noise floor. That means the
+ * rssi values reported in the tx/rx descriptors in the
+ * driver are the SNR expressed in db.
+ *
+ * If you assume that the noise floor is -95, which is an
+ * excellent assumption 99.5 % of the time, then you can
+ * derive the absolute signal level (i.e. -95 + rssi).
+ * There are some other slight factors to take into account
+ * depending on whether the rssi measurement is from 11b,
+ * 11g, or 11a.   These differences are at most 2db and
+ * can be documented.
+ *
+ * NB: various calculations are based on the orinoco/wavelan
+ *     drivers for compatibility
+ */
+static void
+ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi)
+{
+    if (rssi < 0) {
+        iq->qual = 0;
+    } else {
+        iq->qual = rssi;
+    }
+
+    /* NB: max is 94 because noise is hardcoded to 161 */
+    if (iq->qual > 94)
+        iq->qual = 94;
+
+    iq->noise = 161;        /* -95dBm */
+    iq->level = iq->noise + iq->qual;
+    iq->updated = 7;
+}
+
+void
+ar6000_scan_node(void *arg, bss_t *ni)
+{
+    struct iw_event iwe;
+#if WIRELESS_EXT > 14
+    char buf[64*2 + 30];
+#endif
+    struct ar_giwscan_param *param;
+    A_CHAR *current_ev;
+    A_CHAR *end_buf;
+    struct ieee80211_common_ie  *cie;
+
+    param = (struct ar_giwscan_param *)arg;
+
+    if (param->current_ev >= param->end_buf) {
+        return;
+    }
+    if ((param->firstPass == TRUE) && (ni->ni_cie.ie_wpa == NULL)) {
+        /*
+         * Only forward wpa bss's in first pass
+         */
+        return;
+    }
+    if ((param->firstPass == FALSE) && (ni->ni_cie.ie_wpa != NULL)) {
+        /*
+         * Only forward non-wpa bss's in 2nd pass
+         */
+        return;
+    }
+
+    current_ev = param->current_ev;
+    end_buf = param->end_buf;
+
+    cie = &ni->ni_cie;
+
+    A_MEMZERO(&iwe, sizeof(iwe));
+    iwe.cmd = SIOCGIWAP;
+    iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+    A_MEMCPY(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6);
+    current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+                                      IW_EV_ADDR_LEN);
+
+    A_MEMZERO(&iwe, sizeof(iwe));
+    iwe.cmd = SIOCGIWESSID;
+    iwe.u.data.flags = 1;
+    iwe.u.data.length = cie->ie_ssid[1];
+    current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
+                                      &cie->ie_ssid[2]);
+
+    if (cie->ie_capInfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) {
+        A_MEMZERO(&iwe, sizeof(iwe));
+        iwe.cmd = SIOCGIWMODE;
+        iwe.u.mode = cie->ie_capInfo & IEEE80211_CAPINFO_ESS ?
+                IW_MODE_MASTER : IW_MODE_ADHOC;
+        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+                                          IW_EV_UINT_LEN);
+    }
+
+    A_MEMZERO(&iwe, sizeof(iwe));
+    iwe.cmd = SIOCGIWFREQ;
+    iwe.u.freq.m = cie->ie_chan * 100000;
+    iwe.u.freq.e = 1;
+    current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+                                      IW_EV_FREQ_LEN);
+
+    A_MEMZERO(&iwe, sizeof(iwe));
+    iwe.cmd = IWEVQUAL;
+    ar6000_set_quality(&iwe.u.qual, ni->ni_rssi);
+    current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+                                      IW_EV_QUAL_LEN);
+
+    A_MEMZERO(&iwe, sizeof(iwe));
+    iwe.cmd = SIOCGIWENCODE;
+    if (cie->ie_capInfo & IEEE80211_CAPINFO_PRIVACY) {
+        iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+    } else {
+        iwe.u.data.flags = IW_ENCODE_DISABLED;
+    }
+    iwe.u.data.length = 0;
+    current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+
+#ifdef NOTYET
+    A_MEMZERO(&iwe, sizeof(iwe));
+    iwe.cmd = SIOCGIWRATE;
+    current_val = current_ev + IW_EV_LCP_LEN;
+    for (j = 0; j < ni->ni_rates.rs_nrates; j++) {
+            if (ni->ni_rates.rs_rates[j]) {
+                iwe.u.bitrate.value = ((ni->ni_rates.rs_rates[j] &
+                    IEEE80211_RATE_VAL) / 2) * 1000000;
+                current_val = iwe_stream_add_value(current_ev,
+                    current_val, end_buf, &iwe,
+                    IW_EV_PARAM_LEN);
+            }
+        }
+        /* remove fixed header if no rates were added */
+        if ((current_val - current_ev) > IW_EV_LCP_LEN)
+            current_ev = current_val;
+#endif /* NOTYET */
+
+#if WIRELESS_EXT > 14
+    A_MEMZERO(&iwe, sizeof(iwe));
+    iwe.cmd = IWEVCUSTOM;
+    snprintf(buf, sizeof(buf), "bcn_int=%d", cie->ie_beaconInt);
+    iwe.u.data.length = strlen(buf);
+    current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+
+    if (cie->ie_wpa != NULL) {
+        static const char rsn_leader[] = "rsn_ie=";
+        static const char wpa_leader[] = "wpa_ie=";
+
+        A_MEMZERO(&iwe, sizeof(iwe));
+        iwe.cmd = IWEVCUSTOM;
+        if (cie->ie_wpa[0] == IEEE80211_ELEMID_RSN) {
+            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wpa,
+                                          cie->ie_wpa[1]+2,
+                                          rsn_leader, sizeof(rsn_leader)-1);
+        } else {
+            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wpa,
+                                          cie->ie_wpa[1]+2,
+                                          wpa_leader, sizeof(wpa_leader)-1);
+        }
+        if (iwe.u.data.length != 0) {
+            current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+        }
+    }
+
+    if (cie->ie_wmm != NULL) {
+        static const char wmm_leader[] = "wmm_ie=";
+
+        A_MEMZERO(&iwe, sizeof(iwe));
+        iwe.cmd = IWEVCUSTOM;
+        iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wmm,
+                                      cie->ie_wmm[1]+2,
+                                      wmm_leader, sizeof(wmm_leader)-1);
+        if (iwe.u.data.length != 0) {
+            current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+        }
+    }
+
+    if (cie->ie_ath != NULL) {
+        static const char ath_leader[] = "ath_ie=";
+
+        A_MEMZERO(&iwe, sizeof(iwe));
+        iwe.cmd = IWEVCUSTOM;
+        iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_ath,
+                                      cie->ie_ath[1]+2,
+                                      ath_leader, sizeof(ath_leader)-1);
+        if (iwe.u.data.length != 0) {
+            current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+        }
+    }
+#endif /* WIRELESS_EXT > 14 */
+
+    param->current_ev = current_ev;
+}
+
+int
+ar6000_ioctl_giwscan(struct net_device *dev,
+            struct iw_request_info *info,
+            struct iw_point *data, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    struct ar_giwscan_param param;
+    int i;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    param.current_ev = extra;
+    param.end_buf = extra + IW_SCAN_MAX_DATA;
+    param.firstPass = TRUE;
+
+    /*
+     * Do two passes to insure WPA scan candidates
+     * are sorted to the front.  This is a hack to deal with
+     * the wireless extensions capping scan results at
+     * IW_SCAN_MAX_DATA bytes.  In densely populated environments
+     * it's easy to overflow this buffer (especially with WPA/RSN
+     * information elements).  Note this sorting hack does not
+     * guarantee we won't overflow anyway.
+     */
+    for (i = 0; i < 2; i++) {
+        /*
+         * Translate data to WE format.
+         */
+        wmi_iterate_nodes(ar->arWmi, ar6000_scan_node, &param);
+        param.firstPass = FALSE;
+        if (param.current_ev >= param.end_buf) {
+            break;
+        }
+    }
+
+    data->length = param.current_ev - extra;
+    return 0;
+}
+
+/* SIOCSIWESSID */
+static int
+ar6000_ioctl_siwessid(struct net_device *dev,
+                     struct iw_request_info *info,
+                     struct iw_point *data, char *ssid)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    A_STATUS status;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    /*
+     * iwconfig passes a null terminated string with length including this
+     * so we need to account for this
+     */
+    if (data->flags && (!data->length || (data->length == 1) ||
+        ((data->length - 1) > sizeof(ar->arSsid))))
+    {
+        /*
+         * ssid is invalid
+         */
+        return -EINVAL;
+    }
+
+    if (down_interruptible(&ar->arSem)) {
+        return -ERESTARTSYS;
+    }
+
+    if (ar->arTxPending[WMI_CONTROL_MBOX]) {
+        /*
+         * sleep until the command queue drains
+         */
+        wait_event_interruptible(arEvent,
+            ar->arTxPending[WMI_CONTROL_MBOX] == 0);
+        if (signal_pending(current)) {
+            return -EINTR;
+        }
+    }
+
+    if ((ar->arSsidLen) || (!data->flags))
+    {
+        if ((!data->flags) ||
+            (A_MEMCMP(ar->arSsid, ssid, ar->arSsidLen) != 0) ||
+            (ar->arSsidLen != (data->length - 1)))
+        {
+            /*
+             * SSID set previously or essid off has been issued.
+             *
+             * Disconnect Command is issued in two cases after wmi is ready
+             * (1) ssid is different from the previous setting
+             * (2) essid off has been issued
+             *
+             */
+            if (ar->arWmiReady == TRUE) {
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                status = wmi_disconnect_cmd(ar->arWmi);
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+                A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+                ar->arSsidLen = 0;
+                A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
+                if (!data->flags) {
+                    up(&ar->arSem);
+                    return 0;
+                }
+            } else {
+                 up(&ar->arSem);
+            }
+        }
+        else
+        {
+            /*
+             * SSID is same, so we assume profile hasn't changed.
+             * If the interface is up and wmi is ready, we issue
+             * a reconnect cmd.
+             */
+            if((ar->arConnected == TRUE || ar->arConnectPending == TRUE) && (ar->arWmiReady == TRUE))
+            {
+                AR6000_SPIN_LOCK(&ar->arLock, 0);
+                status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid,
+                                           ar->arChannelHint);
+                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+                up(&ar->arSem);
+                if (status != A_OK) {
+                    return -EIO;
+                }
+                return 0;
+            }
+            else{
+             up(&ar->arSem);
+             return 0;
+            }
+        }
+    }
+
+    ar->arSsidLen = data->length - 1;
+    A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen);
+
+    /* The ssid length check prevents second "essid off" from the user,
+       to be treated as a connect cmd. The second "essid off" is ignored.
+    */
+    if((ar->arWmiReady == TRUE) && (ar->arSsidLen > 0) )
+    {
+        AR6000_SPIN_LOCK(&ar->arLock, 0);
+        if (SHARED_AUTH == ar->arDot11AuthMode) {
+            ar6000_install_static_wep_keys(ar);
+        }
+        AR_DEBUG_PRINTF("Connect called with authmode %d dot11 auth %d"\
+                        " PW crypto %d PW crypto Len %d GRP crypto %d"\
+                        " GRP crypto Len %d\n",
+                        ar->arAuthMode, ar->arDot11AuthMode,
+                        ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
+                        ar->arGroupCrypto, ar->arGroupCryptoLen);
+
+        status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
+                                 ar->arDot11AuthMode, ar->arAuthMode,
+                                 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
+                                 ar->arGroupCrypto,ar->arGroupCryptoLen,
+                                 ar->arSsidLen, ar->arSsid,
+                                 ar->arReqBssid, ar->arChannelHint);
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+        up(&ar->arSem);
+
+        if (status != A_OK) {
+            return -EIO;
+        }
+        ar->arConnectPending = TRUE;
+    }else{
+      up(&ar->arSem);
+    }
+    return 0;
+}
+
+/* SIOCGIWESSID */
+static int
+ar6000_ioctl_giwessid(struct net_device *dev,
+                     struct iw_request_info *info,
+                     struct iw_point *data, char *essid)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (!ar->arSsidLen) {
+        return -EINVAL;
+    }
+
+    data->flags = 1;
+    data->length = ar->arSsidLen;
+    A_MEMCPY(essid, ar->arSsid, ar->arSsidLen);
+
+    return 0;
+}
+
+/*
+ * SIOCSIWRATE
+ */
+int
+ar6000_ioctl_siwrate(struct net_device *dev,
+            struct iw_request_info *info,
+            struct iw_param *rrq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    A_UINT32  kbps;
+
+    if (rrq->fixed) {
+        kbps = rrq->value / 1000;           /* rrq->value is in bps */
+    } else {
+        kbps = -1;                          /* -1 indicates auto rate */
+    }
+    if(wmi_validate_bitrate(ar->arWmi, kbps) == A_EINVAL)
+    {
+        AR_DEBUG_PRINTF("BitRate is not Valid %d\n", kbps);
+        return -EINVAL;
+    }
+    ar->arBitRate = kbps;
+    if(ar->arWmiReady == TRUE)
+    {
+        AR6000_SPIN_LOCK(&ar->arLock, 0);
+        if (wmi_set_bitrate_cmd(ar->arWmi, kbps) != A_OK) {
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            return -EINVAL;
+        }
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+    }
+    return 0;
+}
+
+/*
+ * SIOCGIWRATE
+ */
+int
+ar6000_ioctl_giwrate(struct net_device *dev,
+            struct iw_request_info *info,
+            struct iw_param *rrq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    int ret = 0;
+
+    if (down_interruptible(&ar->arSem)) {
+        return -ERESTARTSYS;
+    }
+    if(ar->arWmiReady == TRUE)
+    {
+        ar->arBitRate = 0xFFFF;
+        AR6000_SPIN_LOCK(&ar->arLock, 0);
+        if (wmi_get_bitrate_cmd(ar->arWmi) != A_OK) {
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            up(&ar->arSem);
+            return -EIO;
+        }
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        wait_event_interruptible(arEvent, ar->arBitRate != 0xFFFF);
+        if (signal_pending(current)) {
+            ret = -EINTR;
+        }
+    }
+    /* If the interface is down or wmi is not ready or the target is not
+       connected - return the value stored in the device structure */
+    if (!ret) {
+        if (ar->arBitRate == -1) {
+            rrq->fixed = TRUE;
+            rrq->value = 0;
+        } else {
+            rrq->value = ar->arBitRate * 1000;
+        }
+    }
+
+    up(&ar->arSem);
+
+    return ret;
+}
+
+/*
+ * SIOCSIWTXPOW
+ */
+static int
+ar6000_ioctl_siwtxpow(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_param *rrq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    A_UINT8 dbM;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (rrq->disabled) {
+        return -EOPNOTSUPP;
+    }
+
+    if (rrq->fixed) {
+        if (rrq->flags != IW_TXPOW_DBM) {
+            return -EOPNOTSUPP;
+        }
+        ar->arTxPwr= dbM = rrq->value;
+        ar->arTxPwrSet = TRUE;
+    } else {
+        ar->arTxPwr = dbM = 0;
+        ar->arTxPwrSet = FALSE;
+    }
+    if(ar->arWmiReady == TRUE)
+    {
+        AR_DEBUG_PRINTF("Set tx pwr cmd %d dbM\n", dbM);
+        AR6000_SPIN_LOCK(&ar->arLock, 0);
+        wmi_set_txPwr_cmd(ar->arWmi, dbM);
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+    }
+    return 0;
+}
+
+/*
+ * SIOCGIWTXPOW
+ */
+int
+ar6000_ioctl_giwtxpow(struct net_device *dev,
+            struct iw_request_info *info,
+            struct iw_param *rrq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    int ret = 0;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (down_interruptible(&ar->arSem)) {
+        return -ERESTARTSYS;
+    }
+    if((ar->arWmiReady == TRUE) && (ar->arConnected == TRUE))
+    {
+        ar->arTxPwr = 0;
+
+        AR6000_SPIN_LOCK(&ar->arLock, 0);
+        if (wmi_get_txPwr_cmd(ar->arWmi) != A_OK) {
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            up(&ar->arSem);
+            return -EIO;
+        }
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+        wait_event_interruptible(arEvent, ar->arTxPwr != 0);
+
+        if (signal_pending(current)) {
+            ret = -EINTR;
+         }
+    }
+   /* If the interace is down or wmi is not ready or target is not connected
+      then return value stored in the device structure */
+
+    if (!ret) {
+         if (ar->arTxPwrSet == TRUE) {
+            rrq->fixed = TRUE;
+        }
+        rrq->value = ar->arTxPwr;
+        rrq->flags = IW_TXPOW_DBM;
+    }
+
+    up(&ar->arSem);
+
+    return ret;
+}
+
+/*
+ * SIOCSIWRETRY
+ * since iwconfig only provides us with one max retry value, we use it
+ * to apply to data frames of the BE traffic class.
+ */
+static int
+ar6000_ioctl_siwretry(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_param *rrq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (rrq->disabled) {
+        return -EOPNOTSUPP;
+    }
+
+    if ((rrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) {
+        return -EOPNOTSUPP;
+    }
+
+    if ( !(rrq->value >= WMI_MIN_RETRIES) || !(rrq->value <= WMI_MAX_RETRIES)) {
+            return - EINVAL;
+    }
+    if(ar->arWmiReady == TRUE)
+    {
+        if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE,
+                                     rrq->value) == A_OK){
+            return -EINVAL;
+        }
+    }
+    ar->arMaxRetries = rrq->value;
+    return 0;
+}
+
+/*
+ * SIOCGIWRETRY
+ */
+static int
+ar6000_ioctl_giwretry(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_param *rrq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    rrq->disabled = 0;
+    switch (rrq->flags & IW_RETRY_TYPE) {
+    case IW_RETRY_LIFETIME:
+        return -EOPNOTSUPP;
+        break;
+    case IW_RETRY_LIMIT:
+        rrq->flags = IW_RETRY_LIMIT;
+        switch (rrq->flags & IW_RETRY_MODIFIER) {
+        case IW_RETRY_MIN:
+            rrq->flags |= IW_RETRY_MIN;
+            rrq->value = WMI_MIN_RETRIES;
+            break;
+        case IW_RETRY_MAX:
+            rrq->flags |= IW_RETRY_MAX;
+            rrq->value = ar->arMaxRetries;
+            break;
+        }
+        break;
+    }
+    return 0;
+}
+
+/*
+ * SIOCSIWENCODE
+ */
+static int
+ar6000_ioctl_siwencode(struct net_device *dev,
+              struct iw_request_info *info,
+              struct iw_point *erq, char *keybuf)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    int index;
+    DOT11_AUTH_MODE auth = ar->arDot11AuthMode;
+    /*
+     *  Static WEP Keys should be configured before setting the SSID
+     */
+    if (ar->arSsidLen) {
+        return -EIO;
+    }
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    index = erq->flags & IW_ENCODE_INDEX;
+
+    if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
+                  ((index - 1) > WMI_MAX_KEY_INDEX)))
+    {
+        return -EIO;
+    }
+
+    if (erq->flags & IW_ENCODE_DISABLED) {
+        /*
+         * Encryption disabled
+         */
+        if (index) {
+            /*
+             * If key index was specified then clear the specified key
+             */
+            index--;
+            A_MEMZERO(ar->arWepKeyList[index].arKey,
+                      sizeof(ar->arWepKeyList[index].arKey));
+            ar->arWepKeyList[index].arKeyLen = 0;
+        }
+        ar->arDot11AuthMode       = OPEN_AUTH;
+        ar->arPairwiseCrypto      = NONE_CRYPT;
+        ar->arGroupCrypto         = NONE_CRYPT;
+        ar->arAuthMode            = NONE_AUTH;
+    } else {
+        /*
+         * Enabling WEP encryption
+         */
+        if (index) {
+            index--;                /* keyindex is off base 1 in iwconfig */
+        }
+
+        if (erq->flags & IW_ENCODE_OPEN) {
+            auth = OPEN_AUTH;
+        } else if (erq->flags & IW_ENCODE_RESTRICTED) {
+            auth = SHARED_AUTH;
+        }
+
+        if (erq->length) {
+            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq->length)) {
+                return -EIO;
+            }
+
+            A_MEMZERO(ar->arWepKeyList[index].arKey,
+                      sizeof(ar->arWepKeyList[index].arKey));
+            A_MEMCPY(ar->arWepKeyList[index].arKey, keybuf, erq->length);
+            ar->arWepKeyList[index].arKeyLen = erq->length;
+        } else {
+            if (ar->arWepKeyList[index].arKeyLen == 0) {
+                return -EIO;
+            }
+            ar->arDefTxKeyIndex = index;
+        }
+
+        ar->arPairwiseCrypto      = WEP_CRYPT;
+        ar->arGroupCrypto         = WEP_CRYPT;
+        ar->arDot11AuthMode       = auth;
+        ar->arAuthMode            = NONE_AUTH;
+    }
+
+    /*
+     * profile has changed.  Erase ssid to signal change
+     */
+    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+
+    return 0;
+}
+
+static int
+ar6000_ioctl_giwencode(struct net_device *dev,
+              struct iw_request_info *info,
+              struct iw_point *erq, char *key)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    A_UINT8 keyIndex;
+    struct ar_wep_key *wk;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if (ar->arPairwiseCrypto == NONE_CRYPT) {
+        erq->length = 0;
+        erq->flags = IW_ENCODE_DISABLED;
+    } else {
+        /* get the keyIndex */
+        keyIndex = erq->flags & IW_ENCODE_INDEX;
+        if (0 == keyIndex) {
+            keyIndex = ar->arDefTxKeyIndex;
+        } else if ((keyIndex - 1 < WMI_MIN_KEY_INDEX) ||
+                   (keyIndex - 1 > WMI_MAX_KEY_INDEX))
+        {
+            keyIndex = WMI_MIN_KEY_INDEX;
+        } else {
+            keyIndex--;
+        }
+        erq->flags = keyIndex + 1;
+        erq->flags |= IW_ENCODE_ENABLED;
+        wk = &ar->arWepKeyList[keyIndex];
+        if (erq->length > wk->arKeyLen) {
+            erq->length = wk->arKeyLen;
+        }
+        if (wk->arKeyLen) {
+            A_MEMCPY(key, wk->arKey, erq->length);
+        }
+        if (ar->arDot11AuthMode == OPEN_AUTH) {
+            erq->flags |= IW_ENCODE_OPEN;
+        } else if (ar->arDot11AuthMode == SHARED_AUTH) {
+            erq->flags |= IW_ENCODE_RESTRICTED;
+        }
+    }
+
+    return 0;
+}
+
+static int
+ar6000_ioctl_setparam(struct net_device *dev,
+                      struct iw_request_info *info,
+                      void *erq, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    int *i = (int *)extra;
+    int param = i[0];
+    int value = i[1];
+    int ret = 0;
+    A_BOOL profChanged = FALSE;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    switch (param) {
+        case IEEE80211_PARAM_WPA:
+            switch (value) {
+                case WPA_MODE_WPA1:
+                    ar->arAuthMode = WPA_AUTH;
+                    profChanged    = TRUE;
+                    break;
+                case WPA_MODE_WPA2:
+                    ar->arAuthMode = WPA2_AUTH;
+                    profChanged    = TRUE;
+                    break;
+                case WPA_MODE_NONE:
+                    ar->arAuthMode = NONE_AUTH;
+                    profChanged    = TRUE;
+                    break;
+            }
+            break;
+        case IEEE80211_PARAM_AUTHMODE:
+            switch(value) {
+                case IEEE80211_AUTH_WPA_PSK:
+                    if (WPA_AUTH == ar->arAuthMode) {
+                        ar->arAuthMode = WPA_PSK_AUTH;
+                        profChanged    = TRUE;
+                    } else if (WPA2_AUTH == ar->arAuthMode) {
+                        ar->arAuthMode = WPA2_PSK_AUTH;
+                        profChanged    = TRUE;
+                    } else {
+                        AR_DEBUG_PRINTF("Error -  Setting PSK mode when WPA "\
+                                        "param was set to %d\n",
+                                        ar->arAuthMode);
+                        ret = -1;
+                    }
+                    break;
+                case IEEE80211_AUTH_WPA_CCKM:
+                    if (WPA2_AUTH == ar->arAuthMode) {
+                        ar->arAuthMode = WPA2_AUTH_CCKM;
+                    } else {
+                        ar->arAuthMode = WPA_AUTH_CCKM;
+                    }
+                    break;
+                default:
+                    break;
+            }
+            break;
+        case IEEE80211_PARAM_UCASTCIPHER:
+            switch (value) {
+                case IEEE80211_CIPHER_AES_CCM:
+                    ar->arPairwiseCrypto = AES_CRYPT;
+                    profChanged          = TRUE;
+                    break;
+                case IEEE80211_CIPHER_TKIP:
+                    ar->arPairwiseCrypto = TKIP_CRYPT;
+                    profChanged          = TRUE;
+                    break;
+                case IEEE80211_CIPHER_WEP:
+                    ar->arPairwiseCrypto = WEP_CRYPT;
+                    profChanged          = TRUE;
+                    break;
+                case IEEE80211_CIPHER_NONE:
+                    ar->arPairwiseCrypto = NONE_CRYPT;
+                    profChanged          = TRUE;
+                    break;
+            }
+            break;
+        case IEEE80211_PARAM_UCASTKEYLEN:
+            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
+                ret = -EIO;
+            } else {
+                ar->arPairwiseCryptoLen = value;
+            }
+            break;
+        case IEEE80211_PARAM_MCASTCIPHER:
+            switch (value) {
+                case IEEE80211_CIPHER_AES_CCM:
+                    ar->arGroupCrypto = AES_CRYPT;
+                    profChanged       = TRUE;
+                    break;
+                case IEEE80211_CIPHER_TKIP:
+                    ar->arGroupCrypto = TKIP_CRYPT;
+                    profChanged       = TRUE;
+                    break;
+                case IEEE80211_CIPHER_WEP:
+                    ar->arGroupCrypto = WEP_CRYPT;
+                    profChanged       = TRUE;
+                    break;
+                case IEEE80211_CIPHER_NONE:
+                    ar->arGroupCrypto = NONE_CRYPT;
+                    profChanged       = TRUE;
+                    break;
+            }
+            break;
+        case IEEE80211_PARAM_MCASTKEYLEN:
+            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
+                ret = -EIO;
+            } else {
+                ar->arGroupCryptoLen = value;
+            }
+            break;
+        case IEEE80211_PARAM_COUNTERMEASURES:
+            if (ar->arWmiReady == FALSE) {
+                return -EIO;
+            }
+
+            AR6000_SPIN_LOCK(&ar->arLock, 0);
+            wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
+            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+            break;
+        default:
+            break;
+    }
+
+    if (profChanged == TRUE) {
+        /*
+         * profile has changed.  Erase ssid to signal change
+         */
+        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
+    }
+
+    return ret;
+}
+
+int
+ar6000_ioctl_getparam(struct net_device *dev, struct iw_request_info *info,
+            void *w, char *extra)
+{
+    return -EIO;            /* for now */
+}
+
+int
+ar6000_ioctl_setkey(struct net_device *dev, struct iw_request_info *info,
+             void *w, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    struct ieee80211req_key *ik = (struct ieee80211req_key *)extra;
+    KEY_USAGE keyUsage;
+    A_STATUS status;
+    CRYPTO_TYPE keyType = NONE_CRYPT;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    if ( 0 == memcmp(ik->ik_macaddr, "\x00\x00\x00\x00\x00\x00",
+                     IEEE80211_ADDR_LEN)) {
+        keyUsage = GROUP_USAGE;
+    } else {
+        keyUsage = PAIRWISE_USAGE;
+    }
+
+    switch (ik->ik_type) {
+        case IEEE80211_CIPHER_WEP:
+            keyType = WEP_CRYPT;
+            break;
+        case IEEE80211_CIPHER_TKIP:
+            keyType = TKIP_CRYPT;
+            break;
+        case IEEE80211_CIPHER_AES_CCM:
+            keyType = AES_CRYPT;
+            break;
+        default:
+            break;
+    }
+
+    if (IEEE80211_CIPHER_CCKM_KRK != ik->ik_type) {
+        if (NONE_CRYPT == keyType) {
+            return -EIO;
+        }
+
+        status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage,
+                                ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
+                                ik->ik_keydata, SYNC_BEFORE_WMIFLAG);
+
+        if (status != A_OK) {
+            return -EIO;
+        }
+    } else {
+        status = wmi_add_krk_cmd(ar->arWmi, ik->ik_keydata);
+    }
+
+    return 0;
+}
+
+void
+ar6000_install_static_wep_keys(AR_SOFTC_T *ar)
+{
+    A_UINT8 index;
+    A_UINT8 keyUsage;
+
+    for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
+        if (ar->arWepKeyList[index].arKeyLen) {
+            keyUsage = GROUP_USAGE;
+            if (index == ar->arDefTxKeyIndex) {
+                keyUsage |= TX_USAGE;
+            }
+            wmi_addKey_cmd(ar->arWmi,
+                           index,
+                           WEP_CRYPT,
+                           keyUsage,
+                           ar->arWepKeyList[index].arKeyLen,
+                           NULL,
+                           ar->arWepKeyList[index].arKey, NO_SYNC_WMIFLAG);
+        }
+    }
+}
+
+int
+ar6000_ioctl_delkey(struct net_device *dev, struct iw_request_info *info,
+             void *w, char *extra)
+{
+    return 0;
+}
+
+int
+ar6000_ioctl_setmlme(struct net_device *dev, struct iw_request_info *info,
+             void *w, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    struct ieee80211req_mlme *mlme = (struct ieee80211req_mlme *)extra;
+
+    if ((ar->arWmiReady == FALSE) || (ar->arConnected != TRUE)) {
+        return -EIO;
+    }
+
+    switch (mlme->im_op) {
+        case IEEE80211_MLME_DISASSOC:
+        case IEEE80211_MLME_DEAUTH:
+            /* Not Supported */
+            break;
+        default:
+            break;
+    }
+    return 0;
+}
+
+int
+ar6000_ioctl_setwmmparams(struct net_device *dev, struct iw_request_info *info,
+             void *w, char *extra)
+{
+    return -EIO;            /* for now */
+}
+
+int
+ar6000_ioctl_getwmmparams(struct net_device *dev, struct iw_request_info *info,
+             void *w, char *extra)
+{
+    return -EIO;            /* for now */
+}
+
+int
+ar6000_ioctl_setoptie(struct net_device *dev, struct iw_request_info *info,
+             void *w, char *extra)
+{
+    return 0;
+}
+
+int
+ar6000_ioctl_setauthalg(struct net_device *dev, struct iw_request_info *info,
+             void *w, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    struct ieee80211req_authalg *req = (struct ieee80211req_authalg *)extra;
+    int ret = 0;
+
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    if (req->auth_alg == AUTH_ALG_OPEN_SYSTEM) {
+        ar->arDot11AuthMode  = OPEN_AUTH;
+    } else if (req->auth_alg == AUTH_ALG_LEAP) {
+        ar->arDot11AuthMode   = LEAP_AUTH;
+        ar->arPairwiseCrypto  = WEP_CRYPT;
+        ar->arGroupCrypto     = WEP_CRYPT;
+    } else {
+        ret = -EIO;
+    }
+
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return ret;
+}
+static int
+ar6000_ioctl_addpmkid(struct net_device *dev, struct iw_request_info *info,
+             void *w, char *extra)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    struct ieee80211req_addpmkid  *req = (struct ieee80211req_addpmkid *)extra;
+    A_STATUS status;
+
+    if (ar->arWlanState == WLAN_DISABLED) {
+        return -EIO;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+    AR_DEBUG_PRINTF("Add pmkid for %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n",
+                    req->pi_bssid[0], req->pi_bssid[1], req->pi_bssid[2],
+                    req->pi_bssid[3], req->pi_bssid[4], req->pi_bssid[5],
+                    req->pi_enable);
+
+    status = wmi_setPmkid_cmd(ar->arWmi, req->pi_bssid, req->pi_pmkid,
+                              req->pi_enable);
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+    if (status != A_OK) {
+        return -EIO;
+    }
+
+    return 0;
+}
+
+static int
+ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    if(wmi_get_roam_tbl_cmd(ar->arWmi) != A_OK) {
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        return -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return 0;
+}
+
+static int
+ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    /* currently assume only roam times are required */
+    if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != A_OK) {
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        return -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return 0;
+}
+
+static int
+ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_SET_ROAM_CTRL_CMD cmd;
+    A_UINT8 size = sizeof(cmd);
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+
+    if (copy_from_user(&cmd, userdata, size)) {
+        return -EFAULT;
+    }
+
+    if (cmd.roamCtrlType == WMI_SET_HOST_BIAS) {
+        if (cmd.info.bssBiasInfo.numBss > 1) {
+            size += (cmd.info.bssBiasInfo.numBss - 1) * sizeof(WMI_BSS_BIAS);
+        }
+    }
+
+    if (copy_from_user(&cmd, userdata, size)) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != A_OK) {
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        return -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return 0;
+}
+
+static int
+ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_POWERSAVE_TIMERS_CMD cmd;
+    A_UINT8 size = sizeof(cmd);
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    if (copy_from_user(&cmd, userdata, size)) {
+        return -EFAULT;
+    }
+
+    if (copy_from_user(&cmd, userdata, size)) {
+        return -EFAULT;
+    }
+
+    AR6000_SPIN_LOCK(&ar->arLock, 0);
+
+    if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != A_OK) {
+        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+        return -EIO;
+    }
+    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
+
+    return 0;
+}
+
+
+#if defined(DEBUG)
+int dset_debug = 0;
+#define DSET_DEBUG_PRINTF(args...)        if (dset_debug) printk(args);
+#else
+#define DSET_DEBUG_PRINTF(args...)
+#endif
+
+/* Called when a DataSet Open request is received from the Target. */
+void
+ar6000_dset_open_req(void *devt,
+                     A_UINT32 id,
+                     A_UINT32 targ_handle,
+                     A_UINT32 targ_reply_fn,
+                     A_UINT32 targ_reply_arg)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+    DSET_DEBUG_PRINTF("ar6000_dset_open_req id=0x%x\n", id);
+
+    if (!dset_server_alive) {
+        /*
+         * An attempt to open a Host DataSet before the DataSet Server
+         * has started.  (Or this Host chooses not to serve DataSets.)
+         */
+        DSET_DEBUG_PRINTF("DataSet Server not running. Unable to handle open request for id=0x%x\n", id);
+        wmi_dset_open_reply(ar->arWmi, A_ENOTSUP, 0, 0, 0,
+                            targ_handle, targ_reply_fn, targ_reply_arg);
+        return;
+    }
+
+#if CONFIG_HOST_DSET_SUPPORT
+    if (spin_trylock(&dset_request_lock)) {
+        pending_dset_request.cmd                       = AR6000_OPEN_REQ;
+        pending_dset_request.u.open_req.id             = id;
+        pending_dset_request.u.open_req.targ_handle    = targ_handle;
+        pending_dset_request.u.open_req.targ_reply_fn  = targ_reply_fn;
+        pending_dset_request.u.open_req.targ_reply_arg = targ_reply_arg;
+        /* Wakeup waiting thread */
+        pending_dset_request_valid = TRUE;
+        wake_up(&dset_request);
+    } else {
+        wmi_dset_open_reply(ar->arWmi, A_EBUSY, 0, 0, 0,
+                            targ_handle, targ_reply_fn, targ_reply_arg);
+    }
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+}
+
+#if CONFIG_HOST_DSET_SUPPORT
+/* Called when a DataSet Close is received from the Target. */
+void
+ar6000_dset_close(void *devt,
+                  A_UINT32 access_cookie)
+{
+    DSET_DEBUG_PRINTF("ar6000_dset_close access_cookie=0x%x\n", access_cookie);
+}
+
+/* Called when a DataSet Data Request is received from the Target. */
+void
+ar6000_dset_data_req(void *devt,
+                     A_UINT32 access_cookie,
+                     A_UINT32 offset,
+                     A_UINT32 length,
+                     A_UINT32 targ_buf,
+                     A_UINT32 targ_reply_fn,
+                     A_UINT32 targ_reply_arg)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
+
+    DSET_DEBUG_PRINTF("ar6000_dset_data_req: Cookie=0x%x offset=%d length=%d\n",
+        access_cookie, offset, length);
+
+    if (spin_trylock(&dset_request_lock)) {
+        pending_dset_request.cmd                       = AR6000_DATA_REQ;
+        pending_dset_request.u.data_req.access_cookie  = access_cookie;
+        pending_dset_request.u.data_req.offset         = offset;
+        pending_dset_request.u.data_req.length         = length;
+        pending_dset_request.u.data_req.targ_buf       = targ_buf;
+        pending_dset_request.u.data_req.targ_reply_fn  = targ_reply_fn;
+        pending_dset_request.u.data_req.targ_reply_arg = targ_reply_arg;
+
+        /* Wakeup waiting thread */
+        pending_dset_request_valid = TRUE;
+        wake_up(&dset_request);
+    } else {
+        wmi_dset_data_reply(ar->arWmi, A_EBUSY, NULL, length,
+                            targ_buf, targ_reply_fn, targ_reply_arg);
+    }
+}
+
+/* Init cookie queue */
+static void
+ar6000_cookie_init(AR_SOFTC_T *ar)
+{
+    A_UINT32    i;
+
+    ar->arCookieList = NULL;
+    A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem));
+
+    for (i = 0; i < MAX_COOKIE_NUM; i++) {
+        ar6000_free_cookie(ar, &s_ar_cookie_mem[i]);
+    }
+}
+
+/* cleanup cookie queue */
+static void
+ar6000_cookie_cleanup(AR_SOFTC_T *ar)
+{
+    /* It is gone .... */
+    ar->arCookieList = NULL;
+}
+
+/* Init cookie queue */
+static void
+ar6000_free_cookie(AR_SOFTC_T *ar, struct ar_cookie * cookie)
+{
+    /* Insert first */
+    cookie->arc_list_next = ar->arCookieList;
+    ar->arCookieList = cookie;
+}
+
+/* cleanup cookie queue */
+static struct ar_cookie *
+ar6000_alloc_cookie(AR_SOFTC_T  *ar)
+{
+    struct ar_cookie   *cookie;
+
+    cookie = ar->arCookieList;
+    if(cookie != NULL)
+    {
+        ar->arCookieList = cookie->arc_list_next;
+    }
+
+    return cookie;
+}
+
+/* Host-side initialization for DataSets */
+static void
+ar6000_dset_init(void)
+{
+    spin_lock_init(&dset_request_lock);
+    pending_dset_request_valid = FALSE;
+}
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+#if CONFIG_HOST_GPIO_SUPPORT
+/* Host-side initialization for General Purpose I/O support */
+static void
+ar6000_gpio_init(void)
+{
+    gpio_intr_available = FALSE;
+    gpio_data_available = FALSE;
+    gpio_ack_received   = FALSE;
+}
+
+/*
+ * Called when a GPIO interrupt is received from the Target.
+ * intr_values shows which GPIO pins have interrupted.
+ * input_values shows a recent value of GPIO pins.
+ */
+void
+ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values)
+{
+    gpio_intr_results.intr_mask = intr_mask;
+    gpio_intr_results.input_values = input_values;
+    *((volatile A_BOOL *)&gpio_intr_available) = TRUE;
+    wake_up(&arEvent);
+}
+
+/*
+ * This is called when a response is received from the Target
+ * for a previous or ar6000_gpio_input_get or ar6000_gpio_register_get
+ * call.
+ */
+void
+ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value)
+{
+    gpio_reg_results.gpioreg_id = reg_id;
+    gpio_reg_results.value = value;
+    *((volatile A_BOOL *)&gpio_data_available) = TRUE;
+    wake_up(&arEvent);
+}
+
+/*
+ * This is called when an acknowledgement is received from the Target
+ * for a previous or ar6000_gpio_output_set or ar6000_gpio_register_set
+ * call.
+ */
+void
+ar6000_gpio_ack_rx(void)
+{
+    gpio_ack_received = TRUE;
+    wake_up(&arEvent);
+}
+
+A_STATUS
+ar6000_gpio_output_set(struct net_device *dev,
+                       A_UINT32 set_mask,
+                       A_UINT32 clear_mask,
+                       A_UINT32 enable_mask,
+                       A_UINT32 disable_mask)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    gpio_ack_received = FALSE;
+    return wmi_gpio_output_set(ar->arWmi,
+                set_mask, clear_mask, enable_mask, disable_mask);
+}
+
+static A_STATUS
+ar6000_gpio_input_get(struct net_device *dev)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    *((volatile A_BOOL *)&gpio_data_available) = FALSE;
+    return wmi_gpio_input_get(ar->arWmi);
+}
+
+static A_STATUS
+ar6000_gpio_register_set(struct net_device *dev,
+                         A_UINT32 gpioreg_id,
+                         A_UINT32 value)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    gpio_ack_received = FALSE;
+    return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value);
+}
+
+static A_STATUS
+ar6000_gpio_register_get(struct net_device *dev,
+                         A_UINT32 gpioreg_id)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    *((volatile A_BOOL *)&gpio_data_available) = FALSE;
+    return wmi_gpio_register_get(ar->arWmi, gpioreg_id);
+}
+
+static A_STATUS
+ar6000_gpio_intr_ack(struct net_device *dev,
+                     A_UINT32 ack_mask)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+
+    gpio_intr_available = FALSE;
+    return wmi_gpio_intr_ack(ar->arWmi, ack_mask);
+}
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+/* Structures to export the Wireless Handlers */
+static const iw_handler ath_handlers[] = {
+    (iw_handler) NULL,                          /* SIOCSIWCOMMIT */
+    (iw_handler) ar6000_ioctl_giwname,          /* SIOCGIWNAME */
+    (iw_handler) NULL,                          /* SIOCSIWNWID */
+    (iw_handler) NULL,                          /* SIOCGIWNWID */
+    (iw_handler) ar6000_ioctl_siwfreq,          /* SIOCSIWFREQ */
+    (iw_handler) ar6000_ioctl_giwfreq,          /* SIOCGIWFREQ */
+    (iw_handler) ar6000_ioctl_siwmode,          /* SIOCSIWMODE */
+    (iw_handler) ar6000_ioctl_giwmode,          /* SIOCGIWMODE */
+    (iw_handler) ar6000_ioctl_siwsens,          /* SIOCSIWSENS */
+    (iw_handler) ar6000_ioctl_giwsens,          /* SIOCGIWSENS */
+    (iw_handler) NULL /* not _used */,          /* SIOCSIWRANGE */
+    (iw_handler) ar6000_ioctl_giwrange,         /* SIOCGIWRANGE */
+    (iw_handler) NULL /* not used */,           /* SIOCSIWPRIV */
+    (iw_handler) NULL /* kernel code */,        /* SIOCGIWPRIV */
+    (iw_handler) NULL /* not used */,           /* SIOCSIWSTATS */
+    (iw_handler) NULL /* kernel code */,        /* SIOCGIWSTATS */
+    (iw_handler) NULL,                          /* SIOCSIWSPY */
+    (iw_handler) NULL,                          /* SIOCGIWSPY */
+    (iw_handler) NULL,                          /* SIOCSIWTHRSPY */
+    (iw_handler) NULL,                          /* SIOCGIWTHRSPY */
+    (iw_handler) ar6000_ioctl_siwap,            /* SIOCSIWAP */
+    (iw_handler) ar6000_ioctl_giwap,            /* SIOCGIWAP */
+    (iw_handler) NULL,                          /* -- hole -- */
+    (iw_handler) ar6000_ioctl_iwaplist,         /* SIOCGIWAPLIST */
+    (iw_handler) ar6000_ioctl_siwscan,          /* SIOCSIWSCAN */
+    (iw_handler) ar6000_ioctl_giwscan,          /* SIOCGIWSCAN */
+    (iw_handler) ar6000_ioctl_siwessid,         /* SIOCSIWESSID */
+    (iw_handler) ar6000_ioctl_giwessid,         /* SIOCGIWESSID */
+    (iw_handler) NULL,                          /* SIOCSIWNICKN */
+    (iw_handler) NULL,                          /* SIOCGIWNICKN */
+    (iw_handler) NULL,                          /* -- hole -- */
+    (iw_handler) NULL,                          /* -- hole -- */
+    (iw_handler) ar6000_ioctl_siwrate,          /* SIOCSIWRATE */
+    (iw_handler) ar6000_ioctl_giwrate,          /* SIOCGIWRATE */
+#ifdef NOTYET
+    (iw_handler) ar6000_ioctl_siwrts,           /* SIOCSIWRTS */
+    (iw_handler) ar6000_ioctl_giwrts,           /* SIOCGIWRTS */
+    (iw_handler) ar6000_ioctl_siwfrag,          /* SIOCSIWFRAG */
+    (iw_handler) ar6000_ioctl_giwfrag,          /* SIOCGIWFRAG */
+    (iw_handler) ar6000_ioctl_siwtxpow,         /* SIOCSIWTXPOW */
+    (iw_handler) ar6000_ioctl_giwtxpow,         /* SIOCGIWTXPOW */
+    (iw_handler) ar6000_ioctl_siwretry,         /* SIOCSIWRETRY */
+    (iw_handler) ar6000_ioctl_giwretry,         /* SIOCGIWRETRY */
+    (iw_handler) ar6000_ioctl_siwencode,        /* SIOCSIWENCODE */
+    (iw_handler) ar6000_ioctl_giwencode,        /* SIOCGIWENCODE */
+    (iw_handler) ar6000_ioctl_siwpower,         /* SIOCSIWPOWER */
+    (iw_handler) ar6000_ioctl_giwpower,         /* SIOCGIWPOWER */
+#else
+    (iw_handler) NULL,           /* SIOCSIWRTS */
+    (iw_handler) NULL,           /* SIOCGIWRTS */
+    (iw_handler) NULL,          /* SIOCSIWFRAG */
+    (iw_handler) NULL,          /* SIOCGIWFRAG */
+    (iw_handler) ar6000_ioctl_siwtxpow,         /* SIOCSIWTXPOW */
+    (iw_handler) ar6000_ioctl_giwtxpow,         /* SIOCGIWTXPOW */
+    (iw_handler) ar6000_ioctl_siwretry,         /* SIOCSIWRETRY */
+    (iw_handler) ar6000_ioctl_giwretry,         /* SIOCGIWRETRY */
+    (iw_handler) ar6000_ioctl_siwencode,        /* SIOCSIWENCODE */
+    (iw_handler) ar6000_ioctl_giwencode,        /* SIOCGIWENCODE */
+    (iw_handler) NULL,         /* SIOCSIWPOWER */
+    (iw_handler) NULL,         /* SIOCGIWPOWER */
+#endif  /* NOTYET */
+};
+
+static const iw_handler ath_priv_handlers[] = {
+    (iw_handler) ar6000_ioctl_setparam,         /* SIOCWFIRSTPRIV+0 */
+    (iw_handler) ar6000_ioctl_getparam,         /* SIOCWFIRSTPRIV+1 */
+    (iw_handler) ar6000_ioctl_setkey,           /* SIOCWFIRSTPRIV+2 */
+    (iw_handler) ar6000_ioctl_setwmmparams,     /* SIOCWFIRSTPRIV+3 */
+    (iw_handler) ar6000_ioctl_delkey,           /* SIOCWFIRSTPRIV+4 */
+    (iw_handler) ar6000_ioctl_getwmmparams,     /* SIOCWFIRSTPRIV+5 */
+    (iw_handler) NULL,                          /* SIOCWFIRSTPRIV+6 */
+    (iw_handler) NULL,                          /* SIOCWFIRSTPRIV+7 */
+    (iw_handler) ar6000_ioctl_addpmkid,         /* SIOCWFIRSTPRIV+8 */
+    (iw_handler) NULL,                          /* SIOCWFIRSTPRIV+9 */
+#ifdef NOT_YET
+    (iw_handler) ar6000_ioctl_setauthalg,       /* SIOCWFIRSTPRIV+10 */
+#endif
+};
+
+#define IW_PRIV_TYPE_KEY \
+    (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_key))
+#define IW_PRIV_TYPE_DELKEY \
+    (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_del_key))
+#define IW_PRIV_TYPE_MLME \
+    (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme))
+#define IW_PRIV_TYPE_ADDPMKID \
+    (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_addpmkid))
+
+static const struct iw_priv_args ar6000_priv_args[] = {
+    { IEEE80211_IOCTL_SETKEY,
+      IW_PRIV_TYPE_KEY | IW_PRIV_SIZE_FIXED, 0,       "setkey"},
+    { IEEE80211_IOCTL_DELKEY,
+      IW_PRIV_TYPE_DELKEY | IW_PRIV_SIZE_FIXED, 0,    "delkey"},
+    { IEEE80211_IOCTL_SETPARAM,
+      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0,   "setparam"},
+    { IEEE80211_IOCTL_GETPARAM,
+      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,      "getparam"},
+    { IEEE80211_IOCTL_SETWMMPARAMS,
+      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, 0,   "setwmmparams"},
+    { IEEE80211_IOCTL_GETWMMPARAMS,
+      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
+      IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,      "getwmmparams"},
+    { IEEE80211_IOCTL_ADDPMKID,
+      IW_PRIV_TYPE_ADDPMKID | IW_PRIV_SIZE_FIXED, 0,  "addpmkid"},
+};
+
+static void
+ar6000_ioctl_iwsetup(struct iw_handler_def *def)
+{
+#define N(a) (sizeof(a) / sizeof(a[0]))
+    def->private_args = (struct iw_priv_args *)ar6000_priv_args;
+    def->num_private_args = N(ar6000_priv_args);
+#undef N
+}
+
+static struct iw_handler_def ath_iw_handler_def = {
+#define N(a) (sizeof (a) / sizeof (a[0]))
+    .standard         = (iw_handler *)ath_handlers,
+    .num_standard     = N(ath_handlers),
+    .private          = (iw_handler *)ath_priv_handlers,
+    .num_private      = N(ath_priv_handlers),
+#undef N
+};
+
+void *
+a_netbuf_alloc(int size)
+{
+    struct sk_buff *skb;
+
+    skb = dev_alloc_skb(AR6000_DATA_OFFSET + size);
+    skb_reserve(skb, AR6000_DATA_OFFSET);
+
+    return ((void *)skb);
+}
+
+void
+a_netbuf_free(void *bufPtr)
+{
+    struct sk_buff *skb = (struct sk_buff *)bufPtr;
+
+    dev_kfree_skb(skb);
+}
+
+A_UINT32
+a_netbuf_to_len(void *bufPtr)
+{
+    return (((struct sk_buff *)bufPtr)->len);
+}
+
+void *
+a_netbuf_to_data(void *bufPtr)
+{
+    return (((struct sk_buff *)bufPtr)->data);
+}
+
+/*
+ * Add len # of bytes to the beginning of the network buffer
+ * pointed to by bufPtr
+ */
+A_STATUS
+a_netbuf_push(void *bufPtr, A_INT32 len)
+{
+    skb_push((struct sk_buff *)bufPtr, len);
+
+    return A_OK;
+}
+
+/*
+ * Add len # of bytes to the end of the network buffer
+ * pointed to by bufPtr
+ */
+A_STATUS
+a_netbuf_put(void *bufPtr, A_INT32 len)
+{
+    skb_put((struct sk_buff *)bufPtr, len);
+
+    return A_OK;
+}
+
+/*
+ * Trim the network buffer pointed to by bufPtr to len # of bytes
+ */
+A_STATUS
+a_netbuf_trim(void *bufPtr, A_INT32 len)
+{
+    skb_trim((struct sk_buff *)bufPtr, len);
+
+    return A_OK;
+}
+
+/*
+ * Returns the number of bytes available to a a_netbuf_push()
+ */
+A_INT32
+a_netbuf_headroom(void *bufPtr)
+{
+    return (skb_headroom((struct sk_buff *)bufPtr));
+}
+
+/*
+ * Removes specified number of bytes from the beginning of the buffer
+ */
+A_STATUS
+a_netbuf_pull(void *bufPtr, A_INT32 len)
+{
+    skb_pull((struct sk_buff *)bufPtr, len);
+
+    return A_OK;
+}
+
+A_UINT32
+a_copy_to_user(void *to, const void *from, A_UINT32 n)
+{
+    return(copy_to_user(to, from, n));
+}
+
+A_UINT32
+a_copy_from_user(void *to, const void *from, A_UINT32 n)
+{
+    return(copy_from_user(to, from, n));
+}
+
+/* Get power mode command */
+static int
+ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq)
+{
+    AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv;
+    WMI_POWER_MODE_CMD power_mode;
+    int ret = 0;
+
+    if (ar->arWmiReady == FALSE) {
+        return -EIO;
+    }
+
+    power_mode.powerMode = wmi_get_power_mode_cmd(ar->arWmi);
+    if (copy_to_user(rq->ifr_data, &power_mode, sizeof(WMI_POWER_MODE_CMD))) {
+        ret = -EFAULT;
+    }
+
+    return ret;
+}

Added: developers/nbd/ar6k/ar6000/ar6000_drv.h
===================================================================
--- developers/nbd/ar6k/ar6000/ar6000_drv.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/ar6000/ar6000_drv.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the definitions for the AR6000 linux driver.
+ *
+ */
+
+#ifndef _AR6000_H_
+#define _AR6000_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_AR6000                  1
+#define AR6000_MAX_RX_BUFFERS       16
+#define AR6000_BUFFER_SIZE          1552
+#define AR6000_DATA_OFFSET          64
+#define AR6000_TX_TIMEOUT           10
+#define AR6000_ETH_ADDR_LEN         6
+#define AR6000_MAX_ENDPOINTS        4
+#define MAX_NODE_NUM                15
+#define MAX_COOKIE_NUM              150
+
+struct ar_wep_key {
+    A_UINT8                 arKeyIndex;
+    A_UINT8                 arKeyLen;
+    A_UINT8                 arKey[64];
+} ;
+
+struct ar_node_mapping {
+    A_UINT8                 macAddress[6];
+    A_UINT8                 epId;
+    A_UINT8                 txPending;
+};
+
+struct ar_cookie {
+    A_UINT32               arc_bp[2];    /* Must be first field */
+    struct ar_cookie *arc_list_next;
+};
+
+typedef struct ar6_softc {
+    struct net_device       *arNetDev;    /* net_device pointer */
+    void                    *arWmi;
+    int                     arTxPending[AR6000_MAX_ENDPOINTS];
+    int                     arTotalTxDataPending;
+    A_UINT8                 arNumDataEndPts;
+    A_BOOL                  arWmiEnabled;
+    A_BOOL                  arWmiReady;
+    A_BOOL                  arConnected;
+    void                    *arHtcTarget;
+    void                    *arHifDevice;
+    spinlock_t              arLock;
+    struct semaphore        arSem;
+    int                     arRxBuffers[AR6000_MAX_ENDPOINTS];
+    int                     arSsidLen;
+    u_char                  arSsid[32];
+    A_UINT8                 arNetworkType;
+    A_UINT8                 arDot11AuthMode;
+    A_UINT8                 arAuthMode;
+    A_UINT8                 arPairwiseCrypto;
+    A_UINT8                 arPairwiseCryptoLen;
+    A_UINT8                 arGroupCrypto;
+    A_UINT8                 arGroupCryptoLen;
+    A_UINT8                 arDefTxKeyIndex;
+    struct ar_wep_key       arWepKeyList[WMI_MAX_KEY_INDEX + 1];
+    A_UINT8                 arBssid[6];
+    A_UINT8                 arReqBssid[6];
+    A_UINT16                arChannelHint;
+    A_UINT16                arBssChannel;
+    A_UINT16                arListenInterval;
+    struct ar6000_version   arVersion;
+    A_INT8                  arRssi;
+    A_UINT8                 arTxPwr;
+    A_BOOL                  arTxPwrSet;
+    A_INT32                 arBitRate;
+    struct net_device_stats arNetStats;
+    struct iw_statistics    arIwStats;
+    A_INT8                  arNumChannels;
+    A_UINT16                arChannelList[32];
+    A_UINT32                arRegCode;
+    A_BOOL                  statsUpdatePending;
+    TARGET_STATS            arTargetStats;
+    A_INT8                  arMaxRetries;
+    A_UINT8                 arPhyCapability;
+    AR6000_WLAN_STATE       arWlanState;
+    struct ar_node_mapping  arNodeMap[MAX_NODE_NUM];
+    A_UINT8                 arIbssPsEnable;
+    A_UINT8                 arNodeNum;
+    A_UINT8                 arNexEpId;
+    struct ar_cookie        *arCookieList;
+    A_BOOL                  arConnectPending;
+} AR_SOFTC_T;
+
+struct ar_giwscan_param {
+    char    *current_ev;
+    char    *end_buf;
+    A_BOOL  firstPass;
+};
+
+#define AR6000_STAT_INC(ar, stat)       (ar->arNetStats.stat++)
+
+#define AR6000_SPIN_LOCK(lock, param)   do {                            \
+    if (irqs_disabled()) {                                              \
+        AR_DEBUG_PRINTF("IRQs disabled:AR6000_LOCK\n");                 \
+    }                                                                   \
+    spin_lock_bh(lock);                                                 \
+} while (0)
+
+#define AR6000_SPIN_UNLOCK(lock, param) do {                            \
+    if (irqs_disabled()) {                                              \
+        AR_DEBUG_PRINTF("IRQs disabled: AR6000_UNLOCK\n");              \
+    }                                                                   \
+    spin_unlock_bh(lock);                                               \
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AR6000_H_ */

Added: developers/nbd/ar6k/bmi/Makefile
===================================================================
--- developers/nbd/ar6k/bmi/Makefile	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/bmi/Makefile	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1 @@
+obj-$(CONFIG_SDIO_AR6000_WLAN)			+= bmi.o

Added: developers/nbd/ar6k/bmi/bmi.c
===================================================================
--- developers/nbd/ar6k/bmi/bmi.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/bmi/bmi.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the routines that implement the Boot loader messaging
+ * interface
+ */
+
+#include "../include/hif.h"
+#include "../include/bmi.h"
+#include "../include/htc.h"
+#include "bmi_internal.h"
+
+/*
+Although we had envisioned BMI to run on top of HTC, this is not what the
+final implementation boiled down to on dragon. Its a part of BSP and does
+not use the HTC protocol either. On the host side, however, we were still
+living with the original idea. I think the time has come to accept the truth
+and separate it from HTC which has been carrying BMI's burden all this while.
+It shall make HTC state machine relatively simpler
+*/
+
+/* ------ Static Variables ------ */
+
+/* ------ Global Variable Declarations ------- */
+A_BOOL bmiDone;
+extern A_UINT32 debugbmi;
+
+#ifdef DEBUG
+#define AR_DEBUG_PRINTF(...)        if (debugbmi) A_PRINTF(__VA_ARGS__);
+#else
+#define AR_DEBUG_PRINTF(...)
+#endif
+
+/* APIs visible to the driver */
+void
+BMIInit(void)
+{
+    bmiDone = FALSE;
+}
+
+A_STATUS
+BMIDone(HIF_DEVICE *device)
+{
+    A_STATUS status;
+    A_UINT32 cid;
+
+    if (bmiDone) {
+        AR_DEBUG_PRINTF("Command disallowed\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF("BMI Done: Enter (device: 0x%p)\n", device);
+    bmiDone = TRUE;
+    cid = BMI_DONE;
+
+    status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to write to the device\n");
+        return A_ERROR;
+    }
+    AR_DEBUG_PRINTF("BMI Done: Exit\n");
+
+    return A_OK;
+}
+
+A_STATUS
+BMIGetTargetId(HIF_DEVICE *device, A_UINT32 *id)
+{
+    A_STATUS status;
+    A_UINT32 cid;
+
+    if (bmiDone) {
+        AR_DEBUG_PRINTF("Command disallowed\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF("BMI Get Target ID: Enter (device: 0x%p)\n", device);
+    cid = BMI_GET_TARGET_ID;
+
+    status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to write to the device\n");
+        return A_ERROR;
+    }
+
+    status = bmiBufferReceive(device, (A_UCHAR *)id, sizeof(*id));
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to read from the device\n");
+        return A_ERROR;
+    }
+    AR_DEBUG_PRINTF("BMI Get Target ID: Exit (ID: 0x%x)\n", *id);
+
+    return A_OK;
+}
+
+A_STATUS
+BMIReadMemory(HIF_DEVICE *device,
+              A_UINT32 address,
+              A_UCHAR *buffer,
+              A_UINT32 length)
+{
+    A_UINT32 cid;
+    A_STATUS status;
+    A_UINT32 offset;
+    A_UINT32 remaining, rxlen;
+    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
+    A_UCHAR data[BMI_DATASZ_MAX + header];
+
+    if (bmiDone) {
+        AR_DEBUG_PRINTF("Command disallowed\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF(
+       "BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
+        device, address, length);
+
+    cid = BMI_READ_MEMORY;
+
+    remaining = length;
+    while (remaining)
+    {
+        rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX;
+        offset = 0;
+        A_MEMCPY(&data[offset], &cid, sizeof(cid));
+        offset += sizeof(cid);
+        A_MEMCPY(&data[offset], &address, sizeof(address));
+        offset += sizeof(address);
+        A_MEMCPY(&data[offset], &rxlen, sizeof(rxlen));
+        offset += sizeof(length);
+        status = bmiBufferSend(device, data, offset);
+        if (status != A_OK) {
+            AR_DEBUG_PRINTF("Unable to write to the device\n");
+            return A_ERROR;
+        }
+        status = bmiBufferReceive(device, data, rxlen);
+        if (status != A_OK) {
+            AR_DEBUG_PRINTF("Unable to read from the device\n");
+            return A_ERROR;
+        }
+        A_MEMCPY(&buffer[length - remaining], data, rxlen);
+        remaining -= rxlen; address += rxlen;
+    }
+
+    AR_DEBUG_PRINTF("BMI Read Memory: Exit\n");
+    return A_OK;
+}
+
+A_STATUS
+BMIWriteMemory(HIF_DEVICE *device,
+               A_UINT32 address,
+               A_UCHAR *buffer,
+               A_UINT32 length)
+{
+    A_UINT32 cid;
+    A_STATUS status;
+    A_UINT32 offset;
+    A_UINT32 remaining, txlen;
+    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
+    A_UCHAR data[BMI_DATASZ_MAX + header];
+
+    if (bmiDone) {
+        AR_DEBUG_PRINTF("Command disallowed\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF(
+         "BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n",
+          device, address, length);
+
+    cid = BMI_WRITE_MEMORY;
+
+    remaining = length;
+    while (remaining)
+    {
+        txlen = (remaining < (BMI_DATASZ_MAX - header)) ?
+                                       remaining : (BMI_DATASZ_MAX - header);
+        offset = 0;
+        A_MEMCPY(&data[offset], &cid, sizeof(cid));
+        offset += sizeof(cid);
+        A_MEMCPY(&data[offset], &address, sizeof(address));
+        offset += sizeof(address);
+        A_MEMCPY(&data[offset], &txlen, sizeof(txlen));
+        offset += sizeof(txlen);
+        A_MEMCPY(&data[offset], &buffer[length - remaining], txlen);
+        offset += txlen;
+        status = bmiBufferSend(device, data, offset);
+        if (status != A_OK) {
+            AR_DEBUG_PRINTF("Unable to write to the device\n");
+            return A_ERROR;
+        }
+        remaining -= txlen; address += txlen;
+    }
+
+    AR_DEBUG_PRINTF("BMI Write Memory: Exit\n");
+
+    return A_OK;
+}
+
+A_STATUS
+BMIExecute(HIF_DEVICE *device,
+           A_UINT32 address,
+           A_UINT32 *param)
+{
+    A_UINT32 cid;
+    A_STATUS status;
+    A_UINT32 offset;
+    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(*param);
+    A_UCHAR data[header];
+
+    if (bmiDone) {
+        AR_DEBUG_PRINTF("Command disallowed\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF(
+       "BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
+        device, address, *param);
+
+    cid = BMI_EXECUTE;
+
+    offset = 0;
+    A_MEMCPY(&data[offset], &cid, sizeof(cid));
+    offset += sizeof(cid);
+    A_MEMCPY(&data[offset], &address, sizeof(address));
+    offset += sizeof(address);
+    A_MEMCPY(&data[offset], param, sizeof(*param));
+    offset += sizeof(*param);
+    status = bmiBufferSend(device, data, offset);
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to write to the device\n");
+        return A_ERROR;
+    }
+
+    status = bmiBufferReceive(device, data, sizeof(*param));
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to read from the device\n");
+        return A_ERROR;
+    }
+
+    A_MEMCPY(param, data, sizeof(*param));
+
+    AR_DEBUG_PRINTF("BMI Execute: Exit (param: %d)\n", *param);
+    return A_OK;
+}
+
+A_STATUS
+BMISetAppStart(HIF_DEVICE *device,
+               A_UINT32 address)
+{
+    A_UINT32 cid;
+    A_STATUS status;
+    A_UINT32 offset;
+    const A_UINT32 header = sizeof(cid) + sizeof(address);
+    A_UCHAR data[header];
+
+    if (bmiDone) {
+        AR_DEBUG_PRINTF("Command disallowed\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF(
+       "BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n",
+        device, address);
+
+    cid = BMI_SET_APP_START;
+
+    offset = 0;
+    A_MEMCPY(&data[offset], &cid, sizeof(cid));
+    offset += sizeof(cid);
+    A_MEMCPY(&data[offset], &address, sizeof(address));
+    offset += sizeof(address);
+    status = bmiBufferSend(device, data, offset);
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to write to the device\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF("BMI Set App Start: Exit\n");
+    return A_OK;
+}
+
+A_STATUS
+BMIReadSOCRegister(HIF_DEVICE *device,
+                   A_UINT32 address,
+                   A_UINT32 *param)
+{
+    A_UINT32 cid;
+    A_STATUS status;
+    A_UINT32 offset;
+    const A_UINT32 header = sizeof(cid) + sizeof(address);
+    A_UCHAR data[header];
+
+    if (bmiDone) {
+        AR_DEBUG_PRINTF("Command disallowed\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF(
+       "BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n",
+        device, address);
+
+    cid = BMI_READ_SOC_REGISTER;
+
+    offset = 0;
+    A_MEMCPY(&data[offset], &cid, sizeof(cid));
+    offset += sizeof(cid);
+    A_MEMCPY(&data[offset], &address, sizeof(address));
+    offset += sizeof(address);
+    status = bmiBufferSend(device, data, offset);
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to write to the device\n");
+        return A_ERROR;
+    }
+
+    status = bmiBufferReceive(device, data, sizeof(*param));
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to read from the device\n");
+        return A_ERROR;
+    }
+    A_MEMCPY(param, data, sizeof(*param));
+
+    AR_DEBUG_PRINTF("BMI Read SOC Register: Exit (value: %d)\n", *param);
+    return A_OK;
+}
+
+A_STATUS
+BMIWriteSOCRegister(HIF_DEVICE *device,
+                    A_UINT32 address,
+                    A_UINT32 param)
+{
+    A_UINT32 cid;
+    A_STATUS status;
+    A_UINT32 offset;
+    const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(param);
+    A_UCHAR data[header];
+
+    if (bmiDone) {
+        AR_DEBUG_PRINTF("Command disallowed\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF(
+     "BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n",
+      device, address, param);
+
+    cid = BMI_WRITE_SOC_REGISTER;
+
+    offset = 0;
+    A_MEMCPY(&data[offset], &cid, sizeof(cid));
+    offset += sizeof(cid);
+    A_MEMCPY(&data[offset], &address, sizeof(address));
+    offset += sizeof(address);
+    A_MEMCPY(&data[offset], &param, sizeof(param));
+    offset += sizeof(param);
+    status = bmiBufferSend(device, data, offset);
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF("Unable to write to the device\n");
+        return A_ERROR;
+    }
+
+    AR_DEBUG_PRINTF("BMI Read SOC Register: Exit\n");
+    return A_OK;
+}
+
+/* BMI Access routines */
+A_STATUS
+bmiBufferSend(HIF_DEVICE *device,
+              A_UCHAR *buffer,
+              A_UINT32 length)
+{
+    A_STATUS status;
+    A_UINT32 timeout;
+    A_UINT32 address;
+    A_UCHAR cmdCredits;
+    HIF_REQUEST request;
+    A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
+
+    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
+                       &mboxAddress, sizeof(mboxAddress));
+
+    cmdCredits = 0;
+    timeout = BMI_COMMUNICATION_TIMEOUT;
+    while(timeout-- && !cmdCredits) {
+        /* Read the counter register to get the command credits */
+        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                          HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+        address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
+        status = HIFReadWrite(device, address, &cmdCredits, 1,
+                              &request, NULL);
+        if (status != A_OK) {
+            AR_DEBUG_PRINTF("Unable to decrement the command credit count register\n");
+            return A_ERROR;
+        }
+    }
+
+    if (cmdCredits) {
+        HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,
+                              HIF_SYNCHRONOUS, HIF_BYTE_BASIS,
+                              HIF_INCREMENTAL_ADDRESS);
+        address = mboxAddress[ENDPOINT1];
+        status = HIFReadWrite(device, address, buffer, length, &request, NULL);
+        if (status != A_OK) {
+            AR_DEBUG_PRINTF("Unable to send the BMI data to the device\n");
+            return A_ERROR;
+        }
+    } else {
+        AR_DEBUG_PRINTF("BMI Communication timeout\n");
+        return A_ERROR;
+    }
+
+    return status;
+}
+
+A_STATUS
+bmiBufferReceive(HIF_DEVICE *device,
+                 A_UCHAR *buffer,
+                 A_UINT32 length)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    A_UINT32 timeout;
+    A_UCHAR cmdCredits;
+    HIF_REQUEST request;
+    A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
+
+    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
+                       &mboxAddress, sizeof(mboxAddress));
+
+    cmdCredits = 0;
+    timeout = BMI_COMMUNICATION_TIMEOUT;
+    while(timeout-- && !cmdCredits) {
+        /* Read the counter register to get the command credits */
+        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                          HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+        address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1;
+        status = HIFReadWrite(device, address, &cmdCredits, sizeof(cmdCredits),
+                              &request, NULL);
+        if (status != A_OK) {
+            AR_DEBUG_PRINTF("Unable to decrement the command credit count register\n");
+            return A_ERROR;
+        }
+        status = A_ERROR;
+    }
+
+    if (cmdCredits) {
+        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,
+                          HIF_SYNCHRONOUS, HIF_BYTE_BASIS,
+                          HIF_INCREMENTAL_ADDRESS);
+        address = mboxAddress[ENDPOINT1];
+        status = HIFReadWrite(device, address, buffer, length, &request, NULL);
+        if (status != A_OK) {
+            AR_DEBUG_PRINTF("Unable to read the BMI data from the device\n");
+            return A_ERROR;
+        }
+    } else {
+        AR_DEBUG_PRINTF("BMI Communication timeout\n");
+        return A_ERROR;
+    }
+
+    return status;
+}

Added: developers/nbd/ar6k/bmi/bmi_internal.h
===================================================================
--- developers/nbd/ar6k/bmi/bmi_internal.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/bmi/bmi_internal.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ */
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/osapi.h"
+#include "../include/hw/mbox_host_reg.h"
+#include "../include/AR6000_bmi.h"
+
+#define BMI_COMMUNICATION_TIMEOUT       100000
+
+A_STATUS
+bmiBufferSend(HIF_DEVICE *device,
+              A_UCHAR *buffer,
+              A_UINT32 length);
+
+A_STATUS
+bmiBufferReceive(HIF_DEVICE *device,
+                 A_UCHAR *buffer,
+                 A_UINT32 length);

Added: developers/nbd/ar6k/hif/Makefile
===================================================================
--- developers/nbd/ar6k/hif/Makefile	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/hif/Makefile	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SDIO_AR6000_WLAN)  += hif.o
+

Added: developers/nbd/ar6k/hif/hif.c
===================================================================
--- developers/nbd/ar6k/hif/hif.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/hif/hif.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2004-2005 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the routines handling the interaction with the SDIO
+ * driver
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/mmc/core.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ops.h>
+#include "hif_internal.h"
+
+/* ------ Static Variables ------ */
+
+/* ------ Global Variable Declarations ------- */
+
+
+const struct sdio_device_id ar6k_id_table[] = {
+	{ SDIO_DEVICE(SDIO_ANY_ID, 0x10b) },
+	{ SDIO_DEVICE(SDIO_ANY_ID, 0x10a) },
+	{ SDIO_DEVICE(SDIO_ANY_ID, 0x109) },
+	{ SDIO_DEVICE(SDIO_ANY_ID, 0x108) },
+	{},
+};
+
+struct sdio_driver ar6k_driver = {
+	.name = "sdio_wlan",
+	.id_table = ar6k_id_table,
+	.probe = hifDeviceInserted,
+	.remove = hifDeviceRemoved,
+};
+
+HTC_CALLBACKS htcCallbacks;
+#if 0
+extern A_UINT32 onebitmode;
+extern A_UINT32 busspeedlow;
+extern A_UINT32 debughif;
+#endif
+
+#define PFX "ar6k_hif: "
+#ifdef DEBUG
+#define ATH_DEBUG_ERROR 1
+#define ATH_DEBUG_WARN  2
+#define ATH_DEBUG_TRACE 3
+#define _AR_DEBUG_PRINTX_ARG(arg...) arg
+#define AR_DEBUG_PRINTF(lvl, args) \
+		A_PRINTF(KERN_ALERT _AR_DEBUG_PRINTX_ARG args);
+#else
+#define AR_DEBUG_PRINTF(lvl, args)
+#endif
+
+/* ------ Functions ------ */
+void
+HIFRegisterCallbacks(HTC_CALLBACKS *callbacks)
+{
+	/* Store the callback and event handlers */
+	htcCallbacks.deviceInsertedHandler = callbacks->deviceInsertedHandler;
+	htcCallbacks.deviceRemovedHandler = callbacks->deviceRemovedHandler;
+	htcCallbacks.deviceSuspendHandler = callbacks->deviceSuspendHandler;
+	htcCallbacks.deviceResumeHandler = callbacks->deviceResumeHandler;
+	htcCallbacks.deviceWakeupHandler = callbacks->deviceWakeupHandler;
+	htcCallbacks.rwCompletionHandler = callbacks->rwCompletionHandler;
+	htcCallbacks.dsrHandler = callbacks->dsrHandler;
+
+	/* Register with bus driver core */
+	if (sdio_register_driver(&ar6k_driver))
+		printk(PFX "failed to register SDIO driver\n");
+}
+
+A_STATUS
+HIFReadWrite(HIF_DEVICE *device,
+			 A_UINT32 address,
+			 A_UCHAR *buffer,
+			 A_UINT32 length,
+			 HIF_REQUEST *request,
+			 void *context)
+{
+	int ret;
+	u8 write, bang;
+
+	/* XXX: handle bigger block sizes */
+#if 0
+	if (request->dmode == HIF_BLOCK_BASIS) {
+		data->blocksz = HIF_MBOX_BLOCK_SIZE;
+		data->blocks = length / HIF_MBOX_BLOCK_SIZE;
+		count = data->blocks;
+		AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+						("Block mode (BlockLen: %d, BlockCount: %d)\n",
+						data.blocksz, data.blocks));
+	} else if (request->dmode == HIF_BYTE_BASIS) {
+		data->blocksz = length;
+		data->blocks = 1;
+		AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+						("Byte mode (BlockLen: %d, BlockCount: %d)\n",
+						data.blocksz, data.blocks));
+	} else {
+		AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+						("Invalid data mode: %d\n", request->dmode));
+		goto err3;
+	}
+#endif
+
+	if ((address >= HIF_MBOX_START_ADDR(0)) &&
+		(address <= HIF_MBOX_END_ADDR(3)))
+	{
+		/*
+		 * Mailbox write. Adjust the address so that the last byte
+		 * falls on the EOM address.
+		 */
+		address += (HIF_MBOX_WIDTH - length);
+	}
+
+	write = (request->direction == HIF_WRITE);
+	bang = !(request->amode == HIF_INCREMENTAL_ADDRESS);
+
+	printk("rwreq: %s at 0x%x [bang=%d, len=%d, async=%d]\n", (write ? "write" : "read"), address, bang, length, (request->emode == HIF_ASYNCHRONOUS));
+	/* XXX: does not handle block mode with blocksz != 1 properly yet */
+	/* Send the command out */
+	if (request->emode == HIF_ASYNCHRONOUS) {
+		mmc_async_io_rw_extended(device->card, write, device->num, address, bang, buffer, length, hifRWCompletionHandler, context);
+		return A_OK;
+	}
+
+	ret = mmc_io_rw_extended(device->card, write, device->num, address, bang, buffer, length);
+	printk("buf: 0x%02x\n", *((u8*)buffer));
+	A_MDELAY(100);
+	return (ret == MMC_ERR_NONE ? A_OK : A_ERROR);
+}
+
+A_STATUS
+HIFConfigureDevice(struct sdio_func *func, HIF_DEVICE_CONFIG_OPCODE opcode,
+				   void *config, A_UINT32 configLen)
+{
+	A_UINT32 count;
+
+	switch(opcode) {
+		case HIF_DEVICE_GET_MBOX_BLOCK_SIZE:
+			((A_UINT32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE;
+			((A_UINT32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE;
+			((A_UINT32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE;
+			((A_UINT32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE;
+			break;
+
+		case HIF_DEVICE_GET_MBOX_ADDR:
+			for (count = 0; count < 4; count ++) {
+				((A_UINT32 *)config)[count] = HIF_MBOX_START_ADDR(count);
+			}
+			break;
+
+		default:
+			AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+							("Invalid configuration opcode: %d\n", opcode));
+			return A_ERROR;
+	}
+
+	return A_OK;
+}
+
+void
+HIFShutDownDevice(struct sdio_func *func)
+{
+	sdio_disable_func(func);
+#if 0
+	A_UINT8 data;
+	A_UINT32 count;
+	SDIO_STATUS status;
+	SDCONFIG_BUS_MODE_DATA busSettings;
+	SDCONFIG_FUNC_ENABLE_DISABLE_DATA fData;
+
+	if (device != NULL) {
+		/* Remove the allocated current if any */
+		status = SDLIB_IssueConfig(device, SDCONFIG_FUNC_FREE_SLOT_CURRENT, NULL, 0);
+
+		/* Disable the card */
+		fData.EnableFlags = SDCONFIG_DISABLE_FUNC;
+		fData.TimeOut = 1;
+		status = SDLIB_IssueConfig(device, SDCONFIG_FUNC_ENABLE_DISABLE,
+							       &fData, sizeof(fData));
+
+		/* Perform a soft I/O reset */
+		data = SDIO_IO_RESET;
+		status = SDLIB_IssueCMD52(device, 0, SDIO_IO_ABORT_REG,
+							      &data, 1, 1);
+
+		/*
+		 * WAR - Codetelligence driver does not seem to shutdown correctly in 1
+		 * bit mode. By default it configures the HC in the 4 bit. Its later in
+		 * our driver that we switch to 1 bit mode. If we try to shutdown, the
+		 * driver hangs so we revert to 4 bit mode, to be transparent to the
+		 * underlying bus driver.
+		 */
+		if (onebitmode) {
+			ZERO_OBJECT(busSettings);
+			busSettings.BusModeFlags = device->pHcd->CardProperties.BusMode;
+			SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags,
+							       SDCONFIG_BUS_WIDTH_4_BIT);
+
+			/* Issue config request to change the bus width to 4 bit */
+			status = SDLIB_IssueConfig(device->handle, SDCONFIG_BUS_MODE_CTRL,
+							           &busSettings,
+							           sizeof(SDCONFIG_BUS_MODE_DATA));
+		}
+
+	} else {
+		/* Unregister with bus driver core */
+		status = SDIO_UnregisterFunction(&FunctionContext.function);
+	}
+#endif
+}
+
+void
+hifRWCompletionHandler(struct mmc_request *mrq)
+{
+	A_STATUS status;
+	void *context;
+
+	if (mrq->cmd->error == MMC_ERR_NONE) {
+		status = A_OK;
+	} else {
+		status = A_ERROR;
+	}
+	context = (void *)mrq->done_data;
+
+	htcCallbacks.rwCompletionHandler(context, status);
+	kfree(mrq->data->sg);
+	kfree(mrq->data);
+	kfree(mrq->cmd);
+	kfree(mrq);
+}
+
+void
+hifIRQHandler(struct sdio_func *func)
+{
+	printk("DEBUG: %s\n", __func__);
+	htcCallbacks.dsrHandler(func);
+}
+
+
+int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id)
+{
+	int ret;
+
+	sdio_claim_host(func);
+	ret = sdio_enable_func(func);
+	if (ret)
+		return ret;
+
+/* XXX: do we need 1-bit mode? */
+#if 0
+	BOOL enabled;
+	A_UINT8 data;
+	A_UINT32 count;
+	int status;
+
+	/* Configure the SDIO Bus Width */
+	if (onebitmode) {
+		data = SD_BUS_WIDTH_1;
+		status = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IF, 1, &data)
+		if (status != MMC_ERR_NONE) {
+			AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+							("Unable to set the bus width to 1 bit\n"));
+			return -EINVAL;
+		}
+	}
+
+	/* Get current bus flags */
+	ZERO_OBJECT(busSettings);
+	busSettings.BusModeFlags = handle->pHcd->CardProperties.BusMode;
+	if (onebitmode) {
+		SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags,
+							   SDCONFIG_BUS_WIDTH_1_BIT);
+	}
+	busSettings.ClockRate = (busspeedlow ? SDIO_CLOCK_FREQUENCY_REDUCED :
+							               SDIO_CLOCK_FREQUENCY_DEFAULT);
+
+	/* Issue config request to override clock rate */
+	status = SDLIB_IssueConfig(handle, SDCONFIG_BUS_MODE_CTRL, &busSettings,
+							   sizeof(SDCONFIG_BUS_MODE_DATA));
+	if (!SDIO_SUCCESS(status)) {
+		AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+						("Unable to configure the host clock\n"));
+		return FALSE;
+	} else {
+		AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+						("Configured clock: %d, Maximum clock: %d\n",
+						busSettings.ActualClockRate,
+						HIF_DEVICE_GET_MAX_CLOCK(handle)));
+	}
+#endif
+
+	/*
+	 * Check if the target supports block mode. This result of this check
+	 * can be used to implement the HIFReadWrite API.
+	 * XXX: probably unnecessary, stack currently only does 1 byte blocks
+	 */
+#if 0
+	if (HIF_DEVICE_GET_SDIO_FUNC_MAXBLKSIZE(handle)) {
+		/* Limit block size to operational block limit or card function
+		   capability */
+		maxBlockSize = min(HIF_DEVICE_GET_OPER_BLOCK_LEN(handle),
+						   HIF_DEVICE_GET_SDIO_FUNC_MAXBLKSIZE(handle));
+
+		/* check if the card support multi-block transfers */
+		if (!(HIF_DEVICE_GET_SDIOCARD_CAPS(handle) & SDIO_CAPS_MULTI_BLOCK)) {
+			AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Byte basis only\n"));
+
+			/* Limit block size to max byte basis */
+			maxBlockSize =  min(maxBlockSize,
+							    (A_UINT16)SDIO_MAX_LENGTH_BYTE_BASIS);
+			maxBlocks = 1;
+		} else {
+			AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Multi-block capable\n"));
+			maxBlocks = HIF_DEVICE_GET_OPER_BLOCKS(handle);
+			status = SDLIB_SetFunctionBlockSize(handle, HIF_MBOX_BLOCK_SIZE);
+			if (!SDIO_SUCCESS(status)) {
+				AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+							    ("Failed to set block size. Err:%d\n", status));
+				return FALSE;
+			}
+		}
+
+		AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+						("Bytes Per Block: %d bytes, Block Count:%d \n",
+						maxBlockSize, maxBlocks));
+	} else {
+		AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+						("Function does not support Block Mode!\n"));
+		return FALSE;
+	}
+
+	/* Allocate the slot current */
+	status = SDLIB_GetDefaultOpCurrent(handle, &slotCurrent.SlotCurrent);
+	if (SDIO_SUCCESS(status)) {
+		AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Allocating Slot current: %d mA\n",
+							    slotCurrent.SlotCurrent));
+		status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ALLOC_SLOT_CURRENT,
+							       &slotCurrent, sizeof(slotCurrent));
+		if (!SDIO_SUCCESS(status)) {
+			AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
+							("Failed to allocate slot current %d\n", status));
+			return FALSE;
+		}
+	}
+#endif
+
+	/*
+	 * Adding a wait of around a second before we issue the very first
+	 * command to dragon. During the process of loading/unloading the
+	 * driver repeatedly it was observed that we get a data timeout
+	 * while accessing function 1 registers in the chip. The theory at
+	 * this point is that some initialization delay in dragon is
+	 * causing the SDIO state in dragon core to be not ready even after
+	 * the ready bit indicates that function 1 is ready. Accomodating
+	 * for this behavior by adding some delay in the driver before it
+	 * issues the first command after switching on dragon. Need to
+	 * investigate this a bit more - TODO
+	 */
+	A_MDELAY(1000);
+	/* Inform HTC */
+	if ((htcCallbacks.deviceInsertedHandler(func)) != A_OK) {
+		AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Device rejected\n"));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+void
+HIFAckInterrupt(struct sdio_func *func)
+{
+	/* XXX; should done by the stack already, not sure */
+#if 0
+	SDIO_STATUS status;
+	/* Acknowledge our function IRQ */
+	status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_ACK_IRQ,
+							   NULL, 0);
+#endif
+}
+
+void
+HIFUnMaskInterrupt(struct sdio_func *func)
+{
+	printk("DEBUG: %s\n", __func__);
+	sdio_claim_irq(func, hifIRQHandler);
+}
+
+void HIFMaskInterrupt(struct sdio_func *func)
+{
+	printk("DEBUG: %s\n", __func__);
+	sdio_release_irq(func);
+}
+
+void
+hifDeviceRemoved(struct sdio_func *func)
+{
+	printk("DEBUG: %s\n", __func__);
+	sdio_release_host(func);
+	htcCallbacks.deviceRemovedHandler(func);
+}
+

Added: developers/nbd/ar6k/hif/hif_internal.h
===================================================================
--- developers/nbd/ar6k/hif/hif_internal.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/hif/hif_internal.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ * All rights reserved.
+ *
+   $ATH_LICENSE_AR6K0$
+ *
+ */
+
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/osapi.h"
+#include "../include/hif.h"
+
+#define MANUFACTURER_ID_BASE               0x100
+#define FUNCTION_CLASS                     0x0
+#define MANUFACTURER_CODE                  0x271
+
+#define BUS_REQUEST_MAX_NUM                32
+
+#define SDIO_CLOCK_FREQUENCY_DEFAULT       24000000
+#define SDIO_CLOCK_FREQUENCY_REDUCED       12000000
+
+#define SDWLAN_ENABLE_DISABLE_TIMEOUT      20
+#define FLAGS_CARD_ENAB                    0x02
+#define FLAGS_CARD_IRQ_UNMSK               0x04
+
+#define HIF_MBOX_BLOCK_SIZE                128
+#define HIF_MBOX_BASE_ADDR                 0x800
+#define HIF_MBOX_WIDTH                     0x800
+#define HIF_MBOX0_BLOCK_SIZE               1
+#define HIF_MBOX1_BLOCK_SIZE               HIF_MBOX_BLOCK_SIZE
+#define HIF_MBOX2_BLOCK_SIZE               HIF_MBOX_BLOCK_SIZE
+#define HIF_MBOX3_BLOCK_SIZE               HIF_MBOX_BLOCK_SIZE
+
+#define HIF_MBOX_START_ADDR(mbox)                        \
+    HIF_MBOX_BASE_ADDR + mbox * HIF_MBOX_WIDTH
+
+#define HIF_MBOX_END_ADDR(mbox)	                         \
+    HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1
+
+#if 0
+typedef struct target_function_context {
+    struct sdio_func           function; /* function description of the bus driver */
+    OS_SEMAPHORE         instanceSem; /* instance lock. Unused */
+    SDLIST               instanceList; /* list of instances. Unused */
+} TARGET_FUNCTION_CONTEXT;
+#endif
+
+int
+hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id);
+
+void
+hifDeviceRemoved(struct sdio_func *func);
+
+void
+hifRWCompletionHandler(struct mmc_request *mrq);
+
+void
+hifIRQHandler(struct sdio_func *func);
+
+

Added: developers/nbd/ar6k/htc/Makefile
===================================================================
--- developers/nbd/ar6k/htc/Makefile	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/htc/Makefile	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,5 @@
+#
+# SDIO ar6000 wlan htc function driver
+#
+obj-$(CONFIG_SDIO_AR6000_WLAN)	+= htc.o htc_events.o htc_recv.o htc_send.o htc_utils.o
+

Added: developers/nbd/ar6k/htc/htc.c
===================================================================
--- developers/nbd/ar6k/htc/htc.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/htc/htc.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the HTC APIs that are exposed to higher layers.
+ */
+
+#include "htc_internal.h"
+
+/* ------ Global Variable Declarations ------- */
+HTC_TARGET *AtherosTargetList[HIF_MAX_DEVICES];
+HTC_GLOBAL_EVENT_TABLE AtherosEventTable;
+A_MUTEX_T creditCS, counterCS, instanceCS;
+A_WAITQUEUE_HEAD htcEvent;
+
+#ifdef DEBUG
+extern A_UINT32 debughtc;
+extern A_UINT32 txcreditsavailable[HTC_MAILBOX_NUM_MAX];
+extern A_UINT32 txcreditsconsumed[HTC_MAILBOX_NUM_MAX];
+extern A_UINT32 txcreditintrenable[HTC_MAILBOX_NUM_MAX];
+extern A_UINT32 txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX];
+#endif
+
+extern int tx_attempt[HTC_MAILBOX_NUM_MAX];    /* Num of attempts to add */
+extern int tx_post[HTC_MAILBOX_NUM_MAX];       /* Num of attemps succeded */
+extern int tx_complete[HTC_MAILBOX_NUM_MAX];   /* Num of tx complete */
+
+/* Initializes the HTC module */
+A_STATUS
+HTCInit(void)
+{
+    HTC_CALLBACKS htcCallbacks;
+    static A_BOOL HTCInitialized = FALSE;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Enter\n"));
+    if (HTCInitialized) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Exit\n"));
+        return A_OK;
+    }
+
+    A_MEMZERO(&AtherosEventTable, sizeof(HTC_GLOBAL_EVENT_TABLE));
+    A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS));
+    A_INIT_WAITQUEUE_HEAD(&htcEvent);
+
+    htcCallbacks.deviceInsertedHandler = htcTargetInsertedHandler;
+    htcCallbacks.deviceRemovedHandler = htcTargetRemovedHandler;
+    htcCallbacks.rwCompletionHandler = htcRWCompletionHandler;
+#ifdef CF
+        htcCallbacks.deviceInterruptEnabler = htcInterruptEnabler;
+        htcCallbacks.deviceInterruptDisabler = htcInterruptDisabler;
+#endif /* CF */
+
+    htcCallbacks.dsrHandler = htcDSRHandler;
+    HIFRegisterCallbacks(&htcCallbacks);
+    HTCInitialized = TRUE;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCInit: Exit\n"));
+    return A_OK;
+}
+
+/* Enables Dragon interrupts */
+A_STATUS
+HTCStart(HTC_TARGET *target)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n"));
+
+    /* Unmask the host controller interrupts */
+    HIFUnMaskInterrupt(target->device);
+
+    /* Enable all the interrupts except for the dragon interrupt */
+    target->table.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
+                                      INT_STATUS_ENABLE_CPU_SET(0x01) |
+                                      INT_STATUS_ENABLE_COUNTER_SET(0x01) |
+                                      INT_STATUS_ENABLE_MBOX_DATA_SET(0x0F);
+
+    /* Set up the CPU Interrupt Status Register */
+    target->table.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00);
+
+    /* Set up the Error Interrupt Status Register */
+    target->table.error_status_enable =
+                                  ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) |
+                                  ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01);
+
+    /* Set up the Counter Interrupt Status Register */
+    target->table.counter_int_status_enable =
+        COUNTER_INT_STATUS_ENABLE_BIT_SET(0xFF);
+
+    /* Write to the register */
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
+    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address,
+                          &target->table.int_status_enable, 4, &request, NULL);
+    if (status != A_OK) {
+        /* Can't write it for some reason */
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+                        ("Failed to enable INT_STATUS_ENABLE | CPU_INT_STATUS_ENABLE | ERROR_STATUS_ENABLE | COUNTER_INT_STATUS_ENABLE, err: %d\n", status));
+        HTCStop(target);
+        return status;
+    }
+
+#ifdef DEBUG
+    txcreditintrenable[ENDPOINT1] += 1;
+    txcreditintrenable[ENDPOINT2] += 1;
+    txcreditintrenable[ENDPOINT3] += 1;
+    txcreditintrenable[ENDPOINT4] += 1;
+    txcreditintrenableaggregate[ENDPOINT1] += 1;
+    txcreditintrenableaggregate[ENDPOINT2] += 1;
+    txcreditintrenableaggregate[ENDPOINT3] += 1;
+    txcreditintrenableaggregate[ENDPOINT4] += 1;
+#endif /* DEBUG */
+
+    /* Wait on a timed semaphore that will get signalled once the block
+       size negotiation with the target has completed. Furthermore, we have
+       to do it only once during the lifetime of the target detection */
+    if (!target->ready) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                        ("Waiting for the block size negotiation to finish\n"));
+        A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(htcEvent, (target->ready == TRUE),
+                                           HTC_TARGET_RESPONSE_TIMEOUT);
+
+        if (target->ready) {
+            status = A_OK;
+        } else {
+            status = A_ERROR;
+            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+                                ("Failed to negotiate the block sizes\n"));
+            HTCStop(target);
+        }
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
+    return status;
+}
+
+/*
+ * Provides an interface for the higher layer module to register for
+ * different events supported by the HTC module
+ */
+A_STATUS
+HTCEventReg(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId,
+            HTC_EVENT_ID eventId, HTC_EVENT_HANDLER eventHandler,
+            void *param)
+{
+    /*
+     * Add the event handler against the specified event and store it in
+     * the event table
+     */
+    A_STATUS status;
+    HTC_ENDPOINT *endPoint;
+    HTC_EVENT_INFO eventInfo;
+    HTC_DATA_REQUEST_QUEUE *sendQueue, *recvQueue;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
+                    ("HTCEventReg: Enter (eventId: 0x%x, endPointId: %d)\n",
+                    eventId, endPointId));
+
+    if (eventHandler) {
+        if ((status = addToEventTable(target, endPointId, eventId,
+                                      eventHandler, param)) != A_OK)
+        {
+            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+                            ("Could not add the event 0x%x to the event table\n", eventId));
+            return status;
+        }
+    }
+
+    switch(eventId) {
+        case HTC_TARGET_AVAILABLE:
+            if (eventHandler != NULL) {
+                /*
+                 * Dispatch a Target Available event for all the targets
+                 * present. Iterate through the global list of targets but
+                 * currently we shall simply look for the first instance
+                 */
+                target = AtherosTargetList[0];
+                if (target != NULL) {
+                    FRAME_EVENT(eventInfo, (A_UCHAR *)target->device,
+                                sizeof(HIF_DEVICE *), sizeof(HIF_DEVICE *),
+                                A_OK, NULL);
+                    dispatchEvent(target, ENDPOINT_UNUSED, eventId, &eventInfo);
+                }
+            } else {
+                /* Initiate a shut down procedure */
+            }
+            break;
+
+        case HTC_TARGET_UNAVAILABLE:
+            break;
+
+        case HTC_BUFFER_RECEIVED:
+            if (eventHandler == NULL) {
+                /* Flush the queue before unregistering the event handler */
+                endPoint = &target->endPoint[endPointId];
+                recvQueue = &endPoint->recvQueue;
+                flushMboxQueue(endPoint, recvQueue, HTC_BUFFER_RECEIVED);
+            }
+            break;
+
+        case HTC_SKB_RECEIVED:
+            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("skb not handled currently\n"));
+            break;
+
+        case HTC_BUFFER_SENT:
+            if (eventHandler == NULL) {
+                /* Flush the queue before unregistering the event handler */
+                endPoint = &target->endPoint[endPointId];
+                sendQueue = &endPoint->sendQueue;
+                flushMboxQueue(endPoint, sendQueue, HTC_BUFFER_SENT);
+            }
+            break;
+
+        case HTC_SKB_SENT:
+            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("skb not handled currently\n"));
+            break;
+
+        case HTC_DATA_AVAILABLE:
+            /*
+             * Dispatch a data available event with the length. We are
+             * not handling this specific case currently because registering
+             * for HTC_DATA_AVAILABLE event is a part of the discipline
+             * that is imposed before one starts using HTC
+             */
+            break;
+
+        default:
+            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+                            ("Unknown Event ID: 0x%x\n", eventId));
+            return A_EINVAL;
+    }
+
+    /* Check if its a call for registering the event or unregistering it */
+    if (eventHandler == NULL) {
+        if ((status = removeFromEventTable(target, endPointId,
+                                           eventId)) != A_OK)
+        {
+            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+                            ("Could not remove the event 0x%x from the event table\n", eventId));
+            return status;
+        }
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCEventReg: Exit\n"));
+    return A_OK;
+}
+
+/*
+ * Commit an address to either WINDOW_WRITE_ADDR_REG or to
+ * WINDOW_READ_ADDR_REG.  We write the least significan byte (LSB)
+ * last, since it triggers the read/write.
+ */
+static void
+_WRITE_WINDOW_ADDR(HTC_TARGET *target, A_UINT32 whichreg, A_UINT32 value)
+{
+    A_UINT32 window_addr;
+    HIF_REQUEST request;
+    A_STATUS status;
+    A_UINT32 address;
+
+    window_addr = value;
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
+
+    address = getRegAddr(whichreg, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address+1,
+                          (A_UCHAR *)&window_addr+1, 3, &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+
+    status = HIFReadWrite(target->device, address,
+                          (A_UCHAR *)&window_addr, 1, &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+}
+
+void
+HTCStop(HTC_TARGET *target)
+{
+    A_UINT32 count;
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+    A_UINT32 window_data;
+    HTC_ENDPOINT *endPoint;
+    HTC_REG_REQUEST_LIST *regList;
+    HTC_REG_REQUEST_ELEMENT *element;
+    HTC_DATA_REQUEST_QUEUE *sendQueue;
+    HTC_DATA_REQUEST_QUEUE *recvQueue;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStop: Enter"));
+
+    /* Disable all the dragon interrupts */
+    target->table.int_status_enable = 0;
+    target->table.cpu_int_status_enable = 0;
+    target->table.error_status_enable = 0;
+    target->table.counter_int_status_enable = 0;
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
+    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address,
+                          &target->table.int_status_enable, 4, &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+
+    /* Disable the host controller interrupts */
+    HIFMaskInterrupt(target->device);
+
+    /* Flush all the queues and return the buffers to their owner */
+    for (count = ENDPOINT1; count <= ENDPOINT4; count ++) {
+        endPoint = &target->endPoint[count];
+
+        /* Decrement the number of credits consumed */
+        if (endPoint->txCreditsConsumed) {
+            HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,
+                              HIF_SYNCHRONOUS, HIF_BYTE_BASIS,
+                              HIF_FIXED_ADDRESS);
+            address = getRegAddr(TX_CREDIT_COUNTER_DECREMENT_REG, count);
+            status = HIFReadWrite(target->device, address,
+                                  endPoint->txCreditsAvailable,
+                                  endPoint->txCreditsConsumed, &request, NULL);
+            AR_DEBUG_ASSERT(status == A_OK);
+        }
+
+        SET_TX_CREDITS_AVAILABLE(endPoint, 0);
+        SET_TX_CREDITS_CONSUMED(endPoint, 0);
+
+#ifdef DEBUG
+        txcreditsavailable[count] = GET_TX_CREDITS_AVAILABLE(endPoint);
+        txcreditsconsumed[count] = GET_TX_CREDITS_CONSUMED(endPoint);
+#endif
+
+        endPoint->txCreditsIntrEnable = FALSE;
+        endPoint->rxLengthPending = 0;
+        endPoint->enabled = FALSE;
+
+        /* Flush the Pending Receive Queue */
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                        ("Flushing the recv queue & returning the buffers\n"));
+
+        recvQueue = &endPoint->recvQueue;
+        flushMboxQueue(endPoint, recvQueue, HTC_BUFFER_RECEIVED);
+
+        /* Flush the Pending Send Queue */
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                        ("Flushing the send queue & returning the buffers\n"));
+        sendQueue = &endPoint->sendQueue;
+        flushMboxQueue(endPoint, sendQueue, HTC_BUFFER_SENT);
+    }
+
+    /* Clear the tx counters */
+    memset(tx_attempt, 0, sizeof(tx_attempt));
+    memset(tx_post, 0, sizeof(tx_post));
+    memset(tx_complete, 0, sizeof(tx_complete));
+
+    /* Attempting a force reset of the target */
+    window_data = RESET_CONTROL_COLD_RST_MASK;
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
+    address = getRegAddr(WINDOW_DATA_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address, (A_UCHAR *)&window_data,
+                          4, &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+
+    _WRITE_WINDOW_ADDR(target, WINDOW_WRITE_ADDR_REG, RESET_CONTROL_ADDRESS);
+
+    /*
+     * Read back the RESET CAUSE register to ensure that the cold reset
+     * went through.
+     */
+    A_MDELAY(2000); /* 2 second delay to allow dragon to settle down */
+    _WRITE_WINDOW_ADDR(target, WINDOW_READ_ADDR_REG, RESET_CAUSE_ADDRESS);
+
+    window_data = 0;
+    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
+    address = getRegAddr(WINDOW_DATA_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address, (A_UCHAR *)&window_data,
+                          4, &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("window data: %d\n", window_data));
+    window_data &= RESET_CAUSE_LAST_MASK;
+
+    if (window_data != 2) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to cold reset the target\n"));
+    }
+
+    /*
+     * Ensure that all the pending asynchronous register read/writes have
+     * been finished.
+     */
+    regList = &target->regList;
+    for (count = 0; count < HTC_REG_REQUEST_LIST_SIZE; count ++) {
+        element = &regList->element[count];
+        AR_DEBUG_ASSERT(IS_ELEMENT_FREE(element));
+    }
+
+    /* Initialize the shadow copy of the target register table */
+    A_MEMZERO(&target->table, sizeof(HTC_REGISTER_TABLE));
+    target->ready = FALSE;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStop: Exit"));
+}
+
+
+void
+HTCShutDown(HTC_TARGET *target)
+{
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCShutDown: Enter\n"));
+
+    if (target != NULL) {
+        HIFShutDownDevice(target->device);
+        delTargetInstance(target);
+        A_MEMZERO(target, sizeof(HTC_TARGET));
+        A_FREE(target);
+    } else {
+        HIFShutDownDevice(NULL);
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCShutDown: Exit\n"));
+}

Added: developers/nbd/ar6k/htc/htc_events.c
===================================================================
--- developers/nbd/ar6k/htc/htc_events.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/htc/htc_events.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,1056 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the routines handling the different events and callbacks
+ * from the hardware interface layer.
+ */
+
+#include "htc_internal.h"
+
+/* ------ Global Variable Declarations ------- */
+extern A_MUTEX_T instanceCS, counterCS, creditCS;
+extern A_WAITQUEUE_HEAD htcEvent;
+
+#ifdef DEBUG
+extern A_UINT32 debughtc;
+extern A_UINT32 txcreditsavailable[HTC_MAILBOX_NUM_MAX];
+extern A_UINT32 txcreditsconsumed[HTC_MAILBOX_NUM_MAX];
+extern A_UINT32 txcreditintrenable[HTC_MAILBOX_NUM_MAX];
+extern A_UINT32 txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX];
+#endif
+
+extern A_UINT32 tx_complete[HTC_MAILBOX_NUM_MAX]; /* Num of tx complete */
+
+/* ------ Static Variables ------ */
+
+
+/* ------ Functions ------ */
+#ifdef CF
+A_STATUS htcInterruptEnabler(HIF_DEVICE *device) {
+
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+    HTC_TARGET *target;
+
+    target = getTargetInstance(device);
+    AR_DEBUG_ASSERT(target != NULL);
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
+                    ("htcInterruptEnabler Enter target: 0x%p\n", target));
+
+    target->table.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) |
+                                      INT_STATUS_ENABLE_CPU_SET(0x01) |
+                                      INT_STATUS_ENABLE_COUNTER_SET(0x01) |
+                                      INT_STATUS_ENABLE_MBOX_DATA_SET(0x0F);
+    /* Reenable Dragon Interrupts */
+
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address,
+                          &target->table.int_status_enable, 1,
+                          &request, NULL);
+
+	AR_DEBUG_ASSERT(status == A_OK);
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("htcInterruptEnabler Exit\n"));
+
+        return A_OK;
+}
+#endif /* CF */
+
+
+A_STATUS
+htcRWCompletionHandler(void *context,
+                       A_STATUS status)
+{
+    HTC_QUEUE_ELEMENT *element;
+
+    element = (HTC_QUEUE_ELEMENT *)context;
+    AR_DEBUG_ASSERT(element != NULL);
+
+    return(element->completionCB(element, status));
+}
+
+A_STATUS
+htcTxCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,
+                  A_STATUS status)
+{
+    HTC_TARGET *target;
+    HTC_ENDPOINT_ID endPointId;
+    HTC_ENDPOINT *endPoint;
+    HTC_EVENT_INFO eventInfo;
+    HTC_MBOX_BUFFER *mboxBuffer;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,
+                    ("htcTxCompletionCB - Enter\n"));
+
+    /* Get the context */
+    mboxBuffer = GET_MBOX_BUFFER(element);
+    AR_DEBUG_ASSERT(mboxBuffer != NULL);
+    endPoint = mboxBuffer->endPoint;
+    AR_DEBUG_ASSERT(endPoint != NULL);
+    target = endPoint->target;
+    AR_DEBUG_ASSERT(target != NULL);
+    endPointId = GET_ENDPOINT_ID(endPoint);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,
+                    ("mboxBuffer: 0x%p, buffer: 0x%p, endPoint(%d): 0x%p, target: 0x%p\n", mboxBuffer, mboxBuffer->buffer, endPointId, endPoint, target));
+
+    /* Return the buffer to the user if the transmission was not successful */
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_SEND,
+                        ("Frame transmission failed\n"));
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_SEND,
+                        ("EndPoint: %d, Tx credits available: %d\n",
+                         endPointId, GET_TX_CREDITS_AVAILABLE(endPoint)));
+        /*
+         * In the failure case it is possible that while queueing of the
+         * request itself it returned an error status in which case we
+         * would have dispatched an event and freed the element there
+         * itself. Ideally if it failed to queue the request then it
+         * should not generate a callback but we are being a little
+         * conservative.
+         */
+        if (!(IS_ELEMENT_FREE(element))) {
+            mboxBuffer->buffer += HTC_HEADER_LEN;
+            FRAME_EVENT(eventInfo, mboxBuffer->buffer,
+                        mboxBuffer->bufferLength, mboxBuffer->actualLength,
+                        A_ECANCELED, mboxBuffer->cookie);
+            RECYCLE_DATA_REQUEST_ELEMENT(element);
+            dispatchEvent(target, endPointId, HTC_BUFFER_SENT, &eventInfo);
+            AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,
+                            ("htcTxCompletionCB - Exit\n"));
+        }
+        return A_OK;
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,
+                    ("Frame transmission complete\n"));
+
+    /*
+     * The user should see the actual length and buffer length
+     * to be the same. In case of block mode, we use the actual length
+     * parameter to reflect the total number of bytes transmitted after
+     * padding.
+     */
+    mboxBuffer->actualLength = mboxBuffer->bufferLength;
+    mboxBuffer->buffer += HTC_HEADER_LEN;
+
+    /*
+     * Return the transmit buffer to the user through the HTC_BUFFER_SENT
+     * event indicating that the frame was transmitted successfully.
+     */
+    FRAME_EVENT(eventInfo, mboxBuffer->buffer, mboxBuffer->bufferLength,
+                mboxBuffer->actualLength, A_OK, mboxBuffer->cookie);
+    RECYCLE_DATA_REQUEST_ELEMENT(element);
+
+    tx_complete[endPointId] += 1;
+
+    dispatchEvent(target, endPointId, HTC_BUFFER_SENT, &eventInfo);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,
+                    ("htcTxCompletionCB - Exit\n"));
+
+    return A_OK;
+}
+
+A_STATUS
+htcBlkSzNegCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,
+                        A_STATUS status)
+{
+    HTC_TARGET *target;
+    HTC_ENDPOINT *endPoint;
+    HIF_REQUEST request;
+    HTC_MBOX_BUFFER *mboxBuffer;
+    HTC_REG_REQUEST_ELEMENT *regElement;
+    A_UINT32 address;
+
+    /* Get the context */
+    mboxBuffer = GET_MBOX_BUFFER(element);
+    AR_DEBUG_ASSERT(mboxBuffer != NULL);
+    endPoint = mboxBuffer->endPoint;
+    AR_DEBUG_ASSERT(endPoint != NULL);
+    target = endPoint->target;
+    AR_DEBUG_ASSERT(target != NULL);
+
+    /* Recycle the request element */
+    RECYCLE_DATA_REQUEST_ELEMENT(element);
+    element->completionCB = htcTxCompletionCB;
+
+    if (status == A_OK) {
+        /* Mark the state to be ready */
+        endPoint->enabled = TRUE;
+
+        /* Set the state of the target as ready */
+        if (target->endPoint[ENDPOINT1].enabled &&
+            target->endPoint[ENDPOINT2].enabled &&
+            target->endPoint[ENDPOINT3].enabled &&
+            target->endPoint[ENDPOINT4].enabled )
+        {
+            /* Send the INT_WLAN interrupt to the target */
+            target->table.int_wlan = 1;
+            HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,
+                              HIF_ASYNCHRONOUS, HIF_BYTE_BASIS,
+                              HIF_FIXED_ADDRESS);
+            address = getRegAddr(INT_WLAN_REG, ENDPOINT_UNUSED);
+            regElement = allocateRegRequestElement(target);
+            AR_DEBUG_ASSERT(regElement != NULL);
+            FILL_REG_BUFFER(regElement, &target->table.int_wlan, 1,
+                            INT_WLAN_REG, ENDPOINT_UNUSED);
+            status = HIFReadWrite(target->device, address,
+                                  &target->table.int_wlan,
+                                  1, &request, regElement);
+#ifndef HTC_SYNC
+            AR_DEBUG_ASSERT(status == A_OK);
+#else
+			AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
+			if(status == A_OK) {
+				regElement->completionCB(regElement, status);
+			}
+#endif
+        }
+    }
+
+    return A_OK;
+}
+
+A_STATUS
+htcRxCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,
+                  A_STATUS status)
+{
+    HTC_TARGET *target;
+    HTC_ENDPOINT *endPoint;
+    HTC_EVENT_INFO eventInfo;
+    HTC_ENDPOINT_ID endPointId;
+    HTC_MBOX_BUFFER *mboxBuffer;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,
+                    ("htcRxCompletionCB - Enter\n"));
+
+    /* Get the context */
+    mboxBuffer = GET_MBOX_BUFFER(element);
+    AR_DEBUG_ASSERT(mboxBuffer != NULL);
+    endPoint = mboxBuffer->endPoint;
+    AR_DEBUG_ASSERT(endPoint != NULL);
+    target = endPoint->target;
+    AR_DEBUG_ASSERT(target != NULL);
+    endPointId = GET_ENDPOINT_ID(endPoint);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_RECV,
+                    ("mboxBuffer: 0x%p, buffer: 0x%p, endPoint(%d): 0x%p, target: 0x%p\n", mboxBuffer, mboxBuffer->buffer, endPointId, endPoint, target));
+
+    /* Return the buffer to the user if the reception was not successful */
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_RECV,
+                        ("Frame reception failed\n"));
+        /*
+         * In the failure case it is possible that while queueing of the
+         * request itself it returned an error status in which case we
+         * would have dispatched an event and freed the element there
+         * itself. Ideally if it failed to queue the request then it
+         * should not generate a callback but we are being a little
+         * conservative.
+         */
+        if (!(IS_ELEMENT_FREE(element))) {
+            mboxBuffer->actualLength = 0;
+            mboxBuffer->buffer += HTC_HEADER_LEN;
+            FRAME_EVENT(eventInfo, mboxBuffer->buffer,
+                        mboxBuffer->bufferLength, mboxBuffer->actualLength,
+                        A_ECANCELED, mboxBuffer->cookie);
+            RECYCLE_DATA_REQUEST_ELEMENT(element);
+            dispatchEvent(target, endPointId, HTC_BUFFER_RECEIVED, &eventInfo);
+            AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,
+                            ("htcRxCompletionCB - Exit\n"));
+        }
+        return A_OK;
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_RECV,
+                    ("Frame reception complete\n"));
+
+    AR_DEBUG_PRINTBUF(mboxBuffer->buffer, mboxBuffer->actualLength);
+
+    /*
+     * Advance the pointer by the size of HTC header and pass the payload
+     * pointer to the upper layer.
+     */
+    mboxBuffer->actualLength = ((mboxBuffer->buffer[0] << 0) |
+                                (mboxBuffer->buffer[1] << 8));
+    mboxBuffer->buffer += HTC_HEADER_LEN;
+
+    /*
+     * Frame the HTC_BUFFER_RECEIVED to the upper layer indicating that the
+     * packet has been succesfully received.
+     */
+    FRAME_EVENT(eventInfo, mboxBuffer->buffer, mboxBuffer->bufferLength,
+                mboxBuffer->actualLength, A_OK, mboxBuffer->cookie);
+
+    /* Recycle the bufferElement structure */
+    RECYCLE_DATA_REQUEST_ELEMENT(element);
+
+    /* Dispatch the event */
+    dispatchEvent(target, endPointId, HTC_BUFFER_RECEIVED, &eventInfo);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,
+                    ("htcRxCompletion - Exit\n"));
+
+    return A_OK;
+}
+
+A_STATUS
+htcRegCompletionCB(HTC_REG_REQUEST_ELEMENT *element,
+                   A_STATUS status)
+{
+    A_STATUS ret;
+    HTC_TARGET *target;
+    HTC_ENDPOINT *endPoint;
+    HTC_REG_BUFFER *regBuffer;
+    A_UINT8 txCreditsConsumed;
+    A_UINT8 txCreditsAvailable;
+    HTC_ENDPOINT_ID endPointId;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV | ATH_DEBUG_SEND,
+                    ("htcRegCompletion - Enter\n"));
+    AR_DEBUG_ASSERT(status == A_OK);
+
+    /* Get the context */
+    AR_DEBUG_ASSERT(element != NULL);
+    regBuffer = GET_REG_BUFFER(element);
+    AR_DEBUG_ASSERT(regBuffer != NULL);
+    target = regBuffer->target;
+    AR_DEBUG_ASSERT(target != NULL);
+
+    /* Identify the register and the operation responsible for the callback */
+    ret = A_OK;
+    switch(regBuffer->base) {
+    case TX_CREDIT_COUNTER_DECREMENT_REG:
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("TX_CREDIT_COUNTER_DECREMENT_REG\n"));
+        endPointId = regBuffer->offset;
+        endPoint = &target->endPoint[endPointId];
+
+        AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                        ("Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__));
+        A_MUTEX_LOCK(&creditCS);
+
+        /* Calculate the number of credits available */
+        AR_DEBUG_ASSERT(GET_TX_CREDITS_CONSUMED(endPoint) == regBuffer->length);
+        AR_DEBUG_ASSERT(regBuffer->buffer[0] >=
+                        GET_TX_CREDITS_CONSUMED(endPoint));
+        SET_TX_CREDITS_AVAILABLE(endPoint, regBuffer->buffer[0] -
+                                 GET_TX_CREDITS_CONSUMED(endPoint));
+        SET_TX_CREDITS_CONSUMED(endPoint, 0);
+        txCreditsAvailable = GET_TX_CREDITS_AVAILABLE(endPoint);
+        txCreditsConsumed = GET_TX_CREDITS_CONSUMED(endPoint);
+        AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                        ("Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__));
+        A_MUTEX_UNLOCK(&creditCS);
+
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,
+                        ("Pulling %d tx credits from the target\n",
+                        txCreditsAvailable));
+
+#ifdef DEBUG
+        txcreditsavailable[endPointId] = txCreditsAvailable;
+        txcreditsconsumed[endPointId] = txCreditsConsumed;
+#endif /* DEBUG */
+
+        if (txCreditsAvailable) {
+            htcSendFrame(endPoint);
+        } else {
+            /*
+             * Enable the Tx credit counter interrupt so that we can get the
+             * credits posted by the target.
+             */
+            htcEnableCreditCounterInterrupt(target, endPointId);
+
+#ifdef DEBUG
+            txcreditintrenable[endPointId] += 1;
+            txcreditintrenableaggregate[endPointId] += 1;
+#endif /* DEBUG */
+        }
+        break;
+
+    case TX_CREDIT_COUNTER_RESET_REG:
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("TX_CREDIT_COUNTER_RESET_REG\n"));
+        endPointId = regBuffer->offset;
+
+        /*
+         * Enable the Tx credit counter interrupt so that we can get the
+         * credits posted by the target.
+         */
+        htcEnableCreditCounterInterrupt(target, endPointId);
+
+#ifdef DEBUG
+        txcreditintrenable[endPointId] += 1;
+        txcreditintrenableaggregate[endPointId] += 1;
+#endif /* DEBUG */
+        break;
+
+    case COUNTER_INT_STATUS_ENABLE_REG:
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("COUNTER_INT_STATUS_ENABLE: 0x%x\n",
+                        target->table.counter_int_status_enable));
+        break;
+
+    case COUNTER_INT_STATUS_DISABLE_REG:
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("COUNTER_INT_STATUS_DISABLE:0x%x\n",
+                        target->table.counter_int_status_enable));
+        HIFAckInterrupt(target->device);
+        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcDSRHandler - ACK\n"));
+        break;
+
+    case INT_WLAN_REG:
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("INT_WLAN: 0x%x\n",
+                        target->table.int_wlan));
+        target->table.int_wlan = 0;
+
+        /* Mark the target state as ready and signal the waiting sem */
+        target->ready = TRUE;
+        A_WAKE_UP(&htcEvent);
+        break;
+
+	case INT_STATUS_ENABLE_REG:
+		AR_DEBUG_PRINTF(ATH_DEBUG_INF,("INT_STATUS_ENABLE: 0x%x\n",
+						target->table.int_status_enable));
+		break;
+
+    default:
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+                        ("Invalid register address: %d\n", regBuffer->base));
+    }
+
+    /* Free the register request structure */
+    freeRegRequestElement(element);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcRegCompletion - Exit\n"));
+
+    return ret;
+}
+
+
+A_STATUS
+htcTargetInsertedHandler(HIF_DEVICE *device)
+{
+    HTC_TARGET *target;
+    HTC_ENDPOINT *endPoint;
+    A_UINT8 count1, count2;
+    HTC_EVENT_INFO eventInfo;
+    HTC_REG_BUFFER *regBuffer;
+    HTC_QUEUE_ELEMENT *element;
+    HTC_MBOX_BUFFER *mboxBuffer;
+    HTC_REG_REQUEST_LIST *regList;
+    HTC_DATA_REQUEST_QUEUE *sendQueue, *recvQueue;
+    A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
+    A_UINT32 blockSize[HTC_MAILBOX_NUM_MAX];
+#ifdef CF
+	HIF_REQUEST request;
+	A_STATUS status;
+	A_UINT32 address;
+#endif /* CF */
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcTargetInserted - Enter\n"));
+
+    /* Initialize the locks */
+    A_MUTEX_INIT(&instanceCS);
+    A_MUTEX_INIT(&creditCS);
+    A_MUTEX_INIT(&counterCS);
+
+    /* Allocate target memory */
+    if ((target = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
+        return A_ERROR;
+    }
+    A_MEMZERO(target, sizeof(HTC_TARGET));
+    target->device = device;
+    target->ready = FALSE;
+
+    /* Initialize the endpoints, mbox queues, event table */
+    for (count1 = ENDPOINT1; count1 <= ENDPOINT4; count1 ++) {
+        endPoint = &target->endPoint[count1];
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                        ("endPoint[%d]: %p\n", count1, endPoint));
+        A_MEMZERO(endPoint->txCreditsAvailable, HTC_TX_CREDITS_NUM_MAX);
+        endPoint->txCreditsConsumed = 0;
+        endPoint->txCreditsIntrEnable = FALSE;
+        endPoint->rxLengthPending = 0;
+        endPoint->target = target;
+        endPoint->enabled = FALSE;
+        for (count2 = 0; count2<HTC_DATA_REQUEST_RING_BUFFER_SIZE; count2 ++) {
+            /* Send Queue */
+            sendQueue = &endPoint->sendQueue;
+            sendQueue->head = sendQueue->size = 0;
+            element = &sendQueue->element[count2];
+            A_MEMZERO(element, sizeof(HTC_DATA_REQUEST_ELEMENT));
+            element->buffer.free = TRUE;
+            element->completionCB = htcTxCompletionCB;
+            mboxBuffer = GET_MBOX_BUFFER(element);
+            mboxBuffer->endPoint = endPoint;
+
+            /* Receive Queue */
+            recvQueue = &endPoint->recvQueue;
+            recvQueue->head = recvQueue->size = 0;
+            element = &recvQueue->element[count2];
+            A_MEMZERO(element, sizeof(HTC_DATA_REQUEST_ELEMENT));
+            element->buffer.free = TRUE;
+            element->completionCB = htcRxCompletionCB;
+            mboxBuffer = GET_MBOX_BUFFER(element);
+            mboxBuffer->endPoint = endPoint;
+        }
+        A_MEMZERO(&target->endPoint[count1].eventTable,
+                  sizeof(HTC_ENDPOINT_EVENT_TABLE));
+    }
+
+    /* Populate the block size for each of the end points */
+    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+                       &blockSize, sizeof(blockSize));
+    HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR,
+                       &mboxAddress, sizeof(mboxAddress));
+    for (count1 = ENDPOINT1; count1 <= ENDPOINT4; count1 ++) {
+        endPoint = &target->endPoint[count1];
+        endPoint->blockSize = blockSize[count1];
+        endPoint->address = mboxAddress[count1];
+    }
+
+    /* Initialize the shadow copy of the target register table */
+    A_MEMZERO(&target->table, sizeof(HTC_REGISTER_TABLE));
+
+    /* Initialize the register request list */
+    regList = &target->regList;
+    for (count1 = 0; count1 < HTC_REG_REQUEST_LIST_SIZE; count1 ++) {
+        element = &regList->element[count1];
+        A_MEMZERO(element, sizeof(HTC_REG_REQUEST_ELEMENT));
+        element->buffer.free = TRUE;
+        element->completionCB = htcRegCompletionCB;
+        regBuffer = GET_REG_BUFFER(element);
+        regBuffer->target = target;
+    }
+
+    /* Add the target instance to the global list */
+    addTargetInstance(target);
+#ifdef CF
+    /* Disable all the dragon interrupts */
+    target->table.int_status_enable = 0;
+    target->table.cpu_int_status_enable = 0;
+    target->table.error_status_enable = 0;
+    target->table.counter_int_status_enable = 0;
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
+    address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address,
+                          &target->table.int_status_enable, 4, &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+#endif /* CF */
+
+    /*
+     * Frame a TARGET_AVAILABLE event and send it to the host. Return the
+     * HIF_DEVICE handle as a parameter with the event.
+     */
+    FRAME_EVENT(eventInfo, (A_UCHAR *)device, sizeof(HIF_DEVICE *),
+                sizeof(HIF_DEVICE *), A_OK, NULL);
+    dispatchEvent(target, ENDPOINT_UNUSED, HTC_TARGET_AVAILABLE, &eventInfo);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcTargetInserted - Exit\n"));
+
+    return A_OK;
+}
+
+A_STATUS
+htcTargetRemovedHandler(HIF_DEVICE *device)
+{
+    HTC_TARGET *target;
+    HTC_EVENT_INFO eventInfo;
+
+    /* Get the target instance bound to this device */
+    target = getTargetInstance(device);
+
+    if (target != NULL) {
+        /* Frame a TARGET_UNAVAILABLE event and send it to the host */
+        FRAME_EVENT(eventInfo, NULL, 0, 0, A_OK, NULL);
+        dispatchEvent(target, ENDPOINT_UNUSED, HTC_TARGET_UNAVAILABLE,
+                      &eventInfo);
+    }
+
+    return A_OK;
+}
+
+
+#ifdef CF
+A_STATUS
+htcInterruptDisabler(HIF_DEVICE *device,A_BOOL *callDsr)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HTC_TARGET *target;
+    HIF_REQUEST request;
+
+    target = getTargetInstance(device);
+    AR_DEBUG_ASSERT(target != NULL);
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
+                    ("htcInterruptDisabler Enter target: 0x%p\n", target));
+
+    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+    address = getRegAddr(INT_STATUS_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address,
+                          &target->table.host_int_status, 1, &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+
+	/* Handle Suprise removal of CF card. Upon removal of the card the
+     * host_int_status reads 0xFF
+     */
+	if (target->table.host_int_status == 0xFF) {
+        *callDsr=FALSE;
+		return A_OK;
+	}
+
+    if ((target->table.int_status_enable & target->table.host_int_status) == 0) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
+                    ("htcInterruptDisabler: MisRouted / Spurious interrupt : 0x%p\n", target));
+        *callDsr=FALSE;
+    } else {
+            /*
+         * Disable the interrupts from Dragon.
+         *  We do the interrupt servicing in the bottom half and reenable the
+         *  Dragon interrupts at the end of the bottom-half
+             */
+
+        target->table.int_status_enable = 0;
+        HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+        address = getRegAddr(INT_STATUS_ENABLE_REG, ENDPOINT_UNUSED);
+        status = HIFReadWrite(target->device, address,
+                          &target->table.int_status_enable, 1, &request, NULL);
+        AR_DEBUG_ASSERT(status == A_OK);
+        *callDsr=TRUE;
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcInterruptDisabler: Exit\n"));
+    return A_OK;
+}
+#endif /* CF */
+
+A_STATUS
+htcDSRHandler(HIF_DEVICE *device)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HTC_TARGET *target;
+    HIF_REQUEST request;
+    A_UCHAR host_int_status;
+
+    target = getTargetInstance(device);
+    AR_DEBUG_ASSERT(target != NULL);
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC,
+                    ("htcDsrHandler: Enter (target: 0x%p\n", target));
+
+    /*
+     * Read the first 28 bytes of the HTC register table. This will yield us
+     * the value of different int status registers and the lookahead
+     * registers.
+     *    length = sizeof(int_status) + sizeof(cpu_int_status) +
+     *             sizeof(error_int_status) + sizeof(counter_int_status) +
+     *             sizeof(mbox_frame) + sizeof(rx_lookahead_valid) +
+     *             sizeof(hole) +  sizeof(rx_lookahead) +
+     *             sizeof(int_status_enable) + sizeof(cpu_int_status_enable) +
+     *             sizeof(error_status_enable) +
+     *             sizeof(counter_int_status_enable);
+     */
+    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
+    address = getRegAddr(INT_STATUS_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address,
+                          &target->table.host_int_status, 28,
+                          &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+
+#ifdef DEBUG
+    dumpRegisters(target);
+#endif /* DEBUG */
+#ifdef CF
+    /* Update only those registers that are enabled */
+        /* This is not required as we have already checked for spurious interrupt
+         * in htcInterruptDisabler
+         */
+
+    host_int_status = target->table.host_int_status;
+#else
+    /* Update only those registers that are enabled */
+    host_int_status = target->table.host_int_status &
+                      target->table.int_status_enable;
+#endif /* CF */
+
+    AR_DEBUG_ASSERT(host_int_status);
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                    ("Valid interrupt source(s) in INT_STATUS: 0x%x\n",
+                    host_int_status));
+    if (HOST_INT_STATUS_CPU_GET(host_int_status)) {
+        /* CPU Interrupt */
+        htcServiceCPUInterrupt(target);
+    }
+
+    if (HOST_INT_STATUS_ERROR_GET(host_int_status)) {
+        /* Error Interrupt */
+        htcServiceErrorInterrupt(target);
+    }
+
+    if (HOST_INT_STATUS_MBOX_DATA_GET(host_int_status)) {
+        /* Mailbox Interrupt */
+        htcServiceMailboxInterrupt(target);
+    }
+
+    if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) {
+        /* Counter Interrupt */
+        htcServiceCounterInterrupt(target);
+    } else {
+        /* Ack the interrupt */
+        HIFAckInterrupt(target->device);
+        AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcDSRHandler - ACK\n"));
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("htcDSRHandler: Exit\n"));
+    return A_OK;
+}
+
+void
+htcServiceCPUInterrupt(HTC_TARGET *target)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+    A_UINT8 cpu_int_status;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("CPU Interrupt\n"));
+    cpu_int_status = target->table.cpu_int_status &
+                     target->table.cpu_int_status_enable;
+    AR_DEBUG_ASSERT(cpu_int_status);
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                    ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
+                    cpu_int_status));
+
+    /* Figure out the interrupt number */
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Interrupt Number: 0x%x\n",
+                    htcGetBitNumSet(cpu_int_status)));
+
+    /* Clear the interrupt */
+    target->table.cpu_int_status = cpu_int_status; /* W1C */
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+    address = getRegAddr(CPU_INT_STATUS_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address,
+                          &target->table.cpu_int_status, 1, &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+}
+
+
+void
+htcServiceErrorInterrupt(HTC_TARGET *target)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+    A_UINT8 error_int_status;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Error Interrupt\n"));
+    error_int_status = target->table.error_int_status &
+                       target->table.error_status_enable;
+    AR_DEBUG_ASSERT(error_int_status);
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                    ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
+                    error_int_status));
+
+    if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) {
+        /* Wakeup */
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Wakeup\n"));
+    }
+
+    if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) {
+        /* Rx Underflow */
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Rx Underflow\n"));
+    }
+
+    if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) {
+        /* Tx Overflow */
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Tx Overflow\n"));
+    }
+
+    /* Clear the interrupt */
+    target->table.error_int_status = error_int_status; /* W1C */
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_SYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+    address = getRegAddr(ERROR_INT_STATUS_REG, ENDPOINT_UNUSED);
+    status = HIFReadWrite(target->device, address,
+                          &target->table.error_int_status, 1,
+                          &request, NULL);
+    AR_DEBUG_ASSERT(status == A_OK);
+}
+
+void
+htcServiceCounterInterrupt(HTC_TARGET *target)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+    HTC_ENDPOINT *endPoint;
+    HTC_ENDPOINT_ID endPointId;
+    A_UINT8 counter_int_status;
+    A_UINT8 reset_credit_int_status;
+    A_UINT8 update_credit_int_status;
+    HTC_REG_REQUEST_ELEMENT *element;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Counter Interrupt\n"));
+
+    counter_int_status = target->table.counter_int_status &
+                         target->table.counter_int_status_enable;
+    AR_DEBUG_ASSERT(counter_int_status);
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                    ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
+                    counter_int_status));
+
+    /* Service the reset credit counter interrupt */
+    reset_credit_int_status = (counter_int_status & 0x0F);
+    while(reset_credit_int_status) {
+        endPointId = htcGetBitNumSet(reset_credit_int_status);
+        endPoint = &target->endPoint[endPointId];
+        AR_DEBUG_ASSERT(endPoint != NULL);
+
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                        ("endPoint(%d): %p\n", endPointId, endPoint));
+
+        /* Initialize the number of credits available to zero */
+        SET_TX_CREDITS_AVAILABLE(endPoint, 0);
+
+        /* Clear the interrupt */
+        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,
+                          HIF_ASYNCHRONOUS, HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+        address = getRegAddr(TX_CREDIT_COUNTER_RESET_REG, endPointId);
+        element = allocateRegRequestElement(target);
+        AR_DEBUG_ASSERT(element != NULL);
+        FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1], 1,
+                        TX_CREDIT_COUNTER_RESET_REG, endPointId);
+        status = HIFReadWrite(target->device, address,
+                              &endPoint->txCreditsAvailable[1],
+                              1, &request, element);
+
+#ifndef HTC_SYNC
+        AR_DEBUG_ASSERT(status == A_OK);
+#else
+        AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
+		if (status == A_OK) {
+        	/* Enable the Tx credit counter interrupt so that we can get the
+             * credits posted by the target */
+        	htcEnableCreditCounterInterrupt(target, endPointId);
+		}
+#endif
+        reset_credit_int_status &=
+            ~(1 << htcGetBitNumSet(reset_credit_int_status));
+    }
+
+    /* Disable the credit counter interrupt */
+    htcDisableCreditCounterInterrupt(target, ENDPOINT_UNUSED);
+
+    /* Service the credit counter interrupt */
+    update_credit_int_status = counter_int_status & 0xF0;
+    while(update_credit_int_status) {
+        endPointId = htcGetBitNumSet(update_credit_int_status) -
+                     HTC_MAILBOX_NUM_MAX;
+        endPoint = &target->endPoint[endPointId];
+        AR_DEBUG_ASSERT(endPoint != NULL);
+
+        /* This is the minimum number of credits that we would have got */
+        AR_DEBUG_ASSERT(GET_TX_CREDITS_AVAILABLE(endPoint) == 0);
+        SET_TX_CREDITS_AVAILABLE(endPoint, 1);
+
+#ifdef DEBUG
+        txcreditsavailable[endPointId] = GET_TX_CREDITS_AVAILABLE(endPoint);
+        txcreditintrenable[endPointId] -= 1;
+#endif /* DEBUG */
+
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Tx Credits Available: %d\n",
+                                        GET_TX_CREDITS_AVAILABLE(endPoint)));
+
+        if (!target->ready) {
+            htcSendBlkSize(endPoint);
+        } else {
+            htcSendFrame(endPoint);
+        }
+
+        update_credit_int_status &=
+            ~(1 << htcGetBitNumSet(update_credit_int_status));
+    }
+}
+
+void
+htcEnableCreditCounterInterrupt(HTC_TARGET *target,
+                                HTC_ENDPOINT_ID endPointId)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+    HTC_ENDPOINT *endPoint;
+    HTC_REG_REQUEST_ELEMENT *element;
+
+    endPoint = &target->endPoint[endPointId];
+    AR_DEBUG_ASSERT(endPoint != NULL);
+
+    A_MUTEX_LOCK(&counterCS);
+
+    endPoint->txCreditsIntrEnable = TRUE;
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,
+                      HIF_ASYNCHRONOUS, HIF_BYTE_BASIS,
+                      HIF_FIXED_ADDRESS);
+
+    address = getRegAddr(COUNTER_INT_STATUS_ENABLE_REG,
+                         ENDPOINT_UNUSED);
+    element = allocateRegRequestElement(target);
+    AR_DEBUG_ASSERT(element != NULL);
+    FILL_REG_BUFFER(element, NULL, 1, COUNTER_INT_STATUS_ENABLE_REG,
+                    (target->endPoint[0].txCreditsIntrEnable << (4)) |
+                    (target->endPoint[1].txCreditsIntrEnable << (5)) |
+                    (target->endPoint[2].txCreditsIntrEnable << (6)) |
+                    (target->endPoint[3].txCreditsIntrEnable << (7)) | 0x0F);
+    status = HIFReadWrite(target->device, address,
+                     (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
+                     1, &request, element);
+
+#ifndef HTC_SYNC
+    AR_DEBUG_ASSERT(status == A_OK);
+#else
+            AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
+			if(status == A_OK) {
+				element->completionCB(element, status);
+			}
+#endif
+
+    A_MUTEX_UNLOCK(&counterCS);
+}
+
+void
+htcDisableCreditCounterInterrupt(HTC_TARGET *target,
+                                 HTC_ENDPOINT_ID unused)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+    HTC_ENDPOINT *endPoint;
+    HTC_ENDPOINT_ID endPointId;
+    A_UINT8 counter_int_status;
+    A_UINT8 update_credit_int_status;
+    HTC_REG_REQUEST_ELEMENT *element;
+
+    A_MUTEX_LOCK(&counterCS);
+
+    /* The Tx credit counter update bits are reflected in the upper nibble */
+    counter_int_status = target->table.counter_int_status &
+                         target->table.counter_int_status_enable;
+    update_credit_int_status = counter_int_status & 0xF0;
+    while(update_credit_int_status) {
+        endPointId = htcGetBitNumSet(update_credit_int_status) -
+                     HTC_MAILBOX_NUM_MAX;
+        endPoint = &target->endPoint[endPointId];
+        AR_DEBUG_ASSERT(endPoint != NULL);
+
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                        ("endPoint(%d): %p\n", endPointId, endPoint));
+
+        /* Disable the tx credit interrupt */
+        endPoint->txCreditsIntrEnable = FALSE;
+
+        update_credit_int_status &=
+            ~(1 << htcGetBitNumSet(update_credit_int_status));
+    }
+
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+    address = getRegAddr(COUNTER_INT_STATUS_DISABLE_REG, ENDPOINT_UNUSED);
+    element = allocateRegRequestElement(target);
+    AR_DEBUG_ASSERT(element != NULL);
+    FILL_REG_BUFFER(element, NULL, 1,
+                    COUNTER_INT_STATUS_DISABLE_REG,
+                    (target->endPoint[0].txCreditsIntrEnable << (4)) |
+                    (target->endPoint[1].txCreditsIntrEnable << (5)) |
+                    (target->endPoint[2].txCreditsIntrEnable << (6)) |
+                    (target->endPoint[3].txCreditsIntrEnable << (7)) | 0x0F);
+    status = HIFReadWrite(target->device, address,
+                          (A_UCHAR *)&((GET_REG_BUFFER(element))->offset),
+                          1, &request, element);
+
+#ifndef HTC_SYNC
+    AR_DEBUG_ASSERT(status == A_OK);
+#else
+    AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
+	if ( status == A_OK ) {
+		element->completionCB(element, status);
+	}
+#endif
+
+    A_MUTEX_UNLOCK(&counterCS);
+}
+
+void
+htcServiceMailboxInterrupt(HTC_TARGET *target)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_REQUEST request;
+    HTC_ENDPOINT *endPoint;
+    HTC_ENDPOINT_ID endPointId;
+    A_UINT8 mailbox_int_status;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF, ("Mailbox Interrupt\n"));
+
+    /* The Rx interrupt bits are reflected in the lower nibble */
+    mailbox_int_status = target->table.host_int_status &
+                         HOST_INT_STATUS_MBOX_DATA_MASK;
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                    ("Valid mailbox interrupt source(s) in INT_STATUS: 0x%x\n",
+                    mailbox_int_status));
+
+    /* Disable the receive interrupt for all four mailboxes */
+    target->table.int_status_enable &= ~(HOST_INT_STATUS_MBOX_DATA_MASK);
+
+    do {
+        while(mailbox_int_status) {
+            endPointId = htcGetBitNumSet(mailbox_int_status);
+            endPoint = &target->endPoint[endPointId];
+            AR_DEBUG_ASSERT(endPoint != NULL);
+
+            AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                            ("endPoint(%d): %p\n", endPointId, endPoint));
+
+            /* Service the Rx interrupt */
+            htcReceiveFrame(endPoint);
+            mailbox_int_status &= ~(1 << htcGetBitNumSet(mailbox_int_status));
+        }
+
+        /*
+         * Read the register table again. Repeat the process until there are
+         * no more valid packets queued up on receive. It is assumed that
+         * the following request will be serialized along with the request
+         * above and will be completed in the order in which it is received
+         * by the bus driver.
+         */
+        HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,
+                          HIF_SYNCHRONOUS, HIF_BYTE_BASIS,
+                          HIF_INCREMENTAL_ADDRESS);
+        address = getRegAddr(INT_STATUS_REG, ENDPOINT_UNUSED);
+        status = HIFReadWrite(target->device, address,
+                              &target->table.host_int_status,
+                              24, &request, NULL);
+        AR_DEBUG_ASSERT(status == A_OK);
+        mailbox_int_status = target->table.host_int_status &
+                             HOST_INT_STATUS_MBOX_DATA_MASK;
+    } while (mailbox_int_status);
+
+    target->table.int_status_enable |= HOST_INT_STATUS_MBOX_DATA_MASK;
+}

Added: developers/nbd/ar6k/htc/htc_internal.h
===================================================================
--- developers/nbd/ar6k/htc/htc_internal.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/htc/htc_internal.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2004-2005 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * HTC internal specific declarations and prototypes
+ */
+
+#ifndef _HTC_INTERNAL_H_
+#define _HTC_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Header files */
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/hw/mbox_host_reg.h"
+#include "../include/hw/rtc_reg.h"
+#include "../include/htc.h"
+#include "../include/AR6000_bmi.h"
+#include "../include/osapi.h"
+#include "../include/hif.h"
+
+/* HTC operational parameters */
+#define HTC_GLOBAL_EVENT_NUM_MAX           2 /* Target available/unavailable */
+#define HTC_ENDPOINT_EVENT_NUM_MAX         5 /* Endpoint specific */
+#define HTC_REG_REQUEST_LIST_SIZE          16
+#define HTC_MESSAGE_SIZE_MAX               1536 - HTC_HEADER_LEN /* Default maximum message size for each mailbox */
+#define HTC_TX_CREDITS_NUM_MAX             64
+#define HTC_TARGET_RESPONSE_TIMEOUT        2000 /* in ms */
+
+/* Useful macros */
+#define GET_ENDPOINT_ID(endPoint) (endPoint - endPoint->target->endPoint)
+
+/* ------- Debug related stuff ------- */
+enum {
+    ATH_DEBUG_SEND = 0x0001,
+    ATH_DEBUG_RECV = 0x0002,
+    ATH_DEBUG_SYNC = 0x0004,
+    ATH_DEBUG_DUMP = 0x0008,
+    ATH_DEBUG_INF  = 0x0010,
+    ATH_DEBUG_TRC  = 0x0020,
+    ATH_DEBUG_WARN = 0x0040,
+    ATH_DEBUG_ERR  = 0x0080,
+    ATH_DEBUG_ANY  = 0xFFFF,
+};
+
+#ifdef DEBUG
+#define AR_DEBUG_PRINTBUF(buffer, length) do {   \
+    if (debughtc & ATH_DEBUG_DUMP) {             \
+        dumpBytes(buffer, length);               \
+    }                                            \
+} while(0)
+#define PRINTX_ARG(arg...) arg
+#define AR_DEBUG_PRINTF(flags, args) do {        \
+    if (debughtc & (flags)) {                    \
+        A_PRINTF(KERN_ALERT PRINTX_ARG args);      \
+    }                                            \
+} while (0)
+#define AR_DEBUG_ASSERT(test) do {               \
+    if (!(test)) {                               \
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#test));         \
+    }                                            \
+} while(0)
+#else
+#define AR_DEBUG_PRINTF(flags, args)
+#define AR_DEBUG_PRINTBUF(buffer, length)
+#define AR_DEBUG_ASSERT(test)
+#endif
+
+/* ------- Event Related Data Structures ------- */
+typedef struct htc_event_map HTC_EVENT_MAP;
+typedef struct event_table_element EVENT_TABLE_ELEMENT;
+typedef struct htc_endpoint_event_table HTC_ENDPOINT_EVENT_TABLE;
+typedef struct htc_global_event_table HTC_GLOBAL_EVENT_TABLE;
+
+#define FRAME_EVENT(_eventInfo, _buffer, _bufferLength,   \
+                    _actualLength, _status, _cookie) do { \
+    _eventInfo.buffer  = _buffer;                         \
+    _eventInfo.bufferLength = _bufferLength;              \
+    _eventInfo.actualLength = _actualLength;              \
+    _eventInfo.status = _status;                          \
+    _eventInfo.cookie = _cookie;                          \
+} while (0)
+
+struct event_table_element {
+    HTC_EVENT_ID         id;
+    HTC_EVENT_HANDLER    handler;
+    void                *param;
+};
+
+struct htc_endpoint_event_table {
+    EVENT_TABLE_ELEMENT element[HTC_ENDPOINT_EVENT_NUM_MAX];
+};
+
+struct htc_global_event_table {
+    EVENT_TABLE_ELEMENT element[HTC_GLOBAL_EVENT_NUM_MAX];
+
+};
+
+/* ------ Mailbox Related Data Structures ------ */
+typedef struct htc_queue_element HTC_QUEUE_ELEMENT, HTC_REG_REQUEST_ELEMENT, HTC_DATA_REQUEST_ELEMENT;
+typedef struct htc_mbox_buffer HTC_MBOX_BUFFER;
+typedef struct htc_reg_buffer HTC_REG_BUFFER;
+typedef struct htc_data_request_queue HTC_DATA_REQUEST_QUEUE;
+typedef struct htc_reg_request_list HTC_REG_REQUEST_LIST;
+typedef struct htc_endpoint HTC_ENDPOINT;
+
+typedef enum {
+    INT_STATUS_REG,
+    ERROR_INT_STATUS_REG,
+    CPU_INT_STATUS_REG,
+    RX_LOOKAHEAD_VALID_REG,
+    RX_LOOKAHEAD0_REG,
+    RX_LOOKAHEAD1_REG,
+    RX_LOOKAHEAD2_REG,
+    RX_LOOKAHEAD3_REG,
+    TX_CREDIT_COUNTER_REG,
+    TX_CREDIT_COUNTER_RESET_REG,
+    TX_CREDIT_COUNTER_DECREMENT_REG,
+    SCRATCH_REG,
+    INT_STATUS_ENABLE_REG,
+    CPU_INT_STATUS_ENABLE_REG,
+    ERROR_STATUS_ENABLE_REG,
+    COUNTER_INT_STATUS_READ_REG,
+    COUNTER_INT_STATUS_ENABLE_REG,
+    COUNTER_INT_STATUS_DISABLE_REG,
+    INT_WLAN_REG,
+    WINDOW_DATA_REG,
+    WINDOW_WRITE_ADDR_REG,
+    WINDOW_READ_ADDR_REG
+} TARGET_REGISTERS;
+
+#define SET_TX_CREDITS_AVAILABLE(endPoint, credits) \
+                                    endPoint->txCreditsAvailable[0] = (credits)
+#define SET_TX_CREDITS_CONSUMED(endPoint, credits) \
+                                    endPoint->txCreditsConsumed = (credits)
+#define GET_TX_CREDITS_AVAILABLE(endPoint) \
+                                    endPoint->txCreditsAvailable[0]
+#define GET_TX_CREDITS_CONSUMED(endPoint) \
+                                    endPoint->txCreditsConsumed
+
+#define IS_ELEMENT_FREE(element)	element->buffer.free
+#define GET_MBOX_BUFFER(element)	&((element)->buffer.u.mboxBuffer)
+#define GET_REG_BUFFER(element)		&((element)->buffer.u.regBuffer)
+#define GET_QUEUE_TAIL(queue)		&queue->element[(queue->head + queue->size) % HTC_DATA_REQUEST_RING_BUFFER_SIZE]
+#define GET_QUEUE_HEAD(queue)		&queue->element[queue->head]
+#define IS_DATA_QUEUE_EMPTY(queue)      (!queue->size)
+#define IS_DATA_QUEUE_FULL(queue)       (!(HTC_DATA_REQUEST_RING_BUFFER_SIZE - queue->size))
+
+#define RECYCLE_DATA_REQUEST_ELEMENT(element) do { \
+    FILL_MBOX_BUFFER(element, NULL, 0, 0, NULL); \
+    (element)->buffer.free = TRUE; \
+} while (0)
+
+#define FILL_MBOX_BUFFER(element, _buffer, _bufferLength, _actualLength, _cookie) do { \
+    (GET_MBOX_BUFFER(element))->buffer = _buffer; \
+    (GET_MBOX_BUFFER(element))->bufferLength = _bufferLength; \
+    (GET_MBOX_BUFFER(element))->actualLength = _actualLength; \
+    (GET_MBOX_BUFFER(element))->cookie = _cookie; \
+} while (0)
+
+#define FILL_REG_BUFFER(element, _buffer, _length, _base, _offset) do { \
+    (GET_REG_BUFFER(element))->buffer = _buffer; \
+    (GET_REG_BUFFER(element))->length = _length; \
+    (GET_REG_BUFFER(element))->base = _base; \
+    (GET_REG_BUFFER(element))->offset = _offset; \
+} while (0)
+
+struct htc_queue_element {
+    A_STATUS	(*completionCB)(HTC_QUEUE_ELEMENT *element, A_STATUS status);
+    struct htc_buffer {
+        /* In use or available */
+        A_BOOL	free;
+        union {
+            struct htc_mbox_buffer {
+                /*
+                 * Given by the caller and is associated with the buffer being
+                 * queued up.
+                 */
+                void			*cookie;
+
+                /*
+                 * Pointer to the start of the buffer. In the transmit
+                 * direction this points to the start of the payload. In the
+                 * receive direction, however, the buffer when queued up
+                 * points to the start of the HTC header but when returned
+                 * to the caller points to the start of the payload
+                 */
+                A_UCHAR			*buffer;
+
+                /* Holds the length of the buffer */
+                A_UINT32		bufferLength;
+
+                /* Holds the length of the payload */
+                A_UINT32		actualLength;
+
+                HTC_ENDPOINT    *endPoint;
+            } mboxBuffer;
+            struct htc_reg_buffer {
+                HTC_TARGET		*target;
+                A_UCHAR			*buffer;
+                A_UINT32		length;
+                TARGET_REGISTERS	base;
+                A_UINT32		offset;
+            } regBuffer;
+        } u;
+    } buffer;
+};
+
+/* This is a FIFO queue of the pending data read/write requests. When a request
+has to be issued, the element at the head of the queue is dequeued and
+processed. New requests are added at the tail of the queue. The queue can only
+support a fixed number of requests and stops adding new requests once the total
+number of requests that are pending to be processed and the ones that are still
+under process reach the queue capacity */
+struct htc_data_request_queue {
+    A_UINT32                  head;
+    A_UINT32                  size;
+    HTC_DATA_REQUEST_ELEMENT  element[HTC_DATA_REQUEST_RING_BUFFER_SIZE];
+};
+
+/* This is a list of 'free' register read/write requests. When a request has to
+be issued an element is taken from this list and after the completion of the
+request is added back to the list */
+struct htc_reg_request_list {
+    HTC_REG_REQUEST_ELEMENT  element[HTC_REG_REQUEST_LIST_SIZE];
+};
+
+struct htc_endpoint {
+    /* Enabled or Disabled */
+    A_BOOL                   enabled;
+
+    /*
+     * Used to hold the length of the frame received from the target in
+     * case there are no buffers that have been queued up to receive the
+     * data.
+     */
+    A_UINT32                 rxLengthPending;
+
+    /* Number of frames for which the target has space for at any time */
+    A_UINT8                  txCreditsAvailable[1 + HTC_TX_CREDITS_NUM_MAX];
+
+    /*
+     * Number of frames that have been sent since the transmit credits
+     * were last updated.
+     */
+    A_UINT8                  txCreditsConsumed;
+
+    A_BOOL                   txCreditsIntrEnable;
+
+    /* Pending Send Queue */
+    HTC_DATA_REQUEST_QUEUE   sendQueue;
+
+    /* Pending Receive Queue */
+    HTC_DATA_REQUEST_QUEUE   recvQueue;
+
+    /* Inverse reference to the target */
+    HTC_TARGET              *target;
+
+    /* Block size configured for the endpoint */
+    A_UINT32                 blockSize;
+
+    /* Event Table */
+    HTC_ENDPOINT_EVENT_TABLE eventTable;
+
+    /* Stating address of the endpoint */
+    A_UINT32                 address;
+};
+
+/* ------- Target Related Data structures ------- */
+typedef struct htc_register_table HTC_REGISTER_TABLE;
+
+/*
+ * The following Register table only contain those registers that are used
+ * in HTC. It does not reflect the actual register layout in the hardware
+ */
+struct htc_register_table {
+    A_UINT8                      host_int_status;
+    A_UINT8                      cpu_int_status;
+    A_UINT8                      error_int_status;
+    A_UINT8                      counter_int_status;
+    A_UINT8                      mbox_frame;
+    A_UINT8                      rx_lookahead_valid;
+    A_UINT8                      hole[2];
+    A_UINT32                     rx_lookahead[HTC_MAILBOX_NUM_MAX];
+    A_UINT8                      int_status_enable;
+    A_UINT8                      cpu_int_status_enable;
+    A_UINT8                      error_status_enable;
+    A_UINT8                      counter_int_status_enable;
+    A_UINT8                      int_wlan;
+};
+
+struct htc_target {
+    A_BOOL                       ready;
+    void                        *device; /* Handle to the device instance
+                                            reported by the bus driver */
+    HTC_ENDPOINT                 endPoint[HTC_MAILBOX_NUM_MAX];
+    HTC_REGISTER_TABLE           table;
+    HTC_REG_REQUEST_LIST         regList;
+};
+
+
+/* ------- Function Prototypes for Receive -------- */
+void
+htcReceiveFrame(HTC_ENDPOINT *endPoint);
+
+A_UINT32
+htcGetFrameLength(HTC_ENDPOINT *endPoint);
+
+
+/* ------- Function Prototypes for Transmit -------- */
+void
+htcSendFrame(HTC_ENDPOINT *endPoint);
+
+void
+htcSendBlkSize(HTC_ENDPOINT *endPoint);
+
+
+/* ------- Function Prototypes for Events and Callbacks  ------- */
+A_STATUS
+htcRWCompletionHandler(void *element,
+                       A_STATUS status);
+
+A_STATUS
+htcTxCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,
+                  A_STATUS status);
+
+A_STATUS
+htcBlkSzNegCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,
+                        A_STATUS status);
+
+A_STATUS
+htcRxCompletionCB(HTC_DATA_REQUEST_ELEMENT *element,
+                  A_STATUS status);
+
+A_STATUS
+htcRegCompletionCB(HTC_REG_REQUEST_ELEMENT *element,
+                   A_STATUS status);
+
+A_STATUS
+htcTargetInsertedHandler(HIF_DEVICE *device);
+
+A_STATUS
+htcTargetRemovedHandler(HIF_DEVICE *device);
+
+A_STATUS
+htcDSRHandler(HIF_DEVICE *device);
+
+#ifdef CF
+A_STATUS
+htcInterruptDisabler(HIF_DEVICE *device,A_BOOL *callDsr);
+
+A_STATUS
+htcInterruptEnabler(HIF_DEVICE *device);
+#endif /* CF */
+
+void
+htcServiceCPUInterrupt(HTC_TARGET *target);
+
+void
+htcServiceErrorInterrupt(HTC_TARGET *target);
+
+void
+htcServiceCounterInterrupt(HTC_TARGET *target);
+
+void
+htcServiceMailboxInterrupt(HTC_TARGET *target);
+
+void
+htcEnableCreditCounterInterrupt(HTC_TARGET *target,
+                                HTC_ENDPOINT_ID endPointId);
+
+void
+htcDisableCreditCounterInterrupt(HTC_TARGET *target,
+                                 HTC_ENDPOINT_ID endPointId);
+
+/* ------- Function Prototypes for Utility routines ------- */
+A_STATUS
+addToMboxQueue(HTC_DATA_REQUEST_QUEUE *queue,
+               A_UCHAR        *buffer,
+               A_UINT32        bufferLength,
+               A_UINT32        actualLength,
+               void           *cookie);
+
+HTC_DATA_REQUEST_ELEMENT *
+removeFromMboxQueue(HTC_DATA_REQUEST_QUEUE *queue);
+
+void
+flushMboxQueue(HTC_ENDPOINT *endPoint,
+               HTC_DATA_REQUEST_QUEUE *queue,
+               HTC_EVENT_ID eventId);
+
+HTC_REG_REQUEST_ELEMENT *
+allocateRegRequestElement(HTC_TARGET *target);
+
+void
+freeRegRequestElement(HTC_REG_REQUEST_ELEMENT *element);
+
+A_STATUS
+addToEventTable(HTC_TARGET       *target,
+                HTC_ENDPOINT_ID   endPointId,
+                HTC_EVENT_ID      eventId,
+                HTC_EVENT_HANDLER handler,
+                void             *param);
+
+A_STATUS
+removeFromEventTable(HTC_TARGET *target,
+                     HTC_ENDPOINT_ID endPointId,
+                     HTC_EVENT_ID  eventId);
+
+void
+dispatchEvent(HTC_TARGET     *target,
+              HTC_ENDPOINT_ID endPointId,
+              HTC_EVENT_ID    eventId,
+              HTC_EVENT_INFO *eventInfo);
+
+HTC_TARGET *
+getTargetInstance(void *device);
+
+void
+addTargetInstance(HTC_TARGET *target);
+
+void
+delTargetInstance(HTC_TARGET *target);
+
+A_UINT32
+getRegAddr(TARGET_REGISTERS base,
+           HTC_ENDPOINT_ID endPointId);
+
+A_UINT8
+htcGetBitNumSet(A_UINT32 data);
+
+void
+dumpBytes(A_UCHAR *buffer, A_UINT16 length);
+
+void
+dumpRegisters(HTC_TARGET *target);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HTC_INTERNAL_H_ */

Added: developers/nbd/ar6k/htc/htc_recv.c
===================================================================
--- developers/nbd/ar6k/htc/htc_recv.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/htc/htc_recv.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the routines handling the receive path.
+ */
+
+#include "htc_internal.h"
+
+/* ------ Global Variable Declarations ------- */
+#ifdef DEBUG
+extern A_UINT32 debughtc;
+#endif
+
+/* ------ Static Variables ------ */
+
+
+/* ------ Functions ------ */
+/* Makes a buffer available to the HTC module */
+A_STATUS
+HTCBufferReceive(HTC_TARGET *target,
+                 HTC_ENDPOINT_ID endPointId,
+                 A_UCHAR *buffer,
+                 A_UINT32 length,
+                 void *cookie)
+{
+    A_STATUS status;
+    HTC_ENDPOINT *endPoint;
+    HTC_DATA_REQUEST_QUEUE *recvQueue;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,
+                    ("HTCBufferReceive: Enter (endPointId: %d, buffer: 0x%p, length: %d, cookie: 0x%p)\n", endPointId, buffer, length, cookie));
+
+    AR_DEBUG_ASSERT((endPointId >= ENDPOINT1) && (endPointId <= ENDPOINT4));
+
+    /* Extract the end point instance */
+    endPoint = &target->endPoint[endPointId];
+    AR_DEBUG_ASSERT(endPoint != NULL);
+
+    recvQueue = &endPoint->recvQueue;
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_RECV, ("recvQueue: %p\n",
+                    recvQueue));
+
+    /* Add this posted buffer to the pending receive queue */
+    status = addToMboxQueue(recvQueue, buffer, length, 0, cookie);
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_RECV,
+                        ("Mailbox (%d) Send queue full. Unable to add buffer\n",
+                        GET_ENDPOINT_ID(endPoint)));
+        return A_ERROR;
+    }
+
+    /*
+     * If this API was called as a result of a HTC_DATA_AVAILABLE event to
+     * the upper layer, indicating that HTC is out of buffers, then we should
+     * receive the frame in the buffer supplied otherwise we simply add the
+     * buffer to the Pending Receive Queue
+     */
+    if (endPoint->rxLengthPending) {
+        htcReceiveFrame(endPoint);
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,
+                    ("HTCBufferReceive: Exit\n"));
+    return A_OK;
+}
+
+void
+htcReceiveFrame(HTC_ENDPOINT *endPoint)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    A_UINT32 paddedLength;
+    A_UINT32 frameLength;
+    HIF_REQUEST request;
+    HTC_ENDPOINT_ID endPointId;
+    HTC_QUEUE_ELEMENT *element;
+    HTC_MBOX_BUFFER *mboxBuffer;
+    HTC_DATA_REQUEST_QUEUE *recvQueue;
+    HTC_TARGET *target;
+    HTC_EVENT_INFO eventInfo;
+    HIF_DATAMODE dmode;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,
+                    ("htcReceiveFrame - Enter\n"));
+
+    /* Get the context */
+    AR_DEBUG_ASSERT(endPoint != NULL);
+    endPointId = GET_ENDPOINT_ID(endPoint);
+    target = endPoint->target;
+    AR_DEBUG_ASSERT(target != NULL);
+    recvQueue = &endPoint->recvQueue;
+    AR_DEBUG_ASSERT(recvQueue != NULL);
+
+    /*
+     * Receive the frame if we have any pending frames and a buffer to
+     * receive it into.
+     */
+     if (IS_DATA_QUEUE_EMPTY(recvQueue)) {
+         AR_DEBUG_PRINTF(ATH_DEBUG_WARN | ATH_DEBUG_RECV,
+                         ("Mailbox (%d) recv queue empty. Unable to remove buffer\n", endPointId));
+
+         /*
+          * Communicate this situation to the host via the HTC_DATA_AVAILABLE
+          * event to request some buffers in the queue.
+          */
+         endPoint->rxLengthPending = htcGetFrameLength(endPoint);
+         AR_DEBUG_ASSERT(endPoint->rxLengthPending);
+         FRAME_EVENT(eventInfo, NULL, endPoint->rxLengthPending,
+                     0, A_OK, NULL);
+         dispatchEvent(target, endPointId, HTC_DATA_AVAILABLE, &eventInfo);
+         return;
+     }
+
+     /*
+      * Get the length from the lookahead register if there is nothing
+      * pending.
+      */
+     if (endPoint->rxLengthPending) {
+         frameLength = endPoint->rxLengthPending;
+         endPoint->rxLengthPending = 0;
+     } else {
+         frameLength = htcGetFrameLength(endPoint);
+     }
+     AR_DEBUG_ASSERT((frameLength > 0) &&
+                     (frameLength <= HTC_MESSAGE_SIZE_MAX));
+     AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_RECV, ("Frame Length: %d\n",
+                     frameLength));
+
+     /* Adjust the length to be a multiple of block size if appropriate */
+     paddedLength = (frameLength + (endPoint->blockSize - 1)) &
+                    (~(endPoint->blockSize - 1));
+
+     /*
+      * Receive the frame(s). Pull an empty buffer from the head of the
+      * Pending Receive Queue.
+      */
+     element = removeFromMboxQueue(recvQueue);
+     mboxBuffer = GET_MBOX_BUFFER(element);
+     mboxBuffer->actualLength = paddedLength;
+     dmode = (endPoint->blockSize > 1) ? HIF_BLOCK_BASIS : HIF_BYTE_BASIS;
+     HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,
+                       HIF_ASYNCHRONOUS, dmode, HIF_INCREMENTAL_ADDRESS);
+     address = endPoint->address;
+     status = HIFReadWrite(target->device, address, mboxBuffer->buffer,
+                           mboxBuffer->actualLength, &request, element);
+#ifndef HTC_SYNC
+     if (status != A_OK) {
+#else
+     if (status != A_OK && status != A_PENDING) {
+#endif
+         AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_RECV,
+                         ("Frame reception failed\n"));
+         if (!IS_ELEMENT_FREE(element)) {
+             mboxBuffer->actualLength = 0;
+             FRAME_EVENT(eventInfo, mboxBuffer->buffer,
+                         mboxBuffer->bufferLength, mboxBuffer->actualLength,
+                         A_ECANCELED, mboxBuffer->cookie);
+             RECYCLE_DATA_REQUEST_ELEMENT(element);
+             dispatchEvent(target, endPointId, HTC_BUFFER_RECEIVED,
+                           &eventInfo);
+             AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,
+                             ("htcReceiveFrame - Exit\n"));
+             return;
+         }
+     }
+#ifdef HTC_SYNC
+	else if (status == A_OK) {
+		element->completionCB(element, status);
+	}
+#endif
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_RECV,
+                    ("htcReceiveFrame - Exit\n"));
+}
+
+A_UINT32
+htcGetFrameLength(HTC_ENDPOINT *endPoint)
+{
+    HTC_TARGET *target;
+    A_UINT32 frameLength;
+    HTC_ENDPOINT_ID endPointId;
+
+    /* Get the context */
+    AR_DEBUG_ASSERT(endPoint != NULL);
+    target = endPoint->target;
+    AR_DEBUG_ASSERT(target != NULL);
+    endPointId = GET_ENDPOINT_ID(endPoint);
+
+    AR_DEBUG_ASSERT(target->table.rx_lookahead_valid & (1 << endPointId));
+
+    /* The length is contained in the first two bytes - HTC_HEADER_LEN */
+    frameLength = (target->table.rx_lookahead[endPointId] & 0xFFFF) +
+                  HTC_HEADER_LEN;
+    AR_DEBUG_ASSERT(frameLength);
+
+    return frameLength;
+}

Added: developers/nbd/ar6k/htc/htc_send.c
===================================================================
--- developers/nbd/ar6k/htc/htc_send.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/htc/htc_send.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the routines handling the transmit path.
+ */
+
+#include "htc_internal.h"
+
+/* ------ Global Variable Declarations ------- */
+extern A_MUTEX_T creditCS;
+
+#ifdef DEBUG
+extern A_UINT32 debughtc;
+extern A_UINT32 txcreditsavailable[HTC_MAILBOX_NUM_MAX];
+extern A_UINT32 txcreditsconsumed[HTC_MAILBOX_NUM_MAX];
+#ifdef HTC_SYNC
+extern A_UINT32 txcreditintrenable[HTC_MAILBOX_NUM_MAX];
+extern A_UINT32 txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX];
+#endif
+#endif
+
+extern A_UINT32 tx_attempt[HTC_MAILBOX_NUM_MAX];  /* Num of attempts to add */
+extern A_UINT32 tx_post[HTC_MAILBOX_NUM_MAX];     /* Num of attemps succeded */
+extern A_UINT32 tx_complete[HTC_MAILBOX_NUM_MAX]; /* Num of tx complete */
+
+/* ------ Functions ------ */
+A_STATUS
+HTCBufferSend(HTC_TARGET *target,
+              HTC_ENDPOINT_ID endPointId,
+              A_UCHAR *buffer,
+              A_UINT32 length,
+              void *cookie)
+{
+    A_STATUS status;
+    HTC_ENDPOINT *endPoint;
+    HTC_DATA_REQUEST_QUEUE *sendQueue;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,
+                    ("HTCBufferSend: Enter (endPointId: %d, buffer: 0x%p, length: %d, cookie: 0x%p)\n", endPointId, buffer, length, cookie));
+
+    AR_DEBUG_ASSERT((endPointId >= ENDPOINT1) && (endPointId <= ENDPOINT4));
+    AR_DEBUG_ASSERT(length);
+
+    /* Extract the end point instance */
+    endPoint = &target->endPoint[endPointId];
+    AR_DEBUG_ASSERT(endPoint != NULL);
+    sendQueue = &endPoint->sendQueue;
+    AR_DEBUG_ASSERT(sendQueue != NULL);
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,
+                    ("mboxQueue: %p\n", sendQueue));
+
+    /*
+     * Add this posted buffer to the pending send queue. We need to allocate
+     * a bufferElement to store the packet information and we borrow that
+     * buffer from the pending send queue. If circumstances allow us to
+     * transmit it right away then we dequeue it otherwise we let it remain
+     * to be picked in the interrupt handler context.
+     */
+    tx_attempt[endPointId] += 1;
+
+    if (!endPoint->enabled) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Endpoint not enabled: %d\n",
+                                        GET_ENDPOINT_ID(endPoint)));
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+                        ("tx_attempt[%d] = %d, tx_post[%d] = %d, tx_complete[%d] = %d\n", endPointId, tx_attempt[endPointId], endPointId, tx_post[endPointId], endPointId, tx_complete[endPointId]));
+        return A_ERROR;
+    }
+
+    status = addToMboxQueue(sendQueue, buffer, length, 0, cookie);
+    if (status != A_OK) {
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_SEND,
+                        ("Mailbox (%d) PSQ full. Unable to add buffer\n",
+                        endPointId));
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+                        ("tx_attempt[%d] = %d, tx_post[%d] = %d, tx_complete[%d] = %d\n", endPointId, tx_attempt[endPointId], endPointId, tx_post[endPointId], endPointId, tx_complete[endPointId]));
+        return A_ERROR;
+    }
+
+    tx_post[endPointId] += 1;
+
+    /*
+     * The frame shall be dequeued and sent if there are any credits
+     * available.
+     */
+    htcSendFrame(endPoint);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND, ("HTCBufferSend: Exit\n"));
+    return A_OK;
+}
+
+
+void
+htcSendFrame(HTC_ENDPOINT *endPoint)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HIF_DATAMODE dmode;
+    HTC_TARGET *target;
+    HIF_REQUEST request;
+    A_UINT32 frameLength;
+    A_UINT32 paddedLength;
+    HTC_EVENT_INFO eventInfo;
+    A_UINT8 txCreditsConsumed;
+    A_UINT8 txCreditsAvailable;
+    HTC_ENDPOINT_ID endPointId;
+    HTC_QUEUE_ELEMENT *element;
+    HTC_MBOX_BUFFER *mboxBuffer;
+    HTC_REG_REQUEST_LIST *regList;
+    HTC_DATA_REQUEST_QUEUE *sendQueue;
+#ifdef HTC_SYNC
+    HTC_REG_BUFFER *regBuffer;
+#endif
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND, ("htcSendFrame - Enter\n"));
+
+    /* Get the context */
+    AR_DEBUG_ASSERT(endPoint != NULL);
+    endPointId = GET_ENDPOINT_ID(endPoint);
+    target = endPoint->target;
+    AR_DEBUG_ASSERT(target != NULL);
+    sendQueue = &endPoint->sendQueue;
+    AR_DEBUG_ASSERT(sendQueue != NULL);
+    regList = &target->regList;
+    AR_DEBUG_ASSERT(regList != NULL);
+
+    /*
+     * Transmit the frames as long as we have the credits available and
+     * the queue is not out of them
+     */
+    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                    ("Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__));
+    A_MUTEX_LOCK(&creditCS);
+    txCreditsAvailable = GET_TX_CREDITS_AVAILABLE(endPoint);
+    txCreditsConsumed = GET_TX_CREDITS_CONSUMED(endPoint);
+    SET_TX_CREDITS_AVAILABLE(endPoint, 0);
+    SET_TX_CREDITS_CONSUMED(endPoint, txCreditsConsumed + txCreditsAvailable);
+    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                    ("Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__));
+    A_MUTEX_UNLOCK(&creditCS);
+
+    /*
+     * Send the packet only when there are packets to be sent and there
+     * are positive number of credits available.
+     */
+    while((!IS_DATA_QUEUE_EMPTY(sendQueue)) && txCreditsAvailable)
+    {
+        /* Get the request buffer from the Pending Send Queue */
+        element = removeFromMboxQueue(sendQueue);
+        mboxBuffer = GET_MBOX_BUFFER(element);
+
+        /*
+         * Prepend the actual length in the first 2 bytes of the outgoing
+         * packet.
+         */
+        mboxBuffer->buffer -= HTC_HEADER_LEN;
+        A_MEMCPY(mboxBuffer->buffer, &mboxBuffer->bufferLength, HTC_HEADER_LEN);
+
+        /*
+         * Adjust the length in the block mode only when its not an integral
+         * multiple of the block size. Assumption is that the block size is
+         * a power of 2.
+         */
+        frameLength = mboxBuffer->bufferLength + HTC_HEADER_LEN;
+        paddedLength = (frameLength + (endPoint->blockSize - 1)) &
+                       (~(endPoint->blockSize - 1));
+        mboxBuffer->actualLength = paddedLength;
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,
+                        ("Original frame length: %d, Padded frame length: %d\n", frameLength, paddedLength));
+
+        AR_DEBUG_PRINTBUF(mboxBuffer->buffer, mboxBuffer->actualLength);
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,
+                        ("Available Tx credits: %d\n", txCreditsAvailable));
+
+        /* Frame the interface request */
+        dmode = (endPoint->blockSize > 1) ? HIF_BLOCK_BASIS : HIF_BYTE_BASIS;
+        HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO,
+                          HIF_ASYNCHRONOUS, dmode, HIF_INCREMENTAL_ADDRESS);
+        address = endPoint->address;
+
+        /* Send the data to the bus driver */
+        status = HIFReadWrite(target->device, address, mboxBuffer->buffer,
+                              mboxBuffer->actualLength, &request, element);
+#ifndef HTC_SYNC
+        if (status != A_OK) {
+#else
+		if (status != A_OK && status != A_PENDING) {
+#endif
+
+            AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_SEND,
+                            ("Frame transmission failed\n"));
+            AR_DEBUG_PRINTF(ATH_DEBUG_ERR | ATH_DEBUG_SEND,
+                            ("EndPoint: %d, Tx credits available: %d\n",
+                             endPointId, GET_TX_CREDITS_AVAILABLE(endPoint)));
+            /*
+             * We need to check just in case the callback routine was called
+             * with the error status before we reach this point and in that
+             * context we fee up the buffer so its just a conservative design.
+             */
+            if (!IS_ELEMENT_FREE(element)) {
+                mboxBuffer->buffer += HTC_HEADER_LEN;
+                FRAME_EVENT(eventInfo, mboxBuffer->buffer,
+                            mboxBuffer->bufferLength,
+                            mboxBuffer->actualLength,
+                            A_ECANCELED, mboxBuffer->cookie);
+                RECYCLE_DATA_REQUEST_ELEMENT(element);
+                dispatchEvent(target, endPointId, HTC_BUFFER_SENT, &eventInfo);
+            }
+            AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,
+                            ("htcSendFrame - Exit\n"));
+            return;
+        }
+#ifdef HTC_SYNC
+		else if (status == A_OK) {
+			element->completionCB(element, status);
+		}
+#endif
+        txCreditsAvailable -= 1;
+        txCreditsConsumed += 1;
+
+#ifdef DEBUG
+        txcreditsavailable[endPointId] = txCreditsAvailable;
+        txcreditsconsumed[endPointId] = txCreditsConsumed;
+#endif /* DEBUG */
+
+        if (!txCreditsAvailable) {
+
+            AR_DEBUG_ASSERT(txCreditsConsumed);
+
+            /*
+             * Instead of taking an interrupt we can just poll for more
+             * credits that might have been queued up by now.
+             */
+            HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO,
+                              HIF_ASYNCHRONOUS, HIF_BYTE_BASIS,
+                              HIF_FIXED_ADDRESS);
+            address = getRegAddr(TX_CREDIT_COUNTER_DECREMENT_REG, endPointId);
+            element = allocateRegRequestElement(target);
+            AR_DEBUG_ASSERT(element != NULL);
+            FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1],
+                            txCreditsConsumed, TX_CREDIT_COUNTER_DECREMENT_REG,
+                            endPointId);
+            status = HIFReadWrite(target->device, address,
+                                  &endPoint->txCreditsAvailable[1],
+                                  txCreditsConsumed, &request, element);
+#ifndef HTC_SYNC
+            AR_DEBUG_ASSERT(status == A_OK);
+            AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND,
+                            ("htcSendFrame - Exit\n"));
+            return;
+#else
+            AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
+			if ( status == A_OK ) {
+
+				AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                        ("Critical Section (credit): LOCK at line %d in file %s							 \n", __LINE__, __FILE__));
+        		A_MUTEX_LOCK(&creditCS);
+
+    			regBuffer = GET_REG_BUFFER(element);
+        		/* Calculate the number of credits available */
+        		AR_DEBUG_ASSERT(GET_TX_CREDITS_CONSUMED(endPoint) == \
+					regBuffer->length);
+        		SET_TX_CREDITS_AVAILABLE(endPoint, regBuffer->buffer[0] -
+                	GET_TX_CREDITS_CONSUMED(endPoint));
+        		SET_TX_CREDITS_CONSUMED(endPoint, 0);
+        		txCreditsAvailable = GET_TX_CREDITS_AVAILABLE(endPoint);
+        		txCreditsConsumed = GET_TX_CREDITS_CONSUMED(endPoint);
+        		AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                        ("Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__));
+        		A_MUTEX_UNLOCK(&creditCS);
+
+        		AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,
+                        ("Pulling %d tx credits from the target\n",
+                        txCreditsAvailable));
+
+				#ifdef DEBUG
+        			txcreditsavailable[endPointId] = txCreditsAvailable;
+        			txcreditsconsumed[endPointId] = txCreditsConsumed;
+				#endif /* DEBUG */
+
+    			freeRegRequestElement(element);
+
+				if (!txCreditsAvailable) {
+
+            	/* Enable the Tx credit counter interrupt so that we can get
+				 * the credits posted by the target */
+
+            		htcEnableCreditCounterInterrupt(target, endPointId);
+
+					/* Counter Interrupts have been enabled if
+				 	 * txCreditsAvailable is still 0 after polling. We need to
+				 	 * return here as there is nothing we can send till we get
+				 	 * a Counter Interrupt.
+			 	 	 */
+					return;
+				}
+			}
+#endif
+        }
+    }
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                    ("Critical Section (credit): LOCK at line %d in file %s\n", __LINE__, __FILE__));
+    A_MUTEX_LOCK(&creditCS);
+    SET_TX_CREDITS_AVAILABLE(endPoint, txCreditsAvailable);
+    SET_TX_CREDITS_CONSUMED(endPoint, txCreditsConsumed);
+    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                    ("Critical Section (credit): UNLOCK at line %d in file %s\n", __LINE__, __FILE__));
+    A_MUTEX_UNLOCK(&creditCS);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_TRC | ATH_DEBUG_SEND, ("htcSendFrame - Exit\n"));
+}
+
+void
+htcSendBlkSize(HTC_ENDPOINT *endPoint)
+{
+    A_STATUS status;
+    A_UINT32 address;
+    HTC_TARGET *target;
+    HIF_REQUEST request;
+    HTC_ENDPOINT_ID endPointId;
+    HTC_QUEUE_ELEMENT *element;
+    HTC_MBOX_BUFFER *mboxBuffer;
+    HTC_DATA_REQUEST_QUEUE *sendQueue;
+    HTC_REG_REQUEST_LIST *regList;
+
+    /* Get the context */
+    AR_DEBUG_ASSERT(endPoint != NULL);
+    target = endPoint->target;
+    AR_DEBUG_ASSERT(target != NULL);
+    regList = &target->regList;
+    AR_DEBUG_ASSERT(regList != NULL);
+    sendQueue = &endPoint->sendQueue;
+    AR_DEBUG_ASSERT(sendQueue != NULL);
+    endPointId = GET_ENDPOINT_ID(endPoint);
+
+    /* Decrement the tx credit count */
+    AR_DEBUG_ASSERT(endPoint->txCreditsConsumed == 0);
+    endPoint->txCreditsConsumed = 1;
+    HIF_FRAME_REQUEST(&request, HIF_READ, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_FIXED_ADDRESS);
+    address = getRegAddr(TX_CREDIT_COUNTER_DECREMENT_REG, endPointId);
+    element = allocateRegRequestElement(target);
+    AR_DEBUG_ASSERT(element != NULL);
+    FILL_REG_BUFFER(element, &endPoint->txCreditsAvailable[1],
+                    endPoint->txCreditsConsumed,
+                    TX_CREDIT_COUNTER_DECREMENT_REG, endPointId);
+    status = HIFReadWrite(target->device, address,
+                          &endPoint->txCreditsAvailable[1],
+                          endPoint->txCreditsConsumed, &request, element);
+#ifndef HTC_SYNC
+    AR_DEBUG_ASSERT(status == A_OK);
+#else
+    AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
+	if (status == A_OK) {
+		element->completionCB(element, status);
+	}
+#endif
+
+    /* Negotiate the maximum block size for the endpoint */
+    addToMboxQueue(sendQueue, (A_UCHAR *)&endPoint->blockSize,
+                   sizeof(endPoint->blockSize), sizeof(endPoint->blockSize),
+                   NULL);
+    element = removeFromMboxQueue(sendQueue);
+    element->completionCB = htcBlkSzNegCompletionCB;
+    mboxBuffer = GET_MBOX_BUFFER(element);
+    HIF_FRAME_REQUEST(&request, HIF_WRITE, HIF_EXTENDED_IO, HIF_ASYNCHRONOUS,
+                      HIF_BYTE_BASIS, HIF_INCREMENTAL_ADDRESS);
+    address = endPoint->address;
+    status = HIFReadWrite(target->device, address, mboxBuffer->buffer,
+                          mboxBuffer->bufferLength, &request, element);
+#ifndef HTC_SYNC
+    AR_DEBUG_ASSERT(status == A_OK);
+#else
+	AR_DEBUG_ASSERT(status == A_OK || status == A_PENDING);
+	if (status == A_OK) {
+		element->completionCB(element, status);
+	}
+#endif
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF | ATH_DEBUG_SEND,
+                    ("Mailbox(%d), Block size: %d\n",
+                    endPointId, endPoint->blockSize));
+}

Added: developers/nbd/ar6k/htc/htc_utils.c
===================================================================
--- developers/nbd/ar6k/htc/htc_utils.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/htc/htc_utils.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the utility routines used across the entire HTC module.
+ */
+
+#include "htc_internal.h"
+
+/* ------ Global Variable Declarations ------- */
+extern HTC_TARGET *AtherosTargetList[HIF_MAX_DEVICES];
+extern HTC_GLOBAL_EVENT_TABLE AtherosEventTable;
+extern A_MUTEX_T instanceCS;
+
+#ifdef DEBUG
+extern A_UINT32 debughtc;
+#endif
+
+/* ------ Static Variables ------ */
+
+/* ------ Functions ------ */
+void
+dispatchEvent(HTC_TARGET     *target,
+              HTC_ENDPOINT_ID endPointId,
+              HTC_EVENT_ID    eventId,
+              HTC_EVENT_INFO *eventInfo)
+{
+    EVENT_TABLE_ELEMENT *eventElement;
+
+    if (eventId == HTC_TARGET_AVAILABLE) {
+        eventElement = &AtherosEventTable.element[0];
+    } else if (eventId == HTC_TARGET_UNAVAILABLE) {
+        eventElement = &AtherosEventTable.element[1];
+    } else {
+        eventElement =
+            &target->endPoint[endPointId].eventTable.element[eventId];
+    }
+    AR_DEBUG_ASSERT(eventElement != NULL);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                    ("dispatchEvent(endpoint: %d, eventId: 0x%d, handler: 0x%p)\n", endPointId, eventElement->id, eventElement->handler));
+    if (eventElement->handler) {
+        eventElement->handler(target, endPointId, eventId, eventInfo,
+                              eventElement->param);
+    }
+}
+
+
+A_STATUS
+addToEventTable(HTC_TARGET       *target,
+                HTC_ENDPOINT_ID   endPointId,
+                HTC_EVENT_ID      eventId,
+                HTC_EVENT_HANDLER handler,
+                void             *param)
+{
+    EVENT_TABLE_ELEMENT *new;
+
+    if (eventId == HTC_TARGET_AVAILABLE) {
+        new = &AtherosEventTable.element[0];
+    } else if (eventId == HTC_TARGET_UNAVAILABLE) {
+        new = &AtherosEventTable.element[1];
+    } else {
+        new = &target->endPoint[endPointId].eventTable.element[eventId];
+    }
+
+    /* Store the event id, the corresponding handler and the param passed */
+    new->id = eventId;
+    new->handler = handler;
+    new->param = param;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                    ("addToEventTable(endpoint: %d, eventId: 0x%d, handler: 0x%p)\n", endPointId, new->id, new->handler));
+
+    return A_OK;
+}
+
+
+A_STATUS
+removeFromEventTable(HTC_TARGET *target,
+                     HTC_ENDPOINT_ID endPointId,
+                     HTC_EVENT_ID  eventId)
+{
+    EVENT_TABLE_ELEMENT *remove;
+
+    if (eventId == HTC_TARGET_AVAILABLE) {
+        remove = &AtherosEventTable.element[0];
+    } else if (eventId == HTC_TARGET_UNAVAILABLE) {
+        remove = &AtherosEventTable.element[1];
+    } else {
+        remove = &target->endPoint[endPointId].eventTable.element[eventId];
+    }
+
+    /* Remove the event handler */
+    A_MEMZERO(remove, sizeof(EVENT_TABLE_ELEMENT));
+
+    return A_OK;
+}
+
+A_STATUS
+addToMboxQueue(HTC_DATA_REQUEST_QUEUE *queue,
+               A_UCHAR        *buffer,
+               A_UINT32        bufferLength,
+               A_UINT32        actualLength,
+               void           *cookie)
+{
+    A_STATUS status;
+    HTC_DATA_REQUEST_ELEMENT *element;
+
+    AR_DEBUG_ASSERT(queue != NULL);
+    AR_DEBUG_ASSERT(bufferLength);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                    ("Critical Section (queue): LOCK at line %d in file %s\n", __LINE__, __FILE__));
+    A_MUTEX_LOCK(&instanceCS);
+    element = GET_QUEUE_TAIL(queue);
+    if (!(IS_DATA_QUEUE_FULL(queue)) && IS_ELEMENT_FREE(element)) {
+        element->buffer.free = FALSE;
+        FILL_MBOX_BUFFER(element, buffer, bufferLength, actualLength, cookie);
+        queue->size += 1;
+
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                        ("addToMboxQueue (index: %d, size: %d, bufferElement: 0x%p, bufferElement->buffer: 0x%p, bufferElement->cookie: 0x%p)\n", (queue->head + queue->size - 1) % HTC_DATA_REQUEST_RING_BUFFER_SIZE, queue->size, element, (GET_MBOX_BUFFER(element))->buffer, (GET_MBOX_BUFFER(element))->cookie));
+        status = A_OK;
+    } else {
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Queue size: %d\n", queue->size));
+        status = A_ERROR;
+    }
+    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                    ("Critical Section (queue): UNLOCK at line %d in file %s\n", __LINE__, __FILE__));
+    A_MUTEX_UNLOCK(&instanceCS);
+
+    return status;
+}
+
+HTC_DATA_REQUEST_ELEMENT *
+removeFromMboxQueue(HTC_DATA_REQUEST_QUEUE *queue) {
+    HTC_DATA_REQUEST_ELEMENT *element;
+    AR_DEBUG_ASSERT(queue != NULL);
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                    ("Critical Section (queue): LOCK at line %d in file %s\n", __LINE__, __FILE__));
+    A_MUTEX_LOCK(&instanceCS);
+    if (!(IS_DATA_QUEUE_EMPTY(queue))) {
+        element = GET_QUEUE_HEAD(queue);
+        queue->head = (queue->head + 1) % HTC_DATA_REQUEST_RING_BUFFER_SIZE;
+        queue->size -= 1;
+
+        AR_DEBUG_PRINTF(ATH_DEBUG_INF,
+                        ("removeFromMboxQueue (index: %d, size: %d, bufferElement: 0x%p, bufferElement->buffer: 0x%p, bufferElement->cookie: 0x%p)\n", queue->head, queue->size, element, (GET_MBOX_BUFFER(element))->buffer, (GET_MBOX_BUFFER(element))->cookie));
+    } else {
+        element = NULL;
+    }
+    AR_DEBUG_PRINTF(ATH_DEBUG_SYNC,
+                    ("Critical Section (queue): UNLOCK at line %d in file %s\n", __LINE__, __FILE__));
+    A_MUTEX_UNLOCK(&instanceCS);
+
+    return element;
+}
+
+void
+flushMboxQueue(HTC_ENDPOINT *endPoint,
+               HTC_DATA_REQUEST_QUEUE *queue,
+               HTC_EVENT_ID eventId)
+{
+    HTC_DATA_REQUEST_ELEMENT *curr;
+    HTC_EVENT_INFO eventInfo;
+    HTC_ENDPOINT_EVENT_TABLE *eventTable;
+    HTC_ENDPOINT_ID endPointId;
+    EVENT_TABLE_ELEMENT *eventElement;
+    HTC_MBOX_BUFFER *mboxBuffer;
+
+    eventTable = &endPoint->eventTable;
+    endPointId = GET_ENDPOINT_ID(endPoint);
+
+    /*
+     * Release the buffer to WMI using the registered event handler. If WMI
+     * has not registered any callbacks for a particular endpoint then it
+     * means that its queues will not have any buffers so we skip that
+     * endpoint.
+     */
+    if ((eventElement = &eventTable->element[eventId]) != NULL) {
+        while ((curr = removeFromMboxQueue(queue)) != NULL) {
+            /* Frame the event and dispatch it */
+            mboxBuffer = GET_MBOX_BUFFER(curr);
+            FRAME_EVENT(eventInfo, mboxBuffer->buffer,
+                        mboxBuffer->bufferLength, mboxBuffer->actualLength,
+                        A_ECANCELED, mboxBuffer->cookie);
+            if (eventElement->handler) {
+                eventElement->handler(endPoint->target, endPointId, eventId,
+                                      &eventInfo, eventElement->param);
+            }
+            RECYCLE_DATA_REQUEST_ELEMENT(curr);
+        }
+    }
+
+    /* Initialize the head and tail pointer */
+    queue->head = 0;
+    queue->size = 0;
+}
+
+HTC_REG_REQUEST_ELEMENT *
+allocateRegRequestElement(HTC_TARGET *target) {
+    A_UINT32 count;
+    HTC_REG_REQUEST_ELEMENT *element;
+
+    A_MUTEX_LOCK(&instanceCS);
+    element = NULL;
+    for (count = 0; count < HTC_REG_REQUEST_LIST_SIZE; count ++) {
+        element = &target->regList.element[count];
+        if (IS_ELEMENT_FREE(element)) {
+            element->buffer.free = FALSE;
+            break;
+        }
+    }
+    A_MUTEX_UNLOCK(&instanceCS);
+
+    return element;
+}
+
+void
+freeRegRequestElement(HTC_REG_REQUEST_ELEMENT *element) {
+    A_MUTEX_LOCK(&instanceCS);
+    FILL_REG_BUFFER(element, NULL, 0, 0, 0);
+    element->buffer.free = TRUE;
+    A_MUTEX_UNLOCK(&instanceCS);
+}
+
+HTC_TARGET *
+getTargetInstance(void *device)
+{
+    return AtherosTargetList[0];
+}
+
+void
+addTargetInstance(HTC_TARGET *target)
+{
+    AtherosTargetList[0] = target;
+}
+
+void
+delTargetInstance(HTC_TARGET *target)
+{
+    AtherosTargetList[0] = NULL;
+}
+
+A_UINT32
+getRegAddr(TARGET_REGISTERS base,
+           HTC_ENDPOINT_ID endPointId)
+{
+    A_UINT32 address;
+
+    switch(base) {
+    case TX_CREDIT_COUNTER_RESET_REG:
+        address = COUNT_DEC_ADDRESS + endPointId * 4;
+        break;
+
+    case TX_CREDIT_COUNTER_DECREMENT_REG:
+        address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + endPointId) * 4;
+        break;
+
+    case TX_CREDIT_COUNTER_REG:
+        address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + endPointId) * 4;
+        break;
+
+    case INT_STATUS_ENABLE_REG:
+        address = INT_STATUS_ENABLE_ADDRESS;
+        break;
+
+    case COUNTER_INT_STATUS_ENABLE_REG:
+    case COUNTER_INT_STATUS_DISABLE_REG:
+        address = COUNTER_INT_STATUS_ENABLE_ADDRESS;
+        break;
+
+    case INT_STATUS_REG:
+        address = HOST_INT_STATUS_ADDRESS;
+        break;
+
+    case CPU_INT_STATUS_REG:
+        address = CPU_INT_STATUS_ADDRESS;
+        break;
+
+    case ERROR_INT_STATUS_REG:
+        address = ERROR_INT_STATUS_ADDRESS;
+        break;
+
+    case INT_WLAN_REG:
+        address = INT_WLAN_ADDRESS;
+        break;
+
+    case WINDOW_DATA_REG:
+        address = WINDOW_DATA_ADDRESS;
+        break;
+
+    case WINDOW_WRITE_ADDR_REG:
+        address = WINDOW_WRITE_ADDR_ADDRESS;
+        break;
+
+    case WINDOW_READ_ADDR_REG:
+        address = WINDOW_READ_ADDR_ADDRESS;
+        break;
+
+    default:
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid register: %d\n", base));
+        AR_DEBUG_ASSERT(0);
+        address = 0;
+        break;
+    }
+
+    return address;
+}
+
+void
+dumpBytes(A_UCHAR *buffer, A_UINT16 length)
+{
+    A_CHAR stream[60];
+    A_UINT32 i;
+    A_UINT16 offset, count;
+
+    AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("Dumping %d Bytes : ------>\n", length));
+
+    count = 0;
+    offset = 0;
+    for(i = 0; i < length; i++) {
+        sprintf(stream + offset, "%2x ", buffer[i]);
+	count ++;
+	offset += 3;
+
+	if(count == 16) {
+	    count = 0;
+	    offset = 0;
+	    AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("[H]: %s\n", stream));
+	    A_MEMZERO(stream, 60);
+	}
+    }
+
+    if(offset != 0) {
+	AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("[H]: %s\n", stream));
+    }
+}
+
+void
+dumpRegisters(HTC_TARGET *target)
+{
+    HTC_REGISTER_TABLE *reg;
+
+    reg = &target->table;
+    AR_DEBUG_PRINTF(ATH_DEBUG_DUMP, ("\n<------- Register Table -------->\nInt Status:                0x%x\nCPU Int Status:            0x%x\nError Int Status:          0x%x\nCounter Int Status:        0x%x\nMbox Frame:                0x%x\nRx Lookahead Valid:        0x%x\nRx Lookahead 0:            0x%x\nRx Lookahead 1:            0x%x\nRx Lookahead 2:            0x%x\nRx Lookahead 3:            0x%x\nInt Status Enable:         0x%x\nCounter Int Status Enable: 0x%x\n<------------------------------->\n", reg->host_int_status, reg->cpu_int_status, reg->error_int_status, reg->counter_int_status, reg->mbox_frame, reg->rx_lookahead_valid, reg->rx_lookahead[ENDPOINT1], reg->rx_lookahead[ENDPOINT2], reg->rx_lookahead[ENDPOINT3], reg->rx_lookahead[ENDPOINT4], reg->int_status_enable, reg->counter_int_status_enable));
+}
+
+A_UINT8
+htcGetBitNumSet(A_UINT32 data)
+{
+    A_UINT8 count;
+
+    count = 0;
+    while(!(data & 0x1)) {
+        count += 1;
+        data >>= 1;
+    }
+
+    return count;
+}
+

Added: developers/nbd/ar6k/include/AR6000_bmi.h
===================================================================
--- developers/nbd/ar6k/include/AR6000_bmi.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/AR6000_bmi.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+#ifndef __AR6000_BMI_H__
+#define __AR6000_BMI_H__
+
+/*
+ * Bootloader Messaging Interface (BMI)
+ *
+ * BMI is a very simple messaging interface used during initialization
+ * to read memory, write memory, execute code, and to define an
+ * application entry PC.
+ *
+ * It is used to download an application to AR6000, to provide
+ * patches to code that is already resident on AR6000, and generally
+ * to examine and modify state.  The Host has an opportunity to use
+ * BMI only once during bootup.  Once the Host issues a BMI_DONE
+ * command, this opportunity ends.
+ *
+ * The Host writes BMI requests to mailbox0, and reads BMI responses
+ * from mailbox0.   BMI requests all begin with a command
+ * (see below for specific commands), and are followed by
+ * command-specific data.
+ *
+ * Flow control:
+ * The Host can only issue a command once the Target gives it a
+ * "BMI Command Credit", using AR6000 Counter #4.  As soon as the
+ * Target has completed a command, it issues another BMI Command
+ * Credit (so the Host can issue the next command).
+ *
+ * BMI handles all required Target-side cache flushing.
+ */
+
+
+/* Maximum data size used for BMI transfers */
+#define BMI_DATASZ_MAX                     32
+
+/* BMI Commands */
+
+#define BMI_NO_COMMAND                      0
+
+#define BMI_DONE                            1
+        /*
+         * Semantics: Host is done using BMI
+         * Request format:
+         *    A_UINT32      command (BMI_DONE)
+         * Response format: none
+         */
+
+#define BMI_READ_MEMORY                     2
+        /*
+         * Semantics: Host reads AR6000 memory
+         * Request format:
+         *    A_UINT32      command (BMI_READ_MEMORY)
+         *    A_UINT32      address
+         *    A_UINT32      length, at most BMI_DATASZ_MAX
+         * Response format:
+         *    A_UINT8       data[length]
+         */
+
+#define BMI_WRITE_MEMORY                    3
+        /*
+         * Semantics: Host writes AR6000 memory
+         * Request format:
+         *    A_UINT32       command (BMI_WRITE_MEMORY)
+         *    A_UINT32      address
+         *    A_UINT32      length, at most BMI_DATASZ_MAX
+         *    A_UINT8       data[length]
+         * Response format: none
+         */
+
+#define BMI_EXECUTE                         4
+        /*
+         * Semantics: Causes AR6000 to execute code
+         * Request format:
+         *    A_UINT32      command (BMI_EXECUTE)
+         *    A_UINT32      address
+         *    A_UINT32      parameter
+         * Response format:
+         *    A_UINT32      return value
+         */
+
+#define BMI_SET_APP_START                   5
+        /*
+         * Semantics: Set Target application starting address
+         * Request format:
+         *    A_UINT32      command (BMI_SET_APP_START)
+         *    A_UINT32      address
+         * Response format: none
+         */
+
+#define BMI_READ_SOC_REGISTER               6
+        /*
+         * Semantics: Read a 32-bit Target SOC register.
+         * Request format:
+         *    A_UINT32      command (BMI_READ_REGISTER)
+         *    A_UINT32      address
+         * Response format:
+         *    A_UINT32      value
+         */
+
+#define BMI_WRITE_SOC_REGISTER              7
+        /*
+         * Semantics: Write a 32-bit Target SOC register.
+         * Request format:
+         *    A_UINT32      command (BMI_WRITE_REGISTER)
+         *    A_UINT32      address
+         *    A_UINT32      value
+         *
+         * Response format: none
+         */
+
+#define BMI_GET_TARGET_ID                  8
+        /*
+         * Semantics: Fetch the 4-byte Target ID.
+         * Request format:
+         *    A_UINT32      command (BMI_GET_TARGET_ID)
+         *
+         * Response format:
+         *    A_UINT32      TargetID
+         */
+
+#endif /* __AR6000_BMI_H__ */

Added: developers/nbd/ar6k/include/AR6000_gpio.h
===================================================================
--- developers/nbd/ar6k/include/AR6000_gpio.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/AR6000_gpio.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2005-2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+
+#define GPIO_PIN_COUNT 18
+
+/*
+ * Possible values for WMIX_GPIO_SET_REGISTER_CMDID.
+ * NB: These match hardware order, so that addresses can
+ * easily be computed.
+ */
+#define GPIO_ID_OUT             0x00000000
+#define GPIO_ID_OUT_W1TS        0x00000001
+#define GPIO_ID_OUT_W1TC        0x00000002
+#define GPIO_ID_ENABLE          0x00000003
+#define GPIO_ID_ENABLE_W1TS     0x00000004
+#define GPIO_ID_ENABLE_W1TC     0x00000005
+#define GPIO_ID_IN              0x00000006
+#define GPIO_ID_STATUS          0x00000007
+#define GPIO_ID_STATUS_W1TS     0x00000008
+#define GPIO_ID_STATUS_W1TC     0x00000009
+#define GPIO_ID_PIN0            0x0000000a
+#define GPIO_ID_PIN(n)          (GPIO_ID_PIN0+(n))
+
+#define GPIO_LAST_REGISTER_ID   GPIO_ID_PIN(17)
+#define GPIO_ID_NONE            0xffffffff

Added: developers/nbd/ar6k/include/AR6000_version.h
===================================================================
--- developers/nbd/ar6k/include/AR6000_version.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/AR6000_version.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+
+#define __VER_MAJOR_ 1
+#define __VER_MINOR_ 1
+#define __VER_PATCH_ 0
+
+
+/* The makear6ksdk script (used for release builds) modifies the following line. */
+#define __BUILD_NUMBER_ 2
+
+
+/* Format of the version number. */
+#define VER_MAJOR_BIT_OFFSET		28
+#define VER_MINOR_BIT_OFFSET		24
+#define VER_PATCH_BIT_OFFSET		16
+#define VER_BUILD_NUM_BIT_OFFSET	0
+
+
+/*
+ * The version has the following format:
+ * Bits 28-31: Major version
+ * Bits 24-27: Minor version
+ * Bits 16-23: Patch version
+ * Bits 0-15:  Build number (automatically generated during build process )
+ * E.g. Build 1.1.3.7 would be represented as 0x11030007.
+ *
+ * DO NOT split the following macro into multiple lines as this may confuse the build scripts.
+ */
+#define AR6000_SW_VERSION 	( ( __VER_MAJOR_ << VER_MAJOR_BIT_OFFSET ) + ( __VER_MINOR_ << VER_MINOR_BIT_OFFSET ) + ( __VER_PATCH_ << VER_PATCH_BIT_OFFSET ) + ( __BUILD_NUMBER_ << VER_BUILD_NUM_BIT_OFFSET ) )
+
+

Added: developers/nbd/ar6k/include/app/dset.h
===================================================================
--- developers/nbd/ar6k/include/app/dset.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/app/dset.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,77 @@
+#ifndef _DSET_H_
+#define _DSET_H_
+
+/*
+ * Structures used to communicate between an application and the kernel for
+ * DataSet ioctls.
+ *
+ * Pass a dset_request_t with cmd=AR6000_XIOCTL_WMI_WAITDSETREQ in order to
+ * wait for the next DataSet Request to arrive.  Once a request is received
+ * from the Target, the kernel fills in information about the Request and
+ * returns from the ioctl to the application.  When the ioctl returns,
+ * cmd is set to either AR6000_OPEN_REQ or AR6000_DATA_REQ.
+ *
+ * Pass a dset_open_reply_t with cmd=AR6000_IOCTL_WMI_DSET_OPEN_REPLY in order
+ * to send a DataSet Open reply to the Target.  The targ_* fields should simply
+ * be copied from the original Open Request.  The status field should be set
+ * to 0 for success or non-zero for failure.
+ *
+ * Pass a dset_data_reply_t with cmd=AR6000_IOCTL_WMI_DSET_DATA_REPLY in order
+ * to send a DataSet Data reply to the Target.  The targ_* fields should simply
+ * be copied from the original Data Request.  The status field should be set
+ * to 0 for success or non-zero for failure.  The buf field is a pointer
+ * to a buffer that contains the requested data.
+ */
+
+/* A DataSet Request, either Open Request or Data Request */
+typedef struct dset_request_s {
+    unsigned int      cmd;
+    union {
+        struct open_req_s {
+            unsigned int        id;
+            unsigned int        targ_handle;
+            unsigned int        targ_reply_fn;
+            unsigned int        targ_reply_arg;
+        } open_req;
+        struct data_req_s {
+            unsigned int        access_cookie;
+            unsigned int        offset;
+            unsigned int        length;
+            unsigned int        targ_buf;
+            unsigned int        targ_reply_fn;
+            unsigned int        targ_reply_arg;
+        } data_req;
+    } u;
+} dset_request_t;
+
+/*
+ * Values in cmd on return from an AR6000_IOCTL_EXTENDED ioctl that had
+ * cmd=AR6000_XIOCTL_WMI_WAITDSETREQ.
+ */
+#define AR6000_OPEN_REQ         1
+#define AR6000_DATA_REQ         2
+
+/* Open Reply from Application to Kernel (to be sent to Target) */
+typedef struct dset_open_reply {
+    unsigned int        cmd;
+    unsigned int        status;
+    unsigned int        targ_handle;
+    unsigned int        targ_reply_fn;
+    unsigned int        targ_reply_arg;
+    unsigned int        access_cookie;
+    unsigned int        size;
+    unsigned int        version;
+} dset_open_reply_t;
+
+/* Data Reply from Application to Kernel (to be sent to Target) */
+typedef struct dset_data_reply {
+    unsigned int        cmd;
+    unsigned int        status;
+    char               *buf;
+    unsigned int        length;
+    unsigned int        targ_buf;
+    unsigned int        targ_reply_fn;
+    unsigned int        targ_reply_arg;
+} dset_data_reply_t;
+
+#endif /* _DSET_H_ */

Added: developers/nbd/ar6k/include/ar6000_api.h
===================================================================
--- developers/nbd/ar6k/include/ar6000_api.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/ar6000_api.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the API to access the OS dependent atheros host driver
+ * by the WMI or WLAN generic modules.
+ *
+ */
+
+#ifndef _AR6000_API_H_
+#define _AR6000_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ar6_softc;
+
+void ar6000_ready_event(void *devt, A_UINT8 *datap, A_UINT8 phyCap);
+A_UINT8 ar6000_iptos_to_userPriority(A_UINT8 *pkt);
+A_STATUS ar6000_control_tx(void *devt, void *osbuf, int endPt);
+void ar6000_connect_event(struct ar6_softc *ar, A_UINT16 channel,
+                          A_UINT8 *bssid, A_UINT16 listenInterval,
+                          A_UINT8 beaconIeLen, A_UINT8 assocReqLen,
+                          A_UINT8 assocRespLen,A_UINT8 *assocInfo);
+void ar6000_disconnect_event(struct ar6_softc *ar, A_UINT8 reason,
+                             A_UINT8 *bssid, A_UINT8 assocRespLen,
+                             A_UINT8 *assocInfo);
+void ar6000_tkip_micerr_event(struct ar6_softc *ar, A_UINT8 keyid,
+                              A_BOOL ismcast);
+void ar6000_bitrate_rx(void *devt, A_INT32 rateKbps);
+void ar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList);
+void ar6000_regDomain_event(struct ar6_softc *ar, A_UINT32 regCode);
+void ar6000_txPwr_rx(void *devt, A_UINT8 txPwr);
+void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps,
+                                 WMI_NEIGHBOR_INFO *info);
+void ar6000_set_numdataendpts(struct ar6_softc *ar, A_UINT32 num);
+void ar6000_scanComplete_event(struct ar6_softc *ar);
+void ar6000_targetStats_event(struct ar6_softc *ar,  WMI_TARGET_STATS *pStats);
+void ar6000_rssiThreshold_event(struct ar6_softc *, WMI_RSSI_THRESHOLD_VAL);
+void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal);
+void ar6000_cac_event(struct ar6_softc *ar, A_UINT8 ac, A_UINT8 cac_indication,
+                                A_UINT8 statusCode, A_UINT8 *tspecSuggestion);
+
+void
+ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl);
+
+void
+ar6000_roam_data_event(struct ar6_softc **ar, WMI_TARGET_ROAM_DATA *p);
+
+void ar6000_dset_open_req(void *devt,
+                          A_UINT32 id,
+                          A_UINT32 targ_handle,
+                          A_UINT32 targ_reply_fn,
+                          A_UINT32 targ_reply_arg);
+void ar6000_dset_close(void *devt, A_UINT32 access_cookie);
+void ar6000_dset_data_req(void *devt,
+                          A_UINT32 access_cookie,
+                          A_UINT32 offset,
+                          A_UINT32 length,
+                          A_UINT32 targ_buf,
+                          A_UINT32 targ_reply_fn,
+                          A_UINT32 targ_reply_arg);
+
+void ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values);
+void ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value);
+void ar6000_gpio_ack_rx(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _AR6000_API_H_ */

Added: developers/nbd/ar6k/include/athdefs.h
===================================================================
--- developers/nbd/ar6k/include/athdefs.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/athdefs.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,82 @@
+
+#ifndef __ATHDEFS_H__
+#define __ATHDEFS_H__
+
+/*
+ * This file contains definitions that may be used across both
+ * Host and Target software.  Nothing here is module-dependent
+ * or platform-dependent.
+ */
+
+/*
+ * Generic error codes that can be used by hw, sta, ap, sim, dk
+ * and any other environments. Since these are enums, feel free to
+ * add any more codes that you need.
+ */
+
+typedef enum {
+    A_ERROR = -1,               /* Generic error return */
+    A_OK = 0,                   /* success */
+                                /* Following values start at 1 */
+    A_DEVICE_NOT_FOUND,         /* not able to find PCI device */
+    A_NO_MEMORY,                /* not able to allocate memory, not available */
+    A_MEMORY_NOT_AVAIL,         /* memory region is not free for mapping */
+    A_NO_FREE_DESC,             /* no free descriptors available */
+    A_BAD_ADDRESS,              /* address does not match descriptor */
+    A_WIN_DRIVER_ERROR,         /* used in NT_HW version, if problem at init */
+    A_REGS_NOT_MAPPED,          /* registers not correctly mapped */
+    A_EPERM,                    /* Not superuser */
+    A_EACCES,                   /* Access denied */
+    A_ENOENT,                   /* No such entry, search failed, etc. */
+    A_EEXIST,                   /* The object already exists (can't create) */
+    A_EFAULT,                   /* Bad address fault */
+    A_EBUSY,                    /* Object is busy */
+    A_EINVAL,                   /* Invalid parameter */
+    A_EMSGSIZE,                 /* Inappropriate message buffer length */
+    A_ECANCELED,                /* Operation canceled */
+    A_ENOTSUP,                  /* Operation not supported */
+    A_ECOMM,                    /* Communication error on send */
+    A_EPROTO,                   /* Protocol error */
+    A_ENODEV,                   /* No such device */
+    A_EDEVNOTUP,                /* device is not UP */
+    A_NO_RESOURCE,              /* No resources for requested operation */
+    A_HARDWARE,                 /* Hardware failure */
+    A_PENDING,                  /* Asynchronous routine; will send up results la
+ter (typically in callback) */
+    A_EBADCHANNEL,              /* The channel cannot be used */
+    A_DECRYPT_ERROR,            /* Decryption error */
+    A_PHY_ERROR,                /* RX PHY error */
+    A_CONSUMED                  /* Object was consumed */
+} A_STATUS;
+
+#define A_SUCCESS(x)        (x == A_OK)
+#define A_FAILED(x)         (!A_SUCCESS(x))
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/*
+ * The following definition is WLAN specific definition
+ */
+typedef enum {
+    MODE_11A = 0,   /* 11a Mode */
+    MODE_11G = 1,   /* 11g + 11b Mode */
+    MODE_11B = 2,   /* 11b Mode */
+    MODE_11GONLY = 3, /* 11g only Mode */
+    MODE_UNKNOWN = 4,
+
+    MODE_MAX = 4
+} WLAN_PHY_MODE;
+
+typedef enum {
+    WLAN_11A_CAPABILITY   = 1,
+    WLAN_11G_CAPABILITY   = 2,
+    WLAN_11AG_CAPABILITY  = 3,
+}WALN_CAPABILITY;
+
+#endif /* __ATHDEFS_H__ */

Added: developers/nbd/ar6k/include/athdrv.h
===================================================================
--- developers/nbd/ar6k/include/athdrv.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/athdrv.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,598 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the definitions for the AR6000 linux driver.
+ *
+ */
+
+#ifndef _ATHDRV_H_
+#define _ATHDRV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * There are two types of ioctl's here: Standard ioctls and
+ * eXtended ioctls.  All extended ioctls (XIOCTL) are multiplexed
+ * off of the single ioctl command, AR6000_IOCTL_EXTENDED.  The
+ * arguments for every XIOCTL starts with a 32-bit command word
+ * that is used to select which extended ioctl is in use.  After
+ * the command word are command-specific arguments.
+ */
+
+/* Linux standard Wireless Extensions, private ioctl interfaces */
+#define IEEE80211_IOCTL_SETPARAM             (SIOCIWFIRSTPRIV+0)
+#define IEEE80211_IOCTL_GETPARAM             (SIOCIWFIRSTPRIV+1)
+#define IEEE80211_IOCTL_SETKEY               (SIOCIWFIRSTPRIV+2)
+#define IEEE80211_IOCTL_SETWMMPARAMS         (SIOCIWFIRSTPRIV+3)
+#define IEEE80211_IOCTL_DELKEY               (SIOCIWFIRSTPRIV+4)
+#define IEEE80211_IOCTL_GETWMMPARAMS         (SIOCIWFIRSTPRIV+5)
+#define IEEE80211_IOCTL_SETMLME              (SIOCIWFIRSTPRIV+6)
+#define IEEE80211_IOCTL_SETOPTIE             (SIOCIWFIRSTPRIV+6)
+#define IEEE80211_IOCTL_GETOPTIE             (SIOCIWFIRSTPRIV+7)
+#define IEEE80211_IOCTL_ADDPMKID             (SIOCIWFIRSTPRIV+8)
+//#define IEEE80211_IOCTL_SETAUTHALG           (SIOCIWFIRSTPRIV+10)
+#define IEEE80211_IOCTL_LASTONE              (SIOCIWFIRSTPRIV+9)
+
+
+
+/*                      ====WMI Ioctls====                                    */
+/*
+ *
+ * Many ioctls simply provide WMI services to application code:
+ * an application makes such an ioctl call with a set of arguments
+ * that are packaged into the corresponding WMI message, and sent
+ * to the Target.
+ */
+
+#define AR6000_IOCTL_WMI_GETREV              (SIOCIWFIRSTPRIV+10)
+/*
+ * arguments:
+ *   ar6000_version *revision
+ */
+
+#define AR6000_IOCTL_WMI_SETPWR              (SIOCIWFIRSTPRIV+11)
+/*
+ * arguments:
+ *   WMI_POWER_MODE_CMD pwrModeCmd (see include/wmi.h)
+ * uses: WMI_SET_POWER_MODE_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SETSCAN             (SIOCIWFIRSTPRIV+12)
+/*
+ * arguments:
+ *   WMI_SCAN_PARAMS_CMD scanParams (see include/wmi.h)
+ * uses: WMI_SET_SCAN_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SETLISTENINT        (SIOCIWFIRSTPRIV+13)
+/*
+ * arguments:
+ *   UINT32 listenInterval
+ * uses: WMI_SET_LISTEN_INT_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SETBSSFILTER        (SIOCIWFIRSTPRIV+14)
+/*
+ * arguments:
+ *   WMI_BSS_FILTER filter (see include/wmi.h)
+ * uses: WMI_SET_BSS_FILTER_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_CHANNELPARAMS   (SIOCIWFIRSTPRIV+16)
+/*
+ * arguments:
+ *   WMI_CHANNEL_PARAMS_CMD chParams
+ * uses: WMI_SET_CHANNEL_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_PROBEDSSID      (SIOCIWFIRSTPRIV+17)
+/*
+ * arguments:
+ *   WMI_PROBED_SSID_CMD probedSsids (see include/wmi.h)
+ * uses: WMI_SETPROBED_SSID_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_PMPARAMS        (SIOCIWFIRSTPRIV+18)
+/*
+ * arguments:
+ *   WMI_POWER_PARAMS_CMD powerParams (see include/wmi.h)
+ * uses: WMI_SET_POWER_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_BADAP           (SIOCIWFIRSTPRIV+19)
+/*
+ * arguments:
+ *   WMI_ADD_BAD_AP_CMD badAPs (see include/wmi.h)
+ * uses: WMI_ADD_BAD_AP_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_GET_QOS_QUEUE       (SIOCIWFIRSTPRIV+20)
+/*
+ * arguments:
+ *   ar6000_queuereq queueRequest (see below)
+ */
+
+#define AR6000_IOCTL_WMI_CREATE_QOS          (SIOCIWFIRSTPRIV+21)
+/*
+ * arguments:
+ *   WMI_CREATE_PSTREAM createPstreamCmd (see include/wmi.h)
+ * uses: WMI_CREATE_PSTREAM_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_DELETE_QOS          (SIOCIWFIRSTPRIV+22)
+/*
+ * arguments:
+ *   WMI_DELETE_PSTREAM_CMD deletePstreamCmd (see include/wmi.h)
+ * uses: WMI_DELETE_PSTREAM_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_LINKTHRESHOLD   (SIOCIWFIRSTPRIV+23)
+/*
+ * arguments:
+ *   WMI_RSSI_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h)
+ * uses: WMI_RSSI_THRESHOLD_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)
+/*
+ * arguments:
+ *   WMI_TARGET_ERROR_REPORT_BITMASK errorReportBitMask (see include/wmi.h)
+ * uses: WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_GET_TARGET_STATS    (SIOCIWFIRSTPRIV+25)
+/*
+ * arguments:
+ *   TARGET_STATS *targetStats (see below)
+ * uses: WMI_GET_STATISTICS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_ASSOC_INFO      (SIOCIWFIRSTPRIV+26)
+/*
+ * arguments:
+ *   WMI_SET_ASSOC_INFO_CMD setAssocInfoCmd
+ * uses: WMI_SET_ASSOC_INFO_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_ACCESS_PARAMS   (SIOCIWFIRSTPRIV+27)
+/*
+ * arguments:
+ *   WMI_SET_ACCESS_PARAMS_CMD setAccessParams (see include/wmi.h)
+ * uses: WMI_SET_ACCESS_PARAMS_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_BMISS_TIME      (SIOCIWFIRSTPRIV+28)
+/*
+ * arguments:
+ *   UINT32 beaconMissTime
+ * uses: WMI_SET_BMISS_TIME_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_DISC_TIMEOUT    (SIOCIWFIRSTPRIV+29)
+/*
+ * arguments:
+ *   WMI_DISC_TIMEOUT_CMD disconnectTimeoutCmd (see include/wmi.h)
+ * uses: WMI_SET_DISC_TIMEOUT_CMDID
+ */
+
+#define AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS    (SIOCIWFIRSTPRIV+30)
+/*
+ * arguments:
+ *   WMI_IBSS_PM_CAPS_CMD ibssPowerMgmtCapsCmd
+ * uses: WMI_SET_IBSS_PM_CAPS_CMDID
+ */
+
+/*
+ * There is a very small space available for driver-private
+ * wireless ioctls.  In order to circumvent this limitation,
+ * we multiplex a bunch of ioctls (XIOCTLs) on top of a
+ * single AR6000_IOCTL_EXTENDED ioctl.
+ */
+#define AR6000_IOCTL_EXTENDED                (SIOCIWFIRSTPRIV+31)
+
+
+/*                         ====BMI Extended Ioctls====                        */
+
+#define AR6000_XIOCTL_BMI_DONE                 1
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_BMI_DONE)
+ * uses: BMI_DONE
+ */
+
+#define AR6000_XIOCTL_BMI_READ_MEMORY          2
+/*
+ * arguments:
+ *   union {
+ *     struct {
+ *       UINT32 cmd (AR6000_XIOCTL_BMI_READ_MEMORY)
+ *       UINT32 address
+ *       UINT32 length
+ *     }
+ *     char results[length]
+ *   }
+ * uses: BMI_READ_MEMORY
+ */
+
+#define AR6000_XIOCTL_BMI_WRITE_MEMORY         3
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_MEMORY)
+ *   UINT32 address
+ *   UINT32 length
+ *   char data[length]
+ * uses: BMI_WRITE_MEMORY
+ */
+
+#define AR6000_XIOCTL_BMI_EXECUTE              4
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_BMI_EXECUTE)
+ *   UINT32 TargetAddress
+ *   UINT32 parameter
+ * uses: BMI_EXECUTE
+ */
+
+#define AR6000_XIOCTL_BMI_SET_APP_START        5
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_BMI_SET_APP_START)
+ *   UINT32 TargetAddress
+ * uses: BMI_SET_APP_START
+ */
+
+#define AR6000_XIOCTL_BMI_READ_SOC_REGISTER    6
+/*
+ * arguments:
+ *   union {
+ *     struct {
+ *       UINT32 cmd (AR6000_XIOCTL_BMI_READ_SOC_REGISTER)
+ *       UINT32 TargetAddress, 32-bit aligned
+ *     }
+ *     UINT32 result
+ *   }
+ * uses: BMI_READ_SOC_REGISTER
+ */
+
+#define AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER   7
+/*
+ * arguments:
+ *     struct {
+ *       UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER)
+ *       UINT32 TargetAddress, 32-bit aligned
+ *       UINT32 newValue
+ *     }
+ * uses: BMI_WRITE_SOC_REGISTER
+ */
+
+#define AR6000_XIOCTL_BMI_TEST                 8
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_BMI_TEST)
+ *   UINT32 address
+ *   UINT32 length
+ *   UINT32 count
+ */
+
+
+
+/*                      ====DataSet Extended Ioctls====                       */
+
+#define AR6000_XIOCTL_WMI_DSET_WAIT_REQ        9
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_WMI_DSET_WAIT_REQ)
+ */
+
+#define AR6000_XIOCTL_WMI_DSET_OPEN_REPLY     10
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_WMI_DSET_OPEN_REPLY)
+ *   dset_open_reply_t (see host/include/app/dset.h)
+ * uses: WMIX_DSETOPEN_REPLY_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_DSET_DATA_REPLY     11
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_WMI_DSET_DATA_REPLY)
+ *   dset_data_reply_t (see host/include/app/dset.h)
+ * uses: WMIX_DSETDATA_REPLY_CMDID
+ */
+
+#define AR6000_XIOCTL_FORCE_TARGET_RESET      12
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_FORCE_TARGET_RESET)
+ */
+
+
+#ifdef HTC_RAW_INTERFACE
+/* HTC Raw Interface Ioctls */
+#define AR6000_XIOCTL_HTC_RAW_OPEN            13
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_HTC_RAW_OPEN)
+ */
+
+#define AR6000_XIOCTL_HTC_RAW_CLOSE           14
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_HTC_RAW_CLOSE)
+ */
+
+#define AR6000_XIOCTL_HTC_RAW_READ            15
+/*
+ * arguments:
+ *   union {
+ *     struct {
+ *       UINT32 cmd (AR6000_XIOCTL_HTC_RAW_READ)
+ *       UINT32 mailboxID
+ *       UINT32 length
+ *     }
+ *     results[length]
+ *   }
+ */
+
+#define AR6000_XIOCTL_HTC_RAW_WRITE           16
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_HTC_RAW_WRITE)
+ *   UINT32 mailboxID
+ *   UINT32 length
+ *   char buffer[length]
+ */
+#endif /* HTC_RAW_INTERFACE */
+
+#define AR6000_XIOCTL_CHECK_TARGET_READY      17
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_CHECK_TARGET_READY)
+ */
+
+
+
+/*                ====GPIO (General Purpose I/O) Extended Ioctls====          */
+
+#define AR6000_XIOCTL_GPIO_OUTPUT_SET         18
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_GPIO_OUTPUT_SET)
+ *   ar6000_gpio_output_set_cmd_s (see below)
+ * uses: WMIX_GPIO_OUTPUT_SET_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_INPUT_GET          19
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_GPIO_INPUT_GET)
+ * uses: WMIX_GPIO_INPUT_GET_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_REGISTER_SET       20
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_SET)
+ *   ar6000_gpio_register_cmd_s (see below)
+ * uses: WMIX_GPIO_REGISTER_SET_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_REGISTER_GET       21
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_GET)
+ *   ar6000_gpio_register_cmd_s (see below)
+ * uses: WMIX_GPIO_REGISTER_GET_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_INTR_ACK           22
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_ACK)
+ *   ar6000_cpio_intr_ack_cmd_s (see below)
+ * uses: WMIX_GPIO_INTR_ACK_CMDID
+ */
+
+#define AR6000_XIOCTL_GPIO_INTR_WAIT          23
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_WAIT)
+ */
+
+
+
+/*                    ====more wireless commands====                          */
+
+#define AR6000_XIOCTL_SET_ADHOC_BSSID         24
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BSSID)
+ *   WMI_SET_ADHOC_BSSID_CMD setAdHocBssidCmd (see include/wmi.h)
+ */
+
+#define AR6000_XIOCTL_SET_OPT_MODE            25
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_SET_OPT_MODE)
+ *   WMI_SET_OPT_MODE_CMD setOptModeCmd (see include/wmi.h)
+ * uses: WMI_SET_OPT_MODE_CMDID
+ */
+
+#define AR6000_XIOCTL_OPT_SEND_FRAME          26
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_OPT_SEND_FRAME)
+ *   WMI_OPT_TX_FRAME_CMD optTxFrameCmd (see include/wmi.h)
+ * uses: WMI_OPT_TX_FRAME_CMDID
+ */
+
+#define AR6000_XIOCTL_SET_ADHOC_BEACON_INTVAL 27
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BEACON_INTVAL)
+ *   WMI_BEACON_INT_CMD beaconIntCmd (see include/wmi.h)
+ * uses: WMI_SET_BEACON_INT_CMDID
+ */
+
+
+#define IEEE80211_IOCTL_SETAUTHALG           28
+
+
+#define AR6000_XIOCTL_SET_VOICE_PKT_SIZE        29
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_SET_VOICE_PKT_SIZE)
+ *   WMI_SET_VOICE_PKT_SIZE_CMD setVoicePktSizeCmd (see include/wmi.h)
+ * uses: WMI_SET_VOICE_PKT_SIZE_CMDID
+ */
+
+
+#define AR6000_XIOCTL_SET_MAX_SP                30
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTL_SET_MAX_SP)
+ *   WMI_SET_MAX_SP_LEN_CMD maxSPLen(see include/wmi.h)
+ * uses: WMI_SET_MAX_SP_LEN_CMDID
+ */
+
+#define AR6000_XIOCTL_WMI_GET_ROAM_TBL             31
+
+#define AR6000_XIOCTL_WMI_SET_ROAM_CTRL            32
+
+#define AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS    33
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS)
+ *   WMI_SET_POWERSAVE_TIMERS_CMD powerSaveTimers(see include/wmi.h)
+ *   WMI_SET_POWERSAVE_TIMERS_CMDID
+ */
+
+#define AR6000_XIOCTRL_WMI_GET_POWER_MODE          34
+/*
+ * arguments:
+ *   UINT32 cmd (AR6000_XIOCTRL_WMI_GET_POWER_MODE)
+ */
+
+#define AR6000_XIOCTRL_WMI_SET_WLAN_STATE          35
+typedef enum {
+    WLAN_DISABLED,
+    WLAN_ENABLED
+} AR6000_WLAN_STATE;
+/*
+ * arguments:
+ * enable/disable
+ */
+
+#define AR6000_XIOCTL_WMI_GET_ROAM_DATA            36
+
+/* used by AR6000_IOCTL_WMI_GETREV */
+struct ar6000_version {
+    A_UINT32        host_ver;
+    A_UINT32        target_ver;
+};
+
+/* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */
+struct ar6000_queuereq{
+    A_UINT8         trafficDirection;
+    A_UINT8         trafficClass;
+    A_INT8          queueNumber;
+};
+
+/* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */
+typedef struct targetStats_t {
+    A_UINT64    tx_packets;
+    A_UINT64    tx_bytes;
+    A_UINT64    tx_unicast_pkts;
+    A_UINT64    tx_unicast_bytes;
+    A_UINT64    tx_multicast_pkts;
+    A_UINT64    tx_multicast_bytes;
+    A_UINT64    tx_broadcast_pkts;
+    A_UINT64    tx_broadcast_bytes;
+    A_UINT64    tx_rts_success_cnt;
+    A_UINT64    tx_packet_per_ac[4];
+
+    A_UINT64    tx_errors;
+    A_UINT64    tx_failed_cnt;
+    A_UINT64    tx_retry_cnt;
+    A_UINT64    tx_rts_fail_cnt;
+    A_UINT64    rx_packets;
+    A_UINT64    rx_bytes;
+    A_UINT64    rx_unicast_pkts;
+    A_UINT64    rx_unicast_bytes;
+    A_UINT64    rx_multicast_pkts;
+    A_UINT64    rx_multicast_bytes;
+    A_UINT64    rx_broadcast_pkts;
+    A_UINT64    rx_broadcast_bytes;
+    A_UINT64    rx_fragment_pkt;
+
+    A_UINT64    rx_errors;
+    A_UINT64    rx_crcerr;
+    A_UINT64    rx_key_cache_miss;
+    A_UINT64    rx_decrypt_err;
+    A_UINT64    rx_duplicate_frames;
+
+    A_UINT64    tkip_local_mic_failure;
+    A_UINT64    tkip_counter_measures_invoked;
+    A_UINT64    tkip_replays;
+    A_UINT64    tkip_format_errors;
+    A_UINT64    ccmp_format_errors;
+    A_UINT64    ccmp_replays;
+
+    A_UINT64    power_save_failure_cnt;
+    A_INT16     noise_floor_calibation;
+
+    A_UINT64    cs_bmiss_cnt;
+    A_UINT64    cs_lowRssi_cnt;
+    A_UINT64    cs_connect_cnt;
+    A_UINT64    cs_disconnect_cnt;
+    A_UINT8     cs_aveBeacon_rssi;
+    A_UINT8     cs_lastRoam_msec;
+}TARGET_STATS;
+
+/* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */
+struct ar6000_gpio_output_set_cmd_s {
+    A_UINT32 set_mask;
+    A_UINT32 clear_mask;
+    A_UINT32 enable_mask;
+    A_UINT32 disable_mask;
+};
+
+/*
+ * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET
+ */
+struct ar6000_gpio_register_cmd_s {
+    A_UINT32 gpioreg_id;
+    A_UINT32 value;
+};
+
+/* used by AR6000_XIOCTL_GPIO_INTR_ACK */
+struct ar6000_gpio_intr_ack_cmd_s {
+    A_UINT32 ack_mask;
+};
+
+/* used by AR6000_XIOCTL_GPIO_INTR_WAIT */
+struct ar6000_gpio_intr_wait_cmd_s {
+    A_UINT32 intr_mask;
+    A_UINT32 input_values;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ATHDRV_H_ */

Added: developers/nbd/ar6k/include/athtypes.h
===================================================================
--- developers/nbd/ar6k/include/athtypes.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/athtypes.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2003-2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the definitions of the basic atheros data types.
+ * It is used to map the data types in atheros files to a platform specific
+ * type.
+ *
+ */
+
+#ifndef _ATHTYPES_LINUX_H_
+#define _ATHTYPES_LINUX_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#endif
+
+typedef int8_t      A_INT8;
+typedef int16_t     A_INT16;
+typedef int32_t     A_INT32;
+typedef int64_t     A_INT64;
+
+typedef u_int8_t     A_UINT8;
+typedef u_int16_t    A_UINT16;
+typedef u_int32_t    A_UINT32;
+typedef u_int64_t    A_UINT64;
+
+typedef int             A_BOOL;
+typedef char            A_CHAR;
+typedef unsigned char   A_UCHAR;
+
+#endif /* _ATHTYPES_LINUX_H_ */

Added: developers/nbd/ar6k/include/bmi.h
===================================================================
--- developers/nbd/ar6k/include/bmi.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/bmi.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * BMI declarations and prototypes
+ */
+
+#ifndef _BMI_H_
+#define _BMI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Header files */
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/hif.h"
+#include "../include/osapi.h"
+
+void
+BMIInit(void);
+
+A_STATUS
+BMIDone(HIF_DEVICE *device);
+
+A_STATUS
+BMIGetTargetId(HIF_DEVICE *device, A_UINT32 *id);
+
+A_STATUS
+BMIReadMemory(HIF_DEVICE *device,
+              A_UINT32 address,
+              A_UCHAR *buffer,
+              A_UINT32 length);
+
+A_STATUS
+BMIWriteMemory(HIF_DEVICE *device,
+               A_UINT32 address,
+               A_UCHAR *buffer,
+               A_UINT32 length);
+
+A_STATUS
+BMIExecute(HIF_DEVICE *device,
+           A_UINT32 address,
+           A_UINT32 *param);
+
+A_STATUS
+BMISetAppStart(HIF_DEVICE *device,
+               A_UINT32 address);
+
+A_STATUS
+BMIReadSOCRegister(HIF_DEVICE *device,
+                   A_UINT32 address,
+                   A_UINT32 *param);
+
+A_STATUS
+BMIWriteSOCRegister(HIF_DEVICE *device,
+                    A_UINT32 address,
+                    A_UINT32 param);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BMI_H_ */

Added: developers/nbd/ar6k/include/dset_api.h
===================================================================
--- developers/nbd/ar6k/include/dset_api.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/dset_api.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2005-2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * Host-side DataSet API.
+ *
+ */
+
+#ifndef _DSET_API_H_
+#define _DSET_API_H_
+
+/*
+ * Host-side DataSet support is optional, and is not
+ * currently required for correct operation.  To disable
+ * Host-side DataSet support, set this to 0.
+ */
+#define CONFIG_HOST_DSET_SUPPORT 1
+
+/* Called to send a DataSet Open Reply back to the Target. */
+A_STATUS wmi_dset_open_reply(struct wmi_t *wmip,
+                             A_UINT32 status,
+                             A_UINT32 access_cookie,
+                             A_UINT32 size,
+                             A_UINT32 version,
+                             A_UINT32 targ_handle,
+                             A_UINT32 targ_reply_fn,
+                             A_UINT32 targ_reply_arg);
+
+/* Called to send a DataSet Data Reply back to the Target. */
+A_STATUS wmi_dset_data_reply(struct wmi_t *wmip,
+                             A_UINT32 status,
+                             A_UINT8 *host_buf,
+                             A_UINT32 length,
+                             A_UINT32 targ_buf,
+                             A_UINT32 targ_reply_fn,
+                             A_UINT32 targ_reply_arg);
+
+#endif /* _DSET_API_H_ */

Added: developers/nbd/ar6k/include/gpio_api.h
===================================================================
--- developers/nbd/ar6k/include/gpio_api.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/gpio_api.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ */
+
+#ifndef _GPIO_API_H_
+#define _GPIO_API_H_
+
+/*
+ * Host-side GPIO support is optional.
+ * If run-time access to GPIO pins is not required, then
+ * this should be changed to 0.
+ */
+#define CONFIG_HOST_GPIO_SUPPORT 1
+
+/*
+ * Host-side General Purpose I/O API.
+ *
+ * $Id: //depot/sw/releases/etnaGPL1.1/host/include/gpio_api.h#2 $
+ */
+
+/*
+ * Send a command to the Target in order to change output on GPIO pins.
+ */
+A_STATUS wmi_gpio_output_set(struct wmi_t *wmip,
+                             A_UINT32 set_mask,
+                             A_UINT32 clear_mask,
+                             A_UINT32 enable_mask,
+                             A_UINT32 disable_mask);
+
+/*
+ * Send a command to the Target requesting input state of GPIO pins.
+ */
+A_STATUS wmi_gpio_input_get(struct wmi_t *wmip);
+
+/*
+ * Send a command to the Target to change the value of a GPIO register.
+ */
+A_STATUS wmi_gpio_register_set(struct wmi_t *wmip,
+                               A_UINT32 gpioreg_id,
+                               A_UINT32 value);
+
+/*
+ * Send a command to the Target to fetch the value of a GPIO register.
+ */
+A_STATUS wmi_gpio_register_get(struct wmi_t *wmip, A_UINT32 gpioreg_id);
+
+/*
+ * Send a command to the Target, acknowledging some GPIO interrupts.
+ */
+A_STATUS wmi_gpio_intr_ack(struct wmi_t *wmip, A_UINT32 ack_mask);
+
+#endif /* _GPIO_API_H_ */

Added: developers/nbd/ar6k/include/hif.h
===================================================================
--- developers/nbd/ar6k/include/hif.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/hif.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * HIF specific declarations and prototypes
+ */
+
+#ifndef _HIF_H_
+#define _HIF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Header files */
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/osapi.h"
+
+typedef struct htc_callbacks HTC_CALLBACKS;
+typedef struct hif_request HIF_REQUEST;
+typedef struct sdio_func HIF_DEVICE;
+
+typedef enum {
+    HIF_READ,
+    HIF_WRITE
+} HIF_DIRECTION;
+
+typedef enum {
+    HIF_BASIC_IO,
+    HIF_EXTENDED_IO
+} HIF_CMDTYPE;
+
+typedef enum {
+    HIF_SYNCHRONOUS,
+    HIF_ASYNCHRONOUS
+} HIF_EXECMODE;
+
+typedef enum {
+    HIF_BYTE_BASIS,
+    HIF_BLOCK_BASIS
+} HIF_DATAMODE;
+
+typedef enum {
+    HIF_FIXED_ADDRESS,
+    HIF_INCREMENTAL_ADDRESS
+} HIF_ADDRMODE;
+
+typedef enum {
+    HIF_DEVICE_POWER_STATE,
+    HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
+    HIF_DEVICE_GET_MBOX_ADDR,
+} HIF_DEVICE_CONFIG_OPCODE;
+
+#define HIF_MAX_DEVICES                 1
+
+#define HIF_FRAME_REQUEST(request, _direction, _type,    \
+                          _emode, _dmode, _amode) do {   \
+    (request)->direction = _direction;                   \
+    (request)->type = _type;                             \
+    (request)->emode = _emode;                           \
+    (request)->dmode = _dmode;                           \
+    (request)->amode = _amode;                           \
+} while(0)
+
+struct htc_callbacks {
+    A_UCHAR *name;
+    A_UINT32 id;
+    A_STATUS (* deviceInsertedHandler)(HIF_DEVICE *device);
+    A_STATUS (* deviceRemovedHandler)(HIF_DEVICE *device);
+    A_STATUS (* deviceSuspendHandler)(HIF_DEVICE *device);
+    A_STATUS (* deviceResumeHandler)(HIF_DEVICE *device);
+    A_STATUS (* deviceWakeupHandler)(HIF_DEVICE *device);
+    A_STATUS (* rwCompletionHandler)(void *context, A_STATUS status);
+#ifdef CF
+    A_STATUS (* deviceInterruptDisabler)(HIF_DEVICE *device,A_BOOL *callDsr);
+    A_STATUS (* deviceInterruptEnabler)(HIF_DEVICE *device);
+#endif /* CF */
+    A_STATUS (* dsrHandler)(HIF_DEVICE *device);
+};
+
+/*
+ * The request structure captures different attributes that can precisely
+ * characterize a command and its behavior for different physical interfaces.
+ */
+struct hif_request {
+    HIF_DIRECTION       direction; /* HIF_READ/HIF_WRITE */
+    HIF_CMDTYPE	        type; /* HIF_BASIC_IO/HIF_EXTENDED_IO */
+    HIF_EXECMODE        emode; /* HIF_SYNCHRONOUS/HIF_ASYNCHRONOUS */
+    HIF_DATAMODE        dmode; /* HIF_BYTE_BASIS/HIF_BLOCK_BASIS */
+    HIF_ADDRMODE        amode; /* HIF_FIXED_ADDRESS/HIF_INCREMENTAL_ADDRESS */
+};
+
+/*
+ * This API is used by the HTC layer to register different callback routines
+ * with the HIF layer. Support for following events has been captured - DSR,
+ * Read/Write completion, Device insertion/removal, Device suspension/
+ * resumption/wakeup. In addition to this, the API is also used to register
+ * the name and the revision of the chip. The latter can be used to verify
+ * the revision of the chip read from the device before reporting it to HTC.
+ */
+void
+HIFRegisterCallbacks(HTC_CALLBACKS *callbacks);
+
+/*
+ * This API is used to provide the read/write interface over the specific bus
+ * interface.
+ * address - Starting address in the dragon's address space. For mailbox
+ *           writes, it refers to the start of the mbox boundary. It should
+ *           be ensured that the last byte falls on the mailbox's EOM. For
+ *           mailbox reads, it refers to the end of the mbox boundary.
+ * buffer - Pointer to the buffer containg the data to be transmitted or
+ *          received.
+ * length - Amount of data to be transmitted or received.
+ * request - Characterizes the attributes of the command.
+ *     direction - Direction of transfer (HIF_READ/HIF_WRITE).
+ *     type - An interface may support different kind of read/write commands.
+ *            For example: SDIO supports CMD52/CMD53s. The command type
+ *            is thus divided into a basic and an extended command and can
+ *            be specified using HIF_BASIC_IO/HIF_EXTENDED_IO.
+ *     emode - This indicates the whether the command is to be executed in a
+ *             blocking or non-blocking fashion (HIF_SYNCHRONOUS/
+ *             HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
+ *             implemented using the asynchronous mode allowing the the bus
+ *             driver to indicate the completion of operation through the
+ *             registered callback routine. The requirement primarily comes
+ *             from the contexts these operations get called from (a driver's
+ *             transmit context or the ISR context in case of receive).
+ *             Support for both of these modes is essential.
+ *     dmode - An interface may support different kinds of commands based on
+ *             the tradeoff between the amount of data it can carry and the
+ *             setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
+ *             HIF_BLOCK_BASIS). In case of latter, the data is rounded off
+ *             to the nearest block size by padding. The size of the block is
+ *             configurable at compile time using the HIF_BLOCK_SIZE and is
+ *             negotiated with the target during initialization after the
+ *             dragon interrupts are enabled.
+ *     amode - This indicates if the address has to be incremented on dragon
+ *             after every read/write operation (HIF?FIXED_ADDRESS/
+ *             HIF_INCREMENTAL_ADDRESS).
+ */
+A_STATUS
+HIFReadWrite(HIF_DEVICE    *device,
+             A_UINT32       address,
+             A_UCHAR       *buffer,
+             A_UINT32       length,
+             HIF_REQUEST   *request,
+             void          *context);
+
+#if 0
+Not required since the hif layer can automatically do all this once the device
+is discovered and then report the instance to the HTC layer only after
+everything is successfully finished.
+/*
+ * This is called right after the device insertion event is reported to HTC.
+ * It is expected to perform atleast the following functions:
+ *   i) Configure the interface - bus width, clock rate, operational current.
+ *  ii) Enable the interrupts and unmask any IRQs.
+ * iii) Enable dragon by writing to the IO Enable bit if the interface supports
+ *      one.
+ */
+A_STATUS
+HIFInitializeInterface(void *device);
+#endif
+
+/*
+ * This can be initiated from the unload driver context ie when the HTCShutdown
+ * routine is called.
+ */
+void
+HIFShutDownDevice(HIF_DEVICE *device);
+
+/*
+ * This should translate to an acknowledgment to the bus driver indicating that
+ * the previous interrupt request has been serviced and the all the relevant
+ * sources have been cleared. HTC is ready to process more interrupts.
+ * This should prevent the bus driver from raising an interrupt unless the
+ * previous one has been serviced and acknowledged using the previous API.
+ */
+void
+HIFAckInterrupt(HIF_DEVICE *device);
+
+void
+HIFMaskInterrupt(HIF_DEVICE *device);
+
+void
+HIFUnMaskInterrupt(HIF_DEVICE *device);
+
+A_STATUS
+HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
+                   void *config, A_UINT32 configLen);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HIF_H_ */

Added: developers/nbd/ar6k/include/host_version.h
===================================================================
--- developers/nbd/ar6k/include/host_version.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/host_version.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains version information for the sample host driver for the
+ * AR6000 chip
+ *
+ *
+ */
+
+#ifndef _HOST_VERSION_H_
+#define _HOST_VERSION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../include/AR6000_version.h"
+
+/*
+ * The version number is made up of major, minor, patch and build
+ * numbers. These are 16 bit numbers.  The build and release script will
+ * set the build number using a Perforce counter.  Here the build number is
+ * set to 9999 so that builds done without the build-release script are easily
+ * identifiable.
+ */
+
+#define ATH_SW_VER_MAJOR      __VER_MAJOR_
+#define ATH_SW_VER_MINOR      __VER_MINOR_
+#define ATH_SW_VER_PATCH      __VER_PATCH_
+#define ATH_SW_VER_BUILD 2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HOST_VERSION_H_ */

Added: developers/nbd/ar6k/include/htc.h
===================================================================
--- developers/nbd/ar6k/include/htc.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/htc.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * htc.h  -  HTC Module specific declarations and prototypes
+ */
+
+#ifndef _HTC_H_
+#define _HTC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* ------ MBOX ID ------ */
+typedef enum
+{
+    ENDPOINT_UNUSED = -1,
+    ENDPOINT1 = 0,
+    ENDPOINT2,
+    ENDPOINT3,
+    ENDPOINT4,
+} HTC_ENDPOINT_ID;
+
+/* ------ Event Types ------ */
+typedef enum
+{
+    HTC_BUFFER_RECEIVED = 0,
+    HTC_SKB_RECEIVED,
+    HTC_BUFFER_SENT,
+    HTC_SKB_SENT,
+    HTC_DATA_AVAILABLE,
+    HTC_TARGET_AVAILABLE,
+    HTC_TARGET_UNAVAILABLE,
+} HTC_EVENT_ID;
+
+#define HTC_MAILBOX_NUM_MAX                4
+#define HTC_HEADER_LEN                     2
+#define HTC_DATA_REQUEST_RING_BUFFER_SIZE  30
+
+/* ------- Target Specific Data structures ------- */
+typedef struct htc_target HTC_TARGET;
+
+/* ------- Event Specific Data Structures ------- */
+typedef struct htc_event_info HTC_EVENT_INFO;
+typedef void   (*HTC_EVENT_HANDLER) (HTC_TARGET *,
+                                     HTC_ENDPOINT_ID,
+                                     HTC_EVENT_ID,
+                                     HTC_EVENT_INFO *,
+                                     void *);
+
+/* WMI layer extracts the relevant information from this data structure */
+struct htc_event_info
+{
+    A_UCHAR             *buffer;
+    void                *cookie;
+    A_UINT32             bufferLength;
+    A_UINT32             actualLength;
+    A_STATUS             status;
+};
+
+/* ------ Function Prototypes ------ */
+A_STATUS
+HTCInit(void);
+
+A_STATUS
+HTCStart(HTC_TARGET *target);
+/* target - IN */
+
+A_STATUS
+HTCEventReg(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId,
+            HTC_EVENT_ID eventId, HTC_EVENT_HANDLER eventHandler,
+            void *param);
+/* target - IN, endPointId - IN, eventId - IN, eventHandler - IN, param - IN */
+
+A_STATUS
+HTCBufferReceive(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId,
+                 A_UCHAR *buffer, A_UINT32 length, void *cookie);
+/* target - IN, endPointId - IN, buffer - IN, length - IN, cookie - IN */
+
+#if 0
+A_STATUS
+HTCSkbReceive(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId,
+              struct sk_buff *skb, void *cookie);
+#endif
+
+A_STATUS
+HTCBufferSend(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId,
+              A_UCHAR *buffer, A_UINT32 length, void *cookie);
+/* target - IN, endPointId - IN, buffer - IN, length - IN, cookie - IN */
+
+#if 0
+A_STATUS
+HTCSkbSend(HTC_TARGET *target, HTC_ENDPOINT_ID endPointId,
+           struct sk_buff *skb, void *cookie);
+#endif
+
+void
+HTCStop(HTC_TARGET *target);
+/* target - IN */
+
+void
+HTCShutDown(HTC_TARGET *target);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HTC_H_ */

Added: developers/nbd/ar6k/include/hw/mbox_host_reg.h
===================================================================
--- developers/nbd/ar6k/include/hw/mbox_host_reg.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/hw/mbox_host_reg.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+
+#ifndef _MBOX_HOST_REG_REG_H_
+#define _MBOX_HOST_REG_REG_H_
+
+#define HOST_INT_STATUS_ADDRESS                  0x00000400
+#define HOST_INT_STATUS_OFFSET                   0x00000400
+#define HOST_INT_STATUS_ERROR_MSB                7
+#define HOST_INT_STATUS_ERROR_LSB                7
+#define HOST_INT_STATUS_ERROR_MASK               0x00000080
+#define HOST_INT_STATUS_ERROR_GET(x)             (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
+#define HOST_INT_STATUS_ERROR_SET(x)             (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK)
+#define HOST_INT_STATUS_CPU_MSB                  6
+#define HOST_INT_STATUS_CPU_LSB                  6
+#define HOST_INT_STATUS_CPU_MASK                 0x00000040
+#define HOST_INT_STATUS_CPU_GET(x)               (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
+#define HOST_INT_STATUS_CPU_SET(x)               (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK)
+#define HOST_INT_STATUS_DRAGON_INT_MSB           5
+#define HOST_INT_STATUS_DRAGON_INT_LSB           5
+#define HOST_INT_STATUS_DRAGON_INT_MASK          0x00000020
+#define HOST_INT_STATUS_DRAGON_INT_GET(x)        (((x) & HOST_INT_STATUS_DRAGON_INT_MASK) >> HOST_INT_STATUS_DRAGON_INT_LSB)
+#define HOST_INT_STATUS_DRAGON_INT_SET(x)        (((x) << HOST_INT_STATUS_DRAGON_INT_LSB) & HOST_INT_STATUS_DRAGON_INT_MASK)
+#define HOST_INT_STATUS_COUNTER_MSB              4
+#define HOST_INT_STATUS_COUNTER_LSB              4
+#define HOST_INT_STATUS_COUNTER_MASK             0x00000010
+#define HOST_INT_STATUS_COUNTER_GET(x)           (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
+#define HOST_INT_STATUS_COUNTER_SET(x)           (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK)
+#define HOST_INT_STATUS_MBOX_DATA_MSB            3
+#define HOST_INT_STATUS_MBOX_DATA_LSB            0
+#define HOST_INT_STATUS_MBOX_DATA_MASK           0x0000000f
+#define HOST_INT_STATUS_MBOX_DATA_GET(x)         (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB)
+#define HOST_INT_STATUS_MBOX_DATA_SET(x)         (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK)
+
+#define CPU_INT_STATUS_ADDRESS                   0x00000401
+#define CPU_INT_STATUS_OFFSET                    0x00000401
+#define CPU_INT_STATUS_BIT_MSB                   7
+#define CPU_INT_STATUS_BIT_LSB                   0
+#define CPU_INT_STATUS_BIT_MASK                  0x000000ff
+#define CPU_INT_STATUS_BIT_GET(x)                (((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB)
+#define CPU_INT_STATUS_BIT_SET(x)                (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK)
+
+#define ERROR_INT_STATUS_ADDRESS                 0x00000402
+#define ERROR_INT_STATUS_OFFSET                  0x00000402
+#define ERROR_INT_STATUS_SPI_MSB                 3
+#define ERROR_INT_STATUS_SPI_LSB                 3
+#define ERROR_INT_STATUS_SPI_MASK                0x00000008
+#define ERROR_INT_STATUS_SPI_GET(x)              (((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB)
+#define ERROR_INT_STATUS_SPI_SET(x)              (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK)
+#define ERROR_INT_STATUS_WAKEUP_MSB              2
+#define ERROR_INT_STATUS_WAKEUP_LSB              2
+#define ERROR_INT_STATUS_WAKEUP_MASK             0x00000004
+#define ERROR_INT_STATUS_WAKEUP_GET(x)           (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
+#define ERROR_INT_STATUS_WAKEUP_SET(x)           (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB        1
+#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB        1
+#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK       0x00000002
+#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x)     (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
+#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x)     (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
+#define ERROR_INT_STATUS_TX_OVERFLOW_MSB         0
+#define ERROR_INT_STATUS_TX_OVERFLOW_LSB         0
+#define ERROR_INT_STATUS_TX_OVERFLOW_MASK        0x00000001
+#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x)      (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB)
+#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x)      (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK)
+
+#define COUNTER_INT_STATUS_ADDRESS               0x00000403
+#define COUNTER_INT_STATUS_OFFSET                0x00000403
+#define COUNTER_INT_STATUS_COUNTER_MSB           7
+#define COUNTER_INT_STATUS_COUNTER_LSB           0
+#define COUNTER_INT_STATUS_COUNTER_MASK          0x000000ff
+#define COUNTER_INT_STATUS_COUNTER_GET(x)        (((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB)
+#define COUNTER_INT_STATUS_COUNTER_SET(x)        (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK)
+
+#define MBOX_FRAME_ADDRESS                       0x00000404
+#define MBOX_FRAME_OFFSET                        0x00000404
+#define MBOX_FRAME_RX_EOM_MSB                    7
+#define MBOX_FRAME_RX_EOM_LSB                    4
+#define MBOX_FRAME_RX_EOM_MASK                   0x000000f0
+#define MBOX_FRAME_RX_EOM_GET(x)                 (((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB)
+#define MBOX_FRAME_RX_EOM_SET(x)                 (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK)
+#define MBOX_FRAME_RX_SOM_MSB                    3
+#define MBOX_FRAME_RX_SOM_LSB                    0
+#define MBOX_FRAME_RX_SOM_MASK                   0x0000000f
+#define MBOX_FRAME_RX_SOM_GET(x)                 (((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB)
+#define MBOX_FRAME_RX_SOM_SET(x)                 (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK)
+
+#define RX_LOOKAHEAD_VALID_ADDRESS               0x00000405
+#define RX_LOOKAHEAD_VALID_OFFSET                0x00000405
+#define RX_LOOKAHEAD_VALID_MBOX_MSB              3
+#define RX_LOOKAHEAD_VALID_MBOX_LSB              0
+#define RX_LOOKAHEAD_VALID_MBOX_MASK             0x0000000f
+#define RX_LOOKAHEAD_VALID_MBOX_GET(x)           (((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB)
+#define RX_LOOKAHEAD_VALID_MBOX_SET(x)           (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK)
+
+#define RX_LOOKAHEAD0_ADDRESS                    0x00000408
+#define RX_LOOKAHEAD0_OFFSET                     0x00000408
+#define RX_LOOKAHEAD0_DATA_MSB                   7
+#define RX_LOOKAHEAD0_DATA_LSB                   0
+#define RX_LOOKAHEAD0_DATA_MASK                  0x000000ff
+#define RX_LOOKAHEAD0_DATA_GET(x)                (((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB)
+#define RX_LOOKAHEAD0_DATA_SET(x)                (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK)
+
+#define RX_LOOKAHEAD1_ADDRESS                    0x0000040c
+#define RX_LOOKAHEAD1_OFFSET                     0x0000040c
+#define RX_LOOKAHEAD1_DATA_MSB                   7
+#define RX_LOOKAHEAD1_DATA_LSB                   0
+#define RX_LOOKAHEAD1_DATA_MASK                  0x000000ff
+#define RX_LOOKAHEAD1_DATA_GET(x)                (((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB)
+#define RX_LOOKAHEAD1_DATA_SET(x)                (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK)
+
+#define RX_LOOKAHEAD2_ADDRESS                    0x00000410
+#define RX_LOOKAHEAD2_OFFSET                     0x00000410
+#define RX_LOOKAHEAD2_DATA_MSB                   7
+#define RX_LOOKAHEAD2_DATA_LSB                   0
+#define RX_LOOKAHEAD2_DATA_MASK                  0x000000ff
+#define RX_LOOKAHEAD2_DATA_GET(x)                (((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB)
+#define RX_LOOKAHEAD2_DATA_SET(x)                (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK)
+
+#define RX_LOOKAHEAD3_ADDRESS                    0x00000414
+#define RX_LOOKAHEAD3_OFFSET                     0x00000414
+#define RX_LOOKAHEAD3_DATA_MSB                   7
+#define RX_LOOKAHEAD3_DATA_LSB                   0
+#define RX_LOOKAHEAD3_DATA_MASK                  0x000000ff
+#define RX_LOOKAHEAD3_DATA_GET(x)                (((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB)
+#define RX_LOOKAHEAD3_DATA_SET(x)                (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK)
+
+#define INT_STATUS_ENABLE_ADDRESS                0x00000418
+#define INT_STATUS_ENABLE_OFFSET                 0x00000418
+#define INT_STATUS_ENABLE_ERROR_MSB              7
+#define INT_STATUS_ENABLE_ERROR_LSB              7
+#define INT_STATUS_ENABLE_ERROR_MASK             0x00000080
+#define INT_STATUS_ENABLE_ERROR_GET(x)           (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB)
+#define INT_STATUS_ENABLE_ERROR_SET(x)           (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
+#define INT_STATUS_ENABLE_CPU_MSB                6
+#define INT_STATUS_ENABLE_CPU_LSB                6
+#define INT_STATUS_ENABLE_CPU_MASK               0x00000040
+#define INT_STATUS_ENABLE_CPU_GET(x)             (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB)
+#define INT_STATUS_ENABLE_CPU_SET(x)             (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
+#define INT_STATUS_ENABLE_DRAGON_INT_MSB         5
+#define INT_STATUS_ENABLE_DRAGON_INT_LSB         5
+#define INT_STATUS_ENABLE_DRAGON_INT_MASK        0x00000020
+#define INT_STATUS_ENABLE_DRAGON_INT_GET(x)      (((x) & INT_STATUS_ENABLE_DRAGON_INT_MASK) >> INT_STATUS_ENABLE_DRAGON_INT_LSB)
+#define INT_STATUS_ENABLE_DRAGON_INT_SET(x)      (((x) << INT_STATUS_ENABLE_DRAGON_INT_LSB) & INT_STATUS_ENABLE_DRAGON_INT_MASK)
+#define INT_STATUS_ENABLE_COUNTER_MSB            4
+#define INT_STATUS_ENABLE_COUNTER_LSB            4
+#define INT_STATUS_ENABLE_COUNTER_MASK           0x00000010
+#define INT_STATUS_ENABLE_COUNTER_GET(x)         (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB)
+#define INT_STATUS_ENABLE_COUNTER_SET(x)         (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK)
+#define INT_STATUS_ENABLE_MBOX_DATA_MSB          3
+#define INT_STATUS_ENABLE_MBOX_DATA_LSB          0
+#define INT_STATUS_ENABLE_MBOX_DATA_MASK         0x0000000f
+#define INT_STATUS_ENABLE_MBOX_DATA_GET(x)       (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB)
+#define INT_STATUS_ENABLE_MBOX_DATA_SET(x)       (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK)
+
+#define CPU_INT_STATUS_ENABLE_ADDRESS            0x00000419
+#define CPU_INT_STATUS_ENABLE_OFFSET             0x00000419
+#define CPU_INT_STATUS_ENABLE_BIT_MSB            7
+#define CPU_INT_STATUS_ENABLE_BIT_LSB            0
+#define CPU_INT_STATUS_ENABLE_BIT_MASK           0x000000ff
+#define CPU_INT_STATUS_ENABLE_BIT_GET(x)         (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB)
+#define CPU_INT_STATUS_ENABLE_BIT_SET(x)         (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK)
+
+#define ERROR_STATUS_ENABLE_ADDRESS              0x0000041a
+#define ERROR_STATUS_ENABLE_OFFSET               0x0000041a
+#define ERROR_STATUS_ENABLE_WAKEUP_MSB           2
+#define ERROR_STATUS_ENABLE_WAKEUP_LSB           2
+#define ERROR_STATUS_ENABLE_WAKEUP_MASK          0x00000004
+#define ERROR_STATUS_ENABLE_WAKEUP_GET(x)        (((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB)
+#define ERROR_STATUS_ENABLE_WAKEUP_SET(x)        (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB     1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB     1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK    0x00000002
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x)  (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x)  (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB      0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB      0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK     0x00000001
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x)   (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x)   (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
+
+#define COUNTER_INT_STATUS_ENABLE_ADDRESS        0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_OFFSET         0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_BIT_MSB        7
+#define COUNTER_INT_STATUS_ENABLE_BIT_LSB        0
+#define COUNTER_INT_STATUS_ENABLE_BIT_MASK       0x000000ff
+#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x)     (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB)
+#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x)     (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK)
+
+#define COUNT_ADDRESS                            0x00000420
+#define COUNT_OFFSET                             0x00000420
+#define COUNT_VALUE_MSB                          7
+#define COUNT_VALUE_LSB                          0
+#define COUNT_VALUE_MASK                         0x000000ff
+#define COUNT_VALUE_GET(x)                       (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB)
+#define COUNT_VALUE_SET(x)                       (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK)
+
+#define COUNT_DEC_ADDRESS                        0x00000440
+#define COUNT_DEC_OFFSET                         0x00000440
+#define COUNT_DEC_VALUE_MSB                      7
+#define COUNT_DEC_VALUE_LSB                      0
+#define COUNT_DEC_VALUE_MASK                     0x000000ff
+#define COUNT_DEC_VALUE_GET(x)                   (((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB)
+#define COUNT_DEC_VALUE_SET(x)                   (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK)
+
+#define SCRATCH_ADDRESS                          0x00000460
+#define SCRATCH_OFFSET                           0x00000460
+#define SCRATCH_VALUE_MSB                        7
+#define SCRATCH_VALUE_LSB                        0
+#define SCRATCH_VALUE_MASK                       0x000000ff
+#define SCRATCH_VALUE_GET(x)                     (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB)
+#define SCRATCH_VALUE_SET(x)                     (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK)
+
+#define FIFO_TIMEOUT_ADDRESS                     0x00000468
+#define FIFO_TIMEOUT_OFFSET                      0x00000468
+#define FIFO_TIMEOUT_VALUE_MSB                   7
+#define FIFO_TIMEOUT_VALUE_LSB                   0
+#define FIFO_TIMEOUT_VALUE_MASK                  0x000000ff
+#define FIFO_TIMEOUT_VALUE_GET(x)                (((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB)
+#define FIFO_TIMEOUT_VALUE_SET(x)                (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK)
+
+#define FIFO_TIMEOUT_ENABLE_ADDRESS              0x00000469
+#define FIFO_TIMEOUT_ENABLE_OFFSET               0x00000469
+#define FIFO_TIMEOUT_ENABLE_SET_MSB              0
+#define FIFO_TIMEOUT_ENABLE_SET_LSB              0
+#define FIFO_TIMEOUT_ENABLE_SET_MASK             0x00000001
+#define FIFO_TIMEOUT_ENABLE_SET_GET(x)           (((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB)
+#define FIFO_TIMEOUT_ENABLE_SET_SET(x)           (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK)
+
+#define DISABLE_SLEEP_ADDRESS                    0x0000046a
+#define DISABLE_SLEEP_OFFSET                     0x0000046a
+#define DISABLE_SLEEP_FOR_INT_MSB                1
+#define DISABLE_SLEEP_FOR_INT_LSB                1
+#define DISABLE_SLEEP_FOR_INT_MASK               0x00000002
+#define DISABLE_SLEEP_FOR_INT_GET(x)             (((x) & DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB)
+#define DISABLE_SLEEP_FOR_INT_SET(x)             (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK)
+#define DISABLE_SLEEP_ON_MSB                     0
+#define DISABLE_SLEEP_ON_LSB                     0
+#define DISABLE_SLEEP_ON_MASK                    0x00000001
+#define DISABLE_SLEEP_ON_GET(x)                  (((x) & DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB)
+#define DISABLE_SLEEP_ON_SET(x)                  (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK)
+
+#define LOCAL_BUS_ENDIAN_ADDRESS                 0x0000046e
+#define LOCAL_BUS_ENDIAN_OFFSET                  0x0000046e
+#define LOCAL_BUS_ENDIAN_BIG_MSB                 0
+#define LOCAL_BUS_ENDIAN_BIG_LSB                 0
+#define LOCAL_BUS_ENDIAN_BIG_MASK                0x00000001
+#define LOCAL_BUS_ENDIAN_BIG_GET(x)              (((x) & LOCAL_BUS_ENDIAN_BIG_MASK) >> LOCAL_BUS_ENDIAN_BIG_LSB)
+#define LOCAL_BUS_ENDIAN_BIG_SET(x)              (((x) << LOCAL_BUS_ENDIAN_BIG_LSB) & LOCAL_BUS_ENDIAN_BIG_MASK)
+
+#define LOCAL_BUS_ADDRESS                        0x00000470
+#define LOCAL_BUS_OFFSET                         0x00000470
+#define LOCAL_BUS_SOFT_RESET_MSB                 4
+#define LOCAL_BUS_SOFT_RESET_LSB                 4
+#define LOCAL_BUS_SOFT_RESET_MASK                0x00000010
+#define LOCAL_BUS_SOFT_RESET_GET(x)              (((x) & LOCAL_BUS_SOFT_RESET_MASK) >> LOCAL_BUS_SOFT_RESET_LSB)
+#define LOCAL_BUS_SOFT_RESET_SET(x)              (((x) << LOCAL_BUS_SOFT_RESET_LSB) & LOCAL_BUS_SOFT_RESET_MASK)
+#define LOCAL_BUS_IO_ENABLE_MSB                  3
+#define LOCAL_BUS_IO_ENABLE_LSB                  3
+#define LOCAL_BUS_IO_ENABLE_MASK                 0x00000008
+#define LOCAL_BUS_IO_ENABLE_GET(x)               (((x) & LOCAL_BUS_IO_ENABLE_MASK) >> LOCAL_BUS_IO_ENABLE_LSB)
+#define LOCAL_BUS_IO_ENABLE_SET(x)               (((x) << LOCAL_BUS_IO_ENABLE_LSB) & LOCAL_BUS_IO_ENABLE_MASK)
+#define LOCAL_BUS_KEEP_AWAKE_MSB                 2
+#define LOCAL_BUS_KEEP_AWAKE_LSB                 2
+#define LOCAL_BUS_KEEP_AWAKE_MASK                0x00000004
+#define LOCAL_BUS_KEEP_AWAKE_GET(x)              (((x) & LOCAL_BUS_KEEP_AWAKE_MASK) >> LOCAL_BUS_KEEP_AWAKE_LSB)
+#define LOCAL_BUS_KEEP_AWAKE_SET(x)              (((x) << LOCAL_BUS_KEEP_AWAKE_LSB) & LOCAL_BUS_KEEP_AWAKE_MASK)
+#define LOCAL_BUS_STATE_MSB                      1
+#define LOCAL_BUS_STATE_LSB                      0
+#define LOCAL_BUS_STATE_MASK                     0x00000003
+#define LOCAL_BUS_STATE_GET(x)                   (((x) & LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB)
+#define LOCAL_BUS_STATE_SET(x)                   (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK)
+
+#define INT_WLAN_ADDRESS                         0x00000472
+#define INT_WLAN_OFFSET                          0x00000472
+#define INT_WLAN_VECTOR_MSB                      7
+#define INT_WLAN_VECTOR_LSB                      0
+#define INT_WLAN_VECTOR_MASK                     0x000000ff
+#define INT_WLAN_VECTOR_GET(x)                   (((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
+#define INT_WLAN_VECTOR_SET(x)                   (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
+
+#define WINDOW_DATA_ADDRESS                      0x00000474
+#define WINDOW_DATA_OFFSET                       0x00000474
+#define WINDOW_DATA_DATA_MSB                     7
+#define WINDOW_DATA_DATA_LSB                     0
+#define WINDOW_DATA_DATA_MASK                    0x000000ff
+#define WINDOW_DATA_DATA_GET(x)                  (((x) & WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB)
+#define WINDOW_DATA_DATA_SET(x)                  (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK)
+
+#define WINDOW_WRITE_ADDR_ADDRESS                0x00000478
+#define WINDOW_WRITE_ADDR_OFFSET                 0x00000478
+#define WINDOW_WRITE_ADDR_ADDR_MSB               7
+#define WINDOW_WRITE_ADDR_ADDR_LSB               0
+#define WINDOW_WRITE_ADDR_ADDR_MASK              0x000000ff
+#define WINDOW_WRITE_ADDR_ADDR_GET(x)            (((x) & WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB)
+#define WINDOW_WRITE_ADDR_ADDR_SET(x)            (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK)
+
+#define WINDOW_READ_ADDR_ADDRESS                 0x0000047c
+#define WINDOW_READ_ADDR_OFFSET                  0x0000047c
+#define WINDOW_READ_ADDR_ADDR_MSB                7
+#define WINDOW_READ_ADDR_ADDR_LSB                0
+#define WINDOW_READ_ADDR_ADDR_MASK               0x000000ff
+#define WINDOW_READ_ADDR_ADDR_GET(x)             (((x) & WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB)
+#define WINDOW_READ_ADDR_ADDR_SET(x)             (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK)
+
+#define SPI_CONFIG_ADDRESS                       0x00000480
+#define SPI_CONFIG_OFFSET                        0x00000480
+#define SPI_CONFIG_SPI_RESET_MSB                 4
+#define SPI_CONFIG_SPI_RESET_LSB                 4
+#define SPI_CONFIG_SPI_RESET_MASK                0x00000010
+#define SPI_CONFIG_SPI_RESET_GET(x)              (((x) & SPI_CONFIG_SPI_RESET_MASK) >> SPI_CONFIG_SPI_RESET_LSB)
+#define SPI_CONFIG_SPI_RESET_SET(x)              (((x) << SPI_CONFIG_SPI_RESET_LSB) & SPI_CONFIG_SPI_RESET_MASK)
+#define SPI_CONFIG_INTERRUPT_ENABLE_MSB          3
+#define SPI_CONFIG_INTERRUPT_ENABLE_LSB          3
+#define SPI_CONFIG_INTERRUPT_ENABLE_MASK         0x00000008
+#define SPI_CONFIG_INTERRUPT_ENABLE_GET(x)       (((x) & SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> SPI_CONFIG_INTERRUPT_ENABLE_LSB)
+#define SPI_CONFIG_INTERRUPT_ENABLE_SET(x)       (((x) << SPI_CONFIG_INTERRUPT_ENABLE_LSB) & SPI_CONFIG_INTERRUPT_ENABLE_MASK)
+#define SPI_CONFIG_TEST_MODE_MSB                 2
+#define SPI_CONFIG_TEST_MODE_LSB                 2
+#define SPI_CONFIG_TEST_MODE_MASK                0x00000004
+#define SPI_CONFIG_TEST_MODE_GET(x)              (((x) & SPI_CONFIG_TEST_MODE_MASK) >> SPI_CONFIG_TEST_MODE_LSB)
+#define SPI_CONFIG_TEST_MODE_SET(x)              (((x) << SPI_CONFIG_TEST_MODE_LSB) & SPI_CONFIG_TEST_MODE_MASK)
+#define SPI_CONFIG_DATA_SIZE_MSB                 1
+#define SPI_CONFIG_DATA_SIZE_LSB                 0
+#define SPI_CONFIG_DATA_SIZE_MASK                0x00000003
+#define SPI_CONFIG_DATA_SIZE_GET(x)              (((x) & SPI_CONFIG_DATA_SIZE_MASK) >> SPI_CONFIG_DATA_SIZE_LSB)
+#define SPI_CONFIG_DATA_SIZE_SET(x)              (((x) << SPI_CONFIG_DATA_SIZE_LSB) & SPI_CONFIG_DATA_SIZE_MASK)
+
+#define SPI_STATUS_ADDRESS                       0x00000481
+#define SPI_STATUS_OFFSET                        0x00000481
+#define SPI_STATUS_ADDR_ERR_MSB                  3
+#define SPI_STATUS_ADDR_ERR_LSB                  3
+#define SPI_STATUS_ADDR_ERR_MASK                 0x00000008
+#define SPI_STATUS_ADDR_ERR_GET(x)               (((x) & SPI_STATUS_ADDR_ERR_MASK) >> SPI_STATUS_ADDR_ERR_LSB)
+#define SPI_STATUS_ADDR_ERR_SET(x)               (((x) << SPI_STATUS_ADDR_ERR_LSB) & SPI_STATUS_ADDR_ERR_MASK)
+#define SPI_STATUS_RD_ERR_MSB                    2
+#define SPI_STATUS_RD_ERR_LSB                    2
+#define SPI_STATUS_RD_ERR_MASK                   0x00000004
+#define SPI_STATUS_RD_ERR_GET(x)                 (((x) & SPI_STATUS_RD_ERR_MASK) >> SPI_STATUS_RD_ERR_LSB)
+#define SPI_STATUS_RD_ERR_SET(x)                 (((x) << SPI_STATUS_RD_ERR_LSB) & SPI_STATUS_RD_ERR_MASK)
+#define SPI_STATUS_WR_ERR_MSB                    1
+#define SPI_STATUS_WR_ERR_LSB                    1
+#define SPI_STATUS_WR_ERR_MASK                   0x00000002
+#define SPI_STATUS_WR_ERR_GET(x)                 (((x) & SPI_STATUS_WR_ERR_MASK) >> SPI_STATUS_WR_ERR_LSB)
+#define SPI_STATUS_WR_ERR_SET(x)                 (((x) << SPI_STATUS_WR_ERR_LSB) & SPI_STATUS_WR_ERR_MASK)
+#define SPI_STATUS_READY_MSB                     0
+#define SPI_STATUS_READY_LSB                     0
+#define SPI_STATUS_READY_MASK                    0x00000001
+#define SPI_STATUS_READY_GET(x)                  (((x) & SPI_STATUS_READY_MASK) >> SPI_STATUS_READY_LSB)
+#define SPI_STATUS_READY_SET(x)                  (((x) << SPI_STATUS_READY_LSB) & SPI_STATUS_READY_MASK)
+
+#define CIS_WINDOW_ADDRESS                       0x00000600
+#define CIS_WINDOW_OFFSET                        0x00000600
+#define CIS_WINDOW_DATA_MSB                      7
+#define CIS_WINDOW_DATA_LSB                      0
+#define CIS_WINDOW_DATA_MASK                     0x000000ff
+#define CIS_WINDOW_DATA_GET(x)                   (((x) & CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB)
+#define CIS_WINDOW_DATA_SET(x)                   (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK)
+
+#ifndef __ASSEMBLER__
+typedef struct mbox_host_reg_reg_s {
+  unsigned char pad0[1024]; /* pad to 0x400 */
+  volatile unsigned char host_int_status;
+  volatile unsigned char cpu_int_status;
+  volatile unsigned char error_int_status;
+  volatile unsigned char counter_int_status;
+  volatile unsigned char mbox_frame;
+  volatile unsigned char rx_lookahead_valid;
+  unsigned char pad1[2]; /* pad to 0x408 */
+  volatile unsigned char rx_lookahead0[4];
+  volatile unsigned char rx_lookahead1[4];
+  volatile unsigned char rx_lookahead2[4];
+  volatile unsigned char rx_lookahead3[4];
+  volatile unsigned char int_status_enable;
+  volatile unsigned char cpu_int_status_enable;
+  volatile unsigned char error_status_enable;
+  volatile unsigned char counter_int_status_enable;
+  unsigned char pad2[4]; /* pad to 0x420 */
+  volatile unsigned char count[8];
+  unsigned char pad3[24]; /* pad to 0x440 */
+  volatile unsigned char count_dec[32];
+  volatile unsigned char scratch[8];
+  volatile unsigned char fifo_timeout;
+  volatile unsigned char fifo_timeout_enable;
+  volatile unsigned char disable_sleep;
+  unsigned char pad4[3]; /* pad to 0x46e */
+  volatile unsigned char local_bus_endian;
+  unsigned char pad5[1]; /* pad to 0x470 */
+  volatile unsigned char local_bus;
+  unsigned char pad6[1]; /* pad to 0x472 */
+  volatile unsigned char int_wlan;
+  unsigned char pad7[1]; /* pad to 0x474 */
+  volatile unsigned char window_data[4];
+  volatile unsigned char window_write_addr[4];
+  volatile unsigned char window_read_addr[4];
+  volatile unsigned char spi_config;
+  volatile unsigned char spi_status;
+  unsigned char pad8[382]; /* pad to 0x600 */
+  volatile unsigned char cis_window[512];
+} mbox_host_reg_reg_t;
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MBOX_HOST_REG_H_ */

Added: developers/nbd/ar6k/include/hw/mbox_reg.h
===================================================================
--- developers/nbd/ar6k/include/hw/mbox_reg.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/hw/mbox_reg.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,550 @@
+/*
+ * Copyright 2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+#ifndef _MBOX_REG_H_
+#define _MBOX_REG_H_
+
+#define MBOX_FIFO_ADDRESS                        0x0c014000
+#define MBOX_FIFO_OFFSET                         0x00000000
+#define MBOX_FIFO_DATA_MSB                       19
+#define MBOX_FIFO_DATA_LSB                       0
+#define MBOX_FIFO_DATA_MASK                      0x000fffff
+#define MBOX_FIFO_DATA_GET(x)                    (((x) & MBOX_FIFO_DATA_MASK) >> MBOX_FIFO_DATA_LSB)
+#define MBOX_FIFO_DATA_SET(x)                    (((x) << MBOX_FIFO_DATA_LSB) & MBOX_FIFO_DATA_MASK)
+
+#define MBOX_FIFO_STATUS_ADDRESS                 0x0c014010
+#define MBOX_FIFO_STATUS_OFFSET                  0x00000010
+#define MBOX_FIFO_STATUS_EMPTY_MSB               19
+#define MBOX_FIFO_STATUS_EMPTY_LSB               16
+#define MBOX_FIFO_STATUS_EMPTY_MASK              0x000f0000
+#define MBOX_FIFO_STATUS_EMPTY_GET(x)            (((x) & MBOX_FIFO_STATUS_EMPTY_MASK) >> MBOX_FIFO_STATUS_EMPTY_LSB)
+#define MBOX_FIFO_STATUS_EMPTY_SET(x)            (((x) << MBOX_FIFO_STATUS_EMPTY_LSB) & MBOX_FIFO_STATUS_EMPTY_MASK)
+#define MBOX_FIFO_STATUS_FULL_MSB                15
+#define MBOX_FIFO_STATUS_FULL_LSB                12
+#define MBOX_FIFO_STATUS_FULL_MASK               0x0000f000
+#define MBOX_FIFO_STATUS_FULL_GET(x)             (((x) & MBOX_FIFO_STATUS_FULL_MASK) >> MBOX_FIFO_STATUS_FULL_LSB)
+#define MBOX_FIFO_STATUS_FULL_SET(x)             (((x) << MBOX_FIFO_STATUS_FULL_LSB) & MBOX_FIFO_STATUS_FULL_MASK)
+
+#define MBOX_DMA_POLICY_ADDRESS                  0x0c014014
+#define MBOX_DMA_POLICY_OFFSET                   0x00000014
+#define MBOX_DMA_POLICY_TX_QUANTUM_MSB           3
+#define MBOX_DMA_POLICY_TX_QUANTUM_LSB           3
+#define MBOX_DMA_POLICY_TX_QUANTUM_MASK          0x00000008
+#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x)        (((x) & MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> MBOX_DMA_POLICY_TX_QUANTUM_LSB)
+#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x)        (((x) << MBOX_DMA_POLICY_TX_QUANTUM_LSB) & MBOX_DMA_POLICY_TX_QUANTUM_MASK)
+#define MBOX_DMA_POLICY_TX_ORDER_MSB             2
+#define MBOX_DMA_POLICY_TX_ORDER_LSB             2
+#define MBOX_DMA_POLICY_TX_ORDER_MASK            0x00000004
+#define MBOX_DMA_POLICY_TX_ORDER_GET(x)          (((x) & MBOX_DMA_POLICY_TX_ORDER_MASK) >> MBOX_DMA_POLICY_TX_ORDER_LSB)
+#define MBOX_DMA_POLICY_TX_ORDER_SET(x)          (((x) << MBOX_DMA_POLICY_TX_ORDER_LSB) & MBOX_DMA_POLICY_TX_ORDER_MASK)
+#define MBOX_DMA_POLICY_RX_QUANTUM_MSB           1
+#define MBOX_DMA_POLICY_RX_QUANTUM_LSB           1
+#define MBOX_DMA_POLICY_RX_QUANTUM_MASK          0x00000002
+#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x)        (((x) & MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> MBOX_DMA_POLICY_RX_QUANTUM_LSB)
+#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x)        (((x) << MBOX_DMA_POLICY_RX_QUANTUM_LSB) & MBOX_DMA_POLICY_RX_QUANTUM_MASK)
+#define MBOX_DMA_POLICY_RX_ORDER_MSB             0
+#define MBOX_DMA_POLICY_RX_ORDER_LSB             0
+#define MBOX_DMA_POLICY_RX_ORDER_MASK            0x00000001
+#define MBOX_DMA_POLICY_RX_ORDER_GET(x)          (((x) & MBOX_DMA_POLICY_RX_ORDER_MASK) >> MBOX_DMA_POLICY_RX_ORDER_LSB)
+#define MBOX_DMA_POLICY_RX_ORDER_SET(x)          (((x) << MBOX_DMA_POLICY_RX_ORDER_LSB) & MBOX_DMA_POLICY_RX_ORDER_MASK)
+
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS     0x0c014018
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET      0x00000018
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX0_DMA_RX_CONTROL_ADDRESS             0x0c01401c
+#define MBOX0_DMA_RX_CONTROL_OFFSET              0x0000001c
+#define MBOX0_DMA_RX_CONTROL_RESUME_MSB          2
+#define MBOX0_DMA_RX_CONTROL_RESUME_LSB          2
+#define MBOX0_DMA_RX_CONTROL_RESUME_MASK         0x00000004
+#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x)       (((x) & MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> MBOX0_DMA_RX_CONTROL_RESUME_LSB)
+#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x)       (((x) << MBOX0_DMA_RX_CONTROL_RESUME_LSB) & MBOX0_DMA_RX_CONTROL_RESUME_MASK)
+#define MBOX0_DMA_RX_CONTROL_START_MSB           1
+#define MBOX0_DMA_RX_CONTROL_START_LSB           1
+#define MBOX0_DMA_RX_CONTROL_START_MASK          0x00000002
+#define MBOX0_DMA_RX_CONTROL_START_GET(x)        (((x) & MBOX0_DMA_RX_CONTROL_START_MASK) >> MBOX0_DMA_RX_CONTROL_START_LSB)
+#define MBOX0_DMA_RX_CONTROL_START_SET(x)        (((x) << MBOX0_DMA_RX_CONTROL_START_LSB) & MBOX0_DMA_RX_CONTROL_START_MASK)
+#define MBOX0_DMA_RX_CONTROL_STOP_MSB            0
+#define MBOX0_DMA_RX_CONTROL_STOP_LSB            0
+#define MBOX0_DMA_RX_CONTROL_STOP_MASK           0x00000001
+#define MBOX0_DMA_RX_CONTROL_STOP_GET(x)         (((x) & MBOX0_DMA_RX_CONTROL_STOP_MASK) >> MBOX0_DMA_RX_CONTROL_STOP_LSB)
+#define MBOX0_DMA_RX_CONTROL_STOP_SET(x)         (((x) << MBOX0_DMA_RX_CONTROL_STOP_LSB) & MBOX0_DMA_RX_CONTROL_STOP_MASK)
+
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS     0x0c014020
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET      0x00000020
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX0_DMA_TX_CONTROL_ADDRESS             0x0c014024
+#define MBOX0_DMA_TX_CONTROL_OFFSET              0x00000024
+#define MBOX0_DMA_TX_CONTROL_RESUME_MSB          2
+#define MBOX0_DMA_TX_CONTROL_RESUME_LSB          2
+#define MBOX0_DMA_TX_CONTROL_RESUME_MASK         0x00000004
+#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x)       (((x) & MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> MBOX0_DMA_TX_CONTROL_RESUME_LSB)
+#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x)       (((x) << MBOX0_DMA_TX_CONTROL_RESUME_LSB) & MBOX0_DMA_TX_CONTROL_RESUME_MASK)
+#define MBOX0_DMA_TX_CONTROL_START_MSB           1
+#define MBOX0_DMA_TX_CONTROL_START_LSB           1
+#define MBOX0_DMA_TX_CONTROL_START_MASK          0x00000002
+#define MBOX0_DMA_TX_CONTROL_START_GET(x)        (((x) & MBOX0_DMA_TX_CONTROL_START_MASK) >> MBOX0_DMA_TX_CONTROL_START_LSB)
+#define MBOX0_DMA_TX_CONTROL_START_SET(x)        (((x) << MBOX0_DMA_TX_CONTROL_START_LSB) & MBOX0_DMA_TX_CONTROL_START_MASK)
+#define MBOX0_DMA_TX_CONTROL_STOP_MSB            0
+#define MBOX0_DMA_TX_CONTROL_STOP_LSB            0
+#define MBOX0_DMA_TX_CONTROL_STOP_MASK           0x00000001
+#define MBOX0_DMA_TX_CONTROL_STOP_GET(x)         (((x) & MBOX0_DMA_TX_CONTROL_STOP_MASK) >> MBOX0_DMA_TX_CONTROL_STOP_LSB)
+#define MBOX0_DMA_TX_CONTROL_STOP_SET(x)         (((x) << MBOX0_DMA_TX_CONTROL_STOP_LSB) & MBOX0_DMA_TX_CONTROL_STOP_MASK)
+
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS     0x0c014028
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET      0x00000028
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX1_DMA_RX_CONTROL_ADDRESS             0x0c01402c
+#define MBOX1_DMA_RX_CONTROL_OFFSET              0x0000002c
+#define MBOX1_DMA_RX_CONTROL_RESUME_MSB          2
+#define MBOX1_DMA_RX_CONTROL_RESUME_LSB          2
+#define MBOX1_DMA_RX_CONTROL_RESUME_MASK         0x00000004
+#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x)       (((x) & MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> MBOX1_DMA_RX_CONTROL_RESUME_LSB)
+#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x)       (((x) << MBOX1_DMA_RX_CONTROL_RESUME_LSB) & MBOX1_DMA_RX_CONTROL_RESUME_MASK)
+#define MBOX1_DMA_RX_CONTROL_START_MSB           1
+#define MBOX1_DMA_RX_CONTROL_START_LSB           1
+#define MBOX1_DMA_RX_CONTROL_START_MASK          0x00000002
+#define MBOX1_DMA_RX_CONTROL_START_GET(x)        (((x) & MBOX1_DMA_RX_CONTROL_START_MASK) >> MBOX1_DMA_RX_CONTROL_START_LSB)
+#define MBOX1_DMA_RX_CONTROL_START_SET(x)        (((x) << MBOX1_DMA_RX_CONTROL_START_LSB) & MBOX1_DMA_RX_CONTROL_START_MASK)
+#define MBOX1_DMA_RX_CONTROL_STOP_MSB            0
+#define MBOX1_DMA_RX_CONTROL_STOP_LSB            0
+#define MBOX1_DMA_RX_CONTROL_STOP_MASK           0x00000001
+#define MBOX1_DMA_RX_CONTROL_STOP_GET(x)         (((x) & MBOX1_DMA_RX_CONTROL_STOP_MASK) >> MBOX1_DMA_RX_CONTROL_STOP_LSB)
+#define MBOX1_DMA_RX_CONTROL_STOP_SET(x)         (((x) << MBOX1_DMA_RX_CONTROL_STOP_LSB) & MBOX1_DMA_RX_CONTROL_STOP_MASK)
+
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS     0x0c014030
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET      0x00000030
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX1_DMA_TX_CONTROL_ADDRESS             0x0c014034
+#define MBOX1_DMA_TX_CONTROL_OFFSET              0x00000034
+#define MBOX1_DMA_TX_CONTROL_RESUME_MSB          2
+#define MBOX1_DMA_TX_CONTROL_RESUME_LSB          2
+#define MBOX1_DMA_TX_CONTROL_RESUME_MASK         0x00000004
+#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x)       (((x) & MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> MBOX1_DMA_TX_CONTROL_RESUME_LSB)
+#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x)       (((x) << MBOX1_DMA_TX_CONTROL_RESUME_LSB) & MBOX1_DMA_TX_CONTROL_RESUME_MASK)
+#define MBOX1_DMA_TX_CONTROL_START_MSB           1
+#define MBOX1_DMA_TX_CONTROL_START_LSB           1
+#define MBOX1_DMA_TX_CONTROL_START_MASK          0x00000002
+#define MBOX1_DMA_TX_CONTROL_START_GET(x)        (((x) & MBOX1_DMA_TX_CONTROL_START_MASK) >> MBOX1_DMA_TX_CONTROL_START_LSB)
+#define MBOX1_DMA_TX_CONTROL_START_SET(x)        (((x) << MBOX1_DMA_TX_CONTROL_START_LSB) & MBOX1_DMA_TX_CONTROL_START_MASK)
+#define MBOX1_DMA_TX_CONTROL_STOP_MSB            0
+#define MBOX1_DMA_TX_CONTROL_STOP_LSB            0
+#define MBOX1_DMA_TX_CONTROL_STOP_MASK           0x00000001
+#define MBOX1_DMA_TX_CONTROL_STOP_GET(x)         (((x) & MBOX1_DMA_TX_CONTROL_STOP_MASK) >> MBOX1_DMA_TX_CONTROL_STOP_LSB)
+#define MBOX1_DMA_TX_CONTROL_STOP_SET(x)         (((x) << MBOX1_DMA_TX_CONTROL_STOP_LSB) & MBOX1_DMA_TX_CONTROL_STOP_MASK)
+
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS     0x0c014038
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET      0x00000038
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX2_DMA_RX_CONTROL_ADDRESS             0x0c01403c
+#define MBOX2_DMA_RX_CONTROL_OFFSET              0x0000003c
+#define MBOX2_DMA_RX_CONTROL_RESUME_MSB          2
+#define MBOX2_DMA_RX_CONTROL_RESUME_LSB          2
+#define MBOX2_DMA_RX_CONTROL_RESUME_MASK         0x00000004
+#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x)       (((x) & MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> MBOX2_DMA_RX_CONTROL_RESUME_LSB)
+#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x)       (((x) << MBOX2_DMA_RX_CONTROL_RESUME_LSB) & MBOX2_DMA_RX_CONTROL_RESUME_MASK)
+#define MBOX2_DMA_RX_CONTROL_START_MSB           1
+#define MBOX2_DMA_RX_CONTROL_START_LSB           1
+#define MBOX2_DMA_RX_CONTROL_START_MASK          0x00000002
+#define MBOX2_DMA_RX_CONTROL_START_GET(x)        (((x) & MBOX2_DMA_RX_CONTROL_START_MASK) >> MBOX2_DMA_RX_CONTROL_START_LSB)
+#define MBOX2_DMA_RX_CONTROL_START_SET(x)        (((x) << MBOX2_DMA_RX_CONTROL_START_LSB) & MBOX2_DMA_RX_CONTROL_START_MASK)
+#define MBOX2_DMA_RX_CONTROL_STOP_MSB            0
+#define MBOX2_DMA_RX_CONTROL_STOP_LSB            0
+#define MBOX2_DMA_RX_CONTROL_STOP_MASK           0x00000001
+#define MBOX2_DMA_RX_CONTROL_STOP_GET(x)         (((x) & MBOX2_DMA_RX_CONTROL_STOP_MASK) >> MBOX2_DMA_RX_CONTROL_STOP_LSB)
+#define MBOX2_DMA_RX_CONTROL_STOP_SET(x)         (((x) << MBOX2_DMA_RX_CONTROL_STOP_LSB) & MBOX2_DMA_RX_CONTROL_STOP_MASK)
+
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS     0x0c014040
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET      0x00000040
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX2_DMA_TX_CONTROL_ADDRESS             0x0c014044
+#define MBOX2_DMA_TX_CONTROL_OFFSET              0x00000044
+#define MBOX2_DMA_TX_CONTROL_RESUME_MSB          2
+#define MBOX2_DMA_TX_CONTROL_RESUME_LSB          2
+#define MBOX2_DMA_TX_CONTROL_RESUME_MASK         0x00000004
+#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x)       (((x) & MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> MBOX2_DMA_TX_CONTROL_RESUME_LSB)
+#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x)       (((x) << MBOX2_DMA_TX_CONTROL_RESUME_LSB) & MBOX2_DMA_TX_CONTROL_RESUME_MASK)
+#define MBOX2_DMA_TX_CONTROL_START_MSB           1
+#define MBOX2_DMA_TX_CONTROL_START_LSB           1
+#define MBOX2_DMA_TX_CONTROL_START_MASK          0x00000002
+#define MBOX2_DMA_TX_CONTROL_START_GET(x)        (((x) & MBOX2_DMA_TX_CONTROL_START_MASK) >> MBOX2_DMA_TX_CONTROL_START_LSB)
+#define MBOX2_DMA_TX_CONTROL_START_SET(x)        (((x) << MBOX2_DMA_TX_CONTROL_START_LSB) & MBOX2_DMA_TX_CONTROL_START_MASK)
+#define MBOX2_DMA_TX_CONTROL_STOP_MSB            0
+#define MBOX2_DMA_TX_CONTROL_STOP_LSB            0
+#define MBOX2_DMA_TX_CONTROL_STOP_MASK           0x00000001
+#define MBOX2_DMA_TX_CONTROL_STOP_GET(x)         (((x) & MBOX2_DMA_TX_CONTROL_STOP_MASK) >> MBOX2_DMA_TX_CONTROL_STOP_LSB)
+#define MBOX2_DMA_TX_CONTROL_STOP_SET(x)         (((x) << MBOX2_DMA_TX_CONTROL_STOP_LSB) & MBOX2_DMA_TX_CONTROL_STOP_MASK)
+
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS     0x0c014048
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET      0x00000048
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX3_DMA_RX_CONTROL_ADDRESS             0x0c01404c
+#define MBOX3_DMA_RX_CONTROL_OFFSET              0x0000004c
+#define MBOX3_DMA_RX_CONTROL_RESUME_MSB          2
+#define MBOX3_DMA_RX_CONTROL_RESUME_LSB          2
+#define MBOX3_DMA_RX_CONTROL_RESUME_MASK         0x00000004
+#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x)       (((x) & MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> MBOX3_DMA_RX_CONTROL_RESUME_LSB)
+#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x)       (((x) << MBOX3_DMA_RX_CONTROL_RESUME_LSB) & MBOX3_DMA_RX_CONTROL_RESUME_MASK)
+#define MBOX3_DMA_RX_CONTROL_START_MSB           1
+#define MBOX3_DMA_RX_CONTROL_START_LSB           1
+#define MBOX3_DMA_RX_CONTROL_START_MASK          0x00000002
+#define MBOX3_DMA_RX_CONTROL_START_GET(x)        (((x) & MBOX3_DMA_RX_CONTROL_START_MASK) >> MBOX3_DMA_RX_CONTROL_START_LSB)
+#define MBOX3_DMA_RX_CONTROL_START_SET(x)        (((x) << MBOX3_DMA_RX_CONTROL_START_LSB) & MBOX3_DMA_RX_CONTROL_START_MASK)
+#define MBOX3_DMA_RX_CONTROL_STOP_MSB            0
+#define MBOX3_DMA_RX_CONTROL_STOP_LSB            0
+#define MBOX3_DMA_RX_CONTROL_STOP_MASK           0x00000001
+#define MBOX3_DMA_RX_CONTROL_STOP_GET(x)         (((x) & MBOX3_DMA_RX_CONTROL_STOP_MASK) >> MBOX3_DMA_RX_CONTROL_STOP_LSB)
+#define MBOX3_DMA_RX_CONTROL_STOP_SET(x)         (((x) << MBOX3_DMA_RX_CONTROL_STOP_LSB) & MBOX3_DMA_RX_CONTROL_STOP_MASK)
+
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS     0x0c014050
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET      0x00000050
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
+#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
+
+#define MBOX3_DMA_TX_CONTROL_ADDRESS             0x0c014054
+#define MBOX3_DMA_TX_CONTROL_OFFSET              0x00000054
+#define MBOX3_DMA_TX_CONTROL_RESUME_MSB          2
+#define MBOX3_DMA_TX_CONTROL_RESUME_LSB          2
+#define MBOX3_DMA_TX_CONTROL_RESUME_MASK         0x00000004
+#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x)       (((x) & MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> MBOX3_DMA_TX_CONTROL_RESUME_LSB)
+#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x)       (((x) << MBOX3_DMA_TX_CONTROL_RESUME_LSB) & MBOX3_DMA_TX_CONTROL_RESUME_MASK)
+#define MBOX3_DMA_TX_CONTROL_START_MSB           1
+#define MBOX3_DMA_TX_CONTROL_START_LSB           1
+#define MBOX3_DMA_TX_CONTROL_START_MASK          0x00000002
+#define MBOX3_DMA_TX_CONTROL_START_GET(x)        (((x) & MBOX3_DMA_TX_CONTROL_START_MASK) >> MBOX3_DMA_TX_CONTROL_START_LSB)
+#define MBOX3_DMA_TX_CONTROL_START_SET(x)        (((x) << MBOX3_DMA_TX_CONTROL_START_LSB) & MBOX3_DMA_TX_CONTROL_START_MASK)
+#define MBOX3_DMA_TX_CONTROL_STOP_MSB            0
+#define MBOX3_DMA_TX_CONTROL_STOP_LSB            0
+#define MBOX3_DMA_TX_CONTROL_STOP_MASK           0x00000001
+#define MBOX3_DMA_TX_CONTROL_STOP_GET(x)         (((x) & MBOX3_DMA_TX_CONTROL_STOP_MASK) >> MBOX3_DMA_TX_CONTROL_STOP_LSB)
+#define MBOX3_DMA_TX_CONTROL_STOP_SET(x)         (((x) << MBOX3_DMA_TX_CONTROL_STOP_LSB) & MBOX3_DMA_TX_CONTROL_STOP_MASK)
+
+#define MBOX_INT_STATUS_ADDRESS                  0x0c014058
+#define MBOX_INT_STATUS_OFFSET                   0x00000058
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB      31
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB      28
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK     0xf0000000
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)   (((x) & MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
+#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)   (((x) << MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB  27
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB  24
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
+#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB      23
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB      20
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK     0x00f00000
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)   (((x) & MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
+#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)   (((x) << MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
+#define MBOX_INT_STATUS_TX_OVERFLOW_MSB          17
+#define MBOX_INT_STATUS_TX_OVERFLOW_LSB          17
+#define MBOX_INT_STATUS_TX_OVERFLOW_MASK         0x00020000
+#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x)       (((x) & MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> MBOX_INT_STATUS_TX_OVERFLOW_LSB)
+#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x)       (((x) << MBOX_INT_STATUS_TX_OVERFLOW_LSB) & MBOX_INT_STATUS_TX_OVERFLOW_MASK)
+#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB         16
+#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB         16
+#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK        0x00010000
+#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x)      (((x) & MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> MBOX_INT_STATUS_RX_UNDERFLOW_LSB)
+#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x)      (((x) << MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & MBOX_INT_STATUS_RX_UNDERFLOW_MASK)
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB         15
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB         12
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK        0x0000f000
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)      (((x) & MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> MBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
+#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)      (((x) << MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & MBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
+#define MBOX_INT_STATUS_RX_NOT_FULL_MSB          11
+#define MBOX_INT_STATUS_RX_NOT_FULL_LSB          8
+#define MBOX_INT_STATUS_RX_NOT_FULL_MASK         0x00000f00
+#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x)       (((x) & MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> MBOX_INT_STATUS_RX_NOT_FULL_LSB)
+#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x)       (((x) << MBOX_INT_STATUS_RX_NOT_FULL_LSB) & MBOX_INT_STATUS_RX_NOT_FULL_MASK)
+#define MBOX_INT_STATUS_HOST_MSB                 7
+#define MBOX_INT_STATUS_HOST_LSB                 0
+#define MBOX_INT_STATUS_HOST_MASK                0x000000ff
+#define MBOX_INT_STATUS_HOST_GET(x)              (((x) & MBOX_INT_STATUS_HOST_MASK) >> MBOX_INT_STATUS_HOST_LSB)
+#define MBOX_INT_STATUS_HOST_SET(x)              (((x) << MBOX_INT_STATUS_HOST_LSB) & MBOX_INT_STATUS_HOST_MASK)
+
+#define MBOX_INT_ENABLE_ADDRESS                  0x0c01405c
+#define MBOX_INT_ENABLE_OFFSET                   0x0000005c
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB      31
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB      28
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK     0xf0000000
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)   (((x) & MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
+#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)   (((x) << MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB  27
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB  24
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
+#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB      23
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB      20
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK     0x00f00000
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)   (((x) & MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
+#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)   (((x) << MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
+#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB          17
+#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB          17
+#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK         0x00020000
+#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x)       (((x) & MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> MBOX_INT_ENABLE_TX_OVERFLOW_LSB)
+#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x)       (((x) << MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & MBOX_INT_ENABLE_TX_OVERFLOW_MASK)
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB         16
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB         16
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK        0x00010000
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)      (((x) & MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> MBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
+#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)      (((x) << MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & MBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB         15
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB         12
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK        0x0000f000
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)      (((x) & MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
+#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)      (((x) << MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
+#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB          11
+#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB          8
+#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK         0x00000f00
+#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x)       (((x) & MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> MBOX_INT_ENABLE_RX_NOT_FULL_LSB)
+#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x)       (((x) << MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & MBOX_INT_ENABLE_RX_NOT_FULL_MASK)
+#define MBOX_INT_ENABLE_HOST_MSB                 7
+#define MBOX_INT_ENABLE_HOST_LSB                 0
+#define MBOX_INT_ENABLE_HOST_MASK                0x000000ff
+#define MBOX_INT_ENABLE_HOST_GET(x)              (((x) & MBOX_INT_ENABLE_HOST_MASK) >> MBOX_INT_ENABLE_HOST_LSB)
+#define MBOX_INT_ENABLE_HOST_SET(x)              (((x) << MBOX_INT_ENABLE_HOST_LSB) & MBOX_INT_ENABLE_HOST_MASK)
+
+#define INT_HOST_ADDRESS                         0x0c014060
+#define INT_HOST_OFFSET                          0x00000060
+#define INT_HOST_VECTOR_MSB                      7
+#define INT_HOST_VECTOR_LSB                      0
+#define INT_HOST_VECTOR_MASK                     0x000000ff
+#define INT_HOST_VECTOR_GET(x)                   (((x) & INT_HOST_VECTOR_MASK) >> INT_HOST_VECTOR_LSB)
+#define INT_HOST_VECTOR_SET(x)                   (((x) << INT_HOST_VECTOR_LSB) & INT_HOST_VECTOR_MASK)
+
+#define LOCAL_COUNT_ADDRESS                      0x0c014080
+#define LOCAL_COUNT_OFFSET                       0x00000080
+#define LOCAL_COUNT_VALUE_MSB                    7
+#define LOCAL_COUNT_VALUE_LSB                    0
+#define LOCAL_COUNT_VALUE_MASK                   0x000000ff
+#define LOCAL_COUNT_VALUE_GET(x)                 (((x) & LOCAL_COUNT_VALUE_MASK) >> LOCAL_COUNT_VALUE_LSB)
+#define LOCAL_COUNT_VALUE_SET(x)                 (((x) << LOCAL_COUNT_VALUE_LSB) & LOCAL_COUNT_VALUE_MASK)
+
+#define COUNT_INC_ADDRESS                        0x0c0140a0
+#define COUNT_INC_OFFSET                         0x000000a0
+#define COUNT_INC_VALUE_MSB                      7
+#define COUNT_INC_VALUE_LSB                      0
+#define COUNT_INC_VALUE_MASK                     0x000000ff
+#define COUNT_INC_VALUE_GET(x)                   (((x) & COUNT_INC_VALUE_MASK) >> COUNT_INC_VALUE_LSB)
+#define COUNT_INC_VALUE_SET(x)                   (((x) << COUNT_INC_VALUE_LSB) & COUNT_INC_VALUE_MASK)
+
+#define LOCAL_SCRATCH_ADDRESS                    0x0c0140c0
+#define LOCAL_SCRATCH_OFFSET                     0x000000c0
+#define LOCAL_SCRATCH_VALUE_MSB                  7
+#define LOCAL_SCRATCH_VALUE_LSB                  0
+#define LOCAL_SCRATCH_VALUE_MASK                 0x000000ff
+#define LOCAL_SCRATCH_VALUE_GET(x)               (((x) & LOCAL_SCRATCH_VALUE_MASK) >> LOCAL_SCRATCH_VALUE_LSB)
+#define LOCAL_SCRATCH_VALUE_SET(x)               (((x) << LOCAL_SCRATCH_VALUE_LSB) & LOCAL_SCRATCH_VALUE_MASK)
+
+#define USE_LOCAL_BUS_ADDRESS                    0x0c0140e0
+#define USE_LOCAL_BUS_OFFSET                     0x000000e0
+#define USE_LOCAL_BUS_PIN_INIT_MSB               0
+#define USE_LOCAL_BUS_PIN_INIT_LSB               0
+#define USE_LOCAL_BUS_PIN_INIT_MASK              0x00000001
+#define USE_LOCAL_BUS_PIN_INIT_GET(x)            (((x) & USE_LOCAL_BUS_PIN_INIT_MASK) >> USE_LOCAL_BUS_PIN_INIT_LSB)
+#define USE_LOCAL_BUS_PIN_INIT_SET(x)            (((x) << USE_LOCAL_BUS_PIN_INIT_LSB) & USE_LOCAL_BUS_PIN_INIT_MASK)
+
+#define SDIO_CONFIG_ADDRESS                      0x0c0140e4
+#define SDIO_CONFIG_OFFSET                       0x000000e4
+#define SDIO_CONFIG_CCCR_IOR1_MSB                0
+#define SDIO_CONFIG_CCCR_IOR1_LSB                0
+#define SDIO_CONFIG_CCCR_IOR1_MASK               0x00000001
+#define SDIO_CONFIG_CCCR_IOR1_GET(x)             (((x) & SDIO_CONFIG_CCCR_IOR1_MASK) >> SDIO_CONFIG_CCCR_IOR1_LSB)
+#define SDIO_CONFIG_CCCR_IOR1_SET(x)             (((x) << SDIO_CONFIG_CCCR_IOR1_LSB) & SDIO_CONFIG_CCCR_IOR1_MASK)
+
+#define MBOX_DEBUG_ADDRESS                       0x0c0140e8
+#define MBOX_DEBUG_OFFSET                        0x000000e8
+#define MBOX_DEBUG_SEL_MSB                       2
+#define MBOX_DEBUG_SEL_LSB                       0
+#define MBOX_DEBUG_SEL_MASK                      0x00000007
+#define MBOX_DEBUG_SEL_GET(x)                    (((x) & MBOX_DEBUG_SEL_MASK) >> MBOX_DEBUG_SEL_LSB)
+#define MBOX_DEBUG_SEL_SET(x)                    (((x) << MBOX_DEBUG_SEL_LSB) & MBOX_DEBUG_SEL_MASK)
+
+#define MBOX_FIFO_RESET_ADDRESS                  0x0c0140ec
+#define MBOX_FIFO_RESET_OFFSET                   0x000000ec
+#define MBOX_FIFO_RESET_INIT_MSB                 0
+#define MBOX_FIFO_RESET_INIT_LSB                 0
+#define MBOX_FIFO_RESET_INIT_MASK                0x00000001
+#define MBOX_FIFO_RESET_INIT_GET(x)              (((x) & MBOX_FIFO_RESET_INIT_MASK) >> MBOX_FIFO_RESET_INIT_LSB)
+#define MBOX_FIFO_RESET_INIT_SET(x)              (((x) << MBOX_FIFO_RESET_INIT_LSB) & MBOX_FIFO_RESET_INIT_MASK)
+
+#define STEREO_CONFIG_ADDRESS                    0x0c0140f0
+#define STEREO_CONFIG_OFFSET                     0x000000f0
+#define STEREO_CONFIG_ENABLE_MSB                 24
+#define STEREO_CONFIG_ENABLE_LSB                 24
+#define STEREO_CONFIG_ENABLE_MASK                0x01000000
+#define STEREO_CONFIG_ENABLE_GET(x)              (((x) & STEREO_CONFIG_ENABLE_MASK) >> STEREO_CONFIG_ENABLE_LSB)
+#define STEREO_CONFIG_ENABLE_SET(x)              (((x) << STEREO_CONFIG_ENABLE_LSB) & STEREO_CONFIG_ENABLE_MASK)
+#define STEREO_CONFIG_RESET_MSB                  23
+#define STEREO_CONFIG_RESET_LSB                  23
+#define STEREO_CONFIG_RESET_MASK                 0x00800000
+#define STEREO_CONFIG_RESET_GET(x)               (((x) & STEREO_CONFIG_RESET_MASK) >> STEREO_CONFIG_RESET_LSB)
+#define STEREO_CONFIG_RESET_SET(x)               (((x) << STEREO_CONFIG_RESET_LSB) & STEREO_CONFIG_RESET_MASK)
+#define STEREO_CONFIG_I2S_DELAY_MSB              22
+#define STEREO_CONFIG_I2S_DELAY_LSB              22
+#define STEREO_CONFIG_I2S_DELAY_MASK             0x00400000
+#define STEREO_CONFIG_I2S_DELAY_GET(x)           (((x) & STEREO_CONFIG_I2S_DELAY_MASK) >> STEREO_CONFIG_I2S_DELAY_LSB)
+#define STEREO_CONFIG_I2S_DELAY_SET(x)           (((x) << STEREO_CONFIG_I2S_DELAY_LSB) & STEREO_CONFIG_I2S_DELAY_MASK)
+#define STEREO_CONFIG_MIC_MASTER_MSB             21
+#define STEREO_CONFIG_MIC_MASTER_LSB             21
+#define STEREO_CONFIG_MIC_MASTER_MASK            0x00200000
+#define STEREO_CONFIG_MIC_MASTER_GET(x)          (((x) & STEREO_CONFIG_MIC_MASTER_MASK) >> STEREO_CONFIG_MIC_MASTER_LSB)
+#define STEREO_CONFIG_MIC_MASTER_SET(x)          (((x) << STEREO_CONFIG_MIC_MASTER_LSB) & STEREO_CONFIG_MIC_MASTER_MASK)
+#define STEREO_CONFIG_MIC_WORD_SIZE_MSB          20
+#define STEREO_CONFIG_MIC_WORD_SIZE_LSB          20
+#define STEREO_CONFIG_MIC_WORD_SIZE_MASK         0x00100000
+#define STEREO_CONFIG_MIC_WORD_SIZE_GET(x)       (((x) & STEREO_CONFIG_MIC_WORD_SIZE_MASK) >> STEREO_CONFIG_MIC_WORD_SIZE_LSB)
+#define STEREO_CONFIG_MIC_WORD_SIZE_SET(x)       (((x) << STEREO_CONFIG_MIC_WORD_SIZE_LSB) & STEREO_CONFIG_MIC_WORD_SIZE_MASK)
+#define STEREO_CONFIG_STEREO_MONO_MSB            19
+#define STEREO_CONFIG_STEREO_MONO_LSB            18
+#define STEREO_CONFIG_STEREO_MONO_MASK           0x000c0000
+#define STEREO_CONFIG_STEREO_MONO_GET(x)         (((x) & STEREO_CONFIG_STEREO_MONO_MASK) >> STEREO_CONFIG_STEREO_MONO_LSB)
+#define STEREO_CONFIG_STEREO_MONO_SET(x)         (((x) << STEREO_CONFIG_STEREO_MONO_LSB) & STEREO_CONFIG_STEREO_MONO_MASK)
+#define STEREO_CONFIG_DATA_WORD_SIZE_MSB         17
+#define STEREO_CONFIG_DATA_WORD_SIZE_LSB         16
+#define STEREO_CONFIG_DATA_WORD_SIZE_MASK        0x00030000
+#define STEREO_CONFIG_DATA_WORD_SIZE_GET(x)      (((x) & STEREO_CONFIG_DATA_WORD_SIZE_MASK) >> STEREO_CONFIG_DATA_WORD_SIZE_LSB)
+#define STEREO_CONFIG_DATA_WORD_SIZE_SET(x)      (((x) << STEREO_CONFIG_DATA_WORD_SIZE_LSB) & STEREO_CONFIG_DATA_WORD_SIZE_MASK)
+#define STEREO_CONFIG_I2S_WORD_SIZE_MSB          15
+#define STEREO_CONFIG_I2S_WORD_SIZE_LSB          15
+#define STEREO_CONFIG_I2S_WORD_SIZE_MASK         0x00008000
+#define STEREO_CONFIG_I2S_WORD_SIZE_GET(x)       (((x) & STEREO_CONFIG_I2S_WORD_SIZE_MASK) >> STEREO_CONFIG_I2S_WORD_SIZE_LSB)
+#define STEREO_CONFIG_I2S_WORD_SIZE_SET(x)       (((x) << STEREO_CONFIG_I2S_WORD_SIZE_LSB) & STEREO_CONFIG_I2S_WORD_SIZE_MASK)
+#define STEREO_CONFIG_MCK_SEL_MSB                14
+#define STEREO_CONFIG_MCK_SEL_LSB                14
+#define STEREO_CONFIG_MCK_SEL_MASK               0x00004000
+#define STEREO_CONFIG_MCK_SEL_GET(x)             (((x) & STEREO_CONFIG_MCK_SEL_MASK) >> STEREO_CONFIG_MCK_SEL_LSB)
+#define STEREO_CONFIG_MCK_SEL_SET(x)             (((x) << STEREO_CONFIG_MCK_SEL_LSB) & STEREO_CONFIG_MCK_SEL_MASK)
+#define STEREO_CONFIG_MCK_CNT_MSB                13
+#define STEREO_CONFIG_MCK_CNT_LSB                10
+#define STEREO_CONFIG_MCK_CNT_MASK               0x00003c00
+#define STEREO_CONFIG_MCK_CNT_GET(x)             (((x) & STEREO_CONFIG_MCK_CNT_MASK) >> STEREO_CONFIG_MCK_CNT_LSB)
+#define STEREO_CONFIG_MCK_CNT_SET(x)             (((x) << STEREO_CONFIG_MCK_CNT_LSB) & STEREO_CONFIG_MCK_CNT_MASK)
+#define STEREO_CONFIG_MCK_RAW_MSB                9
+#define STEREO_CONFIG_MCK_RAW_LSB                9
+#define STEREO_CONFIG_MCK_RAW_MASK               0x00000200
+#define STEREO_CONFIG_MCK_RAW_GET(x)             (((x) & STEREO_CONFIG_MCK_RAW_MASK) >> STEREO_CONFIG_MCK_RAW_LSB)
+#define STEREO_CONFIG_MCK_RAW_SET(x)             (((x) << STEREO_CONFIG_MCK_RAW_LSB) & STEREO_CONFIG_MCK_RAW_MASK)
+#define STEREO_CONFIG_MASTER_MSB                 8
+#define STEREO_CONFIG_MASTER_LSB                 8
+#define STEREO_CONFIG_MASTER_MASK                0x00000100
+#define STEREO_CONFIG_MASTER_GET(x)              (((x) & STEREO_CONFIG_MASTER_MASK) >> STEREO_CONFIG_MASTER_LSB)
+#define STEREO_CONFIG_MASTER_SET(x)              (((x) << STEREO_CONFIG_MASTER_LSB) & STEREO_CONFIG_MASTER_MASK)
+#define STEREO_CONFIG_POSEDGE_MSB                7
+#define STEREO_CONFIG_POSEDGE_LSB                0
+#define STEREO_CONFIG_POSEDGE_MASK               0x000000ff
+#define STEREO_CONFIG_POSEDGE_GET(x)             (((x) & STEREO_CONFIG_POSEDGE_MASK) >> STEREO_CONFIG_POSEDGE_LSB)
+#define STEREO_CONFIG_POSEDGE_SET(x)             (((x) << STEREO_CONFIG_POSEDGE_LSB) & STEREO_CONFIG_POSEDGE_MASK)
+
+#define STEREO_VOLUME_ADDRESS                    0x0c0140f4
+#define STEREO_VOLUME_OFFSET                     0x000000f4
+#define STEREO_VOLUME_CHANNEL1_MSB               12
+#define STEREO_VOLUME_CHANNEL1_LSB               8
+#define STEREO_VOLUME_CHANNEL1_MASK              0x00001f00
+#define STEREO_VOLUME_CHANNEL1_GET(x)            (((x) & STEREO_VOLUME_CHANNEL1_MASK) >> STEREO_VOLUME_CHANNEL1_LSB)
+#define STEREO_VOLUME_CHANNEL1_SET(x)            (((x) << STEREO_VOLUME_CHANNEL1_LSB) & STEREO_VOLUME_CHANNEL1_MASK)
+#define STEREO_VOLUME_CHANNEL0_MSB               4
+#define STEREO_VOLUME_CHANNEL0_LSB               0
+#define STEREO_VOLUME_CHANNEL0_MASK              0x0000001f
+#define STEREO_VOLUME_CHANNEL0_GET(x)            (((x) & STEREO_VOLUME_CHANNEL0_MASK) >> STEREO_VOLUME_CHANNEL0_LSB)
+#define STEREO_VOLUME_CHANNEL0_SET(x)            (((x) << STEREO_VOLUME_CHANNEL0_LSB) & STEREO_VOLUME_CHANNEL0_MASK)
+
+#define HOST_IF_WINDOW_ADDRESS                   0x0c016000
+#define HOST_IF_WINDOW_OFFSET                    0x00002000
+#define HOST_IF_WINDOW_DATA_MSB                  7
+#define HOST_IF_WINDOW_DATA_LSB                  0
+#define HOST_IF_WINDOW_DATA_MASK                 0x000000ff
+#define HOST_IF_WINDOW_DATA_GET(x)               (((x) & HOST_IF_WINDOW_DATA_MASK) >> HOST_IF_WINDOW_DATA_LSB)
+#define HOST_IF_WINDOW_DATA_SET(x)               (((x) << HOST_IF_WINDOW_DATA_LSB) & HOST_IF_WINDOW_DATA_MASK)
+
+#ifndef __ASSEMBLER__
+typedef struct mbox_reg_s {
+  volatile unsigned int mbox_fifo[4];
+  volatile unsigned int mbox_fifo_status;
+  volatile unsigned int mbox_dma_policy;
+  volatile unsigned int mbox0_dma_rx_descriptor_base;
+  volatile unsigned int mbox0_dma_rx_control;
+  volatile unsigned int mbox0_dma_tx_descriptor_base;
+  volatile unsigned int mbox0_dma_tx_control;
+  volatile unsigned int mbox1_dma_rx_descriptor_base;
+  volatile unsigned int mbox1_dma_rx_control;
+  volatile unsigned int mbox1_dma_tx_descriptor_base;
+  volatile unsigned int mbox1_dma_tx_control;
+  volatile unsigned int mbox2_dma_rx_descriptor_base;
+  volatile unsigned int mbox2_dma_rx_control;
+  volatile unsigned int mbox2_dma_tx_descriptor_base;
+  volatile unsigned int mbox2_dma_tx_control;
+  volatile unsigned int mbox3_dma_rx_descriptor_base;
+  volatile unsigned int mbox3_dma_rx_control;
+  volatile unsigned int mbox3_dma_tx_descriptor_base;
+  volatile unsigned int mbox3_dma_tx_control;
+  volatile unsigned int mbox_int_status;
+  volatile unsigned int mbox_int_enable;
+  volatile unsigned int int_host;
+  unsigned char pad0[28]; /* pad to 0x80 */
+  volatile unsigned int local_count[8];
+  volatile unsigned int count_inc[8];
+  volatile unsigned int local_scratch[8];
+  volatile unsigned int use_local_bus;
+  volatile unsigned int sdio_config;
+  volatile unsigned int mbox_debug;
+  volatile unsigned int mbox_fifo_reset;
+  volatile unsigned int stereo_config;
+  volatile unsigned int stereo_volume;
+  unsigned char pad1[7944]; /* pad to 0x2000 */
+  volatile unsigned int host_if_window[2048];
+} mbox_reg_t;
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MBOX_H_ */

Added: developers/nbd/ar6k/include/hw/mc_reg.h
===================================================================
--- developers/nbd/ar6k/include/hw/mc_reg.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/hw/mc_reg.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,1129 @@
+/*
+ * Copyright 2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+#ifndef _MC_REG_H_
+#define _MC_REG_H_
+
+#define BANK0_ADDR_ADDRESS                       0x0c004000
+#define BANK0_ADDR_OFFSET                        0x00000000
+#define BANK0_ADDR_SIZE_MSB                      31
+#define BANK0_ADDR_SIZE_LSB                      28
+#define BANK0_ADDR_SIZE_MASK                     0xf0000000
+#define BANK0_ADDR_SIZE_GET(x)                   (((x) & BANK0_ADDR_SIZE_MASK) >> BANK0_ADDR_SIZE_LSB)
+#define BANK0_ADDR_SIZE_SET(x)                   (((x) << BANK0_ADDR_SIZE_LSB) & BANK0_ADDR_SIZE_MASK)
+#define BANK0_ADDR_BASE_MSB                      27
+#define BANK0_ADDR_BASE_LSB                      10
+#define BANK0_ADDR_BASE_MASK                     0x0ffffc00
+#define BANK0_ADDR_BASE_GET(x)                   (((x) & BANK0_ADDR_BASE_MASK) >> BANK0_ADDR_BASE_LSB)
+#define BANK0_ADDR_BASE_SET(x)                   (((x) << BANK0_ADDR_BASE_LSB) & BANK0_ADDR_BASE_MASK)
+
+#define BANK0_CONFIG_ADDRESS                     0x0c004004
+#define BANK0_CONFIG_OFFSET                      0x00000004
+#define BANK0_CONFIG_ENABLE_MSB                  31
+#define BANK0_CONFIG_ENABLE_LSB                  31
+#define BANK0_CONFIG_ENABLE_MASK                 0x80000000
+#define BANK0_CONFIG_ENABLE_GET(x)               (((x) & BANK0_CONFIG_ENABLE_MASK) >> BANK0_CONFIG_ENABLE_LSB)
+#define BANK0_CONFIG_ENABLE_SET(x)               (((x) << BANK0_CONFIG_ENABLE_LSB) & BANK0_CONFIG_ENABLE_MASK)
+#define BANK0_CONFIG_WIDTH_MSB                   28
+#define BANK0_CONFIG_WIDTH_LSB                   28
+#define BANK0_CONFIG_WIDTH_MASK                  0x10000000
+#define BANK0_CONFIG_WIDTH_GET(x)                (((x) & BANK0_CONFIG_WIDTH_MASK) >> BANK0_CONFIG_WIDTH_LSB)
+#define BANK0_CONFIG_WIDTH_SET(x)                (((x) << BANK0_CONFIG_WIDTH_LSB) & BANK0_CONFIG_WIDTH_MASK)
+#define BANK0_CONFIG_PROTECT_MSB                 26
+#define BANK0_CONFIG_PROTECT_LSB                 26
+#define BANK0_CONFIG_PROTECT_MASK                0x04000000
+#define BANK0_CONFIG_PROTECT_GET(x)              (((x) & BANK0_CONFIG_PROTECT_MASK) >> BANK0_CONFIG_PROTECT_LSB)
+#define BANK0_CONFIG_PROTECT_SET(x)              (((x) << BANK0_CONFIG_PROTECT_LSB) & BANK0_CONFIG_PROTECT_MASK)
+#define BANK0_CONFIG_WB_ENABLE_MSB               25
+#define BANK0_CONFIG_WB_ENABLE_LSB               25
+#define BANK0_CONFIG_WB_ENABLE_MASK              0x02000000
+#define BANK0_CONFIG_WB_ENABLE_GET(x)            (((x) & BANK0_CONFIG_WB_ENABLE_MASK) >> BANK0_CONFIG_WB_ENABLE_LSB)
+#define BANK0_CONFIG_WB_ENABLE_SET(x)            (((x) << BANK0_CONFIG_WB_ENABLE_LSB) & BANK0_CONFIG_WB_ENABLE_MASK)
+#define BANK0_CONFIG_WB_FLUSH_MSB                24
+#define BANK0_CONFIG_WB_FLUSH_LSB                24
+#define BANK0_CONFIG_WB_FLUSH_MASK               0x01000000
+#define BANK0_CONFIG_WB_FLUSH_GET(x)             (((x) & BANK0_CONFIG_WB_FLUSH_MASK) >> BANK0_CONFIG_WB_FLUSH_LSB)
+#define BANK0_CONFIG_WB_FLUSH_SET(x)             (((x) << BANK0_CONFIG_WB_FLUSH_LSB) & BANK0_CONFIG_WB_FLUSH_MASK)
+#define BANK0_CONFIG_SCALE_MSB                   21
+#define BANK0_CONFIG_SCALE_LSB                   20
+#define BANK0_CONFIG_SCALE_MASK                  0x00300000
+#define BANK0_CONFIG_SCALE_GET(x)                (((x) & BANK0_CONFIG_SCALE_MASK) >> BANK0_CONFIG_SCALE_LSB)
+#define BANK0_CONFIG_SCALE_SET(x)                (((x) << BANK0_CONFIG_SCALE_LSB) & BANK0_CONFIG_SCALE_MASK)
+#define BANK0_CONFIG_HOLDOFF_MSB                 19
+#define BANK0_CONFIG_HOLDOFF_LSB                 16
+#define BANK0_CONFIG_HOLDOFF_MASK                0x000f0000
+#define BANK0_CONFIG_HOLDOFF_GET(x)              (((x) & BANK0_CONFIG_HOLDOFF_MASK) >> BANK0_CONFIG_HOLDOFF_LSB)
+#define BANK0_CONFIG_HOLDOFF_SET(x)              (((x) << BANK0_CONFIG_HOLDOFF_LSB) & BANK0_CONFIG_HOLDOFF_MASK)
+#define BANK0_CONFIG_TIMER3_MSB                  15
+#define BANK0_CONFIG_TIMER3_LSB                  12
+#define BANK0_CONFIG_TIMER3_MASK                 0x0000f000
+#define BANK0_CONFIG_TIMER3_GET(x)               (((x) & BANK0_CONFIG_TIMER3_MASK) >> BANK0_CONFIG_TIMER3_LSB)
+#define BANK0_CONFIG_TIMER3_SET(x)               (((x) << BANK0_CONFIG_TIMER3_LSB) & BANK0_CONFIG_TIMER3_MASK)
+#define BANK0_CONFIG_TIMER2_MSB                  11
+#define BANK0_CONFIG_TIMER2_LSB                  8
+#define BANK0_CONFIG_TIMER2_MASK                 0x00000f00
+#define BANK0_CONFIG_TIMER2_GET(x)               (((x) & BANK0_CONFIG_TIMER2_MASK) >> BANK0_CONFIG_TIMER2_LSB)
+#define BANK0_CONFIG_TIMER2_SET(x)               (((x) << BANK0_CONFIG_TIMER2_LSB) & BANK0_CONFIG_TIMER2_MASK)
+#define BANK0_CONFIG_TIMER1_MSB                  7
+#define BANK0_CONFIG_TIMER1_LSB                  4
+#define BANK0_CONFIG_TIMER1_MASK                 0x000000f0
+#define BANK0_CONFIG_TIMER1_GET(x)               (((x) & BANK0_CONFIG_TIMER1_MASK) >> BANK0_CONFIG_TIMER1_LSB)
+#define BANK0_CONFIG_TIMER1_SET(x)               (((x) << BANK0_CONFIG_TIMER1_LSB) & BANK0_CONFIG_TIMER1_MASK)
+#define BANK0_CONFIG_TIMER0_MSB                  3
+#define BANK0_CONFIG_TIMER0_LSB                  0
+#define BANK0_CONFIG_TIMER0_MASK                 0x0000000f
+#define BANK0_CONFIG_TIMER0_GET(x)               (((x) & BANK0_CONFIG_TIMER0_MASK) >> BANK0_CONFIG_TIMER0_LSB)
+#define BANK0_CONFIG_TIMER0_SET(x)               (((x) << BANK0_CONFIG_TIMER0_LSB) & BANK0_CONFIG_TIMER0_MASK)
+
+#define BANK0_READ_ADDRESS                       0x0c004008
+#define BANK0_READ_OFFSET                        0x00000008
+#define BANK0_READ_ENABLE_WAIT_MSB               31
+#define BANK0_READ_ENABLE_WAIT_LSB               31
+#define BANK0_READ_ENABLE_WAIT_MASK              0x80000000
+#define BANK0_READ_ENABLE_WAIT_GET(x)            (((x) & BANK0_READ_ENABLE_WAIT_MASK) >> BANK0_READ_ENABLE_WAIT_LSB)
+#define BANK0_READ_ENABLE_WAIT_SET(x)            (((x) << BANK0_READ_ENABLE_WAIT_LSB) & BANK0_READ_ENABLE_WAIT_MASK)
+#define BANK0_READ_WAIT_EVENT_MSB                30
+#define BANK0_READ_WAIT_EVENT_LSB                28
+#define BANK0_READ_WAIT_EVENT_MASK               0x70000000
+#define BANK0_READ_WAIT_EVENT_GET(x)             (((x) & BANK0_READ_WAIT_EVENT_MASK) >> BANK0_READ_WAIT_EVENT_LSB)
+#define BANK0_READ_WAIT_EVENT_SET(x)             (((x) << BANK0_READ_WAIT_EVENT_LSB) & BANK0_READ_WAIT_EVENT_MASK)
+#define BANK0_READ_END_EVENT_MSB                 26
+#define BANK0_READ_END_EVENT_LSB                 24
+#define BANK0_READ_END_EVENT_MASK                0x07000000
+#define BANK0_READ_END_EVENT_GET(x)              (((x) & BANK0_READ_END_EVENT_MASK) >> BANK0_READ_END_EVENT_LSB)
+#define BANK0_READ_END_EVENT_SET(x)              (((x) << BANK0_READ_END_EVENT_LSB) & BANK0_READ_END_EVENT_MASK)
+#define BANK0_READ_BURST_END_EVENT_MSB           22
+#define BANK0_READ_BURST_END_EVENT_LSB           20
+#define BANK0_READ_BURST_END_EVENT_MASK          0x00700000
+#define BANK0_READ_BURST_END_EVENT_GET(x)        (((x) & BANK0_READ_BURST_END_EVENT_MASK) >> BANK0_READ_BURST_END_EVENT_LSB)
+#define BANK0_READ_BURST_END_EVENT_SET(x)        (((x) << BANK0_READ_BURST_END_EVENT_LSB) & BANK0_READ_BURST_END_EVENT_MASK)
+#define BANK0_READ_BURST_START_EVENT_MSB         18
+#define BANK0_READ_BURST_START_EVENT_LSB         16
+#define BANK0_READ_BURST_START_EVENT_MASK        0x00070000
+#define BANK0_READ_BURST_START_EVENT_GET(x)      (((x) & BANK0_READ_BURST_START_EVENT_MASK) >> BANK0_READ_BURST_START_EVENT_LSB)
+#define BANK0_READ_BURST_START_EVENT_SET(x)      (((x) << BANK0_READ_BURST_START_EVENT_LSB) & BANK0_READ_BURST_START_EVENT_MASK)
+#define BANK0_READ_EVENT3_DC_MSB                 15
+#define BANK0_READ_EVENT3_DC_LSB                 15
+#define BANK0_READ_EVENT3_DC_MASK                0x00008000
+#define BANK0_READ_EVENT3_DC_GET(x)              (((x) & BANK0_READ_EVENT3_DC_MASK) >> BANK0_READ_EVENT3_DC_LSB)
+#define BANK0_READ_EVENT3_DC_SET(x)              (((x) << BANK0_READ_EVENT3_DC_LSB) & BANK0_READ_EVENT3_DC_MASK)
+#define BANK0_READ_EVENT3_BE_MSB                 14
+#define BANK0_READ_EVENT3_BE_LSB                 14
+#define BANK0_READ_EVENT3_BE_MASK                0x00004000
+#define BANK0_READ_EVENT3_BE_GET(x)              (((x) & BANK0_READ_EVENT3_BE_MASK) >> BANK0_READ_EVENT3_BE_LSB)
+#define BANK0_READ_EVENT3_BE_SET(x)              (((x) << BANK0_READ_EVENT3_BE_LSB) & BANK0_READ_EVENT3_BE_MASK)
+#define BANK0_READ_EVENT3_OE_MSB                 13
+#define BANK0_READ_EVENT3_OE_LSB                 13
+#define BANK0_READ_EVENT3_OE_MASK                0x00002000
+#define BANK0_READ_EVENT3_OE_GET(x)              (((x) & BANK0_READ_EVENT3_OE_MASK) >> BANK0_READ_EVENT3_OE_LSB)
+#define BANK0_READ_EVENT3_OE_SET(x)              (((x) << BANK0_READ_EVENT3_OE_LSB) & BANK0_READ_EVENT3_OE_MASK)
+#define BANK0_READ_EVENT3_CS_MSB                 12
+#define BANK0_READ_EVENT3_CS_LSB                 12
+#define BANK0_READ_EVENT3_CS_MASK                0x00001000
+#define BANK0_READ_EVENT3_CS_GET(x)              (((x) & BANK0_READ_EVENT3_CS_MASK) >> BANK0_READ_EVENT3_CS_LSB)
+#define BANK0_READ_EVENT3_CS_SET(x)              (((x) << BANK0_READ_EVENT3_CS_LSB) & BANK0_READ_EVENT3_CS_MASK)
+#define BANK0_READ_EVENT2_DC_MSB                 11
+#define BANK0_READ_EVENT2_DC_LSB                 11
+#define BANK0_READ_EVENT2_DC_MASK                0x00000800
+#define BANK0_READ_EVENT2_DC_GET(x)              (((x) & BANK0_READ_EVENT2_DC_MASK) >> BANK0_READ_EVENT2_DC_LSB)
+#define BANK0_READ_EVENT2_DC_SET(x)              (((x) << BANK0_READ_EVENT2_DC_LSB) & BANK0_READ_EVENT2_DC_MASK)
+#define BANK0_READ_EVENT2_BE_MSB                 10
+#define BANK0_READ_EVENT2_BE_LSB                 10
+#define BANK0_READ_EVENT2_BE_MASK                0x00000400
+#define BANK0_READ_EVENT2_BE_GET(x)              (((x) & BANK0_READ_EVENT2_BE_MASK) >> BANK0_READ_EVENT2_BE_LSB)
+#define BANK0_READ_EVENT2_BE_SET(x)              (((x) << BANK0_READ_EVENT2_BE_LSB) & BANK0_READ_EVENT2_BE_MASK)
+#define BANK0_READ_EVENT2_OE_MSB                 9
+#define BANK0_READ_EVENT2_OE_LSB                 9
+#define BANK0_READ_EVENT2_OE_MASK                0x00000200
+#define BANK0_READ_EVENT2_OE_GET(x)              (((x) & BANK0_READ_EVENT2_OE_MASK) >> BANK0_READ_EVENT2_OE_LSB)
+#define BANK0_READ_EVENT2_OE_SET(x)              (((x) << BANK0_READ_EVENT2_OE_LSB) & BANK0_READ_EVENT2_OE_MASK)
+#define BANK0_READ_EVENT2_CS_MSB                 8
+#define BANK0_READ_EVENT2_CS_LSB                 8
+#define BANK0_READ_EVENT2_CS_MASK                0x00000100
+#define BANK0_READ_EVENT2_CS_GET(x)              (((x) & BANK0_READ_EVENT2_CS_MASK) >> BANK0_READ_EVENT2_CS_LSB)
+#define BANK0_READ_EVENT2_CS_SET(x)              (((x) << BANK0_READ_EVENT2_CS_LSB) & BANK0_READ_EVENT2_CS_MASK)
+#define BANK0_READ_EVENT1_DC_MSB                 7
+#define BANK0_READ_EVENT1_DC_LSB                 7
+#define BANK0_READ_EVENT1_DC_MASK                0x00000080
+#define BANK0_READ_EVENT1_DC_GET(x)              (((x) & BANK0_READ_EVENT1_DC_MASK) >> BANK0_READ_EVENT1_DC_LSB)
+#define BANK0_READ_EVENT1_DC_SET(x)              (((x) << BANK0_READ_EVENT1_DC_LSB) & BANK0_READ_EVENT1_DC_MASK)
+#define BANK0_READ_EVENT1_BE_MSB                 6
+#define BANK0_READ_EVENT1_BE_LSB                 6
+#define BANK0_READ_EVENT1_BE_MASK                0x00000040
+#define BANK0_READ_EVENT1_BE_GET(x)              (((x) & BANK0_READ_EVENT1_BE_MASK) >> BANK0_READ_EVENT1_BE_LSB)
+#define BANK0_READ_EVENT1_BE_SET(x)              (((x) << BANK0_READ_EVENT1_BE_LSB) & BANK0_READ_EVENT1_BE_MASK)
+#define BANK0_READ_EVENT1_OE_MSB                 5
+#define BANK0_READ_EVENT1_OE_LSB                 5
+#define BANK0_READ_EVENT1_OE_MASK                0x00000020
+#define BANK0_READ_EVENT1_OE_GET(x)              (((x) & BANK0_READ_EVENT1_OE_MASK) >> BANK0_READ_EVENT1_OE_LSB)
+#define BANK0_READ_EVENT1_OE_SET(x)              (((x) << BANK0_READ_EVENT1_OE_LSB) & BANK0_READ_EVENT1_OE_MASK)
+#define BANK0_READ_EVENT1_CS_MSB                 4
+#define BANK0_READ_EVENT1_CS_LSB                 4
+#define BANK0_READ_EVENT1_CS_MASK                0x00000010
+#define BANK0_READ_EVENT1_CS_GET(x)              (((x) & BANK0_READ_EVENT1_CS_MASK) >> BANK0_READ_EVENT1_CS_LSB)
+#define BANK0_READ_EVENT1_CS_SET(x)              (((x) << BANK0_READ_EVENT1_CS_LSB) & BANK0_READ_EVENT1_CS_MASK)
+#define BANK0_READ_EVENT0_DC_MSB                 3
+#define BANK0_READ_EVENT0_DC_LSB                 3
+#define BANK0_READ_EVENT0_DC_MASK                0x00000008
+#define BANK0_READ_EVENT0_DC_GET(x)              (((x) & BANK0_READ_EVENT0_DC_MASK) >> BANK0_READ_EVENT0_DC_LSB)
+#define BANK0_READ_EVENT0_DC_SET(x)              (((x) << BANK0_READ_EVENT0_DC_LSB) & BANK0_READ_EVENT0_DC_MASK)
+#define BANK0_READ_EVENT0_BE_MSB                 2
+#define BANK0_READ_EVENT0_BE_LSB                 2
+#define BANK0_READ_EVENT0_BE_MASK                0x00000004
+#define BANK0_READ_EVENT0_BE_GET(x)              (((x) & BANK0_READ_EVENT0_BE_MASK) >> BANK0_READ_EVENT0_BE_LSB)
+#define BANK0_READ_EVENT0_BE_SET(x)              (((x) << BANK0_READ_EVENT0_BE_LSB) & BANK0_READ_EVENT0_BE_MASK)
+#define BANK0_READ_EVENT0_OE_MSB                 1
+#define BANK0_READ_EVENT0_OE_LSB                 1
+#define BANK0_READ_EVENT0_OE_MASK                0x00000002
+#define BANK0_READ_EVENT0_OE_GET(x)              (((x) & BANK0_READ_EVENT0_OE_MASK) >> BANK0_READ_EVENT0_OE_LSB)
+#define BANK0_READ_EVENT0_OE_SET(x)              (((x) << BANK0_READ_EVENT0_OE_LSB) & BANK0_READ_EVENT0_OE_MASK)
+#define BANK0_READ_EVENT0_CS_MSB                 0
+#define BANK0_READ_EVENT0_CS_LSB                 0
+#define BANK0_READ_EVENT0_CS_MASK                0x00000001
+#define BANK0_READ_EVENT0_CS_GET(x)              (((x) & BANK0_READ_EVENT0_CS_MASK) >> BANK0_READ_EVENT0_CS_LSB)
+#define BANK0_READ_EVENT0_CS_SET(x)              (((x) << BANK0_READ_EVENT0_CS_LSB) & BANK0_READ_EVENT0_CS_MASK)
+
+#define BANK0_WRITE_ADDRESS                      0x0c00400c
+#define BANK0_WRITE_OFFSET                       0x0000000c
+#define BANK0_WRITE_ENABLE_WAIT_MSB              31
+#define BANK0_WRITE_ENABLE_WAIT_LSB              31
+#define BANK0_WRITE_ENABLE_WAIT_MASK             0x80000000
+#define BANK0_WRITE_ENABLE_WAIT_GET(x)           (((x) & BANK0_WRITE_ENABLE_WAIT_MASK) >> BANK0_WRITE_ENABLE_WAIT_LSB)
+#define BANK0_WRITE_ENABLE_WAIT_SET(x)           (((x) << BANK0_WRITE_ENABLE_WAIT_LSB) & BANK0_WRITE_ENABLE_WAIT_MASK)
+#define BANK0_WRITE_WAIT_EVENT_MSB               30
+#define BANK0_WRITE_WAIT_EVENT_LSB               28
+#define BANK0_WRITE_WAIT_EVENT_MASK              0x70000000
+#define BANK0_WRITE_WAIT_EVENT_GET(x)            (((x) & BANK0_WRITE_WAIT_EVENT_MASK) >> BANK0_WRITE_WAIT_EVENT_LSB)
+#define BANK0_WRITE_WAIT_EVENT_SET(x)            (((x) << BANK0_WRITE_WAIT_EVENT_LSB) & BANK0_WRITE_WAIT_EVENT_MASK)
+#define BANK0_WRITE_END_EVENT_MSB                26
+#define BANK0_WRITE_END_EVENT_LSB                24
+#define BANK0_WRITE_END_EVENT_MASK               0x07000000
+#define BANK0_WRITE_END_EVENT_GET(x)             (((x) & BANK0_WRITE_END_EVENT_MASK) >> BANK0_WRITE_END_EVENT_LSB)
+#define BANK0_WRITE_END_EVENT_SET(x)             (((x) << BANK0_WRITE_END_EVENT_LSB) & BANK0_WRITE_END_EVENT_MASK)
+#define BANK0_WRITE_BURST_END_EVENT_MSB          22
+#define BANK0_WRITE_BURST_END_EVENT_LSB          20
+#define BANK0_WRITE_BURST_END_EVENT_MASK         0x00700000
+#define BANK0_WRITE_BURST_END_EVENT_GET(x)       (((x) & BANK0_WRITE_BURST_END_EVENT_MASK) >> BANK0_WRITE_BURST_END_EVENT_LSB)
+#define BANK0_WRITE_BURST_END_EVENT_SET(x)       (((x) << BANK0_WRITE_BURST_END_EVENT_LSB) & BANK0_WRITE_BURST_END_EVENT_MASK)
+#define BANK0_WRITE_BURST_START_EVENT_MSB        18
+#define BANK0_WRITE_BURST_START_EVENT_LSB        16
+#define BANK0_WRITE_BURST_START_EVENT_MASK       0x00070000
+#define BANK0_WRITE_BURST_START_EVENT_GET(x)     (((x) & BANK0_WRITE_BURST_START_EVENT_MASK) >> BANK0_WRITE_BURST_START_EVENT_LSB)
+#define BANK0_WRITE_BURST_START_EVENT_SET(x)     (((x) << BANK0_WRITE_BURST_START_EVENT_LSB) & BANK0_WRITE_BURST_START_EVENT_MASK)
+#define BANK0_WRITE_EVENT3_BE_MSB                14
+#define BANK0_WRITE_EVENT3_BE_LSB                14
+#define BANK0_WRITE_EVENT3_BE_MASK               0x00004000
+#define BANK0_WRITE_EVENT3_BE_GET(x)             (((x) & BANK0_WRITE_EVENT3_BE_MASK) >> BANK0_WRITE_EVENT3_BE_LSB)
+#define BANK0_WRITE_EVENT3_BE_SET(x)             (((x) << BANK0_WRITE_EVENT3_BE_LSB) & BANK0_WRITE_EVENT3_BE_MASK)
+#define BANK0_WRITE_EVENT3_WE_MSB                13
+#define BANK0_WRITE_EVENT3_WE_LSB                13
+#define BANK0_WRITE_EVENT3_WE_MASK               0x00002000
+#define BANK0_WRITE_EVENT3_WE_GET(x)             (((x) & BANK0_WRITE_EVENT3_WE_MASK) >> BANK0_WRITE_EVENT3_WE_LSB)
+#define BANK0_WRITE_EVENT3_WE_SET(x)             (((x) << BANK0_WRITE_EVENT3_WE_LSB) & BANK0_WRITE_EVENT3_WE_MASK)
+#define BANK0_WRITE_EVENT3_CS_MSB                12
+#define BANK0_WRITE_EVENT3_CS_LSB                12
+#define BANK0_WRITE_EVENT3_CS_MASK               0x00001000
+#define BANK0_WRITE_EVENT3_CS_GET(x)             (((x) & BANK0_WRITE_EVENT3_CS_MASK) >> BANK0_WRITE_EVENT3_CS_LSB)
+#define BANK0_WRITE_EVENT3_CS_SET(x)             (((x) << BANK0_WRITE_EVENT3_CS_LSB) & BANK0_WRITE_EVENT3_CS_MASK)
+#define BANK0_WRITE_EVENT2_BE_MSB                10
+#define BANK0_WRITE_EVENT2_BE_LSB                10
+#define BANK0_WRITE_EVENT2_BE_MASK               0x00000400
+#define BANK0_WRITE_EVENT2_BE_GET(x)             (((x) & BANK0_WRITE_EVENT2_BE_MASK) >> BANK0_WRITE_EVENT2_BE_LSB)
+#define BANK0_WRITE_EVENT2_BE_SET(x)             (((x) << BANK0_WRITE_EVENT2_BE_LSB) & BANK0_WRITE_EVENT2_BE_MASK)
+#define BANK0_WRITE_EVENT2_WE_MSB                9
+#define BANK0_WRITE_EVENT2_WE_LSB                9
+#define BANK0_WRITE_EVENT2_WE_MASK               0x00000200
+#define BANK0_WRITE_EVENT2_WE_GET(x)             (((x) & BANK0_WRITE_EVENT2_WE_MASK) >> BANK0_WRITE_EVENT2_WE_LSB)
+#define BANK0_WRITE_EVENT2_WE_SET(x)             (((x) << BANK0_WRITE_EVENT2_WE_LSB) & BANK0_WRITE_EVENT2_WE_MASK)
+#define BANK0_WRITE_EVENT2_CS_MSB                8
+#define BANK0_WRITE_EVENT2_CS_LSB                8
+#define BANK0_WRITE_EVENT2_CS_MASK               0x00000100
+#define BANK0_WRITE_EVENT2_CS_GET(x)             (((x) & BANK0_WRITE_EVENT2_CS_MASK) >> BANK0_WRITE_EVENT2_CS_LSB)
+#define BANK0_WRITE_EVENT2_CS_SET(x)             (((x) << BANK0_WRITE_EVENT2_CS_LSB) & BANK0_WRITE_EVENT2_CS_MASK)
+#define BANK0_WRITE_EVENT1_BE_MSB                6
+#define BANK0_WRITE_EVENT1_BE_LSB                6
+#define BANK0_WRITE_EVENT1_BE_MASK               0x00000040
+#define BANK0_WRITE_EVENT1_BE_GET(x)             (((x) & BANK0_WRITE_EVENT1_BE_MASK) >> BANK0_WRITE_EVENT1_BE_LSB)
+#define BANK0_WRITE_EVENT1_BE_SET(x)             (((x) << BANK0_WRITE_EVENT1_BE_LSB) & BANK0_WRITE_EVENT1_BE_MASK)
+#define BANK0_WRITE_EVENT1_WE_MSB                5
+#define BANK0_WRITE_EVENT1_WE_LSB                5
+#define BANK0_WRITE_EVENT1_WE_MASK               0x00000020
+#define BANK0_WRITE_EVENT1_WE_GET(x)             (((x) & BANK0_WRITE_EVENT1_WE_MASK) >> BANK0_WRITE_EVENT1_WE_LSB)
+#define BANK0_WRITE_EVENT1_WE_SET(x)             (((x) << BANK0_WRITE_EVENT1_WE_LSB) & BANK0_WRITE_EVENT1_WE_MASK)
+#define BANK0_WRITE_EVENT1_CS_MSB                4
+#define BANK0_WRITE_EVENT1_CS_LSB                4
+#define BANK0_WRITE_EVENT1_CS_MASK               0x00000010
+#define BANK0_WRITE_EVENT1_CS_GET(x)             (((x) & BANK0_WRITE_EVENT1_CS_MASK) >> BANK0_WRITE_EVENT1_CS_LSB)
+#define BANK0_WRITE_EVENT1_CS_SET(x)             (((x) << BANK0_WRITE_EVENT1_CS_LSB) & BANK0_WRITE_EVENT1_CS_MASK)
+#define BANK0_WRITE_EVENT0_BE_MSB                2
+#define BANK0_WRITE_EVENT0_BE_LSB                2
+#define BANK0_WRITE_EVENT0_BE_MASK               0x00000004
+#define BANK0_WRITE_EVENT0_BE_GET(x)             (((x) & BANK0_WRITE_EVENT0_BE_MASK) >> BANK0_WRITE_EVENT0_BE_LSB)
+#define BANK0_WRITE_EVENT0_BE_SET(x)             (((x) << BANK0_WRITE_EVENT0_BE_LSB) & BANK0_WRITE_EVENT0_BE_MASK)
+#define BANK0_WRITE_EVENT0_WE_MSB                1
+#define BANK0_WRITE_EVENT0_WE_LSB                1
+#define BANK0_WRITE_EVENT0_WE_MASK               0x00000002
+#define BANK0_WRITE_EVENT0_WE_GET(x)             (((x) & BANK0_WRITE_EVENT0_WE_MASK) >> BANK0_WRITE_EVENT0_WE_LSB)
+#define BANK0_WRITE_EVENT0_WE_SET(x)             (((x) << BANK0_WRITE_EVENT0_WE_LSB) & BANK0_WRITE_EVENT0_WE_MASK)
+#define BANK0_WRITE_EVENT0_CS_MSB                0
+#define BANK0_WRITE_EVENT0_CS_LSB                0
+#define BANK0_WRITE_EVENT0_CS_MASK               0x00000001
+#define BANK0_WRITE_EVENT0_CS_GET(x)             (((x) & BANK0_WRITE_EVENT0_CS_MASK) >> BANK0_WRITE_EVENT0_CS_LSB)
+#define BANK0_WRITE_EVENT0_CS_SET(x)             (((x) << BANK0_WRITE_EVENT0_CS_LSB) & BANK0_WRITE_EVENT0_CS_MASK)
+
+#define BANK1_ADDR_ADDRESS                       0x0c004010
+#define BANK1_ADDR_OFFSET                        0x00000010
+#define BANK1_ADDR_SIZE_MSB                      31
+#define BANK1_ADDR_SIZE_LSB                      28
+#define BANK1_ADDR_SIZE_MASK                     0xf0000000
+#define BANK1_ADDR_SIZE_GET(x)                   (((x) & BANK1_ADDR_SIZE_MASK) >> BANK1_ADDR_SIZE_LSB)
+#define BANK1_ADDR_SIZE_SET(x)                   (((x) << BANK1_ADDR_SIZE_LSB) & BANK1_ADDR_SIZE_MASK)
+#define BANK1_ADDR_BASE_MSB                      27
+#define BANK1_ADDR_BASE_LSB                      10
+#define BANK1_ADDR_BASE_MASK                     0x0ffffc00
+#define BANK1_ADDR_BASE_GET(x)                   (((x) & BANK1_ADDR_BASE_MASK) >> BANK1_ADDR_BASE_LSB)
+#define BANK1_ADDR_BASE_SET(x)                   (((x) << BANK1_ADDR_BASE_LSB) & BANK1_ADDR_BASE_MASK)
+
+#define BANK1_CONFIG_ADDRESS                     0x0c004014
+#define BANK1_CONFIG_OFFSET                      0x00000014
+#define BANK1_CONFIG_ENABLE_MSB                  31
+#define BANK1_CONFIG_ENABLE_LSB                  31
+#define BANK1_CONFIG_ENABLE_MASK                 0x80000000
+#define BANK1_CONFIG_ENABLE_GET(x)               (((x) & BANK1_CONFIG_ENABLE_MASK) >> BANK1_CONFIG_ENABLE_LSB)
+#define BANK1_CONFIG_ENABLE_SET(x)               (((x) << BANK1_CONFIG_ENABLE_LSB) & BANK1_CONFIG_ENABLE_MASK)
+#define BANK1_CONFIG_WIDTH_MSB                   28
+#define BANK1_CONFIG_WIDTH_LSB                   28
+#define BANK1_CONFIG_WIDTH_MASK                  0x10000000
+#define BANK1_CONFIG_WIDTH_GET(x)                (((x) & BANK1_CONFIG_WIDTH_MASK) >> BANK1_CONFIG_WIDTH_LSB)
+#define BANK1_CONFIG_WIDTH_SET(x)                (((x) << BANK1_CONFIG_WIDTH_LSB) & BANK1_CONFIG_WIDTH_MASK)
+#define BANK1_CONFIG_PROTECT_MSB                 26
+#define BANK1_CONFIG_PROTECT_LSB                 26
+#define BANK1_CONFIG_PROTECT_MASK                0x04000000
+#define BANK1_CONFIG_PROTECT_GET(x)              (((x) & BANK1_CONFIG_PROTECT_MASK) >> BANK1_CONFIG_PROTECT_LSB)
+#define BANK1_CONFIG_PROTECT_SET(x)              (((x) << BANK1_CONFIG_PROTECT_LSB) & BANK1_CONFIG_PROTECT_MASK)
+#define BANK1_CONFIG_WB_ENABLE_MSB               25
+#define BANK1_CONFIG_WB_ENABLE_LSB               25
+#define BANK1_CONFIG_WB_ENABLE_MASK              0x02000000
+#define BANK1_CONFIG_WB_ENABLE_GET(x)            (((x) & BANK1_CONFIG_WB_ENABLE_MASK) >> BANK1_CONFIG_WB_ENABLE_LSB)
+#define BANK1_CONFIG_WB_ENABLE_SET(x)            (((x) << BANK1_CONFIG_WB_ENABLE_LSB) & BANK1_CONFIG_WB_ENABLE_MASK)
+#define BANK1_CONFIG_WB_FLUSH_MSB                24
+#define BANK1_CONFIG_WB_FLUSH_LSB                24
+#define BANK1_CONFIG_WB_FLUSH_MASK               0x01000000
+#define BANK1_CONFIG_WB_FLUSH_GET(x)             (((x) & BANK1_CONFIG_WB_FLUSH_MASK) >> BANK1_CONFIG_WB_FLUSH_LSB)
+#define BANK1_CONFIG_WB_FLUSH_SET(x)             (((x) << BANK1_CONFIG_WB_FLUSH_LSB) & BANK1_CONFIG_WB_FLUSH_MASK)
+#define BANK1_CONFIG_SCALE_MSB                   21
+#define BANK1_CONFIG_SCALE_LSB                   20
+#define BANK1_CONFIG_SCALE_MASK                  0x00300000
+#define BANK1_CONFIG_SCALE_GET(x)                (((x) & BANK1_CONFIG_SCALE_MASK) >> BANK1_CONFIG_SCALE_LSB)
+#define BANK1_CONFIG_SCALE_SET(x)                (((x) << BANK1_CONFIG_SCALE_LSB) & BANK1_CONFIG_SCALE_MASK)
+#define BANK1_CONFIG_HOLDOFF_MSB                 19
+#define BANK1_CONFIG_HOLDOFF_LSB                 16
+#define BANK1_CONFIG_HOLDOFF_MASK                0x000f0000
+#define BANK1_CONFIG_HOLDOFF_GET(x)              (((x) & BANK1_CONFIG_HOLDOFF_MASK) >> BANK1_CONFIG_HOLDOFF_LSB)
+#define BANK1_CONFIG_HOLDOFF_SET(x)              (((x) << BANK1_CONFIG_HOLDOFF_LSB) & BANK1_CONFIG_HOLDOFF_MASK)
+#define BANK1_CONFIG_TIMER3_MSB                  15
+#define BANK1_CONFIG_TIMER3_LSB                  12
+#define BANK1_CONFIG_TIMER3_MASK                 0x0000f000
+#define BANK1_CONFIG_TIMER3_GET(x)               (((x) & BANK1_CONFIG_TIMER3_MASK) >> BANK1_CONFIG_TIMER3_LSB)
+#define BANK1_CONFIG_TIMER3_SET(x)               (((x) << BANK1_CONFIG_TIMER3_LSB) & BANK1_CONFIG_TIMER3_MASK)
+#define BANK1_CONFIG_TIMER2_MSB                  11
+#define BANK1_CONFIG_TIMER2_LSB                  8
+#define BANK1_CONFIG_TIMER2_MASK                 0x00000f00
+#define BANK1_CONFIG_TIMER2_GET(x)               (((x) & BANK1_CONFIG_TIMER2_MASK) >> BANK1_CONFIG_TIMER2_LSB)
+#define BANK1_CONFIG_TIMER2_SET(x)               (((x) << BANK1_CONFIG_TIMER2_LSB) & BANK1_CONFIG_TIMER2_MASK)
+#define BANK1_CONFIG_TIMER1_MSB                  7
+#define BANK1_CONFIG_TIMER1_LSB                  4
+#define BANK1_CONFIG_TIMER1_MASK                 0x000000f0
+#define BANK1_CONFIG_TIMER1_GET(x)               (((x) & BANK1_CONFIG_TIMER1_MASK) >> BANK1_CONFIG_TIMER1_LSB)
+#define BANK1_CONFIG_TIMER1_SET(x)               (((x) << BANK1_CONFIG_TIMER1_LSB) & BANK1_CONFIG_TIMER1_MASK)
+#define BANK1_CONFIG_TIMER0_MSB                  3
+#define BANK1_CONFIG_TIMER0_LSB                  0
+#define BANK1_CONFIG_TIMER0_MASK                 0x0000000f
+#define BANK1_CONFIG_TIMER0_GET(x)               (((x) & BANK1_CONFIG_TIMER0_MASK) >> BANK1_CONFIG_TIMER0_LSB)
+#define BANK1_CONFIG_TIMER0_SET(x)               (((x) << BANK1_CONFIG_TIMER0_LSB) & BANK1_CONFIG_TIMER0_MASK)
+
+#define BANK1_READ_ADDRESS                       0x0c004018
+#define BANK1_READ_OFFSET                        0x00000018
+#define BANK1_READ_ENABLE_WAIT_MSB               31
+#define BANK1_READ_ENABLE_WAIT_LSB               31
+#define BANK1_READ_ENABLE_WAIT_MASK              0x80000000
+#define BANK1_READ_ENABLE_WAIT_GET(x)            (((x) & BANK1_READ_ENABLE_WAIT_MASK) >> BANK1_READ_ENABLE_WAIT_LSB)
+#define BANK1_READ_ENABLE_WAIT_SET(x)            (((x) << BANK1_READ_ENABLE_WAIT_LSB) & BANK1_READ_ENABLE_WAIT_MASK)
+#define BANK1_READ_WAIT_EVENT_MSB                30
+#define BANK1_READ_WAIT_EVENT_LSB                28
+#define BANK1_READ_WAIT_EVENT_MASK               0x70000000
+#define BANK1_READ_WAIT_EVENT_GET(x)             (((x) & BANK1_READ_WAIT_EVENT_MASK) >> BANK1_READ_WAIT_EVENT_LSB)
+#define BANK1_READ_WAIT_EVENT_SET(x)             (((x) << BANK1_READ_WAIT_EVENT_LSB) & BANK1_READ_WAIT_EVENT_MASK)
+#define BANK1_READ_END_EVENT_MSB                 26
+#define BANK1_READ_END_EVENT_LSB                 24
+#define BANK1_READ_END_EVENT_MASK                0x07000000
+#define BANK1_READ_END_EVENT_GET(x)              (((x) & BANK1_READ_END_EVENT_MASK) >> BANK1_READ_END_EVENT_LSB)
+#define BANK1_READ_END_EVENT_SET(x)              (((x) << BANK1_READ_END_EVENT_LSB) & BANK1_READ_END_EVENT_MASK)
+#define BANK1_READ_BURST_END_EVENT_MSB           22
+#define BANK1_READ_BURST_END_EVENT_LSB           20
+#define BANK1_READ_BURST_END_EVENT_MASK          0x00700000
+#define BANK1_READ_BURST_END_EVENT_GET(x)        (((x) & BANK1_READ_BURST_END_EVENT_MASK) >> BANK1_READ_BURST_END_EVENT_LSB)
+#define BANK1_READ_BURST_END_EVENT_SET(x)        (((x) << BANK1_READ_BURST_END_EVENT_LSB) & BANK1_READ_BURST_END_EVENT_MASK)
+#define BANK1_READ_BURST_START_EVENT_MSB         18
+#define BANK1_READ_BURST_START_EVENT_LSB         16
+#define BANK1_READ_BURST_START_EVENT_MASK        0x00070000
+#define BANK1_READ_BURST_START_EVENT_GET(x)      (((x) & BANK1_READ_BURST_START_EVENT_MASK) >> BANK1_READ_BURST_START_EVENT_LSB)
+#define BANK1_READ_BURST_START_EVENT_SET(x)      (((x) << BANK1_READ_BURST_START_EVENT_LSB) & BANK1_READ_BURST_START_EVENT_MASK)
+#define BANK1_READ_EVENT3_DC_MSB                 15
+#define BANK1_READ_EVENT3_DC_LSB                 15
+#define BANK1_READ_EVENT3_DC_MASK                0x00008000
+#define BANK1_READ_EVENT3_DC_GET(x)              (((x) & BANK1_READ_EVENT3_DC_MASK) >> BANK1_READ_EVENT3_DC_LSB)
+#define BANK1_READ_EVENT3_DC_SET(x)              (((x) << BANK1_READ_EVENT3_DC_LSB) & BANK1_READ_EVENT3_DC_MASK)
+#define BANK1_READ_EVENT3_BE_MSB                 14
+#define BANK1_READ_EVENT3_BE_LSB                 14
+#define BANK1_READ_EVENT3_BE_MASK                0x00004000
+#define BANK1_READ_EVENT3_BE_GET(x)              (((x) & BANK1_READ_EVENT3_BE_MASK) >> BANK1_READ_EVENT3_BE_LSB)
+#define BANK1_READ_EVENT3_BE_SET(x)              (((x) << BANK1_READ_EVENT3_BE_LSB) & BANK1_READ_EVENT3_BE_MASK)
+#define BANK1_READ_EVENT3_OE_MSB                 13
+#define BANK1_READ_EVENT3_OE_LSB                 13
+#define BANK1_READ_EVENT3_OE_MASK                0x00002000
+#define BANK1_READ_EVENT3_OE_GET(x)              (((x) & BANK1_READ_EVENT3_OE_MASK) >> BANK1_READ_EVENT3_OE_LSB)
+#define BANK1_READ_EVENT3_OE_SET(x)              (((x) << BANK1_READ_EVENT3_OE_LSB) & BANK1_READ_EVENT3_OE_MASK)
+#define BANK1_READ_EVENT3_CS_MSB                 12
+#define BANK1_READ_EVENT3_CS_LSB                 12
+#define BANK1_READ_EVENT3_CS_MASK                0x00001000
+#define BANK1_READ_EVENT3_CS_GET(x)              (((x) & BANK1_READ_EVENT3_CS_MASK) >> BANK1_READ_EVENT3_CS_LSB)
+#define BANK1_READ_EVENT3_CS_SET(x)              (((x) << BANK1_READ_EVENT3_CS_LSB) & BANK1_READ_EVENT3_CS_MASK)
+#define BANK1_READ_EVENT2_DC_MSB                 11
+#define BANK1_READ_EVENT2_DC_LSB                 11
+#define BANK1_READ_EVENT2_DC_MASK                0x00000800
+#define BANK1_READ_EVENT2_DC_GET(x)              (((x) & BANK1_READ_EVENT2_DC_MASK) >> BANK1_READ_EVENT2_DC_LSB)
+#define BANK1_READ_EVENT2_DC_SET(x)              (((x) << BANK1_READ_EVENT2_DC_LSB) & BANK1_READ_EVENT2_DC_MASK)
+#define BANK1_READ_EVENT2_BE_MSB                 10
+#define BANK1_READ_EVENT2_BE_LSB                 10
+#define BANK1_READ_EVENT2_BE_MASK                0x00000400
+#define BANK1_READ_EVENT2_BE_GET(x)              (((x) & BANK1_READ_EVENT2_BE_MASK) >> BANK1_READ_EVENT2_BE_LSB)
+#define BANK1_READ_EVENT2_BE_SET(x)              (((x) << BANK1_READ_EVENT2_BE_LSB) & BANK1_READ_EVENT2_BE_MASK)
+#define BANK1_READ_EVENT2_OE_MSB                 9
+#define BANK1_READ_EVENT2_OE_LSB                 9
+#define BANK1_READ_EVENT2_OE_MASK                0x00000200
+#define BANK1_READ_EVENT2_OE_GET(x)              (((x) & BANK1_READ_EVENT2_OE_MASK) >> BANK1_READ_EVENT2_OE_LSB)
+#define BANK1_READ_EVENT2_OE_SET(x)              (((x) << BANK1_READ_EVENT2_OE_LSB) & BANK1_READ_EVENT2_OE_MASK)
+#define BANK1_READ_EVENT2_CS_MSB                 8
+#define BANK1_READ_EVENT2_CS_LSB                 8
+#define BANK1_READ_EVENT2_CS_MASK                0x00000100
+#define BANK1_READ_EVENT2_CS_GET(x)              (((x) & BANK1_READ_EVENT2_CS_MASK) >> BANK1_READ_EVENT2_CS_LSB)
+#define BANK1_READ_EVENT2_CS_SET(x)              (((x) << BANK1_READ_EVENT2_CS_LSB) & BANK1_READ_EVENT2_CS_MASK)
+#define BANK1_READ_EVENT1_DC_MSB                 7
+#define BANK1_READ_EVENT1_DC_LSB                 7
+#define BANK1_READ_EVENT1_DC_MASK                0x00000080
+#define BANK1_READ_EVENT1_DC_GET(x)              (((x) & BANK1_READ_EVENT1_DC_MASK) >> BANK1_READ_EVENT1_DC_LSB)
+#define BANK1_READ_EVENT1_DC_SET(x)              (((x) << BANK1_READ_EVENT1_DC_LSB) & BANK1_READ_EVENT1_DC_MASK)
+#define BANK1_READ_EVENT1_BE_MSB                 6
+#define BANK1_READ_EVENT1_BE_LSB                 6
+#define BANK1_READ_EVENT1_BE_MASK                0x00000040
+#define BANK1_READ_EVENT1_BE_GET(x)              (((x) & BANK1_READ_EVENT1_BE_MASK) >> BANK1_READ_EVENT1_BE_LSB)
+#define BANK1_READ_EVENT1_BE_SET(x)              (((x) << BANK1_READ_EVENT1_BE_LSB) & BANK1_READ_EVENT1_BE_MASK)
+#define BANK1_READ_EVENT1_OE_MSB                 5
+#define BANK1_READ_EVENT1_OE_LSB                 5
+#define BANK1_READ_EVENT1_OE_MASK                0x00000020
+#define BANK1_READ_EVENT1_OE_GET(x)              (((x) & BANK1_READ_EVENT1_OE_MASK) >> BANK1_READ_EVENT1_OE_LSB)
+#define BANK1_READ_EVENT1_OE_SET(x)              (((x) << BANK1_READ_EVENT1_OE_LSB) & BANK1_READ_EVENT1_OE_MASK)
+#define BANK1_READ_EVENT1_CS_MSB                 4
+#define BANK1_READ_EVENT1_CS_LSB                 4
+#define BANK1_READ_EVENT1_CS_MASK                0x00000010
+#define BANK1_READ_EVENT1_CS_GET(x)              (((x) & BANK1_READ_EVENT1_CS_MASK) >> BANK1_READ_EVENT1_CS_LSB)
+#define BANK1_READ_EVENT1_CS_SET(x)              (((x) << BANK1_READ_EVENT1_CS_LSB) & BANK1_READ_EVENT1_CS_MASK)
+#define BANK1_READ_EVENT0_DC_MSB                 3
+#define BANK1_READ_EVENT0_DC_LSB                 3
+#define BANK1_READ_EVENT0_DC_MASK                0x00000008
+#define BANK1_READ_EVENT0_DC_GET(x)              (((x) & BANK1_READ_EVENT0_DC_MASK) >> BANK1_READ_EVENT0_DC_LSB)
+#define BANK1_READ_EVENT0_DC_SET(x)              (((x) << BANK1_READ_EVENT0_DC_LSB) & BANK1_READ_EVENT0_DC_MASK)
+#define BANK1_READ_EVENT0_BE_MSB                 2
+#define BANK1_READ_EVENT0_BE_LSB                 2
+#define BANK1_READ_EVENT0_BE_MASK                0x00000004
+#define BANK1_READ_EVENT0_BE_GET(x)              (((x) & BANK1_READ_EVENT0_BE_MASK) >> BANK1_READ_EVENT0_BE_LSB)
+#define BANK1_READ_EVENT0_BE_SET(x)              (((x) << BANK1_READ_EVENT0_BE_LSB) & BANK1_READ_EVENT0_BE_MASK)
+#define BANK1_READ_EVENT0_OE_MSB                 1
+#define BANK1_READ_EVENT0_OE_LSB                 1
+#define BANK1_READ_EVENT0_OE_MASK                0x00000002
+#define BANK1_READ_EVENT0_OE_GET(x)              (((x) & BANK1_READ_EVENT0_OE_MASK) >> BANK1_READ_EVENT0_OE_LSB)
+#define BANK1_READ_EVENT0_OE_SET(x)              (((x) << BANK1_READ_EVENT0_OE_LSB) & BANK1_READ_EVENT0_OE_MASK)
+#define BANK1_READ_EVENT0_CS_MSB                 0
+#define BANK1_READ_EVENT0_CS_LSB                 0
+#define BANK1_READ_EVENT0_CS_MASK                0x00000001
+#define BANK1_READ_EVENT0_CS_GET(x)              (((x) & BANK1_READ_EVENT0_CS_MASK) >> BANK1_READ_EVENT0_CS_LSB)
+#define BANK1_READ_EVENT0_CS_SET(x)              (((x) << BANK1_READ_EVENT0_CS_LSB) & BANK1_READ_EVENT0_CS_MASK)
+
+#define BANK1_WRITE_ADDRESS                      0x0c00401c
+#define BANK1_WRITE_OFFSET                       0x0000001c
+#define BANK1_WRITE_ENABLE_WAIT_MSB              31
+#define BANK1_WRITE_ENABLE_WAIT_LSB              31
+#define BANK1_WRITE_ENABLE_WAIT_MASK             0x80000000
+#define BANK1_WRITE_ENABLE_WAIT_GET(x)           (((x) & BANK1_WRITE_ENABLE_WAIT_MASK) >> BANK1_WRITE_ENABLE_WAIT_LSB)
+#define BANK1_WRITE_ENABLE_WAIT_SET(x)           (((x) << BANK1_WRITE_ENABLE_WAIT_LSB) & BANK1_WRITE_ENABLE_WAIT_MASK)
+#define BANK1_WRITE_WAIT_EVENT_MSB               30
+#define BANK1_WRITE_WAIT_EVENT_LSB               28
+#define BANK1_WRITE_WAIT_EVENT_MASK              0x70000000
+#define BANK1_WRITE_WAIT_EVENT_GET(x)            (((x) & BANK1_WRITE_WAIT_EVENT_MASK) >> BANK1_WRITE_WAIT_EVENT_LSB)
+#define BANK1_WRITE_WAIT_EVENT_SET(x)            (((x) << BANK1_WRITE_WAIT_EVENT_LSB) & BANK1_WRITE_WAIT_EVENT_MASK)
+#define BANK1_WRITE_END_EVENT_MSB                26
+#define BANK1_WRITE_END_EVENT_LSB                24
+#define BANK1_WRITE_END_EVENT_MASK               0x07000000
+#define BANK1_WRITE_END_EVENT_GET(x)             (((x) & BANK1_WRITE_END_EVENT_MASK) >> BANK1_WRITE_END_EVENT_LSB)
+#define BANK1_WRITE_END_EVENT_SET(x)             (((x) << BANK1_WRITE_END_EVENT_LSB) & BANK1_WRITE_END_EVENT_MASK)
+#define BANK1_WRITE_BURST_END_EVENT_MSB          22
+#define BANK1_WRITE_BURST_END_EVENT_LSB          20
+#define BANK1_WRITE_BURST_END_EVENT_MASK         0x00700000
+#define BANK1_WRITE_BURST_END_EVENT_GET(x)       (((x) & BANK1_WRITE_BURST_END_EVENT_MASK) >> BANK1_WRITE_BURST_END_EVENT_LSB)
+#define BANK1_WRITE_BURST_END_EVENT_SET(x)       (((x) << BANK1_WRITE_BURST_END_EVENT_LSB) & BANK1_WRITE_BURST_END_EVENT_MASK)
+#define BANK1_WRITE_BURST_START_EVENT_MSB        18
+#define BANK1_WRITE_BURST_START_EVENT_LSB        16
+#define BANK1_WRITE_BURST_START_EVENT_MASK       0x00070000
+#define BANK1_WRITE_BURST_START_EVENT_GET(x)     (((x) & BANK1_WRITE_BURST_START_EVENT_MASK) >> BANK1_WRITE_BURST_START_EVENT_LSB)
+#define BANK1_WRITE_BURST_START_EVENT_SET(x)     (((x) << BANK1_WRITE_BURST_START_EVENT_LSB) & BANK1_WRITE_BURST_START_EVENT_MASK)
+#define BANK1_WRITE_EVENT3_BE_MSB                14
+#define BANK1_WRITE_EVENT3_BE_LSB                14
+#define BANK1_WRITE_EVENT3_BE_MASK               0x00004000
+#define BANK1_WRITE_EVENT3_BE_GET(x)             (((x) & BANK1_WRITE_EVENT3_BE_MASK) >> BANK1_WRITE_EVENT3_BE_LSB)
+#define BANK1_WRITE_EVENT3_BE_SET(x)             (((x) << BANK1_WRITE_EVENT3_BE_LSB) & BANK1_WRITE_EVENT3_BE_MASK)
+#define BANK1_WRITE_EVENT3_WE_MSB                13
+#define BANK1_WRITE_EVENT3_WE_LSB                13
+#define BANK1_WRITE_EVENT3_WE_MASK               0x00002000
+#define BANK1_WRITE_EVENT3_WE_GET(x)             (((x) & BANK1_WRITE_EVENT3_WE_MASK) >> BANK1_WRITE_EVENT3_WE_LSB)
+#define BANK1_WRITE_EVENT3_WE_SET(x)             (((x) << BANK1_WRITE_EVENT3_WE_LSB) & BANK1_WRITE_EVENT3_WE_MASK)
+#define BANK1_WRITE_EVENT3_CS_MSB                12
+#define BANK1_WRITE_EVENT3_CS_LSB                12
+#define BANK1_WRITE_EVENT3_CS_MASK               0x00001000
+#define BANK1_WRITE_EVENT3_CS_GET(x)             (((x) & BANK1_WRITE_EVENT3_CS_MASK) >> BANK1_WRITE_EVENT3_CS_LSB)
+#define BANK1_WRITE_EVENT3_CS_SET(x)             (((x) << BANK1_WRITE_EVENT3_CS_LSB) & BANK1_WRITE_EVENT3_CS_MASK)
+#define BANK1_WRITE_EVENT2_BE_MSB                10
+#define BANK1_WRITE_EVENT2_BE_LSB                10
+#define BANK1_WRITE_EVENT2_BE_MASK               0x00000400
+#define BANK1_WRITE_EVENT2_BE_GET(x)             (((x) & BANK1_WRITE_EVENT2_BE_MASK) >> BANK1_WRITE_EVENT2_BE_LSB)
+#define BANK1_WRITE_EVENT2_BE_SET(x)             (((x) << BANK1_WRITE_EVENT2_BE_LSB) & BANK1_WRITE_EVENT2_BE_MASK)
+#define BANK1_WRITE_EVENT2_WE_MSB                9
+#define BANK1_WRITE_EVENT2_WE_LSB                9
+#define BANK1_WRITE_EVENT2_WE_MASK               0x00000200
+#define BANK1_WRITE_EVENT2_WE_GET(x)             (((x) & BANK1_WRITE_EVENT2_WE_MASK) >> BANK1_WRITE_EVENT2_WE_LSB)
+#define BANK1_WRITE_EVENT2_WE_SET(x)             (((x) << BANK1_WRITE_EVENT2_WE_LSB) & BANK1_WRITE_EVENT2_WE_MASK)
+#define BANK1_WRITE_EVENT2_CS_MSB                8
+#define BANK1_WRITE_EVENT2_CS_LSB                8
+#define BANK1_WRITE_EVENT2_CS_MASK               0x00000100
+#define BANK1_WRITE_EVENT2_CS_GET(x)             (((x) & BANK1_WRITE_EVENT2_CS_MASK) >> BANK1_WRITE_EVENT2_CS_LSB)
+#define BANK1_WRITE_EVENT2_CS_SET(x)             (((x) << BANK1_WRITE_EVENT2_CS_LSB) & BANK1_WRITE_EVENT2_CS_MASK)
+#define BANK1_WRITE_EVENT1_BE_MSB                6
+#define BANK1_WRITE_EVENT1_BE_LSB                6
+#define BANK1_WRITE_EVENT1_BE_MASK               0x00000040
+#define BANK1_WRITE_EVENT1_BE_GET(x)             (((x) & BANK1_WRITE_EVENT1_BE_MASK) >> BANK1_WRITE_EVENT1_BE_LSB)
+#define BANK1_WRITE_EVENT1_BE_SET(x)             (((x) << BANK1_WRITE_EVENT1_BE_LSB) & BANK1_WRITE_EVENT1_BE_MASK)
+#define BANK1_WRITE_EVENT1_WE_MSB                5
+#define BANK1_WRITE_EVENT1_WE_LSB                5
+#define BANK1_WRITE_EVENT1_WE_MASK               0x00000020
+#define BANK1_WRITE_EVENT1_WE_GET(x)             (((x) & BANK1_WRITE_EVENT1_WE_MASK) >> BANK1_WRITE_EVENT1_WE_LSB)
+#define BANK1_WRITE_EVENT1_WE_SET(x)             (((x) << BANK1_WRITE_EVENT1_WE_LSB) & BANK1_WRITE_EVENT1_WE_MASK)
+#define BANK1_WRITE_EVENT1_CS_MSB                4
+#define BANK1_WRITE_EVENT1_CS_LSB                4
+#define BANK1_WRITE_EVENT1_CS_MASK               0x00000010
+#define BANK1_WRITE_EVENT1_CS_GET(x)             (((x) & BANK1_WRITE_EVENT1_CS_MASK) >> BANK1_WRITE_EVENT1_CS_LSB)
+#define BANK1_WRITE_EVENT1_CS_SET(x)             (((x) << BANK1_WRITE_EVENT1_CS_LSB) & BANK1_WRITE_EVENT1_CS_MASK)
+#define BANK1_WRITE_EVENT0_BE_MSB                2
+#define BANK1_WRITE_EVENT0_BE_LSB                2
+#define BANK1_WRITE_EVENT0_BE_MASK               0x00000004
+#define BANK1_WRITE_EVENT0_BE_GET(x)             (((x) & BANK1_WRITE_EVENT0_BE_MASK) >> BANK1_WRITE_EVENT0_BE_LSB)
+#define BANK1_WRITE_EVENT0_BE_SET(x)             (((x) << BANK1_WRITE_EVENT0_BE_LSB) & BANK1_WRITE_EVENT0_BE_MASK)
+#define BANK1_WRITE_EVENT0_WE_MSB                1
+#define BANK1_WRITE_EVENT0_WE_LSB                1
+#define BANK1_WRITE_EVENT0_WE_MASK               0x00000002
+#define BANK1_WRITE_EVENT0_WE_GET(x)             (((x) & BANK1_WRITE_EVENT0_WE_MASK) >> BANK1_WRITE_EVENT0_WE_LSB)
+#define BANK1_WRITE_EVENT0_WE_SET(x)             (((x) << BANK1_WRITE_EVENT0_WE_LSB) & BANK1_WRITE_EVENT0_WE_MASK)
+#define BANK1_WRITE_EVENT0_CS_MSB                0
+#define BANK1_WRITE_EVENT0_CS_LSB                0
+#define BANK1_WRITE_EVENT0_CS_MASK               0x00000001
+#define BANK1_WRITE_EVENT0_CS_GET(x)             (((x) & BANK1_WRITE_EVENT0_CS_MASK) >> BANK1_WRITE_EVENT0_CS_LSB)
+#define BANK1_WRITE_EVENT0_CS_SET(x)             (((x) << BANK1_WRITE_EVENT0_CS_LSB) & BANK1_WRITE_EVENT0_CS_MASK)
+
+#define BANK2_ADDR_ADDRESS                       0x0c004020
+#define BANK2_ADDR_OFFSET                        0x00000020
+#define BANK2_ADDR_SIZE_MSB                      31
+#define BANK2_ADDR_SIZE_LSB                      28
+#define BANK2_ADDR_SIZE_MASK                     0xf0000000
+#define BANK2_ADDR_SIZE_GET(x)                   (((x) & BANK2_ADDR_SIZE_MASK) >> BANK2_ADDR_SIZE_LSB)
+#define BANK2_ADDR_SIZE_SET(x)                   (((x) << BANK2_ADDR_SIZE_LSB) & BANK2_ADDR_SIZE_MASK)
+#define BANK2_ADDR_BASE_MSB                      27
+#define BANK2_ADDR_BASE_LSB                      10
+#define BANK2_ADDR_BASE_MASK                     0x0ffffc00
+#define BANK2_ADDR_BASE_GET(x)                   (((x) & BANK2_ADDR_BASE_MASK) >> BANK2_ADDR_BASE_LSB)
+#define BANK2_ADDR_BASE_SET(x)                   (((x) << BANK2_ADDR_BASE_LSB) & BANK2_ADDR_BASE_MASK)
+
+#define BANK2_CONFIG_ADDRESS                     0x0c004024
+#define BANK2_CONFIG_OFFSET                      0x00000024
+#define BANK2_CONFIG_ENABLE_MSB                  31
+#define BANK2_CONFIG_ENABLE_LSB                  31
+#define BANK2_CONFIG_ENABLE_MASK                 0x80000000
+#define BANK2_CONFIG_ENABLE_GET(x)               (((x) & BANK2_CONFIG_ENABLE_MASK) >> BANK2_CONFIG_ENABLE_LSB)
+#define BANK2_CONFIG_ENABLE_SET(x)               (((x) << BANK2_CONFIG_ENABLE_LSB) & BANK2_CONFIG_ENABLE_MASK)
+#define BANK2_CONFIG_WIDTH_MSB                   28
+#define BANK2_CONFIG_WIDTH_LSB                   28
+#define BANK2_CONFIG_WIDTH_MASK                  0x10000000
+#define BANK2_CONFIG_WIDTH_GET(x)                (((x) & BANK2_CONFIG_WIDTH_MASK) >> BANK2_CONFIG_WIDTH_LSB)
+#define BANK2_CONFIG_WIDTH_SET(x)                (((x) << BANK2_CONFIG_WIDTH_LSB) & BANK2_CONFIG_WIDTH_MASK)
+#define BANK2_CONFIG_PROTECT_MSB                 26
+#define BANK2_CONFIG_PROTECT_LSB                 26
+#define BANK2_CONFIG_PROTECT_MASK                0x04000000
+#define BANK2_CONFIG_PROTECT_GET(x)              (((x) & BANK2_CONFIG_PROTECT_MASK) >> BANK2_CONFIG_PROTECT_LSB)
+#define BANK2_CONFIG_PROTECT_SET(x)              (((x) << BANK2_CONFIG_PROTECT_LSB) & BANK2_CONFIG_PROTECT_MASK)
+#define BANK2_CONFIG_WB_ENABLE_MSB               25
+#define BANK2_CONFIG_WB_ENABLE_LSB               25
+#define BANK2_CONFIG_WB_ENABLE_MASK              0x02000000
+#define BANK2_CONFIG_WB_ENABLE_GET(x)            (((x) & BANK2_CONFIG_WB_ENABLE_MASK) >> BANK2_CONFIG_WB_ENABLE_LSB)
+#define BANK2_CONFIG_WB_ENABLE_SET(x)            (((x) << BANK2_CONFIG_WB_ENABLE_LSB) & BANK2_CONFIG_WB_ENABLE_MASK)
+#define BANK2_CONFIG_WB_FLUSH_MSB                24
+#define BANK2_CONFIG_WB_FLUSH_LSB                24
+#define BANK2_CONFIG_WB_FLUSH_MASK               0x01000000
+#define BANK2_CONFIG_WB_FLUSH_GET(x)             (((x) & BANK2_CONFIG_WB_FLUSH_MASK) >> BANK2_CONFIG_WB_FLUSH_LSB)
+#define BANK2_CONFIG_WB_FLUSH_SET(x)             (((x) << BANK2_CONFIG_WB_FLUSH_LSB) & BANK2_CONFIG_WB_FLUSH_MASK)
+#define BANK2_CONFIG_SCALE_MSB                   21
+#define BANK2_CONFIG_SCALE_LSB                   20
+#define BANK2_CONFIG_SCALE_MASK                  0x00300000
+#define BANK2_CONFIG_SCALE_GET(x)                (((x) & BANK2_CONFIG_SCALE_MASK) >> BANK2_CONFIG_SCALE_LSB)
+#define BANK2_CONFIG_SCALE_SET(x)                (((x) << BANK2_CONFIG_SCALE_LSB) & BANK2_CONFIG_SCALE_MASK)
+#define BANK2_CONFIG_HOLDOFF_MSB                 19
+#define BANK2_CONFIG_HOLDOFF_LSB                 16
+#define BANK2_CONFIG_HOLDOFF_MASK                0x000f0000
+#define BANK2_CONFIG_HOLDOFF_GET(x)              (((x) & BANK2_CONFIG_HOLDOFF_MASK) >> BANK2_CONFIG_HOLDOFF_LSB)
+#define BANK2_CONFIG_HOLDOFF_SET(x)              (((x) << BANK2_CONFIG_HOLDOFF_LSB) & BANK2_CONFIG_HOLDOFF_MASK)
+#define BANK2_CONFIG_TIMER3_MSB                  15
+#define BANK2_CONFIG_TIMER3_LSB                  12
+#define BANK2_CONFIG_TIMER3_MASK                 0x0000f000
+#define BANK2_CONFIG_TIMER3_GET(x)               (((x) & BANK2_CONFIG_TIMER3_MASK) >> BANK2_CONFIG_TIMER3_LSB)
+#define BANK2_CONFIG_TIMER3_SET(x)               (((x) << BANK2_CONFIG_TIMER3_LSB) & BANK2_CONFIG_TIMER3_MASK)
+#define BANK2_CONFIG_TIMER2_MSB                  11
+#define BANK2_CONFIG_TIMER2_LSB                  8
+#define BANK2_CONFIG_TIMER2_MASK                 0x00000f00
+#define BANK2_CONFIG_TIMER2_GET(x)               (((x) & BANK2_CONFIG_TIMER2_MASK) >> BANK2_CONFIG_TIMER2_LSB)
+#define BANK2_CONFIG_TIMER2_SET(x)               (((x) << BANK2_CONFIG_TIMER2_LSB) & BANK2_CONFIG_TIMER2_MASK)
+#define BANK2_CONFIG_TIMER1_MSB                  7
+#define BANK2_CONFIG_TIMER1_LSB                  4
+#define BANK2_CONFIG_TIMER1_MASK                 0x000000f0
+#define BANK2_CONFIG_TIMER1_GET(x)               (((x) & BANK2_CONFIG_TIMER1_MASK) >> BANK2_CONFIG_TIMER1_LSB)
+#define BANK2_CONFIG_TIMER1_SET(x)               (((x) << BANK2_CONFIG_TIMER1_LSB) & BANK2_CONFIG_TIMER1_MASK)
+#define BANK2_CONFIG_TIMER0_MSB                  3
+#define BANK2_CONFIG_TIMER0_LSB                  0
+#define BANK2_CONFIG_TIMER0_MASK                 0x0000000f
+#define BANK2_CONFIG_TIMER0_GET(x)               (((x) & BANK2_CONFIG_TIMER0_MASK) >> BANK2_CONFIG_TIMER0_LSB)
+#define BANK2_CONFIG_TIMER0_SET(x)               (((x) << BANK2_CONFIG_TIMER0_LSB) & BANK2_CONFIG_TIMER0_MASK)
+
+#define BANK2_READ_ADDRESS                       0x0c004028
+#define BANK2_READ_OFFSET                        0x00000028
+#define BANK2_READ_ENABLE_WAIT_MSB               31
+#define BANK2_READ_ENABLE_WAIT_LSB               31
+#define BANK2_READ_ENABLE_WAIT_MASK              0x80000000
+#define BANK2_READ_ENABLE_WAIT_GET(x)            (((x) & BANK2_READ_ENABLE_WAIT_MASK) >> BANK2_READ_ENABLE_WAIT_LSB)
+#define BANK2_READ_ENABLE_WAIT_SET(x)            (((x) << BANK2_READ_ENABLE_WAIT_LSB) & BANK2_READ_ENABLE_WAIT_MASK)
+#define BANK2_READ_WAIT_EVENT_MSB                30
+#define BANK2_READ_WAIT_EVENT_LSB                28
+#define BANK2_READ_WAIT_EVENT_MASK               0x70000000
+#define BANK2_READ_WAIT_EVENT_GET(x)             (((x) & BANK2_READ_WAIT_EVENT_MASK) >> BANK2_READ_WAIT_EVENT_LSB)
+#define BANK2_READ_WAIT_EVENT_SET(x)             (((x) << BANK2_READ_WAIT_EVENT_LSB) & BANK2_READ_WAIT_EVENT_MASK)
+#define BANK2_READ_END_EVENT_MSB                 26
+#define BANK2_READ_END_EVENT_LSB                 24
+#define BANK2_READ_END_EVENT_MASK                0x07000000
+#define BANK2_READ_END_EVENT_GET(x)              (((x) & BANK2_READ_END_EVENT_MASK) >> BANK2_READ_END_EVENT_LSB)
+#define BANK2_READ_END_EVENT_SET(x)              (((x) << BANK2_READ_END_EVENT_LSB) & BANK2_READ_END_EVENT_MASK)
+#define BANK2_READ_BURST_END_EVENT_MSB           22
+#define BANK2_READ_BURST_END_EVENT_LSB           20
+#define BANK2_READ_BURST_END_EVENT_MASK          0x00700000
+#define BANK2_READ_BURST_END_EVENT_GET(x)        (((x) & BANK2_READ_BURST_END_EVENT_MASK) >> BANK2_READ_BURST_END_EVENT_LSB)
+#define BANK2_READ_BURST_END_EVENT_SET(x)        (((x) << BANK2_READ_BURST_END_EVENT_LSB) & BANK2_READ_BURST_END_EVENT_MASK)
+#define BANK2_READ_BURST_START_EVENT_MSB         18
+#define BANK2_READ_BURST_START_EVENT_LSB         16
+#define BANK2_READ_BURST_START_EVENT_MASK        0x00070000
+#define BANK2_READ_BURST_START_EVENT_GET(x)      (((x) & BANK2_READ_BURST_START_EVENT_MASK) >> BANK2_READ_BURST_START_EVENT_LSB)
+#define BANK2_READ_BURST_START_EVENT_SET(x)      (((x) << BANK2_READ_BURST_START_EVENT_LSB) & BANK2_READ_BURST_START_EVENT_MASK)
+#define BANK2_READ_EVENT3_DC_MSB                 15
+#define BANK2_READ_EVENT3_DC_LSB                 15
+#define BANK2_READ_EVENT3_DC_MASK                0x00008000
+#define BANK2_READ_EVENT3_DC_GET(x)              (((x) & BANK2_READ_EVENT3_DC_MASK) >> BANK2_READ_EVENT3_DC_LSB)
+#define BANK2_READ_EVENT3_DC_SET(x)              (((x) << BANK2_READ_EVENT3_DC_LSB) & BANK2_READ_EVENT3_DC_MASK)
+#define BANK2_READ_EVENT3_BE_MSB                 14
+#define BANK2_READ_EVENT3_BE_LSB                 14
+#define BANK2_READ_EVENT3_BE_MASK                0x00004000
+#define BANK2_READ_EVENT3_BE_GET(x)              (((x) & BANK2_READ_EVENT3_BE_MASK) >> BANK2_READ_EVENT3_BE_LSB)
+#define BANK2_READ_EVENT3_BE_SET(x)              (((x) << BANK2_READ_EVENT3_BE_LSB) & BANK2_READ_EVENT3_BE_MASK)
+#define BANK2_READ_EVENT3_OE_MSB                 13
+#define BANK2_READ_EVENT3_OE_LSB                 13
+#define BANK2_READ_EVENT3_OE_MASK                0x00002000
+#define BANK2_READ_EVENT3_OE_GET(x)              (((x) & BANK2_READ_EVENT3_OE_MASK) >> BANK2_READ_EVENT3_OE_LSB)
+#define BANK2_READ_EVENT3_OE_SET(x)              (((x) << BANK2_READ_EVENT3_OE_LSB) & BANK2_READ_EVENT3_OE_MASK)
+#define BANK2_READ_EVENT3_CS_MSB                 12
+#define BANK2_READ_EVENT3_CS_LSB                 12
+#define BANK2_READ_EVENT3_CS_MASK                0x00001000
+#define BANK2_READ_EVENT3_CS_GET(x)              (((x) & BANK2_READ_EVENT3_CS_MASK) >> BANK2_READ_EVENT3_CS_LSB)
+#define BANK2_READ_EVENT3_CS_SET(x)              (((x) << BANK2_READ_EVENT3_CS_LSB) & BANK2_READ_EVENT3_CS_MASK)
+#define BANK2_READ_EVENT2_DC_MSB                 11
+#define BANK2_READ_EVENT2_DC_LSB                 11
+#define BANK2_READ_EVENT2_DC_MASK                0x00000800
+#define BANK2_READ_EVENT2_DC_GET(x)              (((x) & BANK2_READ_EVENT2_DC_MASK) >> BANK2_READ_EVENT2_DC_LSB)
+#define BANK2_READ_EVENT2_DC_SET(x)              (((x) << BANK2_READ_EVENT2_DC_LSB) & BANK2_READ_EVENT2_DC_MASK)
+#define BANK2_READ_EVENT2_BE_MSB                 10
+#define BANK2_READ_EVENT2_BE_LSB                 10
+#define BANK2_READ_EVENT2_BE_MASK                0x00000400
+#define BANK2_READ_EVENT2_BE_GET(x)              (((x) & BANK2_READ_EVENT2_BE_MASK) >> BANK2_READ_EVENT2_BE_LSB)
+#define BANK2_READ_EVENT2_BE_SET(x)              (((x) << BANK2_READ_EVENT2_BE_LSB) & BANK2_READ_EVENT2_BE_MASK)
+#define BANK2_READ_EVENT2_OE_MSB                 9
+#define BANK2_READ_EVENT2_OE_LSB                 9
+#define BANK2_READ_EVENT2_OE_MASK                0x00000200
+#define BANK2_READ_EVENT2_OE_GET(x)              (((x) & BANK2_READ_EVENT2_OE_MASK) >> BANK2_READ_EVENT2_OE_LSB)
+#define BANK2_READ_EVENT2_OE_SET(x)              (((x) << BANK2_READ_EVENT2_OE_LSB) & BANK2_READ_EVENT2_OE_MASK)
+#define BANK2_READ_EVENT2_CS_MSB                 8
+#define BANK2_READ_EVENT2_CS_LSB                 8
+#define BANK2_READ_EVENT2_CS_MASK                0x00000100
+#define BANK2_READ_EVENT2_CS_GET(x)              (((x) & BANK2_READ_EVENT2_CS_MASK) >> BANK2_READ_EVENT2_CS_LSB)
+#define BANK2_READ_EVENT2_CS_SET(x)              (((x) << BANK2_READ_EVENT2_CS_LSB) & BANK2_READ_EVENT2_CS_MASK)
+#define BANK2_READ_EVENT1_DC_MSB                 7
+#define BANK2_READ_EVENT1_DC_LSB                 7
+#define BANK2_READ_EVENT1_DC_MASK                0x00000080
+#define BANK2_READ_EVENT1_DC_GET(x)              (((x) & BANK2_READ_EVENT1_DC_MASK) >> BANK2_READ_EVENT1_DC_LSB)
+#define BANK2_READ_EVENT1_DC_SET(x)              (((x) << BANK2_READ_EVENT1_DC_LSB) & BANK2_READ_EVENT1_DC_MASK)
+#define BANK2_READ_EVENT1_BE_MSB                 6
+#define BANK2_READ_EVENT1_BE_LSB                 6
+#define BANK2_READ_EVENT1_BE_MASK                0x00000040
+#define BANK2_READ_EVENT1_BE_GET(x)              (((x) & BANK2_READ_EVENT1_BE_MASK) >> BANK2_READ_EVENT1_BE_LSB)
+#define BANK2_READ_EVENT1_BE_SET(x)              (((x) << BANK2_READ_EVENT1_BE_LSB) & BANK2_READ_EVENT1_BE_MASK)
+#define BANK2_READ_EVENT1_OE_MSB                 5
+#define BANK2_READ_EVENT1_OE_LSB                 5
+#define BANK2_READ_EVENT1_OE_MASK                0x00000020
+#define BANK2_READ_EVENT1_OE_GET(x)              (((x) & BANK2_READ_EVENT1_OE_MASK) >> BANK2_READ_EVENT1_OE_LSB)
+#define BANK2_READ_EVENT1_OE_SET(x)              (((x) << BANK2_READ_EVENT1_OE_LSB) & BANK2_READ_EVENT1_OE_MASK)
+#define BANK2_READ_EVENT1_CS_MSB                 4
+#define BANK2_READ_EVENT1_CS_LSB                 4
+#define BANK2_READ_EVENT1_CS_MASK                0x00000010
+#define BANK2_READ_EVENT1_CS_GET(x)              (((x) & BANK2_READ_EVENT1_CS_MASK) >> BANK2_READ_EVENT1_CS_LSB)
+#define BANK2_READ_EVENT1_CS_SET(x)              (((x) << BANK2_READ_EVENT1_CS_LSB) & BANK2_READ_EVENT1_CS_MASK)
+#define BANK2_READ_EVENT0_DC_MSB                 3
+#define BANK2_READ_EVENT0_DC_LSB                 3
+#define BANK2_READ_EVENT0_DC_MASK                0x00000008
+#define BANK2_READ_EVENT0_DC_GET(x)              (((x) & BANK2_READ_EVENT0_DC_MASK) >> BANK2_READ_EVENT0_DC_LSB)
+#define BANK2_READ_EVENT0_DC_SET(x)              (((x) << BANK2_READ_EVENT0_DC_LSB) & BANK2_READ_EVENT0_DC_MASK)
+#define BANK2_READ_EVENT0_BE_MSB                 2
+#define BANK2_READ_EVENT0_BE_LSB                 2
+#define BANK2_READ_EVENT0_BE_MASK                0x00000004
+#define BANK2_READ_EVENT0_BE_GET(x)              (((x) & BANK2_READ_EVENT0_BE_MASK) >> BANK2_READ_EVENT0_BE_LSB)
+#define BANK2_READ_EVENT0_BE_SET(x)              (((x) << BANK2_READ_EVENT0_BE_LSB) & BANK2_READ_EVENT0_BE_MASK)
+#define BANK2_READ_EVENT0_OE_MSB                 1
+#define BANK2_READ_EVENT0_OE_LSB                 1
+#define BANK2_READ_EVENT0_OE_MASK                0x00000002
+#define BANK2_READ_EVENT0_OE_GET(x)              (((x) & BANK2_READ_EVENT0_OE_MASK) >> BANK2_READ_EVENT0_OE_LSB)
+#define BANK2_READ_EVENT0_OE_SET(x)              (((x) << BANK2_READ_EVENT0_OE_LSB) & BANK2_READ_EVENT0_OE_MASK)
+#define BANK2_READ_EVENT0_CS_MSB                 0
+#define BANK2_READ_EVENT0_CS_LSB                 0
+#define BANK2_READ_EVENT0_CS_MASK                0x00000001
+#define BANK2_READ_EVENT0_CS_GET(x)              (((x) & BANK2_READ_EVENT0_CS_MASK) >> BANK2_READ_EVENT0_CS_LSB)
+#define BANK2_READ_EVENT0_CS_SET(x)              (((x) << BANK2_READ_EVENT0_CS_LSB) & BANK2_READ_EVENT0_CS_MASK)
+
+#define BANK2_WRITE_ADDRESS                      0x0c00402c
+#define BANK2_WRITE_OFFSET                       0x0000002c
+#define BANK2_WRITE_ENABLE_WAIT_MSB              31
+#define BANK2_WRITE_ENABLE_WAIT_LSB              31
+#define BANK2_WRITE_ENABLE_WAIT_MASK             0x80000000
+#define BANK2_WRITE_ENABLE_WAIT_GET(x)           (((x) & BANK2_WRITE_ENABLE_WAIT_MASK) >> BANK2_WRITE_ENABLE_WAIT_LSB)
+#define BANK2_WRITE_ENABLE_WAIT_SET(x)           (((x) << BANK2_WRITE_ENABLE_WAIT_LSB) & BANK2_WRITE_ENABLE_WAIT_MASK)
+#define BANK2_WRITE_WAIT_EVENT_MSB               30
+#define BANK2_WRITE_WAIT_EVENT_LSB               28
+#define BANK2_WRITE_WAIT_EVENT_MASK              0x70000000
+#define BANK2_WRITE_WAIT_EVENT_GET(x)            (((x) & BANK2_WRITE_WAIT_EVENT_MASK) >> BANK2_WRITE_WAIT_EVENT_LSB)
+#define BANK2_WRITE_WAIT_EVENT_SET(x)            (((x) << BANK2_WRITE_WAIT_EVENT_LSB) & BANK2_WRITE_WAIT_EVENT_MASK)
+#define BANK2_WRITE_END_EVENT_MSB                26
+#define BANK2_WRITE_END_EVENT_LSB                24
+#define BANK2_WRITE_END_EVENT_MASK               0x07000000
+#define BANK2_WRITE_END_EVENT_GET(x)             (((x) & BANK2_WRITE_END_EVENT_MASK) >> BANK2_WRITE_END_EVENT_LSB)
+#define BANK2_WRITE_END_EVENT_SET(x)             (((x) << BANK2_WRITE_END_EVENT_LSB) & BANK2_WRITE_END_EVENT_MASK)
+#define BANK2_WRITE_BURST_END_EVENT_MSB          22
+#define BANK2_WRITE_BURST_END_EVENT_LSB          20
+#define BANK2_WRITE_BURST_END_EVENT_MASK         0x00700000
+#define BANK2_WRITE_BURST_END_EVENT_GET(x)       (((x) & BANK2_WRITE_BURST_END_EVENT_MASK) >> BANK2_WRITE_BURST_END_EVENT_LSB)
+#define BANK2_WRITE_BURST_END_EVENT_SET(x)       (((x) << BANK2_WRITE_BURST_END_EVENT_LSB) & BANK2_WRITE_BURST_END_EVENT_MASK)
+#define BANK2_WRITE_BURST_START_EVENT_MSB        18
+#define BANK2_WRITE_BURST_START_EVENT_LSB        16
+#define BANK2_WRITE_BURST_START_EVENT_MASK       0x00070000
+#define BANK2_WRITE_BURST_START_EVENT_GET(x)     (((x) & BANK2_WRITE_BURST_START_EVENT_MASK) >> BANK2_WRITE_BURST_START_EVENT_LSB)
+#define BANK2_WRITE_BURST_START_EVENT_SET(x)     (((x) << BANK2_WRITE_BURST_START_EVENT_LSB) & BANK2_WRITE_BURST_START_EVENT_MASK)
+#define BANK2_WRITE_EVENT3_BE_MSB                14
+#define BANK2_WRITE_EVENT3_BE_LSB                14
+#define BANK2_WRITE_EVENT3_BE_MASK               0x00004000
+#define BANK2_WRITE_EVENT3_BE_GET(x)             (((x) & BANK2_WRITE_EVENT3_BE_MASK) >> BANK2_WRITE_EVENT3_BE_LSB)
+#define BANK2_WRITE_EVENT3_BE_SET(x)             (((x) << BANK2_WRITE_EVENT3_BE_LSB) & BANK2_WRITE_EVENT3_BE_MASK)
+#define BANK2_WRITE_EVENT3_WE_MSB                13
+#define BANK2_WRITE_EVENT3_WE_LSB                13
+#define BANK2_WRITE_EVENT3_WE_MASK               0x00002000
+#define BANK2_WRITE_EVENT3_WE_GET(x)             (((x) & BANK2_WRITE_EVENT3_WE_MASK) >> BANK2_WRITE_EVENT3_WE_LSB)
+#define BANK2_WRITE_EVENT3_WE_SET(x)             (((x) << BANK2_WRITE_EVENT3_WE_LSB) & BANK2_WRITE_EVENT3_WE_MASK)
+#define BANK2_WRITE_EVENT3_CS_MSB                12
+#define BANK2_WRITE_EVENT3_CS_LSB                12
+#define BANK2_WRITE_EVENT3_CS_MASK               0x00001000
+#define BANK2_WRITE_EVENT3_CS_GET(x)             (((x) & BANK2_WRITE_EVENT3_CS_MASK) >> BANK2_WRITE_EVENT3_CS_LSB)
+#define BANK2_WRITE_EVENT3_CS_SET(x)             (((x) << BANK2_WRITE_EVENT3_CS_LSB) & BANK2_WRITE_EVENT3_CS_MASK)
+#define BANK2_WRITE_EVENT2_BE_MSB                10
+#define BANK2_WRITE_EVENT2_BE_LSB                10
+#define BANK2_WRITE_EVENT2_BE_MASK               0x00000400
+#define BANK2_WRITE_EVENT2_BE_GET(x)             (((x) & BANK2_WRITE_EVENT2_BE_MASK) >> BANK2_WRITE_EVENT2_BE_LSB)
+#define BANK2_WRITE_EVENT2_BE_SET(x)             (((x) << BANK2_WRITE_EVENT2_BE_LSB) & BANK2_WRITE_EVENT2_BE_MASK)
+#define BANK2_WRITE_EVENT2_WE_MSB                9
+#define BANK2_WRITE_EVENT2_WE_LSB                9
+#define BANK2_WRITE_EVENT2_WE_MASK               0x00000200
+#define BANK2_WRITE_EVENT2_WE_GET(x)             (((x) & BANK2_WRITE_EVENT2_WE_MASK) >> BANK2_WRITE_EVENT2_WE_LSB)
+#define BANK2_WRITE_EVENT2_WE_SET(x)             (((x) << BANK2_WRITE_EVENT2_WE_LSB) & BANK2_WRITE_EVENT2_WE_MASK)
+#define BANK2_WRITE_EVENT2_CS_MSB                8
+#define BANK2_WRITE_EVENT2_CS_LSB                8
+#define BANK2_WRITE_EVENT2_CS_MASK               0x00000100
+#define BANK2_WRITE_EVENT2_CS_GET(x)             (((x) & BANK2_WRITE_EVENT2_CS_MASK) >> BANK2_WRITE_EVENT2_CS_LSB)
+#define BANK2_WRITE_EVENT2_CS_SET(x)             (((x) << BANK2_WRITE_EVENT2_CS_LSB) & BANK2_WRITE_EVENT2_CS_MASK)
+#define BANK2_WRITE_EVENT1_BE_MSB                6
+#define BANK2_WRITE_EVENT1_BE_LSB                6
+#define BANK2_WRITE_EVENT1_BE_MASK               0x00000040
+#define BANK2_WRITE_EVENT1_BE_GET(x)             (((x) & BANK2_WRITE_EVENT1_BE_MASK) >> BANK2_WRITE_EVENT1_BE_LSB)
+#define BANK2_WRITE_EVENT1_BE_SET(x)             (((x) << BANK2_WRITE_EVENT1_BE_LSB) & BANK2_WRITE_EVENT1_BE_MASK)
+#define BANK2_WRITE_EVENT1_WE_MSB                5
+#define BANK2_WRITE_EVENT1_WE_LSB                5
+#define BANK2_WRITE_EVENT1_WE_MASK               0x00000020
+#define BANK2_WRITE_EVENT1_WE_GET(x)             (((x) & BANK2_WRITE_EVENT1_WE_MASK) >> BANK2_WRITE_EVENT1_WE_LSB)
+#define BANK2_WRITE_EVENT1_WE_SET(x)             (((x) << BANK2_WRITE_EVENT1_WE_LSB) & BANK2_WRITE_EVENT1_WE_MASK)
+#define BANK2_WRITE_EVENT1_CS_MSB                4
+#define BANK2_WRITE_EVENT1_CS_LSB                4
+#define BANK2_WRITE_EVENT1_CS_MASK               0x00000010
+#define BANK2_WRITE_EVENT1_CS_GET(x)             (((x) & BANK2_WRITE_EVENT1_CS_MASK) >> BANK2_WRITE_EVENT1_CS_LSB)
+#define BANK2_WRITE_EVENT1_CS_SET(x)             (((x) << BANK2_WRITE_EVENT1_CS_LSB) & BANK2_WRITE_EVENT1_CS_MASK)
+#define BANK2_WRITE_EVENT0_BE_MSB                2
+#define BANK2_WRITE_EVENT0_BE_LSB                2
+#define BANK2_WRITE_EVENT0_BE_MASK               0x00000004
+#define BANK2_WRITE_EVENT0_BE_GET(x)             (((x) & BANK2_WRITE_EVENT0_BE_MASK) >> BANK2_WRITE_EVENT0_BE_LSB)
+#define BANK2_WRITE_EVENT0_BE_SET(x)             (((x) << BANK2_WRITE_EVENT0_BE_LSB) & BANK2_WRITE_EVENT0_BE_MASK)
+#define BANK2_WRITE_EVENT0_WE_MSB                1
+#define BANK2_WRITE_EVENT0_WE_LSB                1
+#define BANK2_WRITE_EVENT0_WE_MASK               0x00000002
+#define BANK2_WRITE_EVENT0_WE_GET(x)             (((x) & BANK2_WRITE_EVENT0_WE_MASK) >> BANK2_WRITE_EVENT0_WE_LSB)
+#define BANK2_WRITE_EVENT0_WE_SET(x)             (((x) << BANK2_WRITE_EVENT0_WE_LSB) & BANK2_WRITE_EVENT0_WE_MASK)
+#define BANK2_WRITE_EVENT0_CS_MSB                0
+#define BANK2_WRITE_EVENT0_CS_LSB                0
+#define BANK2_WRITE_EVENT0_CS_MASK               0x00000001
+#define BANK2_WRITE_EVENT0_CS_GET(x)             (((x) & BANK2_WRITE_EVENT0_CS_MASK) >> BANK2_WRITE_EVENT0_CS_LSB)
+#define BANK2_WRITE_EVENT0_CS_SET(x)             (((x) << BANK2_WRITE_EVENT0_CS_LSB) & BANK2_WRITE_EVENT0_CS_MASK)
+
+#define MC_REMAP_VALID_ADDRESS                   0x0c004080
+#define MC_REMAP_VALID_OFFSET                    0x00000080
+#define MC_REMAP_VALID_BIT_MSB                   0
+#define MC_REMAP_VALID_BIT_LSB                   0
+#define MC_REMAP_VALID_BIT_MASK                  0x00000001
+#define MC_REMAP_VALID_BIT_GET(x)                (((x) & MC_REMAP_VALID_BIT_MASK) >> MC_REMAP_VALID_BIT_LSB)
+#define MC_REMAP_VALID_BIT_SET(x)                (((x) << MC_REMAP_VALID_BIT_LSB) & MC_REMAP_VALID_BIT_MASK)
+
+#define MC_REMAP_SIZE_ADDRESS                    0x0c004100
+#define MC_REMAP_SIZE_OFFSET                     0x00000100
+#define MC_REMAP_SIZE_VALUE_MSB                  2
+#define MC_REMAP_SIZE_VALUE_LSB                  0
+#define MC_REMAP_SIZE_VALUE_MASK                 0x00000007
+#define MC_REMAP_SIZE_VALUE_GET(x)               (((x) & MC_REMAP_SIZE_VALUE_MASK) >> MC_REMAP_SIZE_VALUE_LSB)
+#define MC_REMAP_SIZE_VALUE_SET(x)               (((x) << MC_REMAP_SIZE_VALUE_LSB) & MC_REMAP_SIZE_VALUE_MASK)
+
+#define MC_REMAP_COMPARE_ADDRESS                 0x0c004180
+#define MC_REMAP_COMPARE_OFFSET                  0x00000180
+#define MC_REMAP_COMPARE_ADDRESS_MSB             17
+#define MC_REMAP_COMPARE_ADDRESS_LSB             4
+#define MC_REMAP_COMPARE_ADDRESS_MASK            0x0003fff0
+#define MC_REMAP_COMPARE_ADDRESS_GET(x)          (((x) & MC_REMAP_COMPARE_ADDRESS_MASK) >> MC_REMAP_COMPARE_ADDRESS_LSB)
+#define MC_REMAP_COMPARE_ADDRESS_SET(x)          (((x) << MC_REMAP_COMPARE_ADDRESS_LSB) & MC_REMAP_COMPARE_ADDRESS_MASK)
+
+#define MC_REMAP_TARGET_ADDRESS                  0x0c004200
+#define MC_REMAP_TARGET_OFFSET                   0x00000200
+#define MC_REMAP_TARGET_ADDRESS_MSB              16
+#define MC_REMAP_TARGET_ADDRESS_LSB              4
+#define MC_REMAP_TARGET_ADDRESS_MASK             0x0001fff0
+#define MC_REMAP_TARGET_ADDRESS_GET(x)           (((x) & MC_REMAP_TARGET_ADDRESS_MASK) >> MC_REMAP_TARGET_ADDRESS_LSB)
+#define MC_REMAP_TARGET_ADDRESS_SET(x)           (((x) << MC_REMAP_TARGET_ADDRESS_LSB) & MC_REMAP_TARGET_ADDRESS_MASK)
+
+#define G729_ROM_ADDRESS                         0x0c004280
+#define G729_ROM_OFFSET                          0x00000280
+#define G729_ROM_ENABLE_MSB                      0
+#define G729_ROM_ENABLE_LSB                      0
+#define G729_ROM_ENABLE_MASK                     0x00000001
+#define G729_ROM_ENABLE_GET(x)                   (((x) & G729_ROM_ENABLE_MASK) >> G729_ROM_ENABLE_LSB)
+#define G729_ROM_ENABLE_SET(x)                   (((x) << G729_ROM_ENABLE_LSB) & G729_ROM_ENABLE_MASK)
+
+#define ERROR_VALID_ADDRESS                      0x0c004284
+#define ERROR_VALID_OFFSET                       0x00000284
+#define ERROR_VALID_ERROR_CAPTURE_ENABLE_MSB     8
+#define ERROR_VALID_ERROR_CAPTURE_ENABLE_LSB     8
+#define ERROR_VALID_ERROR_CAPTURE_ENABLE_MASK    0x00000100
+#define ERROR_VALID_ERROR_CAPTURE_ENABLE_GET(x)  (((x) & ERROR_VALID_ERROR_CAPTURE_ENABLE_MASK) >> ERROR_VALID_ERROR_CAPTURE_ENABLE_LSB)
+#define ERROR_VALID_ERROR_CAPTURE_ENABLE_SET(x)  (((x) << ERROR_VALID_ERROR_CAPTURE_ENABLE_LSB) & ERROR_VALID_ERROR_CAPTURE_ENABLE_MASK)
+#define ERROR_VALID_APB_ERROR_OVERFLOW_MSB       5
+#define ERROR_VALID_APB_ERROR_OVERFLOW_LSB       5
+#define ERROR_VALID_APB_ERROR_OVERFLOW_MASK      0x00000020
+#define ERROR_VALID_APB_ERROR_OVERFLOW_GET(x)    (((x) & ERROR_VALID_APB_ERROR_OVERFLOW_MASK) >> ERROR_VALID_APB_ERROR_OVERFLOW_LSB)
+#define ERROR_VALID_APB_ERROR_OVERFLOW_SET(x)    (((x) << ERROR_VALID_APB_ERROR_OVERFLOW_LSB) & ERROR_VALID_APB_ERROR_OVERFLOW_MASK)
+#define ERROR_VALID_APB_ERROR_VALID_MSB          4
+#define ERROR_VALID_APB_ERROR_VALID_LSB          4
+#define ERROR_VALID_APB_ERROR_VALID_MASK         0x00000010
+#define ERROR_VALID_APB_ERROR_VALID_GET(x)       (((x) & ERROR_VALID_APB_ERROR_VALID_MASK) >> ERROR_VALID_APB_ERROR_VALID_LSB)
+#define ERROR_VALID_APB_ERROR_VALID_SET(x)       (((x) << ERROR_VALID_APB_ERROR_VALID_LSB) & ERROR_VALID_APB_ERROR_VALID_MASK)
+#define ERROR_VALID_AHB_ERROR_OVERFLOW_MSB       1
+#define ERROR_VALID_AHB_ERROR_OVERFLOW_LSB       1
+#define ERROR_VALID_AHB_ERROR_OVERFLOW_MASK      0x00000002
+#define ERROR_VALID_AHB_ERROR_OVERFLOW_GET(x)    (((x) & ERROR_VALID_AHB_ERROR_OVERFLOW_MASK) >> ERROR_VALID_AHB_ERROR_OVERFLOW_LSB)
+#define ERROR_VALID_AHB_ERROR_OVERFLOW_SET(x)    (((x) << ERROR_VALID_AHB_ERROR_OVERFLOW_LSB) & ERROR_VALID_AHB_ERROR_OVERFLOW_MASK)
+#define ERROR_VALID_AHB_ERROR_VALID_MSB          0
+#define ERROR_VALID_AHB_ERROR_VALID_LSB          0
+#define ERROR_VALID_AHB_ERROR_VALID_MASK         0x00000001
+#define ERROR_VALID_AHB_ERROR_VALID_GET(x)       (((x) & ERROR_VALID_AHB_ERROR_VALID_MASK) >> ERROR_VALID_AHB_ERROR_VALID_LSB)
+#define ERROR_VALID_AHB_ERROR_VALID_SET(x)       (((x) << ERROR_VALID_AHB_ERROR_VALID_LSB) & ERROR_VALID_AHB_ERROR_VALID_MASK)
+
+#define AHB_ERROR_ADDRESS                        0x0c004288
+#define AHB_ERROR_OFFSET                         0x00000288
+#define AHB_ERROR_HMASTER_MSB                    31
+#define AHB_ERROR_HMASTER_LSB                    30
+#define AHB_ERROR_HMASTER_MASK                   0xc0000000
+#define AHB_ERROR_HMASTER_GET(x)                 (((x) & AHB_ERROR_HMASTER_MASK) >> AHB_ERROR_HMASTER_LSB)
+#define AHB_ERROR_HMASTER_SET(x)                 (((x) << AHB_ERROR_HMASTER_LSB) & AHB_ERROR_HMASTER_MASK)
+#define AHB_ERROR_HTRANS_MSB                     29
+#define AHB_ERROR_HTRANS_LSB                     28
+#define AHB_ERROR_HTRANS_MASK                    0x30000000
+#define AHB_ERROR_HTRANS_GET(x)                  (((x) & AHB_ERROR_HTRANS_MASK) >> AHB_ERROR_HTRANS_LSB)
+#define AHB_ERROR_HTRANS_SET(x)                  (((x) << AHB_ERROR_HTRANS_LSB) & AHB_ERROR_HTRANS_MASK)
+#define AHB_ERROR_HWRITE_MSB                     27
+#define AHB_ERROR_HWRITE_LSB                     27
+#define AHB_ERROR_HWRITE_MASK                    0x08000000
+#define AHB_ERROR_HWRITE_GET(x)                  (((x) & AHB_ERROR_HWRITE_MASK) >> AHB_ERROR_HWRITE_LSB)
+#define AHB_ERROR_HWRITE_SET(x)                  (((x) << AHB_ERROR_HWRITE_LSB) & AHB_ERROR_HWRITE_MASK)
+#define AHB_ERROR_HBURST_MSB                     26
+#define AHB_ERROR_HBURST_LSB                     24
+#define AHB_ERROR_HBURST_MASK                    0x07000000
+#define AHB_ERROR_HBURST_GET(x)                  (((x) & AHB_ERROR_HBURST_MASK) >> AHB_ERROR_HBURST_LSB)
+#define AHB_ERROR_HBURST_SET(x)                  (((x) << AHB_ERROR_HBURST_LSB) & AHB_ERROR_HBURST_MASK)
+#define AHB_ERROR_HADDR_MSB                      23
+#define AHB_ERROR_HADDR_LSB                      0
+#define AHB_ERROR_HADDR_MASK                     0x00ffffff
+#define AHB_ERROR_HADDR_GET(x)                   (((x) & AHB_ERROR_HADDR_MASK) >> AHB_ERROR_HADDR_LSB)
+#define AHB_ERROR_HADDR_SET(x)                   (((x) << AHB_ERROR_HADDR_LSB) & AHB_ERROR_HADDR_MASK)
+
+#define APB_ERROR_ADDRESS                        0x0c00428c
+#define APB_ERROR_OFFSET                         0x0000028c
+#define APB_ERROR_PADDR_MSB                      31
+#define APB_ERROR_PADDR_LSB                      2
+#define APB_ERROR_PADDR_MASK                     0xfffffffc
+#define APB_ERROR_PADDR_GET(x)                   (((x) & APB_ERROR_PADDR_MASK) >> APB_ERROR_PADDR_LSB)
+#define APB_ERROR_PADDR_SET(x)                   (((x) << APB_ERROR_PADDR_LSB) & APB_ERROR_PADDR_MASK)
+#define APB_ERROR_PVALID_MSB                     1
+#define APB_ERROR_PVALID_LSB                     1
+#define APB_ERROR_PVALID_MASK                    0x00000002
+#define APB_ERROR_PVALID_GET(x)                  (((x) & APB_ERROR_PVALID_MASK) >> APB_ERROR_PVALID_LSB)
+#define APB_ERROR_PVALID_SET(x)                  (((x) << APB_ERROR_PVALID_LSB) & APB_ERROR_PVALID_MASK)
+#define APB_ERROR_PWRITE_MSB                     0
+#define APB_ERROR_PWRITE_LSB                     0
+#define APB_ERROR_PWRITE_MASK                    0x00000001
+#define APB_ERROR_PWRITE_GET(x)                  (((x) & APB_ERROR_PWRITE_MASK) >> APB_ERROR_PWRITE_LSB)
+#define APB_ERROR_PWRITE_SET(x)                  (((x) << APB_ERROR_PWRITE_LSB) & APB_ERROR_PWRITE_MASK)
+
+#define PERF_CONFIG_ADDRESS                      0x0c004290
+#define PERF_CONFIG_OFFSET                       0x00000290
+#define PERF_CONFIG_ENABLE_MSB                   20
+#define PERF_CONFIG_ENABLE_LSB                   20
+#define PERF_CONFIG_ENABLE_MASK                  0x00100000
+#define PERF_CONFIG_ENABLE_GET(x)                (((x) & PERF_CONFIG_ENABLE_MASK) >> PERF_CONFIG_ENABLE_LSB)
+#define PERF_CONFIG_ENABLE_SET(x)                (((x) << PERF_CONFIG_ENABLE_LSB) & PERF_CONFIG_ENABLE_MASK)
+#define PERF_CONFIG_RESET_MSB                    19
+#define PERF_CONFIG_RESET_LSB                    16
+#define PERF_CONFIG_RESET_MASK                   0x000f0000
+#define PERF_CONFIG_RESET_GET(x)                 (((x) & PERF_CONFIG_RESET_MASK) >> PERF_CONFIG_RESET_LSB)
+#define PERF_CONFIG_RESET_SET(x)                 (((x) << PERF_CONFIG_RESET_LSB) & PERF_CONFIG_RESET_MASK)
+#define PERF_CONFIG_COUNTER3_MSB                 15
+#define PERF_CONFIG_COUNTER3_LSB                 12
+#define PERF_CONFIG_COUNTER3_MASK                0x0000f000
+#define PERF_CONFIG_COUNTER3_GET(x)              (((x) & PERF_CONFIG_COUNTER3_MASK) >> PERF_CONFIG_COUNTER3_LSB)
+#define PERF_CONFIG_COUNTER3_SET(x)              (((x) << PERF_CONFIG_COUNTER3_LSB) & PERF_CONFIG_COUNTER3_MASK)
+#define PERF_CONFIG_COUNTER2_MSB                 11
+#define PERF_CONFIG_COUNTER2_LSB                 8
+#define PERF_CONFIG_COUNTER2_MASK                0x00000f00
+#define PERF_CONFIG_COUNTER2_GET(x)              (((x) & PERF_CONFIG_COUNTER2_MASK) >> PERF_CONFIG_COUNTER2_LSB)
+#define PERF_CONFIG_COUNTER2_SET(x)              (((x) << PERF_CONFIG_COUNTER2_LSB) & PERF_CONFIG_COUNTER2_MASK)
+#define PERF_CONFIG_COUNTER1_MSB                 7
+#define PERF_CONFIG_COUNTER1_LSB                 4
+#define PERF_CONFIG_COUNTER1_MASK                0x000000f0
+#define PERF_CONFIG_COUNTER1_GET(x)              (((x) & PERF_CONFIG_COUNTER1_MASK) >> PERF_CONFIG_COUNTER1_LSB)
+#define PERF_CONFIG_COUNTER1_SET(x)              (((x) << PERF_CONFIG_COUNTER1_LSB) & PERF_CONFIG_COUNTER1_MASK)
+#define PERF_CONFIG_COUNTER0_MSB                 3
+#define PERF_CONFIG_COUNTER0_LSB                 0
+#define PERF_CONFIG_COUNTER0_MASK                0x0000000f
+#define PERF_CONFIG_COUNTER0_GET(x)              (((x) & PERF_CONFIG_COUNTER0_MASK) >> PERF_CONFIG_COUNTER0_LSB)
+#define PERF_CONFIG_COUNTER0_SET(x)              (((x) << PERF_CONFIG_COUNTER0_LSB) & PERF_CONFIG_COUNTER0_MASK)
+
+#define PERF_COUNTER_ADDRESS                     0x0c0042a0
+#define PERF_COUNTER_OFFSET                      0x000002a0
+#define PERF_COUNTER_VALUE_MSB                   19
+#define PERF_COUNTER_VALUE_LSB                   0
+#define PERF_COUNTER_VALUE_MASK                  0x000fffff
+#define PERF_COUNTER_VALUE_GET(x)                (((x) & PERF_COUNTER_VALUE_MASK) >> PERF_COUNTER_VALUE_LSB)
+#define PERF_COUNTER_VALUE_SET(x)                (((x) << PERF_COUNTER_VALUE_LSB) & PERF_COUNTER_VALUE_MASK)
+
+#define CPU_SETUP_CONFIG_ADDRESS                 0x0c0042b0
+#define CPU_SETUP_CONFIG_OFFSET                  0x000002b0
+#define CPU_SETUP_CONFIG_ENABLE_MSB              1
+#define CPU_SETUP_CONFIG_ENABLE_LSB              1
+#define CPU_SETUP_CONFIG_ENABLE_MASK             0x00000002
+#define CPU_SETUP_CONFIG_ENABLE_GET(x)           (((x) & CPU_SETUP_CONFIG_ENABLE_MASK) >> CPU_SETUP_CONFIG_ENABLE_LSB)
+#define CPU_SETUP_CONFIG_ENABLE_SET(x)           (((x) << CPU_SETUP_CONFIG_ENABLE_LSB) & CPU_SETUP_CONFIG_ENABLE_MASK)
+#define CPU_SETUP_CONFIG_CLEAR_MSB               0
+#define CPU_SETUP_CONFIG_CLEAR_LSB               0
+#define CPU_SETUP_CONFIG_CLEAR_MASK              0x00000001
+#define CPU_SETUP_CONFIG_CLEAR_GET(x)            (((x) & CPU_SETUP_CONFIG_CLEAR_MASK) >> CPU_SETUP_CONFIG_CLEAR_LSB)
+#define CPU_SETUP_CONFIG_CLEAR_SET(x)            (((x) << CPU_SETUP_CONFIG_CLEAR_LSB) & CPU_SETUP_CONFIG_CLEAR_MASK)
+
+#define MC_SETUP_CONFIG_ADDRESS                  0x0c0042b4
+#define MC_SETUP_CONFIG_OFFSET                   0x000002b4
+#define MC_SETUP_CONFIG_ENABLE_MSB               1
+#define MC_SETUP_CONFIG_ENABLE_LSB               1
+#define MC_SETUP_CONFIG_ENABLE_MASK              0x00000002
+#define MC_SETUP_CONFIG_ENABLE_GET(x)            (((x) & MC_SETUP_CONFIG_ENABLE_MASK) >> MC_SETUP_CONFIG_ENABLE_LSB)
+#define MC_SETUP_CONFIG_ENABLE_SET(x)            (((x) << MC_SETUP_CONFIG_ENABLE_LSB) & MC_SETUP_CONFIG_ENABLE_MASK)
+#define MC_SETUP_CONFIG_CLEAR_MSB                0
+#define MC_SETUP_CONFIG_CLEAR_LSB                0
+#define MC_SETUP_CONFIG_CLEAR_MASK               0x00000001
+#define MC_SETUP_CONFIG_CLEAR_GET(x)             (((x) & MC_SETUP_CONFIG_CLEAR_MASK) >> MC_SETUP_CONFIG_CLEAR_LSB)
+#define MC_SETUP_CONFIG_CLEAR_SET(x)             (((x) << MC_SETUP_CONFIG_CLEAR_LSB) & MC_SETUP_CONFIG_CLEAR_MASK)
+
+#define BB_SETUP_CONFIG_ADDRESS                  0x0c0042b8
+#define BB_SETUP_CONFIG_OFFSET                   0x000002b8
+#define BB_SETUP_CONFIG_ENABLE_MSB               1
+#define BB_SETUP_CONFIG_ENABLE_LSB               1
+#define BB_SETUP_CONFIG_ENABLE_MASK              0x00000002
+#define BB_SETUP_CONFIG_ENABLE_GET(x)            (((x) & BB_SETUP_CONFIG_ENABLE_MASK) >> BB_SETUP_CONFIG_ENABLE_LSB)
+#define BB_SETUP_CONFIG_ENABLE_SET(x)            (((x) << BB_SETUP_CONFIG_ENABLE_LSB) & BB_SETUP_CONFIG_ENABLE_MASK)
+#define BB_SETUP_CONFIG_CLEAR_MSB                0
+#define BB_SETUP_CONFIG_CLEAR_LSB                0
+#define BB_SETUP_CONFIG_CLEAR_MASK               0x00000001
+#define BB_SETUP_CONFIG_CLEAR_GET(x)             (((x) & BB_SETUP_CONFIG_CLEAR_MASK) >> BB_SETUP_CONFIG_CLEAR_LSB)
+#define BB_SETUP_CONFIG_CLEAR_SET(x)             (((x) << BB_SETUP_CONFIG_CLEAR_LSB) & BB_SETUP_CONFIG_CLEAR_MASK)
+
+#define SDIO_SETUP_CONFIG_ADDRESS                0x0c0042bc
+#define SDIO_SETUP_CONFIG_OFFSET                 0x000002bc
+#define SDIO_SETUP_CONFIG_ENABLE_MSB             1
+#define SDIO_SETUP_CONFIG_ENABLE_LSB             1
+#define SDIO_SETUP_CONFIG_ENABLE_MASK            0x00000002
+#define SDIO_SETUP_CONFIG_ENABLE_GET(x)          (((x) & SDIO_SETUP_CONFIG_ENABLE_MASK) >> SDIO_SETUP_CONFIG_ENABLE_LSB)
+#define SDIO_SETUP_CONFIG_ENABLE_SET(x)          (((x) << SDIO_SETUP_CONFIG_ENABLE_LSB) & SDIO_SETUP_CONFIG_ENABLE_MASK)
+#define SDIO_SETUP_CONFIG_CLEAR_MSB              0
+#define SDIO_SETUP_CONFIG_CLEAR_LSB              0
+#define SDIO_SETUP_CONFIG_CLEAR_MASK             0x00000001
+#define SDIO_SETUP_CONFIG_CLEAR_GET(x)           (((x) & SDIO_SETUP_CONFIG_CLEAR_MASK) >> SDIO_SETUP_CONFIG_CLEAR_LSB)
+#define SDIO_SETUP_CONFIG_CLEAR_SET(x)           (((x) << SDIO_SETUP_CONFIG_CLEAR_LSB) & SDIO_SETUP_CONFIG_CLEAR_MASK)
+
+#define CPU_SETUP_CIRCUIT_ADDRESS                0x0c0042c0
+#define CPU_SETUP_CIRCUIT_OFFSET                 0x000002c0
+#define CPU_SETUP_CIRCUIT_VECTOR_MSB             7
+#define CPU_SETUP_CIRCUIT_VECTOR_LSB             0
+#define CPU_SETUP_CIRCUIT_VECTOR_MASK            0x000000ff
+#define CPU_SETUP_CIRCUIT_VECTOR_GET(x)          (((x) & CPU_SETUP_CIRCUIT_VECTOR_MASK) >> CPU_SETUP_CIRCUIT_VECTOR_LSB)
+#define CPU_SETUP_CIRCUIT_VECTOR_SET(x)          (((x) << CPU_SETUP_CIRCUIT_VECTOR_LSB) & CPU_SETUP_CIRCUIT_VECTOR_MASK)
+
+#define MC_SETUP_CIRCUIT_ADDRESS                 0x0c0042e0
+#define MC_SETUP_CIRCUIT_OFFSET                  0x000002e0
+#define MC_SETUP_CIRCUIT_VECTOR_MSB              7
+#define MC_SETUP_CIRCUIT_VECTOR_LSB              0
+#define MC_SETUP_CIRCUIT_VECTOR_MASK             0x000000ff
+#define MC_SETUP_CIRCUIT_VECTOR_GET(x)           (((x) & MC_SETUP_CIRCUIT_VECTOR_MASK) >> MC_SETUP_CIRCUIT_VECTOR_LSB)
+#define MC_SETUP_CIRCUIT_VECTOR_SET(x)           (((x) << MC_SETUP_CIRCUIT_VECTOR_LSB) & MC_SETUP_CIRCUIT_VECTOR_MASK)
+
+#define BB_SETUP_CIRCUIT_ADDRESS                 0x0c004300
+#define BB_SETUP_CIRCUIT_OFFSET                  0x00000300
+#define BB_SETUP_CIRCUIT_VECTOR_MSB              7
+#define BB_SETUP_CIRCUIT_VECTOR_LSB              0
+#define BB_SETUP_CIRCUIT_VECTOR_MASK             0x000000ff
+#define BB_SETUP_CIRCUIT_VECTOR_GET(x)           (((x) & BB_SETUP_CIRCUIT_VECTOR_MASK) >> BB_SETUP_CIRCUIT_VECTOR_LSB)
+#define BB_SETUP_CIRCUIT_VECTOR_SET(x)           (((x) << BB_SETUP_CIRCUIT_VECTOR_LSB) & BB_SETUP_CIRCUIT_VECTOR_MASK)
+
+#define SDIO_SETUP_CIRCUIT_ADDRESS               0x0c004320
+#define SDIO_SETUP_CIRCUIT_OFFSET                0x00000320
+#define SDIO_SETUP_CIRCUIT_VECTOR_MSB            7
+#define SDIO_SETUP_CIRCUIT_VECTOR_LSB            0
+#define SDIO_SETUP_CIRCUIT_VECTOR_MASK           0x000000ff
+#define SDIO_SETUP_CIRCUIT_VECTOR_GET(x)         (((x) & SDIO_SETUP_CIRCUIT_VECTOR_MASK) >> SDIO_SETUP_CIRCUIT_VECTOR_LSB)
+#define SDIO_SETUP_CIRCUIT_VECTOR_SET(x)         (((x) << SDIO_SETUP_CIRCUIT_VECTOR_LSB) & SDIO_SETUP_CIRCUIT_VECTOR_MASK)
+
+#define TIMING_SUMMARY_ADDRESS                   0x0c004340
+#define TIMING_SUMMARY_OFFSET                    0x00000340
+#define TIMING_SUMMARY_VECTOR_MSB                7
+#define TIMING_SUMMARY_VECTOR_LSB                0
+#define TIMING_SUMMARY_VECTOR_MASK               0x000000ff
+#define TIMING_SUMMARY_VECTOR_GET(x)             (((x) & TIMING_SUMMARY_VECTOR_MASK) >> TIMING_SUMMARY_VECTOR_LSB)
+#define TIMING_SUMMARY_VECTOR_SET(x)             (((x) << TIMING_SUMMARY_VECTOR_LSB) & TIMING_SUMMARY_VECTOR_MASK)
+
+#define TIMING_INT_ENABLE_ADDRESS                0x0c004344
+#define TIMING_INT_ENABLE_OFFSET                 0x00000344
+#define TIMING_INT_ENABLE_VECTOR_MSB             7
+#define TIMING_INT_ENABLE_VECTOR_LSB             0
+#define TIMING_INT_ENABLE_VECTOR_MASK            0x000000ff
+#define TIMING_INT_ENABLE_VECTOR_GET(x)          (((x) & TIMING_INT_ENABLE_VECTOR_MASK) >> TIMING_INT_ENABLE_VECTOR_LSB)
+#define TIMING_INT_ENABLE_VECTOR_SET(x)          (((x) << TIMING_INT_ENABLE_VECTOR_LSB) & TIMING_INT_ENABLE_VECTOR_MASK)
+
+#define MC_ERROR_STATUS_ADDRESS                  0x0c004348
+#define MC_ERROR_STATUS_OFFSET                   0x00000348
+#define MC_ERROR_STATUS_AHB_MSB                  1
+#define MC_ERROR_STATUS_AHB_LSB                  1
+#define MC_ERROR_STATUS_AHB_MASK                 0x00000002
+#define MC_ERROR_STATUS_AHB_GET(x)               (((x) & MC_ERROR_STATUS_AHB_MASK) >> MC_ERROR_STATUS_AHB_LSB)
+#define MC_ERROR_STATUS_AHB_SET(x)               (((x) << MC_ERROR_STATUS_AHB_LSB) & MC_ERROR_STATUS_AHB_MASK)
+#define MC_ERROR_STATUS_TIMING_MSB               0
+#define MC_ERROR_STATUS_TIMING_LSB               0
+#define MC_ERROR_STATUS_TIMING_MASK              0x00000001
+#define MC_ERROR_STATUS_TIMING_GET(x)            (((x) & MC_ERROR_STATUS_TIMING_MASK) >> MC_ERROR_STATUS_TIMING_LSB)
+#define MC_ERROR_STATUS_TIMING_SET(x)            (((x) << MC_ERROR_STATUS_TIMING_LSB) & MC_ERROR_STATUS_TIMING_MASK)
+
+#ifndef __ASSEMBLER__
+typedef struct mc_reg_s {
+  volatile unsigned int bank0_addr;
+  volatile unsigned int bank0_config;
+  volatile unsigned int bank0_read;
+  volatile unsigned int bank0_write;
+  volatile unsigned int bank1_addr;
+  volatile unsigned int bank1_config;
+  volatile unsigned int bank1_read;
+  volatile unsigned int bank1_write;
+  volatile unsigned int bank2_addr;
+  volatile unsigned int bank2_config;
+  volatile unsigned int bank2_read;
+  volatile unsigned int bank2_write;
+  unsigned char pad0[80]; /* pad to 0x80 */
+  volatile unsigned int mc_remap_valid[32];
+  volatile unsigned int mc_remap_size[32];
+  volatile unsigned int mc_remap_compare[32];
+  volatile unsigned int mc_remap_target[32];
+  volatile unsigned int g729_rom;
+  volatile unsigned int error_valid;
+  volatile unsigned int ahb_error;
+  volatile unsigned int apb_error;
+  volatile unsigned int perf_config;
+  unsigned char pad1[12]; /* pad to 0x2a0 */
+  volatile unsigned int perf_counter[4];
+  volatile unsigned int cpu_setup_config;
+  volatile unsigned int mc_setup_config;
+  volatile unsigned int bb_setup_config;
+  volatile unsigned int sdio_setup_config;
+  volatile unsigned int cpu_setup_circuit[8];
+  volatile unsigned int mc_setup_circuit[8];
+  volatile unsigned int bb_setup_circuit[8];
+  volatile unsigned int sdio_setup_circuit[8];
+  volatile unsigned int timing_summary;
+  volatile unsigned int timing_int_enable;
+  volatile unsigned int mc_error_status;
+} mc_reg_t;
+#endif /* __ASSEMBLER__ */
+
+#endif /* _MC_H_ */

Added: developers/nbd/ar6k/include/hw/rtc_reg.h
===================================================================
--- developers/nbd/ar6k/include/hw/rtc_reg.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/hw/rtc_reg.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,1204 @@
+/*
+ * Copyright 2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+#ifndef _RTC_REG_H_
+#define _RTC_REG_H_
+
+#define RESET_CONTROL_ADDRESS                    0x0c000000
+#define RESET_CONTROL_OFFSET                     0x00000000
+#define RESET_CONTROL_RST_OUT_MSB                9
+#define RESET_CONTROL_RST_OUT_LSB                9
+#define RESET_CONTROL_RST_OUT_MASK               0x00000200
+#define RESET_CONTROL_RST_OUT_GET(x)             (((x) & RESET_CONTROL_RST_OUT_MASK) >> RESET_CONTROL_RST_OUT_LSB)
+#define RESET_CONTROL_RST_OUT_SET(x)             (((x) << RESET_CONTROL_RST_OUT_LSB) & RESET_CONTROL_RST_OUT_MASK)
+#define RESET_CONTROL_COLD_RST_MSB               8
+#define RESET_CONTROL_COLD_RST_LSB               8
+#define RESET_CONTROL_COLD_RST_MASK              0x00000100
+#define RESET_CONTROL_COLD_RST_GET(x)            (((x) & RESET_CONTROL_COLD_RST_MASK) >> RESET_CONTROL_COLD_RST_LSB)
+#define RESET_CONTROL_COLD_RST_SET(x)            (((x) << RESET_CONTROL_COLD_RST_LSB) & RESET_CONTROL_COLD_RST_MASK)
+#define RESET_CONTROL_WARM_RST_MSB               7
+#define RESET_CONTROL_WARM_RST_LSB               7
+#define RESET_CONTROL_WARM_RST_MASK              0x00000080
+#define RESET_CONTROL_WARM_RST_GET(x)            (((x) & RESET_CONTROL_WARM_RST_MASK) >> RESET_CONTROL_WARM_RST_LSB)
+#define RESET_CONTROL_WARM_RST_SET(x)            (((x) << RESET_CONTROL_WARM_RST_LSB) & RESET_CONTROL_WARM_RST_MASK)
+#define RESET_CONTROL_CPU_WARM_RST_MSB           6
+#define RESET_CONTROL_CPU_WARM_RST_LSB           6
+#define RESET_CONTROL_CPU_WARM_RST_MASK          0x00000040
+#define RESET_CONTROL_CPU_WARM_RST_GET(x)        (((x) & RESET_CONTROL_CPU_WARM_RST_MASK) >> RESET_CONTROL_CPU_WARM_RST_LSB)
+#define RESET_CONTROL_CPU_WARM_RST_SET(x)        (((x) << RESET_CONTROL_CPU_WARM_RST_LSB) & RESET_CONTROL_CPU_WARM_RST_MASK)
+#define RESET_CONTROL_MAC_COLD_RST_MSB           5
+#define RESET_CONTROL_MAC_COLD_RST_LSB           5
+#define RESET_CONTROL_MAC_COLD_RST_MASK          0x00000020
+#define RESET_CONTROL_MAC_COLD_RST_GET(x)        (((x) & RESET_CONTROL_MAC_COLD_RST_MASK) >> RESET_CONTROL_MAC_COLD_RST_LSB)
+#define RESET_CONTROL_MAC_COLD_RST_SET(x)        (((x) << RESET_CONTROL_MAC_COLD_RST_LSB) & RESET_CONTROL_MAC_COLD_RST_MASK)
+#define RESET_CONTROL_MAC_WARM_RST_MSB           4
+#define RESET_CONTROL_MAC_WARM_RST_LSB           4
+#define RESET_CONTROL_MAC_WARM_RST_MASK          0x00000010
+#define RESET_CONTROL_MAC_WARM_RST_GET(x)        (((x) & RESET_CONTROL_MAC_WARM_RST_MASK) >> RESET_CONTROL_MAC_WARM_RST_LSB)
+#define RESET_CONTROL_MAC_WARM_RST_SET(x)        (((x) << RESET_CONTROL_MAC_WARM_RST_LSB) & RESET_CONTROL_MAC_WARM_RST_MASK)
+#define RESET_CONTROL_MBOX_RST_MSB               2
+#define RESET_CONTROL_MBOX_RST_LSB               2
+#define RESET_CONTROL_MBOX_RST_MASK              0x00000004
+#define RESET_CONTROL_MBOX_RST_GET(x)            (((x) & RESET_CONTROL_MBOX_RST_MASK) >> RESET_CONTROL_MBOX_RST_LSB)
+#define RESET_CONTROL_MBOX_RST_SET(x)            (((x) << RESET_CONTROL_MBOX_RST_LSB) & RESET_CONTROL_MBOX_RST_MASK)
+#define RESET_CONTROL_UART_RST_MSB               1
+#define RESET_CONTROL_UART_RST_LSB               1
+#define RESET_CONTROL_UART_RST_MASK              0x00000002
+#define RESET_CONTROL_UART_RST_GET(x)            (((x) & RESET_CONTROL_UART_RST_MASK) >> RESET_CONTROL_UART_RST_LSB)
+#define RESET_CONTROL_UART_RST_SET(x)            (((x) << RESET_CONTROL_UART_RST_LSB) & RESET_CONTROL_UART_RST_MASK)
+#define RESET_CONTROL_SI0_RST_MSB                0
+#define RESET_CONTROL_SI0_RST_LSB                0
+#define RESET_CONTROL_SI0_RST_MASK               0x00000001
+#define RESET_CONTROL_SI0_RST_GET(x)             (((x) & RESET_CONTROL_SI0_RST_MASK) >> RESET_CONTROL_SI0_RST_LSB)
+#define RESET_CONTROL_SI0_RST_SET(x)             (((x) << RESET_CONTROL_SI0_RST_LSB) & RESET_CONTROL_SI0_RST_MASK)
+
+#define XTAL_CONTROL_ADDRESS                     0x0c000004
+#define XTAL_CONTROL_OFFSET                      0x00000004
+#define XTAL_CONTROL_TCXO_MSB                    0
+#define XTAL_CONTROL_TCXO_LSB                    0
+#define XTAL_CONTROL_TCXO_MASK                   0x00000001
+#define XTAL_CONTROL_TCXO_GET(x)                 (((x) & XTAL_CONTROL_TCXO_MASK) >> XTAL_CONTROL_TCXO_LSB)
+#define XTAL_CONTROL_TCXO_SET(x)                 (((x) << XTAL_CONTROL_TCXO_LSB) & XTAL_CONTROL_TCXO_MASK)
+
+#define TCXO_DETECT_ADDRESS                      0x0c000008
+#define TCXO_DETECT_OFFSET                       0x00000008
+#define TCXO_DETECT_PRESENT_MSB                  0
+#define TCXO_DETECT_PRESENT_LSB                  0
+#define TCXO_DETECT_PRESENT_MASK                 0x00000001
+#define TCXO_DETECT_PRESENT_GET(x)               (((x) & TCXO_DETECT_PRESENT_MASK) >> TCXO_DETECT_PRESENT_LSB)
+#define TCXO_DETECT_PRESENT_SET(x)               (((x) << TCXO_DETECT_PRESENT_LSB) & TCXO_DETECT_PRESENT_MASK)
+
+#define XTAL_TEST_ADDRESS                        0x0c00000c
+#define XTAL_TEST_OFFSET                         0x0000000c
+#define XTAL_TEST_NOTCXODET_MSB                  0
+#define XTAL_TEST_NOTCXODET_LSB                  0
+#define XTAL_TEST_NOTCXODET_MASK                 0x00000001
+#define XTAL_TEST_NOTCXODET_GET(x)               (((x) & XTAL_TEST_NOTCXODET_MASK) >> XTAL_TEST_NOTCXODET_LSB)
+#define XTAL_TEST_NOTCXODET_SET(x)               (((x) << XTAL_TEST_NOTCXODET_LSB) & XTAL_TEST_NOTCXODET_MASK)
+
+#define QUADRATURE_ADDRESS                       0x0c000010
+#define QUADRATURE_OFFSET                        0x00000010
+#define QUADRATURE_ADC_MSB                       5
+#define QUADRATURE_ADC_LSB                       4
+#define QUADRATURE_ADC_MASK                      0x00000030
+#define QUADRATURE_ADC_GET(x)                    (((x) & QUADRATURE_ADC_MASK) >> QUADRATURE_ADC_LSB)
+#define QUADRATURE_ADC_SET(x)                    (((x) << QUADRATURE_ADC_LSB) & QUADRATURE_ADC_MASK)
+#define QUADRATURE_SEL_MSB                       2
+#define QUADRATURE_SEL_LSB                       2
+#define QUADRATURE_SEL_MASK                      0x00000004
+#define QUADRATURE_SEL_GET(x)                    (((x) & QUADRATURE_SEL_MASK) >> QUADRATURE_SEL_LSB)
+#define QUADRATURE_SEL_SET(x)                    (((x) << QUADRATURE_SEL_LSB) & QUADRATURE_SEL_MASK)
+#define QUADRATURE_DAC_MSB                       1
+#define QUADRATURE_DAC_LSB                       0
+#define QUADRATURE_DAC_MASK                      0x00000003
+#define QUADRATURE_DAC_GET(x)                    (((x) & QUADRATURE_DAC_MASK) >> QUADRATURE_DAC_LSB)
+#define QUADRATURE_DAC_SET(x)                    (((x) << QUADRATURE_DAC_LSB) & QUADRATURE_DAC_MASK)
+
+#define PLL_CONTROL_ADDRESS                      0x0c000014
+#define PLL_CONTROL_OFFSET                       0x00000014
+#define PLL_CONTROL_DIG_TEST_CLK_MSB             20
+#define PLL_CONTROL_DIG_TEST_CLK_LSB             20
+#define PLL_CONTROL_DIG_TEST_CLK_MASK            0x00100000
+#define PLL_CONTROL_DIG_TEST_CLK_GET(x)          (((x) & PLL_CONTROL_DIG_TEST_CLK_MASK) >> PLL_CONTROL_DIG_TEST_CLK_LSB)
+#define PLL_CONTROL_DIG_TEST_CLK_SET(x)          (((x) << PLL_CONTROL_DIG_TEST_CLK_LSB) & PLL_CONTROL_DIG_TEST_CLK_MASK)
+#define PLL_CONTROL_MAC_OVERRIDE_MSB             19
+#define PLL_CONTROL_MAC_OVERRIDE_LSB             19
+#define PLL_CONTROL_MAC_OVERRIDE_MASK            0x00080000
+#define PLL_CONTROL_MAC_OVERRIDE_GET(x)          (((x) & PLL_CONTROL_MAC_OVERRIDE_MASK) >> PLL_CONTROL_MAC_OVERRIDE_LSB)
+#define PLL_CONTROL_MAC_OVERRIDE_SET(x)          (((x) << PLL_CONTROL_MAC_OVERRIDE_LSB) & PLL_CONTROL_MAC_OVERRIDE_MASK)
+#define PLL_CONTROL_NOPWD_MSB                    18
+#define PLL_CONTROL_NOPWD_LSB                    18
+#define PLL_CONTROL_NOPWD_MASK                   0x00040000
+#define PLL_CONTROL_NOPWD_GET(x)                 (((x) & PLL_CONTROL_NOPWD_MASK) >> PLL_CONTROL_NOPWD_LSB)
+#define PLL_CONTROL_NOPWD_SET(x)                 (((x) << PLL_CONTROL_NOPWD_LSB) & PLL_CONTROL_NOPWD_MASK)
+#define PLL_CONTROL_UPDATING_MSB                 17
+#define PLL_CONTROL_UPDATING_LSB                 17
+#define PLL_CONTROL_UPDATING_MASK                0x00020000
+#define PLL_CONTROL_UPDATING_GET(x)              (((x) & PLL_CONTROL_UPDATING_MASK) >> PLL_CONTROL_UPDATING_LSB)
+#define PLL_CONTROL_UPDATING_SET(x)              (((x) << PLL_CONTROL_UPDATING_LSB) & PLL_CONTROL_UPDATING_MASK)
+#define PLL_CONTROL_BYPASS_MSB                   16
+#define PLL_CONTROL_BYPASS_LSB                   16
+#define PLL_CONTROL_BYPASS_MASK                  0x00010000
+#define PLL_CONTROL_BYPASS_GET(x)                (((x) & PLL_CONTROL_BYPASS_MASK) >> PLL_CONTROL_BYPASS_LSB)
+#define PLL_CONTROL_BYPASS_SET(x)                (((x) << PLL_CONTROL_BYPASS_LSB) & PLL_CONTROL_BYPASS_MASK)
+#define PLL_CONTROL_REFDIV_MSB                   15
+#define PLL_CONTROL_REFDIV_LSB                   12
+#define PLL_CONTROL_REFDIV_MASK                  0x0000f000
+#define PLL_CONTROL_REFDIV_GET(x)                (((x) & PLL_CONTROL_REFDIV_MASK) >> PLL_CONTROL_REFDIV_LSB)
+#define PLL_CONTROL_REFDIV_SET(x)                (((x) << PLL_CONTROL_REFDIV_LSB) & PLL_CONTROL_REFDIV_MASK)
+#define PLL_CONTROL_DIV_MSB                      9
+#define PLL_CONTROL_DIV_LSB                      0
+#define PLL_CONTROL_DIV_MASK                     0x000003ff
+#define PLL_CONTROL_DIV_GET(x)                   (((x) & PLL_CONTROL_DIV_MASK) >> PLL_CONTROL_DIV_LSB)
+#define PLL_CONTROL_DIV_SET(x)                   (((x) << PLL_CONTROL_DIV_LSB) & PLL_CONTROL_DIV_MASK)
+
+#define PLL_SETTLE_ADDRESS                       0x0c000018
+#define PLL_SETTLE_OFFSET                        0x00000018
+#define PLL_SETTLE_TIME_MSB                      10
+#define PLL_SETTLE_TIME_LSB                      0
+#define PLL_SETTLE_TIME_MASK                     0x000007ff
+#define PLL_SETTLE_TIME_GET(x)                   (((x) & PLL_SETTLE_TIME_MASK) >> PLL_SETTLE_TIME_LSB)
+#define PLL_SETTLE_TIME_SET(x)                   (((x) << PLL_SETTLE_TIME_LSB) & PLL_SETTLE_TIME_MASK)
+
+#define XTAL_SETTLE_ADDRESS                      0x0c00001c
+#define XTAL_SETTLE_OFFSET                       0x0000001c
+#define XTAL_SETTLE_TIME_MSB                     6
+#define XTAL_SETTLE_TIME_LSB                     0
+#define XTAL_SETTLE_TIME_MASK                    0x0000007f
+#define XTAL_SETTLE_TIME_GET(x)                  (((x) & XTAL_SETTLE_TIME_MASK) >> XTAL_SETTLE_TIME_LSB)
+#define XTAL_SETTLE_TIME_SET(x)                  (((x) << XTAL_SETTLE_TIME_LSB) & XTAL_SETTLE_TIME_MASK)
+
+#define CORE_CLOCK_ADDRESS                       0x0c000020
+#define CORE_CLOCK_OFFSET                        0x00000020
+#define CORE_CLOCK_DIG_TEST_MSB                  12
+#define CORE_CLOCK_DIG_TEST_LSB                  12
+#define CORE_CLOCK_DIG_TEST_MASK                 0x00001000
+#define CORE_CLOCK_DIG_TEST_GET(x)               (((x) & CORE_CLOCK_DIG_TEST_MASK) >> CORE_CLOCK_DIG_TEST_LSB)
+#define CORE_CLOCK_DIG_TEST_SET(x)               (((x) << CORE_CLOCK_DIG_TEST_LSB) & CORE_CLOCK_DIG_TEST_MASK)
+#define CORE_CLOCK_STANDARD_MSB                  9
+#define CORE_CLOCK_STANDARD_LSB                  8
+#define CORE_CLOCK_STANDARD_MASK                 0x00000300
+#define CORE_CLOCK_STANDARD_GET(x)               (((x) & CORE_CLOCK_STANDARD_MASK) >> CORE_CLOCK_STANDARD_LSB)
+#define CORE_CLOCK_STANDARD_SET(x)               (((x) << CORE_CLOCK_STANDARD_LSB) & CORE_CLOCK_STANDARD_MASK)
+#define CORE_CLOCK_REDUCED_MSB                   1
+#define CORE_CLOCK_REDUCED_LSB                   0
+#define CORE_CLOCK_REDUCED_MASK                  0x00000003
+#define CORE_CLOCK_REDUCED_GET(x)                (((x) & CORE_CLOCK_REDUCED_MASK) >> CORE_CLOCK_REDUCED_LSB)
+#define CORE_CLOCK_REDUCED_SET(x)                (((x) << CORE_CLOCK_REDUCED_LSB) & CORE_CLOCK_REDUCED_MASK)
+
+#define CPU_CLOCK_ADDRESS                        0x0c000024
+#define CPU_CLOCK_OFFSET                         0x00000024
+#define CPU_CLOCK_DISABLE_SYNC_MSB               12
+#define CPU_CLOCK_DISABLE_SYNC_LSB               12
+#define CPU_CLOCK_DISABLE_SYNC_MASK              0x00001000
+#define CPU_CLOCK_DISABLE_SYNC_GET(x)            (((x) & CPU_CLOCK_DISABLE_SYNC_MASK) >> CPU_CLOCK_DISABLE_SYNC_LSB)
+#define CPU_CLOCK_DISABLE_SYNC_SET(x)            (((x) << CPU_CLOCK_DISABLE_SYNC_LSB) & CPU_CLOCK_DISABLE_SYNC_MASK)
+#define CPU_CLOCK_STANDARD_MSB                   9
+#define CPU_CLOCK_STANDARD_LSB                   8
+#define CPU_CLOCK_STANDARD_MASK                  0x00000300
+#define CPU_CLOCK_STANDARD_GET(x)                (((x) & CPU_CLOCK_STANDARD_MASK) >> CPU_CLOCK_STANDARD_LSB)
+#define CPU_CLOCK_STANDARD_SET(x)                (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK)
+#define CPU_CLOCK_REDUCED_MSB                    1
+#define CPU_CLOCK_REDUCED_LSB                    0
+#define CPU_CLOCK_REDUCED_MASK                   0x00000003
+#define CPU_CLOCK_REDUCED_GET(x)                 (((x) & CPU_CLOCK_REDUCED_MASK) >> CPU_CLOCK_REDUCED_LSB)
+#define CPU_CLOCK_REDUCED_SET(x)                 (((x) << CPU_CLOCK_REDUCED_LSB) & CPU_CLOCK_REDUCED_MASK)
+
+#define CLOCK_OUT_ADDRESS                        0x0c000028
+#define CLOCK_OUT_OFFSET                         0x00000028
+#define CLOCK_OUT_SELECT_MSB                     3
+#define CLOCK_OUT_SELECT_LSB                     0
+#define CLOCK_OUT_SELECT_MASK                    0x0000000f
+#define CLOCK_OUT_SELECT_GET(x)                  (((x) & CLOCK_OUT_SELECT_MASK) >> CLOCK_OUT_SELECT_LSB)
+#define CLOCK_OUT_SELECT_SET(x)                  (((x) << CLOCK_OUT_SELECT_LSB) & CLOCK_OUT_SELECT_MASK)
+
+#define CLOCK_CONTROL_ADDRESS                    0x0c00002c
+#define CLOCK_CONTROL_OFFSET                     0x0000002c
+#define CLOCK_CONTROL_UART_CLK_MSB               1
+#define CLOCK_CONTROL_UART_CLK_LSB               1
+#define CLOCK_CONTROL_UART_CLK_MASK              0x00000002
+#define CLOCK_CONTROL_UART_CLK_GET(x)            (((x) & CLOCK_CONTROL_UART_CLK_MASK) >> CLOCK_CONTROL_UART_CLK_LSB)
+#define CLOCK_CONTROL_UART_CLK_SET(x)            (((x) << CLOCK_CONTROL_UART_CLK_LSB) & CLOCK_CONTROL_UART_CLK_MASK)
+#define CLOCK_CONTROL_SI0_CLK_MSB                0
+#define CLOCK_CONTROL_SI0_CLK_LSB                0
+#define CLOCK_CONTROL_SI0_CLK_MASK               0x00000001
+#define CLOCK_CONTROL_SI0_CLK_GET(x)             (((x) & CLOCK_CONTROL_SI0_CLK_MASK) >> CLOCK_CONTROL_SI0_CLK_LSB)
+#define CLOCK_CONTROL_SI0_CLK_SET(x)             (((x) << CLOCK_CONTROL_SI0_CLK_LSB) & CLOCK_CONTROL_SI0_CLK_MASK)
+
+#define BIAS_OVERRIDE_ADDRESS                    0x0c000030
+#define BIAS_OVERRIDE_OFFSET                     0x00000030
+#define BIAS_OVERRIDE_ON_MSB                     0
+#define BIAS_OVERRIDE_ON_LSB                     0
+#define BIAS_OVERRIDE_ON_MASK                    0x00000001
+#define BIAS_OVERRIDE_ON_GET(x)                  (((x) & BIAS_OVERRIDE_ON_MASK) >> BIAS_OVERRIDE_ON_LSB)
+#define BIAS_OVERRIDE_ON_SET(x)                  (((x) << BIAS_OVERRIDE_ON_LSB) & BIAS_OVERRIDE_ON_MASK)
+
+#define REF_VOLTAGE_TRIM_ADDRESS                 0x0c000034
+#define REF_VOLTAGE_TRIM_OFFSET                  0x00000034
+#define REF_VOLTAGE_TRIM_REFSEL_MSB              3
+#define REF_VOLTAGE_TRIM_REFSEL_LSB              0
+#define REF_VOLTAGE_TRIM_REFSEL_MASK             0x0000000f
+#define REF_VOLTAGE_TRIM_REFSEL_GET(x)           (((x) & REF_VOLTAGE_TRIM_REFSEL_MASK) >> REF_VOLTAGE_TRIM_REFSEL_LSB)
+#define REF_VOLTAGE_TRIM_REFSEL_SET(x)           (((x) << REF_VOLTAGE_TRIM_REFSEL_LSB) & REF_VOLTAGE_TRIM_REFSEL_MASK)
+
+#define LDO_CONTROL_ADDRESS                      0x0c000038
+#define LDO_CONTROL_OFFSET                       0x00000038
+#define LDO_CONTROL_CORE_LIMIT_OFF_MSB           14
+#define LDO_CONTROL_CORE_LIMIT_OFF_LSB           14
+#define LDO_CONTROL_CORE_LIMIT_OFF_MASK          0x00004000
+#define LDO_CONTROL_CORE_LIMIT_OFF_GET(x)        (((x) & LDO_CONTROL_CORE_LIMIT_OFF_MASK) >> LDO_CONTROL_CORE_LIMIT_OFF_LSB)
+#define LDO_CONTROL_CORE_LIMIT_OFF_SET(x)        (((x) << LDO_CONTROL_CORE_LIMIT_OFF_LSB) & LDO_CONTROL_CORE_LIMIT_OFF_MASK)
+#define LDO_CONTROL_CORE_LIMIT_MSB               13
+#define LDO_CONTROL_CORE_LIMIT_LSB               11
+#define LDO_CONTROL_CORE_LIMIT_MASK              0x00003800
+#define LDO_CONTROL_CORE_LIMIT_GET(x)            (((x) & LDO_CONTROL_CORE_LIMIT_MASK) >> LDO_CONTROL_CORE_LIMIT_LSB)
+#define LDO_CONTROL_CORE_LIMIT_SET(x)            (((x) << LDO_CONTROL_CORE_LIMIT_LSB) & LDO_CONTROL_CORE_LIMIT_MASK)
+#define LDO_CONTROL_CORE_REG_Z_MSB               10
+#define LDO_CONTROL_CORE_REG_Z_LSB               8
+#define LDO_CONTROL_CORE_REG_Z_MASK              0x00000700
+#define LDO_CONTROL_CORE_REG_Z_GET(x)            (((x) & LDO_CONTROL_CORE_REG_Z_MASK) >> LDO_CONTROL_CORE_REG_Z_LSB)
+#define LDO_CONTROL_CORE_REG_Z_SET(x)            (((x) << LDO_CONTROL_CORE_REG_Z_LSB) & LDO_CONTROL_CORE_REG_Z_MASK)
+#define LDO_CONTROL_RADIO_LIMIT_OFF_MSB          6
+#define LDO_CONTROL_RADIO_LIMIT_OFF_LSB          6
+#define LDO_CONTROL_RADIO_LIMIT_OFF_MASK         0x00000040
+#define LDO_CONTROL_RADIO_LIMIT_OFF_GET(x)       (((x) & LDO_CONTROL_RADIO_LIMIT_OFF_MASK) >> LDO_CONTROL_RADIO_LIMIT_OFF_LSB)
+#define LDO_CONTROL_RADIO_LIMIT_OFF_SET(x)       (((x) << LDO_CONTROL_RADIO_LIMIT_OFF_LSB) & LDO_CONTROL_RADIO_LIMIT_OFF_MASK)
+#define LDO_CONTROL_RADIO_LIMIT_MSB              5
+#define LDO_CONTROL_RADIO_LIMIT_LSB              3
+#define LDO_CONTROL_RADIO_LIMIT_MASK             0x00000038
+#define LDO_CONTROL_RADIO_LIMIT_GET(x)           (((x) & LDO_CONTROL_RADIO_LIMIT_MASK) >> LDO_CONTROL_RADIO_LIMIT_LSB)
+#define LDO_CONTROL_RADIO_LIMIT_SET(x)           (((x) << LDO_CONTROL_RADIO_LIMIT_LSB) & LDO_CONTROL_RADIO_LIMIT_MASK)
+#define LDO_CONTROL_RADIO_REG_Z_MSB              2
+#define LDO_CONTROL_RADIO_REG_Z_LSB              0
+#define LDO_CONTROL_RADIO_REG_Z_MASK             0x00000007
+#define LDO_CONTROL_RADIO_REG_Z_GET(x)           (((x) & LDO_CONTROL_RADIO_REG_Z_MASK) >> LDO_CONTROL_RADIO_REG_Z_LSB)
+#define LDO_CONTROL_RADIO_REG_Z_SET(x)           (((x) << LDO_CONTROL_RADIO_REG_Z_LSB) & LDO_CONTROL_RADIO_REG_Z_MASK)
+
+#define WDT_CONTROL_ADDRESS                      0x0c00003c
+#define WDT_CONTROL_OFFSET                       0x0000003c
+#define WDT_CONTROL_ACTION_MSB                   2
+#define WDT_CONTROL_ACTION_LSB                   0
+#define WDT_CONTROL_ACTION_MASK                  0x00000007
+#define WDT_CONTROL_ACTION_GET(x)                (((x) & WDT_CONTROL_ACTION_MASK) >> WDT_CONTROL_ACTION_LSB)
+#define WDT_CONTROL_ACTION_SET(x)                (((x) << WDT_CONTROL_ACTION_LSB) & WDT_CONTROL_ACTION_MASK)
+
+#define WDT_STATUS_ADDRESS                       0x0c000040
+#define WDT_STATUS_OFFSET                        0x00000040
+#define WDT_STATUS_INTERRUPT_MSB                 0
+#define WDT_STATUS_INTERRUPT_LSB                 0
+#define WDT_STATUS_INTERRUPT_MASK                0x00000001
+#define WDT_STATUS_INTERRUPT_GET(x)              (((x) & WDT_STATUS_INTERRUPT_MASK) >> WDT_STATUS_INTERRUPT_LSB)
+#define WDT_STATUS_INTERRUPT_SET(x)              (((x) << WDT_STATUS_INTERRUPT_LSB) & WDT_STATUS_INTERRUPT_MASK)
+
+#define WDT_ADDRESS                              0x0c000044
+#define WDT_OFFSET                               0x00000044
+#define WDT_TARGET_MSB                           21
+#define WDT_TARGET_LSB                           0
+#define WDT_TARGET_MASK                          0x003fffff
+#define WDT_TARGET_GET(x)                        (((x) & WDT_TARGET_MASK) >> WDT_TARGET_LSB)
+#define WDT_TARGET_SET(x)                        (((x) << WDT_TARGET_LSB) & WDT_TARGET_MASK)
+
+#define WDT_COUNT_ADDRESS                        0x0c000048
+#define WDT_COUNT_OFFSET                         0x00000048
+#define WDT_COUNT_VALUE_MSB                      21
+#define WDT_COUNT_VALUE_LSB                      0
+#define WDT_COUNT_VALUE_MASK                     0x003fffff
+#define WDT_COUNT_VALUE_GET(x)                   (((x) & WDT_COUNT_VALUE_MASK) >> WDT_COUNT_VALUE_LSB)
+#define WDT_COUNT_VALUE_SET(x)                   (((x) << WDT_COUNT_VALUE_LSB) & WDT_COUNT_VALUE_MASK)
+
+#define WDT_RESET_ADDRESS                        0x0c00004c
+#define WDT_RESET_OFFSET                         0x0000004c
+#define WDT_RESET_VALUE_MSB                      0
+#define WDT_RESET_VALUE_LSB                      0
+#define WDT_RESET_VALUE_MASK                     0x00000001
+#define WDT_RESET_VALUE_GET(x)                   (((x) & WDT_RESET_VALUE_MASK) >> WDT_RESET_VALUE_LSB)
+#define WDT_RESET_VALUE_SET(x)                   (((x) << WDT_RESET_VALUE_LSB) & WDT_RESET_VALUE_MASK)
+
+#define INT_STATUS_ADDRESS                       0x0c000050
+#define INT_STATUS_OFFSET                        0x00000050
+#define INT_STATUS_TIMER_MSB                     14
+#define INT_STATUS_TIMER_LSB                     14
+#define INT_STATUS_TIMER_MASK                    0x00004000
+#define INT_STATUS_TIMER_GET(x)                  (((x) & INT_STATUS_TIMER_MASK) >> INT_STATUS_TIMER_LSB)
+#define INT_STATUS_TIMER_SET(x)                  (((x) << INT_STATUS_TIMER_LSB) & INT_STATUS_TIMER_MASK)
+#define INT_STATUS_MAC_MSB                       13
+#define INT_STATUS_MAC_LSB                       13
+#define INT_STATUS_MAC_MASK                      0x00002000
+#define INT_STATUS_MAC_GET(x)                    (((x) & INT_STATUS_MAC_MASK) >> INT_STATUS_MAC_LSB)
+#define INT_STATUS_MAC_SET(x)                    (((x) << INT_STATUS_MAC_LSB) & INT_STATUS_MAC_MASK)
+#define INT_STATUS_MAILBOX_MSB                   12
+#define INT_STATUS_MAILBOX_LSB                   12
+#define INT_STATUS_MAILBOX_MASK                  0x00001000
+#define INT_STATUS_MAILBOX_GET(x)                (((x) & INT_STATUS_MAILBOX_MASK) >> INT_STATUS_MAILBOX_LSB)
+#define INT_STATUS_MAILBOX_SET(x)                (((x) << INT_STATUS_MAILBOX_LSB) & INT_STATUS_MAILBOX_MASK)
+#define INT_STATUS_RTC_ALARM_MSB                 11
+#define INT_STATUS_RTC_ALARM_LSB                 11
+#define INT_STATUS_RTC_ALARM_MASK                0x00000800
+#define INT_STATUS_RTC_ALARM_GET(x)              (((x) & INT_STATUS_RTC_ALARM_MASK) >> INT_STATUS_RTC_ALARM_LSB)
+#define INT_STATUS_RTC_ALARM_SET(x)              (((x) << INT_STATUS_RTC_ALARM_LSB) & INT_STATUS_RTC_ALARM_MASK)
+#define INT_STATUS_HF_TIMER_MSB                  10
+#define INT_STATUS_HF_TIMER_LSB                  10
+#define INT_STATUS_HF_TIMER_MASK                 0x00000400
+#define INT_STATUS_HF_TIMER_GET(x)               (((x) & INT_STATUS_HF_TIMER_MASK) >> INT_STATUS_HF_TIMER_LSB)
+#define INT_STATUS_HF_TIMER_SET(x)               (((x) << INT_STATUS_HF_TIMER_LSB) & INT_STATUS_HF_TIMER_MASK)
+#define INT_STATUS_LF_TIMER3_MSB                 9
+#define INT_STATUS_LF_TIMER3_LSB                 9
+#define INT_STATUS_LF_TIMER3_MASK                0x00000200
+#define INT_STATUS_LF_TIMER3_GET(x)              (((x) & INT_STATUS_LF_TIMER3_MASK) >> INT_STATUS_LF_TIMER3_LSB)
+#define INT_STATUS_LF_TIMER3_SET(x)              (((x) << INT_STATUS_LF_TIMER3_LSB) & INT_STATUS_LF_TIMER3_MASK)
+#define INT_STATUS_LF_TIMER2_MSB                 8
+#define INT_STATUS_LF_TIMER2_LSB                 8
+#define INT_STATUS_LF_TIMER2_MASK                0x00000100
+#define INT_STATUS_LF_TIMER2_GET(x)              (((x) & INT_STATUS_LF_TIMER2_MASK) >> INT_STATUS_LF_TIMER2_LSB)
+#define INT_STATUS_LF_TIMER2_SET(x)              (((x) << INT_STATUS_LF_TIMER2_LSB) & INT_STATUS_LF_TIMER2_MASK)
+#define INT_STATUS_LF_TIMER1_MSB                 7
+#define INT_STATUS_LF_TIMER1_LSB                 7
+#define INT_STATUS_LF_TIMER1_MASK                0x00000080
+#define INT_STATUS_LF_TIMER1_GET(x)              (((x) & INT_STATUS_LF_TIMER1_MASK) >> INT_STATUS_LF_TIMER1_LSB)
+#define INT_STATUS_LF_TIMER1_SET(x)              (((x) << INT_STATUS_LF_TIMER1_LSB) & INT_STATUS_LF_TIMER1_MASK)
+#define INT_STATUS_LF_TIMER0_MSB                 6
+#define INT_STATUS_LF_TIMER0_LSB                 6
+#define INT_STATUS_LF_TIMER0_MASK                0x00000040
+#define INT_STATUS_LF_TIMER0_GET(x)              (((x) & INT_STATUS_LF_TIMER0_MASK) >> INT_STATUS_LF_TIMER0_LSB)
+#define INT_STATUS_LF_TIMER0_SET(x)              (((x) << INT_STATUS_LF_TIMER0_LSB) & INT_STATUS_LF_TIMER0_MASK)
+#define INT_STATUS_KEYPAD_MSB                    5
+#define INT_STATUS_KEYPAD_LSB                    5
+#define INT_STATUS_KEYPAD_MASK                   0x00000020
+#define INT_STATUS_KEYPAD_GET(x)                 (((x) & INT_STATUS_KEYPAD_MASK) >> INT_STATUS_KEYPAD_LSB)
+#define INT_STATUS_KEYPAD_SET(x)                 (((x) << INT_STATUS_KEYPAD_LSB) & INT_STATUS_KEYPAD_MASK)
+#define INT_STATUS_SI_MSB                        4
+#define INT_STATUS_SI_LSB                        4
+#define INT_STATUS_SI_MASK                       0x00000010
+#define INT_STATUS_SI_GET(x)                     (((x) & INT_STATUS_SI_MASK) >> INT_STATUS_SI_LSB)
+#define INT_STATUS_SI_SET(x)                     (((x) << INT_STATUS_SI_LSB) & INT_STATUS_SI_MASK)
+#define INT_STATUS_GPIO_MSB                      3
+#define INT_STATUS_GPIO_LSB                      3
+#define INT_STATUS_GPIO_MASK                     0x00000008
+#define INT_STATUS_GPIO_GET(x)                   (((x) & INT_STATUS_GPIO_MASK) >> INT_STATUS_GPIO_LSB)
+#define INT_STATUS_GPIO_SET(x)                   (((x) << INT_STATUS_GPIO_LSB) & INT_STATUS_GPIO_MASK)
+#define INT_STATUS_UART_MSB                      2
+#define INT_STATUS_UART_LSB                      2
+#define INT_STATUS_UART_MASK                     0x00000004
+#define INT_STATUS_UART_GET(x)                   (((x) & INT_STATUS_UART_MASK) >> INT_STATUS_UART_LSB)
+#define INT_STATUS_UART_SET(x)                   (((x) << INT_STATUS_UART_LSB) & INT_STATUS_UART_MASK)
+#define INT_STATUS_ERROR_MSB                     1
+#define INT_STATUS_ERROR_LSB                     1
+#define INT_STATUS_ERROR_MASK                    0x00000002
+#define INT_STATUS_ERROR_GET(x)                  (((x) & INT_STATUS_ERROR_MASK) >> INT_STATUS_ERROR_LSB)
+#define INT_STATUS_ERROR_SET(x)                  (((x) << INT_STATUS_ERROR_LSB) & INT_STATUS_ERROR_MASK)
+#define INT_STATUS_WDT_INT_MSB                   0
+#define INT_STATUS_WDT_INT_LSB                   0
+#define INT_STATUS_WDT_INT_MASK                  0x00000001
+#define INT_STATUS_WDT_INT_GET(x)                (((x) & INT_STATUS_WDT_INT_MASK) >> INT_STATUS_WDT_INT_LSB)
+#define INT_STATUS_WDT_INT_SET(x)                (((x) << INT_STATUS_WDT_INT_LSB) & INT_STATUS_WDT_INT_MASK)
+
+#define LF_TIMER0_ADDRESS                        0x0c000054
+#define LF_TIMER0_OFFSET                         0x00000054
+#define LF_TIMER0_TARGET_MSB                     31
+#define LF_TIMER0_TARGET_LSB                     0
+#define LF_TIMER0_TARGET_MASK                    0xffffffff
+#define LF_TIMER0_TARGET_GET(x)                  (((x) & LF_TIMER0_TARGET_MASK) >> LF_TIMER0_TARGET_LSB)
+#define LF_TIMER0_TARGET_SET(x)                  (((x) << LF_TIMER0_TARGET_LSB) & LF_TIMER0_TARGET_MASK)
+
+#define LF_TIMER_COUNT0_ADDRESS                  0x0c000058
+#define LF_TIMER_COUNT0_OFFSET                   0x00000058
+#define LF_TIMER_COUNT0_VALUE_MSB                31
+#define LF_TIMER_COUNT0_VALUE_LSB                0
+#define LF_TIMER_COUNT0_VALUE_MASK               0xffffffff
+#define LF_TIMER_COUNT0_VALUE_GET(x)             (((x) & LF_TIMER_COUNT0_VALUE_MASK) >> LF_TIMER_COUNT0_VALUE_LSB)
+#define LF_TIMER_COUNT0_VALUE_SET(x)             (((x) << LF_TIMER_COUNT0_VALUE_LSB) & LF_TIMER_COUNT0_VALUE_MASK)
+
+#define LF_TIMER_CONTROL0_ADDRESS                0x0c00005c
+#define LF_TIMER_CONTROL0_OFFSET                 0x0000005c
+#define LF_TIMER_CONTROL0_ENABLE_MSB             2
+#define LF_TIMER_CONTROL0_ENABLE_LSB             2
+#define LF_TIMER_CONTROL0_ENABLE_MASK            0x00000004
+#define LF_TIMER_CONTROL0_ENABLE_GET(x)          (((x) & LF_TIMER_CONTROL0_ENABLE_MASK) >> LF_TIMER_CONTROL0_ENABLE_LSB)
+#define LF_TIMER_CONTROL0_ENABLE_SET(x)          (((x) << LF_TIMER_CONTROL0_ENABLE_LSB) & LF_TIMER_CONTROL0_ENABLE_MASK)
+#define LF_TIMER_CONTROL0_AUTO_RESTART_MSB       1
+#define LF_TIMER_CONTROL0_AUTO_RESTART_LSB       1
+#define LF_TIMER_CONTROL0_AUTO_RESTART_MASK      0x00000002
+#define LF_TIMER_CONTROL0_AUTO_RESTART_GET(x)    (((x) & LF_TIMER_CONTROL0_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL0_AUTO_RESTART_LSB)
+#define LF_TIMER_CONTROL0_AUTO_RESTART_SET(x)    (((x) << LF_TIMER_CONTROL0_AUTO_RESTART_LSB) & LF_TIMER_CONTROL0_AUTO_RESTART_MASK)
+#define LF_TIMER_CONTROL0_RESET_MSB              0
+#define LF_TIMER_CONTROL0_RESET_LSB              0
+#define LF_TIMER_CONTROL0_RESET_MASK             0x00000001
+#define LF_TIMER_CONTROL0_RESET_GET(x)           (((x) & LF_TIMER_CONTROL0_RESET_MASK) >> LF_TIMER_CONTROL0_RESET_LSB)
+#define LF_TIMER_CONTROL0_RESET_SET(x)           (((x) << LF_TIMER_CONTROL0_RESET_LSB) & LF_TIMER_CONTROL0_RESET_MASK)
+
+#define LF_TIMER_STATUS0_ADDRESS                 0x0c000060
+#define LF_TIMER_STATUS0_OFFSET                  0x00000060
+#define LF_TIMER_STATUS0_INTERRUPT_MSB           0
+#define LF_TIMER_STATUS0_INTERRUPT_LSB           0
+#define LF_TIMER_STATUS0_INTERRUPT_MASK          0x00000001
+#define LF_TIMER_STATUS0_INTERRUPT_GET(x)        (((x) & LF_TIMER_STATUS0_INTERRUPT_MASK) >> LF_TIMER_STATUS0_INTERRUPT_LSB)
+#define LF_TIMER_STATUS0_INTERRUPT_SET(x)        (((x) << LF_TIMER_STATUS0_INTERRUPT_LSB) & LF_TIMER_STATUS0_INTERRUPT_MASK)
+
+#define LF_TIMER1_ADDRESS                        0x0c000064
+#define LF_TIMER1_OFFSET                         0x00000064
+#define LF_TIMER1_TARGET_MSB                     31
+#define LF_TIMER1_TARGET_LSB                     0
+#define LF_TIMER1_TARGET_MASK                    0xffffffff
+#define LF_TIMER1_TARGET_GET(x)                  (((x) & LF_TIMER1_TARGET_MASK) >> LF_TIMER1_TARGET_LSB)
+#define LF_TIMER1_TARGET_SET(x)                  (((x) << LF_TIMER1_TARGET_LSB) & LF_TIMER1_TARGET_MASK)
+
+#define LF_TIMER_COUNT1_ADDRESS                  0x0c000068
+#define LF_TIMER_COUNT1_OFFSET                   0x00000068
+#define LF_TIMER_COUNT1_VALUE_MSB                31
+#define LF_TIMER_COUNT1_VALUE_LSB                0
+#define LF_TIMER_COUNT1_VALUE_MASK               0xffffffff
+#define LF_TIMER_COUNT1_VALUE_GET(x)             (((x) & LF_TIMER_COUNT1_VALUE_MASK) >> LF_TIMER_COUNT1_VALUE_LSB)
+#define LF_TIMER_COUNT1_VALUE_SET(x)             (((x) << LF_TIMER_COUNT1_VALUE_LSB) & LF_TIMER_COUNT1_VALUE_MASK)
+
+#define LF_TIMER_CONTROL1_ADDRESS                0x0c00006c
+#define LF_TIMER_CONTROL1_OFFSET                 0x0000006c
+#define LF_TIMER_CONTROL1_ENABLE_MSB             2
+#define LF_TIMER_CONTROL1_ENABLE_LSB             2
+#define LF_TIMER_CONTROL1_ENABLE_MASK            0x00000004
+#define LF_TIMER_CONTROL1_ENABLE_GET(x)          (((x) & LF_TIMER_CONTROL1_ENABLE_MASK) >> LF_TIMER_CONTROL1_ENABLE_LSB)
+#define LF_TIMER_CONTROL1_ENABLE_SET(x)          (((x) << LF_TIMER_CONTROL1_ENABLE_LSB) & LF_TIMER_CONTROL1_ENABLE_MASK)
+#define LF_TIMER_CONTROL1_AUTO_RESTART_MSB       1
+#define LF_TIMER_CONTROL1_AUTO_RESTART_LSB       1
+#define LF_TIMER_CONTROL1_AUTO_RESTART_MASK      0x00000002
+#define LF_TIMER_CONTROL1_AUTO_RESTART_GET(x)    (((x) & LF_TIMER_CONTROL1_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL1_AUTO_RESTART_LSB)
+#define LF_TIMER_CONTROL1_AUTO_RESTART_SET(x)    (((x) << LF_TIMER_CONTROL1_AUTO_RESTART_LSB) & LF_TIMER_CONTROL1_AUTO_RESTART_MASK)
+#define LF_TIMER_CONTROL1_RESET_MSB              0
+#define LF_TIMER_CONTROL1_RESET_LSB              0
+#define LF_TIMER_CONTROL1_RESET_MASK             0x00000001
+#define LF_TIMER_CONTROL1_RESET_GET(x)           (((x) & LF_TIMER_CONTROL1_RESET_MASK) >> LF_TIMER_CONTROL1_RESET_LSB)
+#define LF_TIMER_CONTROL1_RESET_SET(x)           (((x) << LF_TIMER_CONTROL1_RESET_LSB) & LF_TIMER_CONTROL1_RESET_MASK)
+
+#define LF_TIMER_STATUS1_ADDRESS                 0x0c000070
+#define LF_TIMER_STATUS1_OFFSET                  0x00000070
+#define LF_TIMER_STATUS1_INTERRUPT_MSB           0
+#define LF_TIMER_STATUS1_INTERRUPT_LSB           0
+#define LF_TIMER_STATUS1_INTERRUPT_MASK          0x00000001
+#define LF_TIMER_STATUS1_INTERRUPT_GET(x)        (((x) & LF_TIMER_STATUS1_INTERRUPT_MASK) >> LF_TIMER_STATUS1_INTERRUPT_LSB)
+#define LF_TIMER_STATUS1_INTERRUPT_SET(x)        (((x) << LF_TIMER_STATUS1_INTERRUPT_LSB) & LF_TIMER_STATUS1_INTERRUPT_MASK)
+
+#define LF_TIMER2_ADDRESS                        0x0c000074
+#define LF_TIMER2_OFFSET                         0x00000074
+#define LF_TIMER2_TARGET_MSB                     31
+#define LF_TIMER2_TARGET_LSB                     0
+#define LF_TIMER2_TARGET_MASK                    0xffffffff
+#define LF_TIMER2_TARGET_GET(x)                  (((x) & LF_TIMER2_TARGET_MASK) >> LF_TIMER2_TARGET_LSB)
+#define LF_TIMER2_TARGET_SET(x)                  (((x) << LF_TIMER2_TARGET_LSB) & LF_TIMER2_TARGET_MASK)
+
+#define LF_TIMER_COUNT2_ADDRESS                  0x0c000078
+#define LF_TIMER_COUNT2_OFFSET                   0x00000078
+#define LF_TIMER_COUNT2_VALUE_MSB                31
+#define LF_TIMER_COUNT2_VALUE_LSB                0
+#define LF_TIMER_COUNT2_VALUE_MASK               0xffffffff
+#define LF_TIMER_COUNT2_VALUE_GET(x)             (((x) & LF_TIMER_COUNT2_VALUE_MASK) >> LF_TIMER_COUNT2_VALUE_LSB)
+#define LF_TIMER_COUNT2_VALUE_SET(x)             (((x) << LF_TIMER_COUNT2_VALUE_LSB) & LF_TIMER_COUNT2_VALUE_MASK)
+
+#define LF_TIMER_CONTROL2_ADDRESS                0x0c00007c
+#define LF_TIMER_CONTROL2_OFFSET                 0x0000007c
+#define LF_TIMER_CONTROL2_ENABLE_MSB             2
+#define LF_TIMER_CONTROL2_ENABLE_LSB             2
+#define LF_TIMER_CONTROL2_ENABLE_MASK            0x00000004
+#define LF_TIMER_CONTROL2_ENABLE_GET(x)          (((x) & LF_TIMER_CONTROL2_ENABLE_MASK) >> LF_TIMER_CONTROL2_ENABLE_LSB)
+#define LF_TIMER_CONTROL2_ENABLE_SET(x)          (((x) << LF_TIMER_CONTROL2_ENABLE_LSB) & LF_TIMER_CONTROL2_ENABLE_MASK)
+#define LF_TIMER_CONTROL2_AUTO_RESTART_MSB       1
+#define LF_TIMER_CONTROL2_AUTO_RESTART_LSB       1
+#define LF_TIMER_CONTROL2_AUTO_RESTART_MASK      0x00000002
+#define LF_TIMER_CONTROL2_AUTO_RESTART_GET(x)    (((x) & LF_TIMER_CONTROL2_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL2_AUTO_RESTART_LSB)
+#define LF_TIMER_CONTROL2_AUTO_RESTART_SET(x)    (((x) << LF_TIMER_CONTROL2_AUTO_RESTART_LSB) & LF_TIMER_CONTROL2_AUTO_RESTART_MASK)
+#define LF_TIMER_CONTROL2_RESET_MSB              0
+#define LF_TIMER_CONTROL2_RESET_LSB              0
+#define LF_TIMER_CONTROL2_RESET_MASK             0x00000001
+#define LF_TIMER_CONTROL2_RESET_GET(x)           (((x) & LF_TIMER_CONTROL2_RESET_MASK) >> LF_TIMER_CONTROL2_RESET_LSB)
+#define LF_TIMER_CONTROL2_RESET_SET(x)           (((x) << LF_TIMER_CONTROL2_RESET_LSB) & LF_TIMER_CONTROL2_RESET_MASK)
+
+#define LF_TIMER_STATUS2_ADDRESS                 0x0c000080
+#define LF_TIMER_STATUS2_OFFSET                  0x00000080
+#define LF_TIMER_STATUS2_INTERRUPT_MSB           0
+#define LF_TIMER_STATUS2_INTERRUPT_LSB           0
+#define LF_TIMER_STATUS2_INTERRUPT_MASK          0x00000001
+#define LF_TIMER_STATUS2_INTERRUPT_GET(x)        (((x) & LF_TIMER_STATUS2_INTERRUPT_MASK) >> LF_TIMER_STATUS2_INTERRUPT_LSB)
+#define LF_TIMER_STATUS2_INTERRUPT_SET(x)        (((x) << LF_TIMER_STATUS2_INTERRUPT_LSB) & LF_TIMER_STATUS2_INTERRUPT_MASK)
+
+#define LF_TIMER3_ADDRESS                        0x0c000084
+#define LF_TIMER3_OFFSET                         0x00000084
+#define LF_TIMER3_TARGET_MSB                     31
+#define LF_TIMER3_TARGET_LSB                     0
+#define LF_TIMER3_TARGET_MASK                    0xffffffff
+#define LF_TIMER3_TARGET_GET(x)                  (((x) & LF_TIMER3_TARGET_MASK) >> LF_TIMER3_TARGET_LSB)
+#define LF_TIMER3_TARGET_SET(x)                  (((x) << LF_TIMER3_TARGET_LSB) & LF_TIMER3_TARGET_MASK)
+
+#define LF_TIMER_COUNT3_ADDRESS                  0x0c000088
+#define LF_TIMER_COUNT3_OFFSET                   0x00000088
+#define LF_TIMER_COUNT3_VALUE_MSB                31
+#define LF_TIMER_COUNT3_VALUE_LSB                0
+#define LF_TIMER_COUNT3_VALUE_MASK               0xffffffff
+#define LF_TIMER_COUNT3_VALUE_GET(x)             (((x) & LF_TIMER_COUNT3_VALUE_MASK) >> LF_TIMER_COUNT3_VALUE_LSB)
+#define LF_TIMER_COUNT3_VALUE_SET(x)             (((x) << LF_TIMER_COUNT3_VALUE_LSB) & LF_TIMER_COUNT3_VALUE_MASK)
+
+#define LF_TIMER_CONTROL3_ADDRESS                0x0c00008c
+#define LF_TIMER_CONTROL3_OFFSET                 0x0000008c
+#define LF_TIMER_CONTROL3_ENABLE_MSB             2
+#define LF_TIMER_CONTROL3_ENABLE_LSB             2
+#define LF_TIMER_CONTROL3_ENABLE_MASK            0x00000004
+#define LF_TIMER_CONTROL3_ENABLE_GET(x)          (((x) & LF_TIMER_CONTROL3_ENABLE_MASK) >> LF_TIMER_CONTROL3_ENABLE_LSB)
+#define LF_TIMER_CONTROL3_ENABLE_SET(x)          (((x) << LF_TIMER_CONTROL3_ENABLE_LSB) & LF_TIMER_CONTROL3_ENABLE_MASK)
+#define LF_TIMER_CONTROL3_AUTO_RESTART_MSB       1
+#define LF_TIMER_CONTROL3_AUTO_RESTART_LSB       1
+#define LF_TIMER_CONTROL3_AUTO_RESTART_MASK      0x00000002
+#define LF_TIMER_CONTROL3_AUTO_RESTART_GET(x)    (((x) & LF_TIMER_CONTROL3_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL3_AUTO_RESTART_LSB)
+#define LF_TIMER_CONTROL3_AUTO_RESTART_SET(x)    (((x) << LF_TIMER_CONTROL3_AUTO_RESTART_LSB) & LF_TIMER_CONTROL3_AUTO_RESTART_MASK)
+#define LF_TIMER_CONTROL3_RESET_MSB              0
+#define LF_TIMER_CONTROL3_RESET_LSB              0
+#define LF_TIMER_CONTROL3_RESET_MASK             0x00000001
+#define LF_TIMER_CONTROL3_RESET_GET(x)           (((x) & LF_TIMER_CONTROL3_RESET_MASK) >> LF_TIMER_CONTROL3_RESET_LSB)
+#define LF_TIMER_CONTROL3_RESET_SET(x)           (((x) << LF_TIMER_CONTROL3_RESET_LSB) & LF_TIMER_CONTROL3_RESET_MASK)
+
+#define LF_TIMER_STATUS3_ADDRESS                 0x0c000090
+#define LF_TIMER_STATUS3_OFFSET                  0x00000090
+#define LF_TIMER_STATUS3_INTERRUPT_MSB           0
+#define LF_TIMER_STATUS3_INTERRUPT_LSB           0
+#define LF_TIMER_STATUS3_INTERRUPT_MASK          0x00000001
+#define LF_TIMER_STATUS3_INTERRUPT_GET(x)        (((x) & LF_TIMER_STATUS3_INTERRUPT_MASK) >> LF_TIMER_STATUS3_INTERRUPT_LSB)
+#define LF_TIMER_STATUS3_INTERRUPT_SET(x)        (((x) << LF_TIMER_STATUS3_INTERRUPT_LSB) & LF_TIMER_STATUS3_INTERRUPT_MASK)
+
+#define HF_TIMER_ADDRESS                         0x0c000094
+#define HF_TIMER_OFFSET                          0x00000094
+#define HF_TIMER_TARGET_MSB                      31
+#define HF_TIMER_TARGET_LSB                      12
+#define HF_TIMER_TARGET_MASK                     0xfffff000
+#define HF_TIMER_TARGET_GET(x)                   (((x) & HF_TIMER_TARGET_MASK) >> HF_TIMER_TARGET_LSB)
+#define HF_TIMER_TARGET_SET(x)                   (((x) << HF_TIMER_TARGET_LSB) & HF_TIMER_TARGET_MASK)
+
+#define HF_TIMER_COUNT_ADDRESS                   0x0c000098
+#define HF_TIMER_COUNT_OFFSET                    0x00000098
+#define HF_TIMER_COUNT_VALUE_MSB                 31
+#define HF_TIMER_COUNT_VALUE_LSB                 12
+#define HF_TIMER_COUNT_VALUE_MASK                0xfffff000
+#define HF_TIMER_COUNT_VALUE_GET(x)              (((x) & HF_TIMER_COUNT_VALUE_MASK) >> HF_TIMER_COUNT_VALUE_LSB)
+#define HF_TIMER_COUNT_VALUE_SET(x)              (((x) << HF_TIMER_COUNT_VALUE_LSB) & HF_TIMER_COUNT_VALUE_MASK)
+
+#define HF_LF_COUNT_ADDRESS                      0x0c00009c
+#define HF_LF_COUNT_OFFSET                       0x0000009c
+#define HF_LF_COUNT_VALUE_MSB                    31
+#define HF_LF_COUNT_VALUE_LSB                    0
+#define HF_LF_COUNT_VALUE_MASK                   0xffffffff
+#define HF_LF_COUNT_VALUE_GET(x)                 (((x) & HF_LF_COUNT_VALUE_MASK) >> HF_LF_COUNT_VALUE_LSB)
+#define HF_LF_COUNT_VALUE_SET(x)                 (((x) << HF_LF_COUNT_VALUE_LSB) & HF_LF_COUNT_VALUE_MASK)
+
+#define HF_TIMER_CONTROL_ADDRESS                 0x0c0000a0
+#define HF_TIMER_CONTROL_OFFSET                  0x000000a0
+#define HF_TIMER_CONTROL_ENABLE_MSB              3
+#define HF_TIMER_CONTROL_ENABLE_LSB              3
+#define HF_TIMER_CONTROL_ENABLE_MASK             0x00000008
+#define HF_TIMER_CONTROL_ENABLE_GET(x)           (((x) & HF_TIMER_CONTROL_ENABLE_MASK) >> HF_TIMER_CONTROL_ENABLE_LSB)
+#define HF_TIMER_CONTROL_ENABLE_SET(x)           (((x) << HF_TIMER_CONTROL_ENABLE_LSB) & HF_TIMER_CONTROL_ENABLE_MASK)
+#define HF_TIMER_CONTROL_ON_MSB                  2
+#define HF_TIMER_CONTROL_ON_LSB                  2
+#define HF_TIMER_CONTROL_ON_MASK                 0x00000004
+#define HF_TIMER_CONTROL_ON_GET(x)               (((x) & HF_TIMER_CONTROL_ON_MASK) >> HF_TIMER_CONTROL_ON_LSB)
+#define HF_TIMER_CONTROL_ON_SET(x)               (((x) << HF_TIMER_CONTROL_ON_LSB) & HF_TIMER_CONTROL_ON_MASK)
+#define HF_TIMER_CONTROL_AUTO_RESTART_MSB        1
+#define HF_TIMER_CONTROL_AUTO_RESTART_LSB        1
+#define HF_TIMER_CONTROL_AUTO_RESTART_MASK       0x00000002
+#define HF_TIMER_CONTROL_AUTO_RESTART_GET(x)     (((x) & HF_TIMER_CONTROL_AUTO_RESTART_MASK) >> HF_TIMER_CONTROL_AUTO_RESTART_LSB)
+#define HF_TIMER_CONTROL_AUTO_RESTART_SET(x)     (((x) << HF_TIMER_CONTROL_AUTO_RESTART_LSB) & HF_TIMER_CONTROL_AUTO_RESTART_MASK)
+#define HF_TIMER_CONTROL_RESET_MSB               0
+#define HF_TIMER_CONTROL_RESET_LSB               0
+#define HF_TIMER_CONTROL_RESET_MASK              0x00000001
+#define HF_TIMER_CONTROL_RESET_GET(x)            (((x) & HF_TIMER_CONTROL_RESET_MASK) >> HF_TIMER_CONTROL_RESET_LSB)
+#define HF_TIMER_CONTROL_RESET_SET(x)            (((x) << HF_TIMER_CONTROL_RESET_LSB) & HF_TIMER_CONTROL_RESET_MASK)
+
+#define HF_TIMER_STATUS_ADDRESS                  0x0c0000a4
+#define HF_TIMER_STATUS_OFFSET                   0x000000a4
+#define HF_TIMER_STATUS_INTERRUPT_MSB            0
+#define HF_TIMER_STATUS_INTERRUPT_LSB            0
+#define HF_TIMER_STATUS_INTERRUPT_MASK           0x00000001
+#define HF_TIMER_STATUS_INTERRUPT_GET(x)         (((x) & HF_TIMER_STATUS_INTERRUPT_MASK) >> HF_TIMER_STATUS_INTERRUPT_LSB)
+#define HF_TIMER_STATUS_INTERRUPT_SET(x)         (((x) << HF_TIMER_STATUS_INTERRUPT_LSB) & HF_TIMER_STATUS_INTERRUPT_MASK)
+
+#define RTC_CONTROL_ADDRESS                      0x0c0000a8
+#define RTC_CONTROL_OFFSET                       0x000000a8
+#define RTC_CONTROL_ENABLE_MSB                   2
+#define RTC_CONTROL_ENABLE_LSB                   2
+#define RTC_CONTROL_ENABLE_MASK                  0x00000004
+#define RTC_CONTROL_ENABLE_GET(x)                (((x) & RTC_CONTROL_ENABLE_MASK) >> RTC_CONTROL_ENABLE_LSB)
+#define RTC_CONTROL_ENABLE_SET(x)                (((x) << RTC_CONTROL_ENABLE_LSB) & RTC_CONTROL_ENABLE_MASK)
+#define RTC_CONTROL_LOAD_RTC_MSB                 1
+#define RTC_CONTROL_LOAD_RTC_LSB                 1
+#define RTC_CONTROL_LOAD_RTC_MASK                0x00000002
+#define RTC_CONTROL_LOAD_RTC_GET(x)              (((x) & RTC_CONTROL_LOAD_RTC_MASK) >> RTC_CONTROL_LOAD_RTC_LSB)
+#define RTC_CONTROL_LOAD_RTC_SET(x)              (((x) << RTC_CONTROL_LOAD_RTC_LSB) & RTC_CONTROL_LOAD_RTC_MASK)
+#define RTC_CONTROL_LOAD_ALARM_MSB               0
+#define RTC_CONTROL_LOAD_ALARM_LSB               0
+#define RTC_CONTROL_LOAD_ALARM_MASK              0x00000001
+#define RTC_CONTROL_LOAD_ALARM_GET(x)            (((x) & RTC_CONTROL_LOAD_ALARM_MASK) >> RTC_CONTROL_LOAD_ALARM_LSB)
+#define RTC_CONTROL_LOAD_ALARM_SET(x)            (((x) << RTC_CONTROL_LOAD_ALARM_LSB) & RTC_CONTROL_LOAD_ALARM_MASK)
+
+#define RTC_TIME_ADDRESS                         0x0c0000ac
+#define RTC_TIME_OFFSET                          0x000000ac
+#define RTC_TIME_WEEK_DAY_MSB                    26
+#define RTC_TIME_WEEK_DAY_LSB                    24
+#define RTC_TIME_WEEK_DAY_MASK                   0x07000000
+#define RTC_TIME_WEEK_DAY_GET(x)                 (((x) & RTC_TIME_WEEK_DAY_MASK) >> RTC_TIME_WEEK_DAY_LSB)
+#define RTC_TIME_WEEK_DAY_SET(x)                 (((x) << RTC_TIME_WEEK_DAY_LSB) & RTC_TIME_WEEK_DAY_MASK)
+#define RTC_TIME_HOUR_MSB                        21
+#define RTC_TIME_HOUR_LSB                        16
+#define RTC_TIME_HOUR_MASK                       0x003f0000
+#define RTC_TIME_HOUR_GET(x)                     (((x) & RTC_TIME_HOUR_MASK) >> RTC_TIME_HOUR_LSB)
+#define RTC_TIME_HOUR_SET(x)                     (((x) << RTC_TIME_HOUR_LSB) & RTC_TIME_HOUR_MASK)
+#define RTC_TIME_MINUTE_MSB                      14
+#define RTC_TIME_MINUTE_LSB                      8
+#define RTC_TIME_MINUTE_MASK                     0x00007f00
+#define RTC_TIME_MINUTE_GET(x)                   (((x) & RTC_TIME_MINUTE_MASK) >> RTC_TIME_MINUTE_LSB)
+#define RTC_TIME_MINUTE_SET(x)                   (((x) << RTC_TIME_MINUTE_LSB) & RTC_TIME_MINUTE_MASK)
+#define RTC_TIME_SECOND_MSB                      6
+#define RTC_TIME_SECOND_LSB                      0
+#define RTC_TIME_SECOND_MASK                     0x0000007f
+#define RTC_TIME_SECOND_GET(x)                   (((x) & RTC_TIME_SECOND_MASK) >> RTC_TIME_SECOND_LSB)
+#define RTC_TIME_SECOND_SET(x)                   (((x) << RTC_TIME_SECOND_LSB) & RTC_TIME_SECOND_MASK)
+
+#define RTC_DATE_ADDRESS                         0x0c0000b0
+#define RTC_DATE_OFFSET                          0x000000b0
+#define RTC_DATE_YEAR_MSB                        23
+#define RTC_DATE_YEAR_LSB                        16
+#define RTC_DATE_YEAR_MASK                       0x00ff0000
+#define RTC_DATE_YEAR_GET(x)                     (((x) & RTC_DATE_YEAR_MASK) >> RTC_DATE_YEAR_LSB)
+#define RTC_DATE_YEAR_SET(x)                     (((x) << RTC_DATE_YEAR_LSB) & RTC_DATE_YEAR_MASK)
+#define RTC_DATE_MONTH_MSB                       12
+#define RTC_DATE_MONTH_LSB                       8
+#define RTC_DATE_MONTH_MASK                      0x00001f00
+#define RTC_DATE_MONTH_GET(x)                    (((x) & RTC_DATE_MONTH_MASK) >> RTC_DATE_MONTH_LSB)
+#define RTC_DATE_MONTH_SET(x)                    (((x) << RTC_DATE_MONTH_LSB) & RTC_DATE_MONTH_MASK)
+#define RTC_DATE_MONTH_DAY_MSB                   5
+#define RTC_DATE_MONTH_DAY_LSB                   0
+#define RTC_DATE_MONTH_DAY_MASK                  0x0000003f
+#define RTC_DATE_MONTH_DAY_GET(x)                (((x) & RTC_DATE_MONTH_DAY_MASK) >> RTC_DATE_MONTH_DAY_LSB)
+#define RTC_DATE_MONTH_DAY_SET(x)                (((x) << RTC_DATE_MONTH_DAY_LSB) & RTC_DATE_MONTH_DAY_MASK)
+
+#define RTC_SET_TIME_ADDRESS                     0x0c0000b4
+#define RTC_SET_TIME_OFFSET                      0x000000b4
+#define RTC_SET_TIME_WEEK_DAY_MSB                26
+#define RTC_SET_TIME_WEEK_DAY_LSB                24
+#define RTC_SET_TIME_WEEK_DAY_MASK               0x07000000
+#define RTC_SET_TIME_WEEK_DAY_GET(x)             (((x) & RTC_SET_TIME_WEEK_DAY_MASK) >> RTC_SET_TIME_WEEK_DAY_LSB)
+#define RTC_SET_TIME_WEEK_DAY_SET(x)             (((x) << RTC_SET_TIME_WEEK_DAY_LSB) & RTC_SET_TIME_WEEK_DAY_MASK)
+#define RTC_SET_TIME_HOUR_MSB                    21
+#define RTC_SET_TIME_HOUR_LSB                    16
+#define RTC_SET_TIME_HOUR_MASK                   0x003f0000
+#define RTC_SET_TIME_HOUR_GET(x)                 (((x) & RTC_SET_TIME_HOUR_MASK) >> RTC_SET_TIME_HOUR_LSB)
+#define RTC_SET_TIME_HOUR_SET(x)                 (((x) << RTC_SET_TIME_HOUR_LSB) & RTC_SET_TIME_HOUR_MASK)
+#define RTC_SET_TIME_MINUTE_MSB                  14
+#define RTC_SET_TIME_MINUTE_LSB                  8
+#define RTC_SET_TIME_MINUTE_MASK                 0x00007f00
+#define RTC_SET_TIME_MINUTE_GET(x)               (((x) & RTC_SET_TIME_MINUTE_MASK) >> RTC_SET_TIME_MINUTE_LSB)
+#define RTC_SET_TIME_MINUTE_SET(x)               (((x) << RTC_SET_TIME_MINUTE_LSB) & RTC_SET_TIME_MINUTE_MASK)
+#define RTC_SET_TIME_SECOND_MSB                  6
+#define RTC_SET_TIME_SECOND_LSB                  0
+#define RTC_SET_TIME_SECOND_MASK                 0x0000007f
+#define RTC_SET_TIME_SECOND_GET(x)               (((x) & RTC_SET_TIME_SECOND_MASK) >> RTC_SET_TIME_SECOND_LSB)
+#define RTC_SET_TIME_SECOND_SET(x)               (((x) << RTC_SET_TIME_SECOND_LSB) & RTC_SET_TIME_SECOND_MASK)
+
+#define RTC_SET_DATE_ADDRESS                     0x0c0000b8
+#define RTC_SET_DATE_OFFSET                      0x000000b8
+#define RTC_SET_DATE_YEAR_MSB                    23
+#define RTC_SET_DATE_YEAR_LSB                    16
+#define RTC_SET_DATE_YEAR_MASK                   0x00ff0000
+#define RTC_SET_DATE_YEAR_GET(x)                 (((x) & RTC_SET_DATE_YEAR_MASK) >> RTC_SET_DATE_YEAR_LSB)
+#define RTC_SET_DATE_YEAR_SET(x)                 (((x) << RTC_SET_DATE_YEAR_LSB) & RTC_SET_DATE_YEAR_MASK)
+#define RTC_SET_DATE_MONTH_MSB                   12
+#define RTC_SET_DATE_MONTH_LSB                   8
+#define RTC_SET_DATE_MONTH_MASK                  0x00001f00
+#define RTC_SET_DATE_MONTH_GET(x)                (((x) & RTC_SET_DATE_MONTH_MASK) >> RTC_SET_DATE_MONTH_LSB)
+#define RTC_SET_DATE_MONTH_SET(x)                (((x) << RTC_SET_DATE_MONTH_LSB) & RTC_SET_DATE_MONTH_MASK)
+#define RTC_SET_DATE_MONTH_DAY_MSB               5
+#define RTC_SET_DATE_MONTH_DAY_LSB               0
+#define RTC_SET_DATE_MONTH_DAY_MASK              0x0000003f
+#define RTC_SET_DATE_MONTH_DAY_GET(x)            (((x) & RTC_SET_DATE_MONTH_DAY_MASK) >> RTC_SET_DATE_MONTH_DAY_LSB)
+#define RTC_SET_DATE_MONTH_DAY_SET(x)            (((x) << RTC_SET_DATE_MONTH_DAY_LSB) & RTC_SET_DATE_MONTH_DAY_MASK)
+
+#define RTC_SET_ALARM_ADDRESS                    0x0c0000bc
+#define RTC_SET_ALARM_OFFSET                     0x000000bc
+#define RTC_SET_ALARM_HOUR_MSB                   21
+#define RTC_SET_ALARM_HOUR_LSB                   16
+#define RTC_SET_ALARM_HOUR_MASK                  0x003f0000
+#define RTC_SET_ALARM_HOUR_GET(x)                (((x) & RTC_SET_ALARM_HOUR_MASK) >> RTC_SET_ALARM_HOUR_LSB)
+#define RTC_SET_ALARM_HOUR_SET(x)                (((x) << RTC_SET_ALARM_HOUR_LSB) & RTC_SET_ALARM_HOUR_MASK)
+#define RTC_SET_ALARM_MINUTE_MSB                 14
+#define RTC_SET_ALARM_MINUTE_LSB                 8
+#define RTC_SET_ALARM_MINUTE_MASK                0x00007f00
+#define RTC_SET_ALARM_MINUTE_GET(x)              (((x) & RTC_SET_ALARM_MINUTE_MASK) >> RTC_SET_ALARM_MINUTE_LSB)
+#define RTC_SET_ALARM_MINUTE_SET(x)              (((x) << RTC_SET_ALARM_MINUTE_LSB) & RTC_SET_ALARM_MINUTE_MASK)
+#define RTC_SET_ALARM_SECOND_MSB                 6
+#define RTC_SET_ALARM_SECOND_LSB                 0
+#define RTC_SET_ALARM_SECOND_MASK                0x0000007f
+#define RTC_SET_ALARM_SECOND_GET(x)              (((x) & RTC_SET_ALARM_SECOND_MASK) >> RTC_SET_ALARM_SECOND_LSB)
+#define RTC_SET_ALARM_SECOND_SET(x)              (((x) << RTC_SET_ALARM_SECOND_LSB) & RTC_SET_ALARM_SECOND_MASK)
+
+#define RTC_CONFIG_ADDRESS                       0x0c0000c0
+#define RTC_CONFIG_OFFSET                        0x000000c0
+#define RTC_CONFIG_BCD_MSB                       2
+#define RTC_CONFIG_BCD_LSB                       2
+#define RTC_CONFIG_BCD_MASK                      0x00000004
+#define RTC_CONFIG_BCD_GET(x)                    (((x) & RTC_CONFIG_BCD_MASK) >> RTC_CONFIG_BCD_LSB)
+#define RTC_CONFIG_BCD_SET(x)                    (((x) << RTC_CONFIG_BCD_LSB) & RTC_CONFIG_BCD_MASK)
+#define RTC_CONFIG_TWELVE_HOUR_MSB               1
+#define RTC_CONFIG_TWELVE_HOUR_LSB               1
+#define RTC_CONFIG_TWELVE_HOUR_MASK              0x00000002
+#define RTC_CONFIG_TWELVE_HOUR_GET(x)            (((x) & RTC_CONFIG_TWELVE_HOUR_MASK) >> RTC_CONFIG_TWELVE_HOUR_LSB)
+#define RTC_CONFIG_TWELVE_HOUR_SET(x)            (((x) << RTC_CONFIG_TWELVE_HOUR_LSB) & RTC_CONFIG_TWELVE_HOUR_MASK)
+#define RTC_CONFIG_DSE_MSB                       0
+#define RTC_CONFIG_DSE_LSB                       0
+#define RTC_CONFIG_DSE_MASK                      0x00000001
+#define RTC_CONFIG_DSE_GET(x)                    (((x) & RTC_CONFIG_DSE_MASK) >> RTC_CONFIG_DSE_LSB)
+#define RTC_CONFIG_DSE_SET(x)                    (((x) << RTC_CONFIG_DSE_LSB) & RTC_CONFIG_DSE_MASK)
+
+#define RTC_ALARM_STATUS_ADDRESS                 0x0c0000c4
+#define RTC_ALARM_STATUS_OFFSET                  0x000000c4
+#define RTC_ALARM_STATUS_ENABLE_MSB              1
+#define RTC_ALARM_STATUS_ENABLE_LSB              1
+#define RTC_ALARM_STATUS_ENABLE_MASK             0x00000002
+#define RTC_ALARM_STATUS_ENABLE_GET(x)           (((x) & RTC_ALARM_STATUS_ENABLE_MASK) >> RTC_ALARM_STATUS_ENABLE_LSB)
+#define RTC_ALARM_STATUS_ENABLE_SET(x)           (((x) << RTC_ALARM_STATUS_ENABLE_LSB) & RTC_ALARM_STATUS_ENABLE_MASK)
+#define RTC_ALARM_STATUS_INTERRUPT_MSB           0
+#define RTC_ALARM_STATUS_INTERRUPT_LSB           0
+#define RTC_ALARM_STATUS_INTERRUPT_MASK          0x00000001
+#define RTC_ALARM_STATUS_INTERRUPT_GET(x)        (((x) & RTC_ALARM_STATUS_INTERRUPT_MASK) >> RTC_ALARM_STATUS_INTERRUPT_LSB)
+#define RTC_ALARM_STATUS_INTERRUPT_SET(x)        (((x) << RTC_ALARM_STATUS_INTERRUPT_LSB) & RTC_ALARM_STATUS_INTERRUPT_MASK)
+
+#define UART_WAKEUP_ADDRESS                      0x0c0000c8
+#define UART_WAKEUP_OFFSET                       0x000000c8
+#define UART_WAKEUP_ENABLE_MSB                   0
+#define UART_WAKEUP_ENABLE_LSB                   0
+#define UART_WAKEUP_ENABLE_MASK                  0x00000001
+#define UART_WAKEUP_ENABLE_GET(x)                (((x) & UART_WAKEUP_ENABLE_MASK) >> UART_WAKEUP_ENABLE_LSB)
+#define UART_WAKEUP_ENABLE_SET(x)                (((x) << UART_WAKEUP_ENABLE_LSB) & UART_WAKEUP_ENABLE_MASK)
+
+#define RESET_CAUSE_ADDRESS                      0x0c0000cc
+#define RESET_CAUSE_OFFSET                       0x000000cc
+#define RESET_CAUSE_LAST_MSB                     2
+#define RESET_CAUSE_LAST_LSB                     0
+#define RESET_CAUSE_LAST_MASK                    0x00000007
+#define RESET_CAUSE_LAST_GET(x)                  (((x) & RESET_CAUSE_LAST_MASK) >> RESET_CAUSE_LAST_LSB)
+#define RESET_CAUSE_LAST_SET(x)                  (((x) << RESET_CAUSE_LAST_LSB) & RESET_CAUSE_LAST_MASK)
+
+#define SYSTEM_SLEEP_ADDRESS                     0x0c0000d0
+#define SYSTEM_SLEEP_OFFSET                      0x000000d0
+#define SYSTEM_SLEEP_HOST_IF_MSB                 4
+#define SYSTEM_SLEEP_HOST_IF_LSB                 4
+#define SYSTEM_SLEEP_HOST_IF_MASK                0x00000010
+#define SYSTEM_SLEEP_HOST_IF_GET(x)              (((x) & SYSTEM_SLEEP_HOST_IF_MASK) >> SYSTEM_SLEEP_HOST_IF_LSB)
+#define SYSTEM_SLEEP_HOST_IF_SET(x)              (((x) << SYSTEM_SLEEP_HOST_IF_LSB) & SYSTEM_SLEEP_HOST_IF_MASK)
+#define SYSTEM_SLEEP_MBOX_MSB                    3
+#define SYSTEM_SLEEP_MBOX_LSB                    3
+#define SYSTEM_SLEEP_MBOX_MASK                   0x00000008
+#define SYSTEM_SLEEP_MBOX_GET(x)                 (((x) & SYSTEM_SLEEP_MBOX_MASK) >> SYSTEM_SLEEP_MBOX_LSB)
+#define SYSTEM_SLEEP_MBOX_SET(x)                 (((x) << SYSTEM_SLEEP_MBOX_LSB) & SYSTEM_SLEEP_MBOX_MASK)
+#define SYSTEM_SLEEP_MAC_IF_MSB                  2
+#define SYSTEM_SLEEP_MAC_IF_LSB                  2
+#define SYSTEM_SLEEP_MAC_IF_MASK                 0x00000004
+#define SYSTEM_SLEEP_MAC_IF_GET(x)               (((x) & SYSTEM_SLEEP_MAC_IF_MASK) >> SYSTEM_SLEEP_MAC_IF_LSB)
+#define SYSTEM_SLEEP_MAC_IF_SET(x)               (((x) << SYSTEM_SLEEP_MAC_IF_LSB) & SYSTEM_SLEEP_MAC_IF_MASK)
+#define SYSTEM_SLEEP_LIGHT_MSB                   1
+#define SYSTEM_SLEEP_LIGHT_LSB                   1
+#define SYSTEM_SLEEP_LIGHT_MASK                  0x00000002
+#define SYSTEM_SLEEP_LIGHT_GET(x)                (((x) & SYSTEM_SLEEP_LIGHT_MASK) >> SYSTEM_SLEEP_LIGHT_LSB)
+#define SYSTEM_SLEEP_LIGHT_SET(x)                (((x) << SYSTEM_SLEEP_LIGHT_LSB) & SYSTEM_SLEEP_LIGHT_MASK)
+#define SYSTEM_SLEEP_DISABLE_MSB                 0
+#define SYSTEM_SLEEP_DISABLE_LSB                 0
+#define SYSTEM_SLEEP_DISABLE_MASK                0x00000001
+#define SYSTEM_SLEEP_DISABLE_GET(x)              (((x) & SYSTEM_SLEEP_DISABLE_MASK) >> SYSTEM_SLEEP_DISABLE_LSB)
+#define SYSTEM_SLEEP_DISABLE_SET(x)              (((x) << SYSTEM_SLEEP_DISABLE_LSB) & SYSTEM_SLEEP_DISABLE_MASK)
+
+#define LDO_VOLTAGE_ADDRESS                      0x0c0000d4
+#define LDO_VOLTAGE_OFFSET                       0x000000d4
+#define LDO_VOLTAGE_SLEEP_MSB                    14
+#define LDO_VOLTAGE_SLEEP_LSB                    12
+#define LDO_VOLTAGE_SLEEP_MASK                   0x00007000
+#define LDO_VOLTAGE_SLEEP_GET(x)                 (((x) & LDO_VOLTAGE_SLEEP_MASK) >> LDO_VOLTAGE_SLEEP_LSB)
+#define LDO_VOLTAGE_SLEEP_SET(x)                 (((x) << LDO_VOLTAGE_SLEEP_LSB) & LDO_VOLTAGE_SLEEP_MASK)
+#define LDO_VOLTAGE_WAKEUP_MSB                   10
+#define LDO_VOLTAGE_WAKEUP_LSB                   8
+#define LDO_VOLTAGE_WAKEUP_MASK                  0x00000700
+#define LDO_VOLTAGE_WAKEUP_GET(x)                (((x) & LDO_VOLTAGE_WAKEUP_MASK) >> LDO_VOLTAGE_WAKEUP_LSB)
+#define LDO_VOLTAGE_WAKEUP_SET(x)                (((x) << LDO_VOLTAGE_WAKEUP_LSB) & LDO_VOLTAGE_WAKEUP_MASK)
+#define LDO_VOLTAGE_SOC_ON_MSB                   6
+#define LDO_VOLTAGE_SOC_ON_LSB                   4
+#define LDO_VOLTAGE_SOC_ON_MASK                  0x00000070
+#define LDO_VOLTAGE_SOC_ON_GET(x)                (((x) & LDO_VOLTAGE_SOC_ON_MASK) >> LDO_VOLTAGE_SOC_ON_LSB)
+#define LDO_VOLTAGE_SOC_ON_SET(x)                (((x) << LDO_VOLTAGE_SOC_ON_LSB) & LDO_VOLTAGE_SOC_ON_MASK)
+#define LDO_VOLTAGE_ON_MSB                       2
+#define LDO_VOLTAGE_ON_LSB                       0
+#define LDO_VOLTAGE_ON_MASK                      0x00000007
+#define LDO_VOLTAGE_ON_GET(x)                    (((x) & LDO_VOLTAGE_ON_MASK) >> LDO_VOLTAGE_ON_LSB)
+#define LDO_VOLTAGE_ON_SET(x)                    (((x) << LDO_VOLTAGE_ON_LSB) & LDO_VOLTAGE_ON_MASK)
+
+#define LDO_A_VOLTAGE_ADDRESS                    0x0c0000d8
+#define LDO_A_VOLTAGE_OFFSET                     0x000000d8
+#define LDO_A_VOLTAGE_SLEEP_MSB                  14
+#define LDO_A_VOLTAGE_SLEEP_LSB                  12
+#define LDO_A_VOLTAGE_SLEEP_MASK                 0x00007000
+#define LDO_A_VOLTAGE_SLEEP_GET(x)               (((x) & LDO_A_VOLTAGE_SLEEP_MASK) >> LDO_A_VOLTAGE_SLEEP_LSB)
+#define LDO_A_VOLTAGE_SLEEP_SET(x)               (((x) << LDO_A_VOLTAGE_SLEEP_LSB) & LDO_A_VOLTAGE_SLEEP_MASK)
+#define LDO_A_VOLTAGE_WAKEUP_MSB                 10
+#define LDO_A_VOLTAGE_WAKEUP_LSB                 8
+#define LDO_A_VOLTAGE_WAKEUP_MASK                0x00000700
+#define LDO_A_VOLTAGE_WAKEUP_GET(x)              (((x) & LDO_A_VOLTAGE_WAKEUP_MASK) >> LDO_A_VOLTAGE_WAKEUP_LSB)
+#define LDO_A_VOLTAGE_WAKEUP_SET(x)              (((x) << LDO_A_VOLTAGE_WAKEUP_LSB) & LDO_A_VOLTAGE_WAKEUP_MASK)
+#define LDO_A_VOLTAGE_SOC_ON_MSB                 6
+#define LDO_A_VOLTAGE_SOC_ON_LSB                 4
+#define LDO_A_VOLTAGE_SOC_ON_MASK                0x00000070
+#define LDO_A_VOLTAGE_SOC_ON_GET(x)              (((x) & LDO_A_VOLTAGE_SOC_ON_MASK) >> LDO_A_VOLTAGE_SOC_ON_LSB)
+#define LDO_A_VOLTAGE_SOC_ON_SET(x)              (((x) << LDO_A_VOLTAGE_SOC_ON_LSB) & LDO_A_VOLTAGE_SOC_ON_MASK)
+#define LDO_A_VOLTAGE_ON_MSB                     2
+#define LDO_A_VOLTAGE_ON_LSB                     0
+#define LDO_A_VOLTAGE_ON_MASK                    0x00000007
+#define LDO_A_VOLTAGE_ON_GET(x)                  (((x) & LDO_A_VOLTAGE_ON_MASK) >> LDO_A_VOLTAGE_ON_LSB)
+#define LDO_A_VOLTAGE_ON_SET(x)                  (((x) << LDO_A_VOLTAGE_ON_LSB) & LDO_A_VOLTAGE_ON_MASK)
+
+#define SDIO_LDO_VOLTAGE_ADDRESS                 0x0c0000dc
+#define SDIO_LDO_VOLTAGE_OFFSET                  0x000000dc
+#define SDIO_LDO_VOLTAGE_OFF_MSB                 18
+#define SDIO_LDO_VOLTAGE_OFF_LSB                 16
+#define SDIO_LDO_VOLTAGE_OFF_MASK                0x00070000
+#define SDIO_LDO_VOLTAGE_OFF_GET(x)              (((x) & SDIO_LDO_VOLTAGE_OFF_MASK) >> SDIO_LDO_VOLTAGE_OFF_LSB)
+#define SDIO_LDO_VOLTAGE_OFF_SET(x)              (((x) << SDIO_LDO_VOLTAGE_OFF_LSB) & SDIO_LDO_VOLTAGE_OFF_MASK)
+#define SDIO_LDO_VOLTAGE_SLEEP_MSB               14
+#define SDIO_LDO_VOLTAGE_SLEEP_LSB               12
+#define SDIO_LDO_VOLTAGE_SLEEP_MASK              0x00007000
+#define SDIO_LDO_VOLTAGE_SLEEP_GET(x)            (((x) & SDIO_LDO_VOLTAGE_SLEEP_MASK) >> SDIO_LDO_VOLTAGE_SLEEP_LSB)
+#define SDIO_LDO_VOLTAGE_SLEEP_SET(x)            (((x) << SDIO_LDO_VOLTAGE_SLEEP_LSB) & SDIO_LDO_VOLTAGE_SLEEP_MASK)
+#define SDIO_LDO_VOLTAGE_WAKEUP_MSB              10
+#define SDIO_LDO_VOLTAGE_WAKEUP_LSB              8
+#define SDIO_LDO_VOLTAGE_WAKEUP_MASK             0x00000700
+#define SDIO_LDO_VOLTAGE_WAKEUP_GET(x)           (((x) & SDIO_LDO_VOLTAGE_WAKEUP_MASK) >> SDIO_LDO_VOLTAGE_WAKEUP_LSB)
+#define SDIO_LDO_VOLTAGE_WAKEUP_SET(x)           (((x) << SDIO_LDO_VOLTAGE_WAKEUP_LSB) & SDIO_LDO_VOLTAGE_WAKEUP_MASK)
+#define SDIO_LDO_VOLTAGE_SOC_ON_MSB              6
+#define SDIO_LDO_VOLTAGE_SOC_ON_LSB              4
+#define SDIO_LDO_VOLTAGE_SOC_ON_MASK             0x00000070
+#define SDIO_LDO_VOLTAGE_SOC_ON_GET(x)           (((x) & SDIO_LDO_VOLTAGE_SOC_ON_MASK) >> SDIO_LDO_VOLTAGE_SOC_ON_LSB)
+#define SDIO_LDO_VOLTAGE_SOC_ON_SET(x)           (((x) << SDIO_LDO_VOLTAGE_SOC_ON_LSB) & SDIO_LDO_VOLTAGE_SOC_ON_MASK)
+#define SDIO_LDO_VOLTAGE_ON_MSB                  2
+#define SDIO_LDO_VOLTAGE_ON_LSB                  0
+#define SDIO_LDO_VOLTAGE_ON_MASK                 0x00000007
+#define SDIO_LDO_VOLTAGE_ON_GET(x)               (((x) & SDIO_LDO_VOLTAGE_ON_MASK) >> SDIO_LDO_VOLTAGE_ON_LSB)
+#define SDIO_LDO_VOLTAGE_ON_SET(x)               (((x) << SDIO_LDO_VOLTAGE_ON_LSB) & SDIO_LDO_VOLTAGE_ON_MASK)
+
+#define CORE_PAD_ENABLE_ADDRESS                  0x0c0000e0
+#define CORE_PAD_ENABLE_OFFSET                   0x000000e0
+#define CORE_PAD_ENABLE_SLEEP_MSB                3
+#define CORE_PAD_ENABLE_SLEEP_LSB                3
+#define CORE_PAD_ENABLE_SLEEP_MASK               0x00000008
+#define CORE_PAD_ENABLE_SLEEP_GET(x)             (((x) & CORE_PAD_ENABLE_SLEEP_MASK) >> CORE_PAD_ENABLE_SLEEP_LSB)
+#define CORE_PAD_ENABLE_SLEEP_SET(x)             (((x) << CORE_PAD_ENABLE_SLEEP_LSB) & CORE_PAD_ENABLE_SLEEP_MASK)
+#define CORE_PAD_ENABLE_WAKEUP_MSB               2
+#define CORE_PAD_ENABLE_WAKEUP_LSB               2
+#define CORE_PAD_ENABLE_WAKEUP_MASK              0x00000004
+#define CORE_PAD_ENABLE_WAKEUP_GET(x)            (((x) & CORE_PAD_ENABLE_WAKEUP_MASK) >> CORE_PAD_ENABLE_WAKEUP_LSB)
+#define CORE_PAD_ENABLE_WAKEUP_SET(x)            (((x) << CORE_PAD_ENABLE_WAKEUP_LSB) & CORE_PAD_ENABLE_WAKEUP_MASK)
+#define CORE_PAD_ENABLE_SOC_ON_MSB               1
+#define CORE_PAD_ENABLE_SOC_ON_LSB               1
+#define CORE_PAD_ENABLE_SOC_ON_MASK              0x00000002
+#define CORE_PAD_ENABLE_SOC_ON_GET(x)            (((x) & CORE_PAD_ENABLE_SOC_ON_MASK) >> CORE_PAD_ENABLE_SOC_ON_LSB)
+#define CORE_PAD_ENABLE_SOC_ON_SET(x)            (((x) << CORE_PAD_ENABLE_SOC_ON_LSB) & CORE_PAD_ENABLE_SOC_ON_MASK)
+#define CORE_PAD_ENABLE_ON_MSB                   0
+#define CORE_PAD_ENABLE_ON_LSB                   0
+#define CORE_PAD_ENABLE_ON_MASK                  0x00000001
+#define CORE_PAD_ENABLE_ON_GET(x)                (((x) & CORE_PAD_ENABLE_ON_MASK) >> CORE_PAD_ENABLE_ON_LSB)
+#define CORE_PAD_ENABLE_ON_SET(x)                (((x) << CORE_PAD_ENABLE_ON_LSB) & CORE_PAD_ENABLE_ON_MASK)
+
+#define SDIO_WRAPPER_ADDRESS                     0x0c0000e4
+#define SDIO_WRAPPER_OFFSET                      0x000000e4
+#define SDIO_WRAPPER_SLEEP_MSB                   3
+#define SDIO_WRAPPER_SLEEP_LSB                   3
+#define SDIO_WRAPPER_SLEEP_MASK                  0x00000008
+#define SDIO_WRAPPER_SLEEP_GET(x)                (((x) & SDIO_WRAPPER_SLEEP_MASK) >> SDIO_WRAPPER_SLEEP_LSB)
+#define SDIO_WRAPPER_SLEEP_SET(x)                (((x) << SDIO_WRAPPER_SLEEP_LSB) & SDIO_WRAPPER_SLEEP_MASK)
+#define SDIO_WRAPPER_WAKEUP_MSB                  2
+#define SDIO_WRAPPER_WAKEUP_LSB                  2
+#define SDIO_WRAPPER_WAKEUP_MASK                 0x00000004
+#define SDIO_WRAPPER_WAKEUP_GET(x)               (((x) & SDIO_WRAPPER_WAKEUP_MASK) >> SDIO_WRAPPER_WAKEUP_LSB)
+#define SDIO_WRAPPER_WAKEUP_SET(x)               (((x) << SDIO_WRAPPER_WAKEUP_LSB) & SDIO_WRAPPER_WAKEUP_MASK)
+#define SDIO_WRAPPER_SOC_ON_MSB                  1
+#define SDIO_WRAPPER_SOC_ON_LSB                  1
+#define SDIO_WRAPPER_SOC_ON_MASK                 0x00000002
+#define SDIO_WRAPPER_SOC_ON_GET(x)               (((x) & SDIO_WRAPPER_SOC_ON_MASK) >> SDIO_WRAPPER_SOC_ON_LSB)
+#define SDIO_WRAPPER_SOC_ON_SET(x)               (((x) << SDIO_WRAPPER_SOC_ON_LSB) & SDIO_WRAPPER_SOC_ON_MASK)
+#define SDIO_WRAPPER_ON_MSB                      0
+#define SDIO_WRAPPER_ON_LSB                      0
+#define SDIO_WRAPPER_ON_MASK                     0x00000001
+#define SDIO_WRAPPER_ON_GET(x)                   (((x) & SDIO_WRAPPER_ON_MASK) >> SDIO_WRAPPER_ON_LSB)
+#define SDIO_WRAPPER_ON_SET(x)                   (((x) << SDIO_WRAPPER_ON_LSB) & SDIO_WRAPPER_ON_MASK)
+
+#define MAC_SLEEP_CONTROL_ADDRESS                0x0c0000e8
+#define MAC_SLEEP_CONTROL_OFFSET                 0x000000e8
+#define MAC_SLEEP_CONTROL_ENABLE_MSB             1
+#define MAC_SLEEP_CONTROL_ENABLE_LSB             0
+#define MAC_SLEEP_CONTROL_ENABLE_MASK            0x00000003
+#define MAC_SLEEP_CONTROL_ENABLE_GET(x)          (((x) & MAC_SLEEP_CONTROL_ENABLE_MASK) >> MAC_SLEEP_CONTROL_ENABLE_LSB)
+#define MAC_SLEEP_CONTROL_ENABLE_SET(x)          (((x) << MAC_SLEEP_CONTROL_ENABLE_LSB) & MAC_SLEEP_CONTROL_ENABLE_MASK)
+
+#define KEEP_AWAKE_ADDRESS                       0x0c0000ec
+#define KEEP_AWAKE_OFFSET                        0x000000ec
+#define KEEP_AWAKE_COUNT_MSB                     7
+#define KEEP_AWAKE_COUNT_LSB                     0
+#define KEEP_AWAKE_COUNT_MASK                    0x000000ff
+#define KEEP_AWAKE_COUNT_GET(x)                  (((x) & KEEP_AWAKE_COUNT_MASK) >> KEEP_AWAKE_COUNT_LSB)
+#define KEEP_AWAKE_COUNT_SET(x)                  (((x) << KEEP_AWAKE_COUNT_LSB) & KEEP_AWAKE_COUNT_MASK)
+
+#define CHIP_REV_ADDRESS                         0x0c0000f0
+#define CHIP_REV_OFFSET                          0x000000f0
+#define CHIP_REV_ID_MSB                          7
+#define CHIP_REV_ID_LSB                          0
+#define CHIP_REV_ID_MASK                         0x000000ff
+#define CHIP_REV_ID_GET(x)                       (((x) & CHIP_REV_ID_MASK) >> CHIP_REV_ID_LSB)
+#define CHIP_REV_ID_SET(x)                       (((x) << CHIP_REV_ID_LSB) & CHIP_REV_ID_MASK)
+
+#define DERIVED_RTC_CLK_ADDRESS                  0x0c0000f4
+#define DERIVED_RTC_CLK_OFFSET                   0x000000f4
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB      18
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB      18
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK     0x00040000
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x)   (((x) & DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) >> DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB)
+#define DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x)   (((x) << DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) & DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK)
+#define DERIVED_RTC_CLK_FORCE_MSB                17
+#define DERIVED_RTC_CLK_FORCE_LSB                16
+#define DERIVED_RTC_CLK_FORCE_MASK               0x00030000
+#define DERIVED_RTC_CLK_FORCE_GET(x)             (((x) & DERIVED_RTC_CLK_FORCE_MASK) >> DERIVED_RTC_CLK_FORCE_LSB)
+#define DERIVED_RTC_CLK_FORCE_SET(x)             (((x) << DERIVED_RTC_CLK_FORCE_LSB) & DERIVED_RTC_CLK_FORCE_MASK)
+#define DERIVED_RTC_CLK_PERIOD_MSB               15
+#define DERIVED_RTC_CLK_PERIOD_LSB               1
+#define DERIVED_RTC_CLK_PERIOD_MASK              0x0000fffe
+#define DERIVED_RTC_CLK_PERIOD_GET(x)            (((x) & DERIVED_RTC_CLK_PERIOD_MASK) >> DERIVED_RTC_CLK_PERIOD_LSB)
+#define DERIVED_RTC_CLK_PERIOD_SET(x)            (((x) << DERIVED_RTC_CLK_PERIOD_LSB) & DERIVED_RTC_CLK_PERIOD_MASK)
+
+#define ACG_DISABLE_ADDRESS                      0x0c0000f8
+#define ACG_DISABLE_OFFSET                       0x000000f8
+#define ACG_DISABLE_CPU_MSB                      3
+#define ACG_DISABLE_CPU_LSB                      3
+#define ACG_DISABLE_CPU_MASK                     0x00000008
+#define ACG_DISABLE_CPU_GET(x)                   (((x) & ACG_DISABLE_CPU_MASK) >> ACG_DISABLE_CPU_LSB)
+#define ACG_DISABLE_CPU_SET(x)                   (((x) << ACG_DISABLE_CPU_LSB) & ACG_DISABLE_CPU_MASK)
+#define ACG_DISABLE_SDIO_MSB                     2
+#define ACG_DISABLE_SDIO_LSB                     2
+#define ACG_DISABLE_SDIO_MASK                    0x00000004
+#define ACG_DISABLE_SDIO_GET(x)                  (((x) & ACG_DISABLE_SDIO_MASK) >> ACG_DISABLE_SDIO_LSB)
+#define ACG_DISABLE_SDIO_SET(x)                  (((x) << ACG_DISABLE_SDIO_LSB) & ACG_DISABLE_SDIO_MASK)
+#define ACG_DISABLE_BB_AND_BBB_MSB               1
+#define ACG_DISABLE_BB_AND_BBB_LSB               1
+#define ACG_DISABLE_BB_AND_BBB_MASK              0x00000002
+#define ACG_DISABLE_BB_AND_BBB_GET(x)            (((x) & ACG_DISABLE_BB_AND_BBB_MASK) >> ACG_DISABLE_BB_AND_BBB_LSB)
+#define ACG_DISABLE_BB_AND_BBB_SET(x)            (((x) << ACG_DISABLE_BB_AND_BBB_LSB) & ACG_DISABLE_BB_AND_BBB_MASK)
+#define ACG_DISABLE_AMBA_MAC_MSB                 0
+#define ACG_DISABLE_AMBA_MAC_LSB                 0
+#define ACG_DISABLE_AMBA_MAC_MASK                0x00000001
+#define ACG_DISABLE_AMBA_MAC_GET(x)              (((x) & ACG_DISABLE_AMBA_MAC_MASK) >> ACG_DISABLE_AMBA_MAC_LSB)
+#define ACG_DISABLE_AMBA_MAC_SET(x)              (((x) << ACG_DISABLE_AMBA_MAC_LSB) & ACG_DISABLE_AMBA_MAC_MASK)
+
+#define KEY_ENABLE_ADDRESS                       0x0c0000fc
+#define KEY_ENABLE_OFFSET                        0x000000fc
+#define KEY_ENABLE_ON_MSB                        0
+#define KEY_ENABLE_ON_LSB                        0
+#define KEY_ENABLE_ON_MASK                       0x00000001
+#define KEY_ENABLE_ON_GET(x)                     (((x) & KEY_ENABLE_ON_MASK) >> KEY_ENABLE_ON_LSB)
+#define KEY_ENABLE_ON_SET(x)                     (((x) << KEY_ENABLE_ON_LSB) & KEY_ENABLE_ON_MASK)
+
+#define KEY_DEBOUNCE_ADDRESS                     0x0c000100
+#define KEY_DEBOUNCE_OFFSET                      0x00000100
+#define KEY_DEBOUNCE_TIME_MSB                    3
+#define KEY_DEBOUNCE_TIME_LSB                    0
+#define KEY_DEBOUNCE_TIME_MASK                   0x0000000f
+#define KEY_DEBOUNCE_TIME_GET(x)                 (((x) & KEY_DEBOUNCE_TIME_MASK) >> KEY_DEBOUNCE_TIME_LSB)
+#define KEY_DEBOUNCE_TIME_SET(x)                 (((x) << KEY_DEBOUNCE_TIME_LSB) & KEY_DEBOUNCE_TIME_MASK)
+
+#define KEY_LONG_PRESS_ADDRESS                   0x0c000104
+#define KEY_LONG_PRESS_OFFSET                    0x00000104
+#define KEY_LONG_PRESS_TIME_MSB                  5
+#define KEY_LONG_PRESS_TIME_LSB                  0
+#define KEY_LONG_PRESS_TIME_MASK                 0x0000003f
+#define KEY_LONG_PRESS_TIME_GET(x)               (((x) & KEY_LONG_PRESS_TIME_MASK) >> KEY_LONG_PRESS_TIME_LSB)
+#define KEY_LONG_PRESS_TIME_SET(x)               (((x) << KEY_LONG_PRESS_TIME_LSB) & KEY_LONG_PRESS_TIME_MASK)
+
+#define KEY_REPEAT_ADDRESS                       0x0c000108
+#define KEY_REPEAT_OFFSET                        0x00000108
+#define KEY_REPEAT_TIME_MSB                      5
+#define KEY_REPEAT_TIME_LSB                      0
+#define KEY_REPEAT_TIME_MASK                     0x0000003f
+#define KEY_REPEAT_TIME_GET(x)                   (((x) & KEY_REPEAT_TIME_MASK) >> KEY_REPEAT_TIME_LSB)
+#define KEY_REPEAT_TIME_SET(x)                   (((x) << KEY_REPEAT_TIME_LSB) & KEY_REPEAT_TIME_MASK)
+
+#define KEY_MATRIX_LO_ADDRESS                    0x0c00010c
+#define KEY_MATRIX_LO_OFFSET                     0x0000010c
+#define KEY_MATRIX_LO_ROW0_MSB                   31
+#define KEY_MATRIX_LO_ROW0_LSB                   24
+#define KEY_MATRIX_LO_ROW0_MASK                  0xff000000
+#define KEY_MATRIX_LO_ROW0_GET(x)                (((x) & KEY_MATRIX_LO_ROW0_MASK) >> KEY_MATRIX_LO_ROW0_LSB)
+#define KEY_MATRIX_LO_ROW0_SET(x)                (((x) << KEY_MATRIX_LO_ROW0_LSB) & KEY_MATRIX_LO_ROW0_MASK)
+#define KEY_MATRIX_LO_ROW1_MSB                   23
+#define KEY_MATRIX_LO_ROW1_LSB                   16
+#define KEY_MATRIX_LO_ROW1_MASK                  0x00ff0000
+#define KEY_MATRIX_LO_ROW1_GET(x)                (((x) & KEY_MATRIX_LO_ROW1_MASK) >> KEY_MATRIX_LO_ROW1_LSB)
+#define KEY_MATRIX_LO_ROW1_SET(x)                (((x) << KEY_MATRIX_LO_ROW1_LSB) & KEY_MATRIX_LO_ROW1_MASK)
+#define KEY_MATRIX_LO_ROW2_MSB                   15
+#define KEY_MATRIX_LO_ROW2_LSB                   8
+#define KEY_MATRIX_LO_ROW2_MASK                  0x0000ff00
+#define KEY_MATRIX_LO_ROW2_GET(x)                (((x) & KEY_MATRIX_LO_ROW2_MASK) >> KEY_MATRIX_LO_ROW2_LSB)
+#define KEY_MATRIX_LO_ROW2_SET(x)                (((x) << KEY_MATRIX_LO_ROW2_LSB) & KEY_MATRIX_LO_ROW2_MASK)
+#define KEY_MATRIX_LO_ROW3_MSB                   7
+#define KEY_MATRIX_LO_ROW3_LSB                   0
+#define KEY_MATRIX_LO_ROW3_MASK                  0x000000ff
+#define KEY_MATRIX_LO_ROW3_GET(x)                (((x) & KEY_MATRIX_LO_ROW3_MASK) >> KEY_MATRIX_LO_ROW3_LSB)
+#define KEY_MATRIX_LO_ROW3_SET(x)                (((x) << KEY_MATRIX_LO_ROW3_LSB) & KEY_MATRIX_LO_ROW3_MASK)
+
+#define KEY_MATRIX_HI_ADDRESS                    0x0c000110
+#define KEY_MATRIX_HI_OFFSET                     0x00000110
+#define KEY_MATRIX_HI_ROW4_MSB                   31
+#define KEY_MATRIX_HI_ROW4_LSB                   24
+#define KEY_MATRIX_HI_ROW4_MASK                  0xff000000
+#define KEY_MATRIX_HI_ROW4_GET(x)                (((x) & KEY_MATRIX_HI_ROW4_MASK) >> KEY_MATRIX_HI_ROW4_LSB)
+#define KEY_MATRIX_HI_ROW4_SET(x)                (((x) << KEY_MATRIX_HI_ROW4_LSB) & KEY_MATRIX_HI_ROW4_MASK)
+#define KEY_MATRIX_HI_ROW5_MSB                   23
+#define KEY_MATRIX_HI_ROW5_LSB                   16
+#define KEY_MATRIX_HI_ROW5_MASK                  0x00ff0000
+#define KEY_MATRIX_HI_ROW5_GET(x)                (((x) & KEY_MATRIX_HI_ROW5_MASK) >> KEY_MATRIX_HI_ROW5_LSB)
+#define KEY_MATRIX_HI_ROW5_SET(x)                (((x) << KEY_MATRIX_HI_ROW5_LSB) & KEY_MATRIX_HI_ROW5_MASK)
+#define KEY_MATRIX_HI_ROW6_MSB                   15
+#define KEY_MATRIX_HI_ROW6_LSB                   8
+#define KEY_MATRIX_HI_ROW6_MASK                  0x0000ff00
+#define KEY_MATRIX_HI_ROW6_GET(x)                (((x) & KEY_MATRIX_HI_ROW6_MASK) >> KEY_MATRIX_HI_ROW6_LSB)
+#define KEY_MATRIX_HI_ROW6_SET(x)                (((x) << KEY_MATRIX_HI_ROW6_LSB) & KEY_MATRIX_HI_ROW6_MASK)
+#define KEY_MATRIX_HI_ROW7_MSB                   7
+#define KEY_MATRIX_HI_ROW7_LSB                   0
+#define KEY_MATRIX_HI_ROW7_MASK                  0x000000ff
+#define KEY_MATRIX_HI_ROW7_GET(x)                (((x) & KEY_MATRIX_HI_ROW7_MASK) >> KEY_MATRIX_HI_ROW7_LSB)
+#define KEY_MATRIX_HI_ROW7_SET(x)                (((x) << KEY_MATRIX_HI_ROW7_LSB) & KEY_MATRIX_HI_ROW7_MASK)
+
+#define KEY_CODE_ADDRESS                         0x0c000114
+#define KEY_CODE_OFFSET                          0x00000114
+#define KEY_CODE_MULTIPRESS_MSB                  7
+#define KEY_CODE_MULTIPRESS_LSB                  7
+#define KEY_CODE_MULTIPRESS_MASK                 0x00000080
+#define KEY_CODE_MULTIPRESS_GET(x)               (((x) & KEY_CODE_MULTIPRESS_MASK) >> KEY_CODE_MULTIPRESS_LSB)
+#define KEY_CODE_MULTIPRESS_SET(x)               (((x) << KEY_CODE_MULTIPRESS_LSB) & KEY_CODE_MULTIPRESS_MASK)
+#define KEY_CODE_ROW_MSB                         6
+#define KEY_CODE_ROW_LSB                         4
+#define KEY_CODE_ROW_MASK                        0x00000070
+#define KEY_CODE_ROW_GET(x)                      (((x) & KEY_CODE_ROW_MASK) >> KEY_CODE_ROW_LSB)
+#define KEY_CODE_ROW_SET(x)                      (((x) << KEY_CODE_ROW_LSB) & KEY_CODE_ROW_MASK)
+#define KEY_CODE_COL_MSB                         2
+#define KEY_CODE_COL_LSB                         0
+#define KEY_CODE_COL_MASK                        0x00000007
+#define KEY_CODE_COL_GET(x)                      (((x) & KEY_CODE_COL_MASK) >> KEY_CODE_COL_LSB)
+#define KEY_CODE_COL_SET(x)                      (((x) << KEY_CODE_COL_LSB) & KEY_CODE_COL_MASK)
+
+#define KEY_STATUS_ADDRESS                       0x0c000118
+#define KEY_STATUS_OFFSET                        0x00000118
+#define KEY_STATUS_KEY_RELEASE_ENABLE_MSB        7
+#define KEY_STATUS_KEY_RELEASE_ENABLE_LSB        7
+#define KEY_STATUS_KEY_RELEASE_ENABLE_MASK       0x00000080
+#define KEY_STATUS_KEY_RELEASE_ENABLE_GET(x)     (((x) & KEY_STATUS_KEY_RELEASE_ENABLE_MASK) >> KEY_STATUS_KEY_RELEASE_ENABLE_LSB)
+#define KEY_STATUS_KEY_RELEASE_ENABLE_SET(x)     (((x) << KEY_STATUS_KEY_RELEASE_ENABLE_LSB) & KEY_STATUS_KEY_RELEASE_ENABLE_MASK)
+#define KEY_STATUS_FIRST_PRESS_ENABLE_MSB        6
+#define KEY_STATUS_FIRST_PRESS_ENABLE_LSB        6
+#define KEY_STATUS_FIRST_PRESS_ENABLE_MASK       0x00000040
+#define KEY_STATUS_FIRST_PRESS_ENABLE_GET(x)     (((x) & KEY_STATUS_FIRST_PRESS_ENABLE_MASK) >> KEY_STATUS_FIRST_PRESS_ENABLE_LSB)
+#define KEY_STATUS_FIRST_PRESS_ENABLE_SET(x)     (((x) << KEY_STATUS_FIRST_PRESS_ENABLE_LSB) & KEY_STATUS_FIRST_PRESS_ENABLE_MASK)
+#define KEY_STATUS_LONG_PRESS_ENABLE_MSB         5
+#define KEY_STATUS_LONG_PRESS_ENABLE_LSB         5
+#define KEY_STATUS_LONG_PRESS_ENABLE_MASK        0x00000020
+#define KEY_STATUS_LONG_PRESS_ENABLE_GET(x)      (((x) & KEY_STATUS_LONG_PRESS_ENABLE_MASK) >> KEY_STATUS_LONG_PRESS_ENABLE_LSB)
+#define KEY_STATUS_LONG_PRESS_ENABLE_SET(x)      (((x) << KEY_STATUS_LONG_PRESS_ENABLE_LSB) & KEY_STATUS_LONG_PRESS_ENABLE_MASK)
+#define KEY_STATUS_REPEAT_PRESS_ENABLE_MSB       4
+#define KEY_STATUS_REPEAT_PRESS_ENABLE_LSB       4
+#define KEY_STATUS_REPEAT_PRESS_ENABLE_MASK      0x00000010
+#define KEY_STATUS_REPEAT_PRESS_ENABLE_GET(x)    (((x) & KEY_STATUS_REPEAT_PRESS_ENABLE_MASK) >> KEY_STATUS_REPEAT_PRESS_ENABLE_LSB)
+#define KEY_STATUS_REPEAT_PRESS_ENABLE_SET(x)    (((x) << KEY_STATUS_REPEAT_PRESS_ENABLE_LSB) & KEY_STATUS_REPEAT_PRESS_ENABLE_MASK)
+#define KEY_STATUS_KEY_RELEASE_INTERRUPT_MSB     3
+#define KEY_STATUS_KEY_RELEASE_INTERRUPT_LSB     3
+#define KEY_STATUS_KEY_RELEASE_INTERRUPT_MASK    0x00000008
+#define KEY_STATUS_KEY_RELEASE_INTERRUPT_GET(x)  (((x) & KEY_STATUS_KEY_RELEASE_INTERRUPT_MASK) >> KEY_STATUS_KEY_RELEASE_INTERRUPT_LSB)
+#define KEY_STATUS_KEY_RELEASE_INTERRUPT_SET(x)  (((x) << KEY_STATUS_KEY_RELEASE_INTERRUPT_LSB) & KEY_STATUS_KEY_RELEASE_INTERRUPT_MASK)
+#define KEY_STATUS_FIRST_PRESS_INTERRUPT_MSB     2
+#define KEY_STATUS_FIRST_PRESS_INTERRUPT_LSB     2
+#define KEY_STATUS_FIRST_PRESS_INTERRUPT_MASK    0x00000004
+#define KEY_STATUS_FIRST_PRESS_INTERRUPT_GET(x)  (((x) & KEY_STATUS_FIRST_PRESS_INTERRUPT_MASK) >> KEY_STATUS_FIRST_PRESS_INTERRUPT_LSB)
+#define KEY_STATUS_FIRST_PRESS_INTERRUPT_SET(x)  (((x) << KEY_STATUS_FIRST_PRESS_INTERRUPT_LSB) & KEY_STATUS_FIRST_PRESS_INTERRUPT_MASK)
+#define KEY_STATUS_LONG_PRESS_INTERRUPT_MSB      1
+#define KEY_STATUS_LONG_PRESS_INTERRUPT_LSB      1
+#define KEY_STATUS_LONG_PRESS_INTERRUPT_MASK     0x00000002
+#define KEY_STATUS_LONG_PRESS_INTERRUPT_GET(x)   (((x) & KEY_STATUS_LONG_PRESS_INTERRUPT_MASK) >> KEY_STATUS_LONG_PRESS_INTERRUPT_LSB)
+#define KEY_STATUS_LONG_PRESS_INTERRUPT_SET(x)   (((x) << KEY_STATUS_LONG_PRESS_INTERRUPT_LSB) & KEY_STATUS_LONG_PRESS_INTERRUPT_MASK)
+#define KEY_STATUS_REPEAT_PRESS_INTERRUPT_MSB    0
+#define KEY_STATUS_REPEAT_PRESS_INTERRUPT_LSB    0
+#define KEY_STATUS_REPEAT_PRESS_INTERRUPT_MASK   0x00000001
+#define KEY_STATUS_REPEAT_PRESS_INTERRUPT_GET(x) (((x) & KEY_STATUS_REPEAT_PRESS_INTERRUPT_MASK) >> KEY_STATUS_REPEAT_PRESS_INTERRUPT_LSB)
+#define KEY_STATUS_REPEAT_PRESS_INTERRUPT_SET(x) (((x) << KEY_STATUS_REPEAT_PRESS_INTERRUPT_LSB) & KEY_STATUS_REPEAT_PRESS_INTERRUPT_MASK)
+
+#ifndef __ASSEMBLER__
+typedef struct rtc_reg_s {
+  volatile unsigned int reset_control;
+  volatile unsigned int xtal_control;
+  volatile unsigned int tcxo_detect;
+  volatile unsigned int xtal_test;
+  volatile unsigned int quadrature;
+  volatile unsigned int pll_control;
+  volatile unsigned int pll_settle;
+  volatile unsigned int xtal_settle;
+  volatile unsigned int core_clock;
+  volatile unsigned int cpu_clock;
+  volatile unsigned int clock_out;
+  volatile unsigned int clock_control;
+  volatile unsigned int bias_override;
+  volatile unsigned int ref_voltage_trim;
+  volatile unsigned int ldo_control;
+  volatile unsigned int wdt_control;
+  volatile unsigned int wdt_status;
+  volatile unsigned int wdt;
+  volatile unsigned int wdt_count;
+  volatile unsigned int wdt_reset;
+  volatile unsigned int int_status;
+  volatile unsigned int lf_timer0;
+  volatile unsigned int lf_timer_count0;
+  volatile unsigned int lf_timer_control0;
+  volatile unsigned int lf_timer_status0;
+  volatile unsigned int lf_timer1;
+  volatile unsigned int lf_timer_count1;
+  volatile unsigned int lf_timer_control1;
+  volatile unsigned int lf_timer_status1;
+  volatile unsigned int lf_timer2;
+  volatile unsigned int lf_timer_count2;
+  volatile unsigned int lf_timer_control2;
+  volatile unsigned int lf_timer_status2;
+  volatile unsigned int lf_timer3;
+  volatile unsigned int lf_timer_count3;
+  volatile unsigned int lf_timer_control3;
+  volatile unsigned int lf_timer_status3;
+  volatile unsigned int hf_timer;
+  volatile unsigned int hf_timer_count;
+  volatile unsigned int hf_lf_count;
+  volatile unsigned int hf_timer_control;
+  volatile unsigned int hf_timer_status;
+  volatile unsigned int rtc_control;
+  volatile unsigned int rtc_time;
+  volatile unsigned int rtc_date;
+  volatile unsigned int rtc_set_time;
+  volatile unsigned int rtc_set_date;
+  volatile unsigned int rtc_set_alarm;
+  volatile unsigned int rtc_config;
+  volatile unsigned int rtc_alarm_status;
+  volatile unsigned int uart_wakeup;
+  volatile unsigned int reset_cause;
+  volatile unsigned int system_sleep;
+  volatile unsigned int ldo_voltage;
+  volatile unsigned int ldo_a_voltage;
+  volatile unsigned int sdio_ldo_voltage;
+  volatile unsigned int core_pad_enable;
+  volatile unsigned int sdio_wrapper;
+  volatile unsigned int mac_sleep_control;
+  volatile unsigned int keep_awake;
+  volatile unsigned int chip_rev;
+  volatile unsigned int derived_rtc_clk;
+  volatile unsigned int acg_disable;
+  volatile unsigned int key_enable;
+  volatile unsigned int key_debounce;
+  volatile unsigned int key_long_press;
+  volatile unsigned int key_repeat;
+  volatile unsigned int key_matrix_lo;
+  volatile unsigned int key_matrix_hi;
+  volatile unsigned int key_code;
+  volatile unsigned int key_status;
+} rtc_reg_t;
+#endif /* __ASSEMBLER__ */
+
+#endif /* _RTC_H_ */

Added: developers/nbd/ar6k/include/ieee80211.h
===================================================================
--- developers/nbd/ar6k/include/ieee80211.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/ieee80211.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,333 @@
+/*-
+ * Copyright (c) 2001 Atsushi Onoe
+ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+ * Copyright 2006 ATheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ * */
+#ifndef _NET80211_IEEE80211_H_
+#define _NET80211_IEEE80211_H_
+
+/*
+ * 802.11 protocol definitions.
+ */
+
+#define IEEE80211_ADDR_LEN  6       /* size of 802.11 address */
+/* is 802.11 address multicast/broadcast? */
+#define IEEE80211_IS_MULTICAST(_a)  (*(_a) & 0x01)
+#define IEEE80211_ADDR_EQ(addr1, addr2)     \
+    (A_MEMCMP(addr1, addr2, IEEE80211_ADDR_LEN) == 0)
+
+#define IEEE80211_KEYBUF_SIZE 16
+#define IEEE80211_MICBUF_SIZE (8+8)  /* space for both tx and rx */
+
+/*
+ * NB: these values are ordered carefully; there are lots of
+ * of implications in any reordering.  In particular beware
+ * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
+ */
+#define IEEE80211_CIPHER_WEP            0
+#define IEEE80211_CIPHER_TKIP           1
+#define IEEE80211_CIPHER_AES_OCB        2
+#define IEEE80211_CIPHER_AES_CCM        3
+#define IEEE80211_CIPHER_CKIP           5
+#define IEEE80211_CIPHER_CCKM_KRK       6
+#define IEEE80211_CIPHER_NONE           7       /* pseudo value */
+
+#define IEEE80211_CIPHER_MAX            (IEEE80211_CIPHER_NONE+1)
+
+#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) \
+        (((len) == 5) || ((len) == 13) || ((len) == 16))
+
+/*
+ * generic definitions for IEEE 802.11 frames
+ */
+struct ieee80211_frame {
+    A_UINT8    i_fc[2];
+    A_UINT8    i_dur[2];
+    A_UINT8    i_addr1[IEEE80211_ADDR_LEN];
+    A_UINT8    i_addr2[IEEE80211_ADDR_LEN];
+    A_UINT8    i_addr3[IEEE80211_ADDR_LEN];
+    A_UINT8    i_seq[2];
+    /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */
+    /* see below */
+} __ATTRIB_PACK;
+
+#define IEEE80211_FC0_VERSION_MASK          0x03
+#define IEEE80211_FC0_VERSION_SHIFT         0
+#define IEEE80211_FC0_VERSION_0             0x00
+#define IEEE80211_FC0_TYPE_MASK             0x0c
+#define IEEE80211_FC0_TYPE_SHIFT            2
+#define IEEE80211_FC0_TYPE_MGT              0x00
+#define IEEE80211_FC0_TYPE_CTL              0x04
+#define IEEE80211_FC0_TYPE_DATA             0x08
+
+#define IEEE80211_FC0_SUBTYPE_MASK          0xf0
+#define IEEE80211_FC0_SUBTYPE_SHIFT         4
+/* for TYPE_MGT */
+#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ     0x00
+#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP    0x10
+#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ   0x20
+#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP  0x30
+#define IEEE80211_FC0_SUBTYPE_PROBE_REQ     0x40
+#define IEEE80211_FC0_SUBTYPE_PROBE_RESP    0x50
+#define IEEE80211_FC0_SUBTYPE_BEACON        0x80
+#define IEEE80211_FC0_SUBTYPE_ATIM          0x90
+#define IEEE80211_FC0_SUBTYPE_DISASSOC      0xa0
+#define IEEE80211_FC0_SUBTYPE_AUTH          0xb0
+#define IEEE80211_FC0_SUBTYPE_DEAUTH        0xc0
+/* for TYPE_CTL */
+#define IEEE80211_FC0_SUBTYPE_PS_POLL       0xa0
+#define IEEE80211_FC0_SUBTYPE_RTS           0xb0
+#define IEEE80211_FC0_SUBTYPE_CTS           0xc0
+#define IEEE80211_FC0_SUBTYPE_ACK           0xd0
+#define IEEE80211_FC0_SUBTYPE_CF_END        0xe0
+#define IEEE80211_FC0_SUBTYPE_CF_END_ACK    0xf0
+/* for TYPE_DATA (bit combination) */
+#define IEEE80211_FC0_SUBTYPE_DATA          0x00
+#define IEEE80211_FC0_SUBTYPE_CF_ACK        0x10
+#define IEEE80211_FC0_SUBTYPE_CF_POLL       0x20
+#define IEEE80211_FC0_SUBTYPE_CF_ACPL       0x30
+#define IEEE80211_FC0_SUBTYPE_NODATA        0x40
+#define IEEE80211_FC0_SUBTYPE_CFACK         0x50
+#define IEEE80211_FC0_SUBTYPE_CFPOLL        0x60
+#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70
+#define IEEE80211_FC0_SUBTYPE_QOS           0x80
+#define IEEE80211_FC0_SUBTYPE_QOS_NULL      0xc0
+
+#define IEEE80211_FC1_DIR_MASK              0x03
+#define IEEE80211_FC1_DIR_NODS              0x00    /* STA->STA */
+#define IEEE80211_FC1_DIR_TODS              0x01    /* STA->AP  */
+#define IEEE80211_FC1_DIR_FROMDS            0x02    /* AP ->STA */
+#define IEEE80211_FC1_DIR_DSTODS            0x03    /* AP ->AP  */
+
+#define IEEE80211_FC1_MORE_FRAG             0x04
+#define IEEE80211_FC1_RETRY                 0x08
+#define IEEE80211_FC1_PWR_MGT               0x10
+#define IEEE80211_FC1_MORE_DATA             0x20
+#define IEEE80211_FC1_WEP                   0x40
+#define IEEE80211_FC1_ORDER                 0x80
+
+#define IEEE80211_SEQ_FRAG_MASK             0x000f
+#define IEEE80211_SEQ_FRAG_SHIFT            0
+#define IEEE80211_SEQ_SEQ_MASK              0xfff0
+#define IEEE80211_SEQ_SEQ_SHIFT             4
+
+#define IEEE80211_NWID_LEN                  32
+
+/*
+ * 802.11 rate set.
+ */
+#define IEEE80211_RATE_SIZE     8       /* 802.11 standard */
+#define IEEE80211_RATE_MAXSIZE  15      /* max rates we'll handle */
+
+#define WMM_NUM_AC                  4   /* 4 AC categories */
+
+#define WMM_PARAM_ACI_M         0x60    /* Mask for ACI field */
+#define WMM_PARAM_ACI_S         5   /* Shift for ACI field */
+#define WMM_PARAM_ACM_M         0x10    /* Mask for ACM bit */
+#define WMM_PARAM_ACM_S         4       /* Shift for ACM bit */
+#define WMM_PARAM_AIFSN_M       0x0f    /* Mask for aifsn field */
+#define WMM_PARAM_LOGCWMIN_M    0x0f    /* Mask for CwMin field (in log) */
+#define WMM_PARAM_LOGCWMAX_M    0xf0    /* Mask for CwMax field (in log) */
+#define WMM_PARAM_LOGCWMAX_S    4   /* Shift for CwMax field */
+
+#define WMM_AC_TO_TID(_ac) (       \
+    ((_ac) == WMM_AC_VO) ? 6 : \
+    ((_ac) == WMM_AC_VI) ? 5 : \
+    ((_ac) == WMM_AC_BK) ? 1 : \
+    0)
+
+#define TID_TO_WMM_AC(_tid) (      \
+    ((_tid) < 1) ? WMM_AC_BE : \
+    ((_tid) < 3) ? WMM_AC_BK : \
+    ((_tid) < 6) ? WMM_AC_VI : \
+    WMM_AC_VO)
+/*
+ * Management information element payloads.
+ */
+
+enum {
+    IEEE80211_ELEMID_SSID       = 0,
+    IEEE80211_ELEMID_RATES      = 1,
+    IEEE80211_ELEMID_FHPARMS    = 2,
+    IEEE80211_ELEMID_DSPARMS    = 3,
+    IEEE80211_ELEMID_CFPARMS    = 4,
+    IEEE80211_ELEMID_TIM        = 5,
+    IEEE80211_ELEMID_IBSSPARMS  = 6,
+    IEEE80211_ELEMID_COUNTRY    = 7,
+    IEEE80211_ELEMID_CHALLENGE  = 16,
+    /* 17-31 reserved for challenge text extension */
+    IEEE80211_ELEMID_PWRCNSTR   = 32,
+    IEEE80211_ELEMID_PWRCAP     = 33,
+    IEEE80211_ELEMID_TPCREQ     = 34,
+    IEEE80211_ELEMID_TPCREP     = 35,
+    IEEE80211_ELEMID_SUPPCHAN   = 36,
+    IEEE80211_ELEMID_CHANSWITCH = 37,
+    IEEE80211_ELEMID_MEASREQ    = 38,
+    IEEE80211_ELEMID_MEASREP    = 39,
+    IEEE80211_ELEMID_QUIET      = 40,
+    IEEE80211_ELEMID_IBSSDFS    = 41,
+    IEEE80211_ELEMID_ERP        = 42,
+    IEEE80211_ELEMID_RSN        = 48,
+    IEEE80211_ELEMID_XRATES     = 50,
+    IEEE80211_ELEMID_TPC        = 150,
+    IEEE80211_ELEMID_CCKM       = 156,
+    IEEE80211_ELEMID_VENDOR     = 221,  /* vendor private */
+};
+
+#define ATH_OUI             0x7f0300        /* Atheros OUI */
+#define ATH_OUI_TYPE        0x01
+#define ATH_OUI_SUBTYPE     0x01
+#define ATH_OUI_VERSION     0x00
+
+#define WPA_OUI             0xf25000
+#define WPA_OUI_TYPE        0x01
+#define WPA_VERSION         1          /* current supported version */
+
+#define WPA_CSE_NULL        0x00
+#define WPA_CSE_WEP40       0x01
+#define WPA_CSE_TKIP        0x02
+#define WPA_CSE_CCMP        0x04
+#define WPA_CSE_WEP104      0x05
+
+#define WPA_ASE_NONE        0x00
+#define WPA_ASE_8021X_UNSPEC    0x01
+#define WPA_ASE_8021X_PSK   0x02
+
+#define RSN_OUI         0xac0f00
+#define RSN_VERSION     1       /* current supported version */
+
+#define RSN_CSE_NULL        0x00
+#define RSN_CSE_WEP40       0x01
+#define RSN_CSE_TKIP        0x02
+#define RSN_CSE_WRAP        0x03
+#define RSN_CSE_CCMP        0x04
+#define RSN_CSE_WEP104      0x05
+
+#define RSN_ASE_NONE        0x00
+#define RSN_ASE_8021X_UNSPEC    0x01
+#define RSN_ASE_8021X_PSK   0x02
+
+#define RSN_CAP_PREAUTH     0x01
+
+#define WMM_OUI         0xf25000
+#define WMM_OUI_TYPE        0x02
+#define WMM_INFO_OUI_SUBTYPE    0x00
+#define WMM_PARAM_OUI_SUBTYPE   0x01
+#define WMM_VERSION     1
+
+/* WMM stream classes */
+#define WMM_NUM_AC  4
+#define WMM_AC_BE   0       /* best effort */
+#define WMM_AC_BK   1       /* background */
+#define WMM_AC_VI   2       /* video */
+#define WMM_AC_VO   3       /* voice */
+
+/* TSPEC related */
+#define ACTION_CATEGORY_CODE_TSPEC                 17
+#define ACTION_CODE_TSPEC_ADDTS                    0
+#define ACTION_CODE_TSPEC_ADDTS_RESP               1
+#define ACTION_CODE_TSPEC_DELTS                    2
+
+typedef enum {
+    TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0,
+    TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1,
+    TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3,
+    TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8,
+    TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9,
+    TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA,
+    TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB,
+    TSPEC_STATUS_CODE_DELTS_SENT    = 0x30,
+    TSPEC_STATUS_CODE_DELTS_RECV    = 0x31,
+} TSPEC_STATUS_CODE;
+
+/*
+ * WMM/802.11e Tspec Element
+ */
+typedef struct wmm_tspec_ie_t {
+    A_UINT8     elementId;
+    A_UINT8     len;
+    A_UINT8     oui[3];
+    A_UINT8     ouiType;
+    A_UINT8     ouiSubType;
+    A_UINT8     version;
+    A_UINT16    tsInfo_info;
+    A_UINT8     tsInfo_reserved;
+    A_UINT16    nominalMSDU;
+    A_UINT16    maxMSDU;
+    A_UINT32    minServiceInt;
+    A_UINT32    maxServiceInt;
+    A_UINT32    inactivityInt;
+    A_UINT32    suspensionInt;
+    A_UINT32    serviceStartTime;
+    A_UINT32    minDataRate;
+    A_UINT32    meanDataRate;
+    A_UINT32    peakDataRate;
+    A_UINT32    maxBurstSize;
+    A_UINT32    delayBound;
+    A_UINT32    minPhyRate;
+    A_UINT16    sba;
+    A_UINT16    mediumTime;
+} __ATTRIB_PACK WMM_TSPEC_IE;
+
+
+/*
+ * BEACON management packets
+ *
+ *  octet timestamp[8]
+ *  octet beacon interval[2]
+ *  octet capability information[2]
+ *  information element
+ *      octet elemid
+ *      octet length
+ *      octet information[length]
+ */
+
+#define IEEE80211_BEACON_INTERVAL(beacon) \
+    ((beacon)[8] | ((beacon)[9] << 8))
+#define IEEE80211_BEACON_CAPABILITY(beacon) \
+    ((beacon)[10] | ((beacon)[11] << 8))
+
+#define IEEE80211_CAPINFO_ESS               0x0001
+#define IEEE80211_CAPINFO_IBSS              0x0002
+#define IEEE80211_CAPINFO_CF_POLLABLE       0x0004
+#define IEEE80211_CAPINFO_CF_POLLREQ        0x0008
+#define IEEE80211_CAPINFO_PRIVACY           0x0010
+#define IEEE80211_CAPINFO_SHORT_PREAMBLE    0x0020
+#define IEEE80211_CAPINFO_PBCC              0x0040
+#define IEEE80211_CAPINFO_CHNL_AGILITY      0x0080
+/* bits 8-9 are reserved */
+#define IEEE80211_CAPINFO_SHORT_SLOTTIME    0x0400
+#define IEEE80211_CAPINFO_APSD              0x0800
+/* bit 12 is reserved */
+#define IEEE80211_CAPINFO_DSSSOFDM          0x2000
+/* bits 14-15 are reserved */
+
+/*
+ * Authentication Modes
+ */
+
+enum ieee80211_authmode {
+    IEEE80211_AUTH_NONE     = 0,
+    IEEE80211_AUTH_OPEN     = 1,
+    IEEE80211_AUTH_SHARED   = 2,
+    IEEE80211_AUTH_8021X    = 3,
+    IEEE80211_AUTH_AUTO     = 4,   /* auto-select/accept */
+    /* NB: these are used only for ioctls */
+    IEEE80211_AUTH_WPA      = 5,  /* WPA/RSN  w/ 802.1x */
+    IEEE80211_AUTH_WPA_PSK  = 6,  /* WPA/RSN  w/ PSK */
+    IEEE80211_AUTH_WPA_CCKM = 7,  /* WPA/RSN IE  w/ CCKM */
+};
+
+#endif /* _NET80211_IEEE80211_H_ */

Added: developers/nbd/ar6k/include/ieee80211_ioctl.h
===================================================================
--- developers/nbd/ar6k/include/ieee80211_ioctl.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/ieee80211_ioctl.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ * Portions Copyright (c) 2001 Atsushi Onoe,  2002-2005 Sam Leffler, Errno Consulting
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the definitions for the AR6000 linux driver.
+ *
+ */
+
+#ifndef _IEEE80211_IOCTL_H_
+#define _IEEE80211_IOCTL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Extracted from the MADWIFI net80211/ieee80211_ioctl.h
+ */
+
+/*
+ * WPA/RSN get/set key request.  Specify the key/cipher
+ * type and whether the key is to be used for sending and/or
+ * receiving.  The key index should be set only when working
+ * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
+ * Otherwise a unicast/pairwise key is specified by the bssid
+ * (on a station) or mac address (on an ap).  They key length
+ * must include any MIC key data; otherwise it should be no
+ more than IEEE80211_KEYBUF_SIZE.
+ */
+struct ieee80211req_key {
+	u_int8_t	ik_type;	/* key/cipher type */
+	u_int8_t	ik_pad;
+	u_int16_t	ik_keyix;	/* key index */
+	u_int8_t	ik_keylen;	/* key length in bytes */
+	u_int8_t	ik_flags;
+#define IEEE80211_KEY_XMIT  0x01
+#define IEEE80211_KEY_RECV  0x02
+#define	IEEE80211_KEY_DEFAULT	0x80	/* default xmit key */
+	u_int8_t	ik_macaddr[IEEE80211_ADDR_LEN];
+	u_int64_t	ik_keyrsc;	/* key receive sequence counter */
+	u_int64_t	ik_keytsc;	/* key transmit sequence counter */
+	u_int8_t	ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
+};
+/*
+ * Delete a key either by index or address.  Set the index
+ * to IEEE80211_KEYIX_NONE when deleting a unicast key.
+ */
+struct ieee80211req_del_key {
+	u_int8_t	idk_keyix;	/* key index */
+	u_int8_t	idk_macaddr[IEEE80211_ADDR_LEN];
+};
+/*
+ * MLME state manipulation request.  IEEE80211_MLME_ASSOC
+ * only makes sense when operating as a station.  The other
+ * requests can be used when operating as a station or an
+ * ap (to effect a station).
+ */
+struct ieee80211req_mlme {
+	u_int8_t	im_op;		/* operation to perform */
+#define	IEEE80211_MLME_ASSOC		1	/* associate station */
+#define	IEEE80211_MLME_DISASSOC		2	/* disassociate station */
+#define	IEEE80211_MLME_DEAUTH		3	/* deauthenticate station */
+#define	IEEE80211_MLME_AUTHORIZE	4	/* authorize station */
+#define	IEEE80211_MLME_UNAUTHORIZE	5	/* unauthorize station */
+	u_int16_t	im_reason;	/* 802.11 reason code */
+	u_int8_t	im_macaddr[IEEE80211_ADDR_LEN];
+};
+
+struct ieee80211req_addpmkid {
+    u_int8_t    pi_bssid[IEEE80211_ADDR_LEN];
+    u_int8_t    pi_enable;
+    u_int8_t    pi_pmkid[16];
+};
+
+#define AUTH_ALG_OPEN_SYSTEM	0x01
+#define AUTH_ALG_SHARED_KEY	0x02
+#define AUTH_ALG_LEAP		0x04
+
+struct ieee80211req_authalg {
+   u_int8_t auth_alg;
+};
+
+enum {
+    IEEE80211_PARAM_AUTHMODE = 3,   /* Authentication Mode */
+    IEEE80211_PARAM_MCASTCIPHER = 5,
+    IEEE80211_PARAM_MCASTKEYLEN = 6,    /* multicast key length */
+    IEEE80211_PARAM_UCASTCIPHER = 8,
+    IEEE80211_PARAM_UCASTKEYLEN = 9,    /* unicast key length */
+	IEEE80211_PARAM_WPA		= 10,	/* WPA mode (0,1,2) */
+	IEEE80211_PARAM_ROAMING		= 12,	/* roaming mode */
+	IEEE80211_PARAM_PRIVACY		= 13,	/* privacy invoked */
+	IEEE80211_PARAM_COUNTERMEASURES	= 14,	/* WPA/TKIP countermeasures */
+	IEEE80211_PARAM_DROPUNENCRYPTED	= 15,	/* discard unencrypted frames */
+};
+
+/*
+ * Values for IEEE80211_PARAM_WPA
+ */
+#define WPA_MODE_WPA1   1
+#define WPA_MODE_WPA2   2
+#define WPA_MODE_AUTO   3
+#define WPA_MODE_NONE   4
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IEEE80211_IOCTL_H_ */

Added: developers/nbd/ar6k/include/ieee80211_node.h
===================================================================
--- developers/nbd/ar6k/include/ieee80211_node.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/ieee80211_node.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001 Atsushi Onoe
+ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+ * Copyright 2006 ATheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+#ifndef _IEEE80211_NODE_H_
+#define _IEEE80211_NODE_H_
+
+/*
+ * Node locking definitions.
+ */
+#define IEEE80211_NODE_LOCK_INIT(_nt)   A_MUTEX_INIT(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK_DESTROY(_nt)
+#define IEEE80211_NODE_LOCK(_nt)        A_MUTEX_LOCK(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_UNLOCK(_nt)      A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK_BH(_nt)     A_MUTEX_LOCK(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_UNLOCK_BH(_nt)   A_MUTEX_UNLOCK(&(_nt)->nt_nodelock)
+#define IEEE80211_NODE_LOCK_ASSERT(_nt)
+
+/*
+ * Node reference counting definitions.
+ *
+ * ieee80211_node_initref   initialize the reference count to 1
+ * ieee80211_node_incref    add a reference
+ * ieee80211_node_decref    remove a reference
+ * ieee80211_node_dectestref    remove a reference and return 1 if this
+ *              is the last reference, otherwise 0
+ * ieee80211_node_refcnt    reference count for printing (only)
+ */
+#define ieee80211_node_initref(_ni)     ((_ni)->ni_refcnt = 1)
+#define ieee80211_node_incref(_ni)      ((_ni)->ni_refcnt++)
+#define ieee80211_node_decref(_ni)      ((_ni)->ni_refcnt--)
+#define ieee80211_node_dectestref(_ni)  (((_ni)->ni_refcnt--) == 0)
+#define ieee80211_node_refcnt(_ni)      ((_ni)->ni_refcnt)
+
+#define IEEE80211_NODE_HASHSIZE 32
+/* simple hash is enough for variation of macaddr */
+#define IEEE80211_NODE_HASH(addr)   \
+    (((const A_UINT8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \
+        IEEE80211_NODE_HASHSIZE)
+
+/*
+ * Table of ieee80211_node instances.  Each ieee80211com
+ * has at least one for holding the scan candidates.
+ * When operating as an access point or in ibss mode there
+ * is a second table for associated stations or neighbors.
+ */
+struct ieee80211_node_table {
+    void                   *nt_wmip;       /* back reference */
+    A_MUTEX_T               nt_nodelock;    /* on node table */
+    struct bss              *nt_node_first; /* information of all nodes */
+    struct bss              *nt_node_last;  /* information of all nodes */
+    struct bss              *nt_hash[IEEE80211_NODE_HASHSIZE];
+    const char              *nt_name;   /* for debugging */
+    A_UINT32                nt_scangen; /* gen# for timeout scan */
+    A_TIMER                 nt_inact_timer;
+};
+
+#define WLAN_NODE_INACT_TIMEOUT_MSEC            10000
+
+#endif /* _IEEE80211_NODE_H_ */

Added: developers/nbd/ar6k/include/osapi.h
===================================================================
--- developers/nbd/ar6k/include/osapi.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/osapi.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2003-2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the definitions of the basic atheros data types.
+ * It is used to map the data types in atheros files to a platform specific
+ * type.
+ *
+ */
+
+#ifndef _OSAPI_H_
+#define _OSAPI_H_
+
+#ifdef __KERNEL__
+
+#ifdef __linux__
+#include "../include/osapi_linux.h"
+#endif
+
+/*
+ * OS specific network buffer acess routines
+ */
+void *a_netbuf_alloc(int size);
+void a_netbuf_free(void *bufPtr);
+void *a_netbuf_to_data(void *bufPtr);
+A_UINT32 a_netbuf_to_len(void *bufPtr);
+A_STATUS a_netbuf_push(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_put(void *bufPtr, A_INT32 len);
+A_STATUS a_netbuf_trim(void *bufPtr, A_INT32 len);
+A_INT32 a_netbuf_headroom(void *bufPtr);
+A_STATUS a_netbuf_pull(void *bufPtr, A_INT32 len);
+A_UINT32 a_copy_to_user(void *to, const void *from, A_UINT32 n);
+A_UINT32 a_copy_from_user(void *to, const void *from, A_UINT32 n);
+#endif /* __KERNEL__ */
+
+#ifdef __GNUC__
+#define __ATTRIB_PACK           __attribute__ ((packed))
+#define __ATTRIB_PRINTF         __attribute__ ((format (printf, 1, 2)))
+#define __ATTRIB_NORETURN       __attribute__ ((noreturn))
+#ifndef INLINE
+#define INLINE                  __inline__
+#endif
+#else /* Not GCC */
+#define __ATTRIB_PACK
+#define __ATTRIB_PRINTF
+#define __ATTRIB_NORETURN
+#ifndef INLINE
+#define INLINE                  __inline
+#endif
+#endif /* End __GNUC__ */
+
+#endif /* _OSAPI_H_ */

Added: developers/nbd/ar6k/include/osapi_linux.h
===================================================================
--- developers/nbd/ar6k/include/osapi_linux.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/osapi_linux.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2003-2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the definitions of the basic atheros data types.
+ * It is used to map the data types in atheros files to a platform specific
+ * type.
+ *
+ */
+
+#ifndef _OSAPI_LINUX_H_
+#define _OSAPI_LINUX_H_
+
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#include <linux/jiffies.h>
+#endif
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#ifdef KERNEL_2_4
+#include <asm/arch/irq.h>
+#include <asm/irq.h>
+#endif
+
+/*
+ * Endianes macros
+ */
+#define A_BE2CPU8(x)       ntohb(x)
+#define A_BE2CPU16(x)      ntohs(x)
+#define A_BE2CPU32(x)      ntohl(x)
+
+#define A_LE2CPU8(x)       (x)
+#define A_LE2CPU16(x)      (x)
+#define A_LE2CPU32(x)      (x)
+
+#define A_CPU2BE8(x)       htonb(x)
+#define A_CPU2BE16(x)      htons(x)
+#define A_CPU2BE32(x)      htonl(x)
+
+#define A_MEMCPY(dst, src, len)         memcpy((A_UINT8 *)(dst), (src), (len))
+#define A_MEMZERO(addr, len)            memset(addr, 0, len)
+#define A_MEMCMP(addr1, addr2, len)     memcmp((addr1), (addr2), (len))
+#define A_MALLOC(size)                  kmalloc((size), GFP_KERNEL)
+#define A_MALLOC_NOWAIT(size)           kmalloc((size), GFP_ATOMIC)
+#define A_FREE(addr)                    kfree(addr)
+#define A_PRINTF(args...)               printk(args)
+
+/* Mutual Exclusion */
+typedef spinlock_t                      A_MUTEX_T;
+#define A_MUTEX_INIT(mutex)             spin_lock_init(mutex)
+#define A_MUTEX_LOCK(mutex)             spin_lock_bh(mutex)
+#define A_MUTEX_UNLOCK(mutex)           spin_unlock_bh(mutex)
+
+/*
+ * Timer Functions
+ */
+#define A_MDELAY(msecs)                 mdelay(msecs)
+typedef struct timer_list               A_TIMER;
+
+#define A_INIT_TIMER(pTimer, pFunction, pArg) do {              \
+    init_timer(pTimer);                                         \
+    (pTimer)->function = (pFunction);                           \
+    (pTimer)->data	 = (unsigned long)(pArg);                   \
+} while (0)
+
+/*
+ * Start a Timer that elapses after 'periodMSec' milli-seconds
+ * Support is provided for a one-shot timer. The 'repeatFlag' is
+ * ignored.
+ */
+#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do {                   \
+    if (repeatFlag) {                                                       \
+        printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__);     \
+        panic("Timer Repeat");                                              \
+    }                                                                       \
+    mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000);                \
+} while (0)
+
+/*
+ * Cancel the Timer.
+ */
+#define A_UNTIMEOUT(pTimer) do {                                \
+    del_timer((pTimer));                                        \
+} while (0)
+
+#define A_DELETE_TIMER(pTimer) do {                             \
+} while (0)
+
+/*
+ * Wait Queue related functions
+ */
+typedef wait_queue_head_t               A_WAITQUEUE_HEAD;
+#define A_INIT_WAITQUEUE_HEAD(head)     init_waitqueue_head(head)
+#ifdef mvlcee31_2_4_20_omap2420_gsm_gprs
+#ifndef wait_event_interruptible_timeout
+#define __wait_event_interruptible_timeout(wq, condition, ret)          \
+do {                                                                    \
+        wait_queue_t __wait;                                            \
+        init_waitqueue_entry(&__wait, current);                         \
+                                                                        \
+        add_wait_queue(&wq, &__wait);                                   \
+        for (;;) {                                                      \
+                set_current_state(TASK_INTERRUPTIBLE);                  \
+                if (condition)                                          \
+                        break;                                          \
+                if (!signal_pending(current)) {                         \
+                        ret = schedule_timeout(ret);                    \
+                        if (!ret)                                       \
+                                break;                                  \
+                        continue;                                       \
+                }                                                       \
+                ret = -ERESTARTSYS;                                     \
+                break;                                                  \
+        }                                                               \
+        current->state = TASK_RUNNING;                                  \
+        remove_wait_queue(&wq, &__wait);                                \
+} while (0)
+
+#define wait_event_interruptible_timeout(wq, condition, timeout)        \
+({                                                                      \
+        long __ret = timeout;                                           \
+        if (!(condition))                                               \
+                __wait_event_interruptible_timeout(wq, condition, __ret); \
+        __ret;                                                          \
+})
+#endif /* wait_event_interruptible_timeout */
+
+#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \
+    wait_event_interruptible_timeout(head, condition, timeout); \
+} while (0)
+#else
+#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \
+    wait_event_interruptible_timeout(head, condition, timeout); \
+} while (0)
+#endif /* mvlcee31_2_4_20-omap2420_gsm_gprs */
+
+#define A_WAKE_UP(head)                 wake_up(head)
+
+#ifdef DEBUG
+#define A_ASSERT(expr)  \
+    if (!(expr)) {   \
+        printk( "\n" __FILE__ ":%d: Assertion " #expr " failed!\n",__LINE__); \
+        panic(#expr); \
+    }
+
+#else
+#define A_ASSERT(expr)
+#endif /* DEBUG */
+
+#endif /* _OSAPI_LINUX_H_ */

Added: developers/nbd/ar6k/include/queue.h
===================================================================
--- developers/nbd/ar6k/include/queue.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/queue.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $
+ * $Id: //depot/sw/releases/etnaGPL1.1/host/include/queue.h#1 $
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define	_SYS_QUEUE_H_
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *				SLIST	LIST	STAILQ	TAILQ
+ * _HEAD			+	+	+	+
+ * _HEAD_INITIALIZER		+	+	+	+
+ * _ENTRY			+	+	+	+
+ * _INIT			+	+	+	+
+ * _EMPTY			+	+	+	+
+ * _FIRST			+	+	+	+
+ * _NEXT			+	+	+	+
+ * _PREV			-	-	-	+
+ * _LAST			-	-	+	+
+ * _FOREACH			+	+	+	+
+ * _FOREACH_SAFE		+	+	+	+
+ * _FOREACH_REVERSE		-	-	-	+
+ * _FOREACH_REVERSE_SAFE	-	-	-	+
+ * _INSERT_HEAD			+	+	+	+
+ * _INSERT_BEFORE		-	+	-	+
+ * _INSERT_AFTER		+	+	+	+
+ * _INSERT_TAIL			-	-	+	+
+ * _CONCAT			-	-	+	+
+ * _REMOVE_HEAD			+	-	+	-
+ * _REMOVE			+	+	+	+
+ *
+ */
+#define	QUEUE_MACRO_DEBUG 0
+#if QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct qm_trace {
+	char * lastfile;
+	int lastline;
+	char * prevfile;
+	int prevline;
+};
+
+#define	TRACEBUF	struct qm_trace trace;
+#define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
+
+#define	QMD_TRACE_HEAD(head) do {					\
+	(head)->trace.prevline = (head)->trace.lastline;		\
+	(head)->trace.prevfile = (head)->trace.lastfile;		\
+	(head)->trace.lastline = __LINE__;				\
+	(head)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#define	QMD_TRACE_ELEM(elem) do {					\
+	(elem)->trace.prevline = (elem)->trace.lastline;		\
+	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
+	(elem)->trace.lastline = __LINE__;				\
+	(elem)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#else
+#define	QMD_TRACE_ELEM(elem)
+#define	QMD_TRACE_HEAD(head)
+#define	TRACEBUF
+#define	TRASHIT(x)
+#endif	/* QUEUE_MACRO_DEBUG */
+
+/*
+ * Singly-linked List declarations.
+ */
+#define	SLIST_HEAD(name, type)						\
+struct name {								\
+	struct type *slh_first;	/* first element */			\
+}
+
+#define	SLIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	SLIST_ENTRY(type)						\
+struct {								\
+	struct type *sle_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
+
+#define	SLIST_FIRST(head)	((head)->slh_first)
+
+#define	SLIST_FOREACH(var, head, field)					\
+	for ((var) = SLIST_FIRST((head));				\
+	    (var);							\
+	    (var) = SLIST_NEXT((var), field))
+
+#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = SLIST_FIRST((head));				\
+	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
+	for ((varp) = &SLIST_FIRST((head));				\
+	    ((var) = *(varp)) != NULL;					\
+	    (varp) = &SLIST_NEXT((var), field))
+
+#define	SLIST_INIT(head) do {						\
+	SLIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
+	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
+	SLIST_NEXT((slistelm), field) = (elm);				\
+} while (0)
+
+#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
+	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
+	SLIST_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define	SLIST_REMOVE(head, elm, type, field) do {			\
+	if (SLIST_FIRST((head)) == (elm)) {				\
+		SLIST_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = SLIST_FIRST((head));		\
+		while (SLIST_NEXT(curelm, field) != (elm))		\
+			curelm = SLIST_NEXT(curelm, field);		\
+		SLIST_NEXT(curelm, field) =				\
+		    SLIST_NEXT(SLIST_NEXT(curelm, field), field);	\
+	}								\
+} while (0)
+
+#define	SLIST_REMOVE_HEAD(head, field) do {				\
+	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *stqh_first;/* first element */			\
+	struct type **stqh_last;/* addr of last next element */		\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_CONCAT(head1, head2) do {				\
+	if (!STAILQ_EMPTY((head2))) {					\
+		*(head1)->stqh_last = (head2)->stqh_first;		\
+		(head1)->stqh_last = (head2)->stqh_last;		\
+		STAILQ_INIT((head2));					\
+	}								\
+} while (0)
+
+#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
+
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+
+#define	STAILQ_FOREACH(var, head, field)				\
+	for((var) = STAILQ_FIRST((head));				\
+	   (var);							\
+	   (var) = STAILQ_NEXT((var), field))
+
+
+#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = STAILQ_FIRST((head));				\
+	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	STAILQ_INIT(head) do {						\
+	STAILQ_FIRST((head)) = NULL;					\
+	(head)->stqh_last = &STAILQ_FIRST((head));			\
+} while (0)
+
+#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_NEXT((tqelm), field) = (elm);				\
+} while (0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	STAILQ_NEXT((elm), field) = NULL;				\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY((head)) ?						\
+		NULL :							\
+	        ((struct type *)					\
+		((char *)((head)->stqh_last) - __offsetof(struct type, field))))
+
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	if (STAILQ_FIRST((head)) == (elm)) {				\
+		STAILQ_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = STAILQ_FIRST((head));		\
+		while (STAILQ_NEXT(curelm, field) != (elm))		\
+			curelm = STAILQ_NEXT(curelm, field);		\
+		if ((STAILQ_NEXT(curelm, field) =			\
+		     STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
+			(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
+	}								\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD(head, field) do {				\
+	if ((STAILQ_FIRST((head)) =					\
+	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {			\
+	if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL)	\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+/*
+ * List declarations.
+ */
+#define	ATH_LIST_HEAD(name, type)					\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+}
+
+#define	LIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	LIST_ENTRY(type)						\
+struct {								\
+	struct type *le_next;	/* next element */			\
+	struct type **le_prev;	/* address of previous next element */	\
+}
+
+/*
+ * List functions.
+ */
+
+#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
+
+#define	LIST_FIRST(head)	((head)->lh_first)
+
+#define	LIST_FOREACH(var, head, field)					\
+	for ((var) = LIST_FIRST((head));				\
+	    (var);							\
+	    (var) = LIST_NEXT((var), field))
+
+#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = LIST_FIRST((head));				\
+	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	LIST_INIT(head) do {						\
+	LIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
+	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+		LIST_NEXT((listelm), field)->field.le_prev =		\
+		    &LIST_NEXT((elm), field);				\
+	LIST_NEXT((listelm), field) = (elm);				\
+	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
+} while (0)
+
+#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	LIST_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
+} while (0)
+
+#define	LIST_INSERT_HEAD(head, elm, field) do {				\
+	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
+		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+	LIST_FIRST((head)) = (elm);					\
+	(elm)->field.le_prev = &LIST_FIRST((head));			\
+} while (0)
+
+#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
+
+#define	LIST_REMOVE(elm, field) do {					\
+	if (LIST_NEXT((elm), field) != NULL)				\
+		LIST_NEXT((elm), field)->field.le_prev = 		\
+		    (elm)->field.le_prev;				\
+	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define	TAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *tqh_first;	/* first element */			\
+	struct type **tqh_last;	/* addr of last next element */		\
+	TRACEBUF							\
+}
+
+#define	TAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).tqh_first }
+
+#define	TAILQ_ENTRY(type)						\
+struct {								\
+	struct type *tqe_next;	/* next element */			\
+	struct type **tqe_prev;	/* address of previous next element */	\
+	TRACEBUF							\
+}
+
+/*
+ * Tail queue functions.
+ */
+#define	TAILQ_CONCAT(head1, head2, field) do {				\
+	if (!TAILQ_EMPTY(head2)) {					\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		TAILQ_INIT((head2));					\
+		QMD_TRACE_HEAD(head);					\
+		QMD_TRACE_HEAD(head2);					\
+	}								\
+} while (0)
+
+#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
+
+#define	TAILQ_FIRST(head)	((head)->tqh_first)
+
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var);							\
+	    (var) = TAILQ_NEXT((var), field))
+
+#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var);							\
+	    (var) = TAILQ_PREV((var), headname, field))
+
+#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
+	    (var) = (tvar))
+
+#define	TAILQ_INIT(head) do {						\
+	TAILQ_FIRST((head)) = NULL;					\
+	(head)->tqh_last = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+} while (0)
+
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    &TAILQ_NEXT((elm), field);				\
+	else {								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	TAILQ_NEXT((listelm), field) = (elm);				\
+	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	TAILQ_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
+		TAILQ_FIRST((head))->field.tqe_prev =			\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_FIRST((head)) = (elm);					\
+	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	TAILQ_NEXT((elm), field) = NULL;				\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_LAST(head, headname)					\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define	TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	if ((TAILQ_NEXT((elm), field)) != NULL)				\
+		TAILQ_NEXT((elm), field)->field.tqe_prev = 		\
+		    (elm)->field.tqe_prev;				\
+	else {								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
+	TRASHIT((elm)->field.tqe_next);					\
+	TRASHIT((elm)->field.tqe_prev);					\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+
+#ifdef _KERNEL
+
+/*
+ * XXX insque() and remque() are an old way of handling certain queues.
+ * They bogusly assumes that all queue heads look alike.
+ */
+
+struct quehead {
+	struct quehead *qh_link;
+	struct quehead *qh_rlink;
+};
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+
+static __inline void
+insque(void *a, void *b)
+{
+	struct quehead *element = (struct quehead *)a,
+		 *head = (struct quehead *)b;
+
+	element->qh_link = head->qh_link;
+	element->qh_rlink = head;
+	head->qh_link = element;
+	element->qh_link->qh_rlink = element;
+}
+
+static __inline void
+remque(void *a)
+{
+	struct quehead *element = (struct quehead *)a;
+
+	element->qh_link->qh_rlink = element->qh_rlink;
+	element->qh_rlink->qh_link = element->qh_link;
+	element->qh_rlink = 0;
+}
+
+#else /* !(__GNUC__ || __INTEL_COMPILER) */
+
+void	insque(void *a, void *b);
+void	remque(void *a);
+
+#endif /* __GNUC__ || __INTEL_COMPILER */
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_QUEUE_H_ */

Added: developers/nbd/ar6k/include/wlan_api.h
===================================================================
--- developers/nbd/ar6k/include/wlan_api.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/wlan_api.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the API for the host wlan module
+ *
+ *
+ */
+
+#ifndef _HOST_WLAN_API_H_
+#define _HOST_WLAN_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ieee80211_node_table;
+struct ieee80211_frame;
+
+struct ieee80211_common_ie {
+    A_UINT16    ie_chan;
+    A_UINT8     *ie_tstamp;
+    A_UINT8     *ie_ssid;
+    A_UINT8     *ie_rates;
+    A_UINT8     *ie_xrates;
+    A_UINT8     *ie_country;
+    A_UINT8     *ie_wpa;
+    A_UINT8     *ie_wmm;
+    A_UINT8     *ie_ath;
+    A_UINT16    ie_capInfo;
+    A_UINT16    ie_beaconInt;
+    A_UINT8     *ie_tim;
+    A_UINT8     *ie_chswitch;
+    A_UINT8     ie_erp;
+};
+
+typedef struct bss {
+    A_UINT8                      ni_macaddr[6];
+    A_INT8                       ni_rssi;
+    struct bss                   *ni_list_next;
+    struct bss                   *ni_list_prev;
+    struct bss                   *ni_hash_next;
+    struct bss                   *ni_hash_prev;
+    struct ieee80211_common_ie   ni_cie;
+    A_UINT8                     *ni_buf;
+    struct ieee80211_node_table *ni_table;
+    A_UINT32                     ni_refcnt;
+    int                          ni_scangen;
+    A_UINT32                     ni_tstamp;
+} bss_t;
+
+typedef void wlan_node_iter_func(void *arg, bss_t *);
+
+bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size);
+void wlan_node_free(bss_t *ni);
+void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
+                const A_UINT8 *macaddr);
+bss_t *wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr);
+void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni);
+void wlan_free_allnodes(struct ieee80211_node_table *nt);
+void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
+                        void *arg);
+
+void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt);
+void wlan_node_table_reset(struct ieee80211_node_table *nt);
+void wlan_node_table_cleanup(struct ieee80211_node_table *nt);
+
+A_STATUS wlan_parse_beacon(A_UINT8 *buf, int framelen,
+                           struct ieee80211_common_ie *cie);
+
+A_UINT16 wlan_ieee2freq(int chan);
+A_UINT32 wlan_freq2ieee(A_UINT16 freq);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HOST_WLAN_API_H_ */

Added: developers/nbd/ar6k/include/wmi.h
===================================================================
--- developers/nbd/ar6k/include/wmi.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/wmi.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,1141 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ * This file contains the definitions of the WMI protocol specified in the
+ * Wireless Module Interface (WMI).  It includes definitions of all the
+ * commands and events. Commands are messages from the host to the WM.
+ * Events and Replies are messages from the WM to the host.
+ *
+ * Ownership of correctness in regards to WMI commands
+ * belongs to the host driver and the WM is not required to validate
+ * parameters for value, proper range, or any other checking.
+ *
+ * $Id: //depot/sw/releases/etnaGPL1.1/include/wmi.h#1 $
+ *
+ */
+
+#ifndef _WMI_H_
+#define _WMI_H_
+
+#include "wmix.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WMI_PROTOCOL_VERSION    0x0001
+#define WMI_PROTOCOL_REVISION   0x0000
+
+#define ATH_MAC_LEN             6               /* length of mac in bytes */
+#define WMI_CMD_MAX_LEN         100
+#define WMI_CONTROL_MSG_MAX_LEN     256
+#define WMI_OPT_CONTROL_MSG_MAX_LEN 1536
+#define IS_ETHERTYPE(_typeOrLen)        ((_typeOrLen) >= 0x0600)
+#define RFC1042OUI      {0x00, 0x00, 0x00}
+
+#define IP_ETHERTYPE 0x0800
+
+/*
+ * Data Path
+ */
+typedef struct {
+    A_UINT8     dstMac[ATH_MAC_LEN];
+    A_UINT8     srcMac[ATH_MAC_LEN];
+    A_UINT16    typeOrLen;
+} __ATTRIB_PACK ATH_MAC_HDR;
+
+typedef struct {
+    A_UINT8     dsap;
+    A_UINT8     ssap;
+    A_UINT8     cntl;
+    A_UINT8     orgCode[3];
+    A_UINT16    etherType;
+} __ATTRIB_PACK ATH_LLC_SNAP_HDR;
+
+typedef enum {
+    DATA_MSGTYPE = 0x0,
+    CNTL_MSGTYPE,
+    SYNC_MSGTYPE
+} WMI_MSG_TYPE;
+
+
+typedef struct {
+    A_INT8      rssi;
+    A_UINT8     info;            /* WMI_MSG_TYPE in lower 2 bits - b1b0 */
+                                 /* UP in next 3 bits - b4b3b2 */
+#define WMI_DATA_HDR_MSG_TYPE_MASK  0x03
+#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
+#define WMI_DATA_HDR_UP_MASK        0x07
+#define WMI_DATA_HDR_UP_SHIFT       2
+#define WMI_DATA_HDR_IS_MSG_TYPE(h, t)  (((h)->info & (WMI_DATA_HDR_MSG_TYPE_MASK)) == (t))
+} __ATTRIB_PACK WMI_DATA_HDR;
+
+/*
+ * Control Path
+ */
+typedef struct {
+    A_UINT16    commandId;
+} __ATTRIB_PACK WMI_CMD_HDR;        /* used for commands and events */
+
+/*
+ * List of Commnands
+ */
+typedef enum {
+    WMI_CONNECT_CMDID           = 0x0001,
+    WMI_RECONNECT_CMDID,
+    WMI_DISCONNECT_CMDID,
+    WMI_SYNCHRONIZE_CMDID,
+    WMI_CREATE_PSTREAM_CMDID,
+    WMI_DELETE_PSTREAM_CMDID,
+    WMI_START_SCAN_CMDID,
+    WMI_SET_SCAN_PARAMS_CMDID,
+    WMI_SET_BSS_FILTER_CMDID,
+    WMI_SET_PROBED_SSID_CMDID,
+    WMI_SET_LISTEN_INT_CMDID,
+    WMI_SET_BMISS_TIME_CMDID,
+    WMI_SET_DISC_TIMEOUT_CMDID,
+    WMI_GET_CHANNEL_LIST_CMDID,
+    WMI_SET_BEACON_INT_CMDID,
+    WMI_GET_STATISTICS_CMDID,
+    WMI_SET_CHANNEL_PARAMS_CMDID,
+    WMI_SET_POWER_MODE_CMDID,
+    WMI_SET_IBSS_PM_CAPS_CMDID,
+    WMI_SET_POWER_PARAMS_CMDID,
+    WMI_SET_POWERSAVE_TIMERS_CMDID,
+    WMI_ADD_CIPHER_KEY_CMDID,
+    WMI_DELETE_CIPHER_KEY_CMDID,
+    WMI_ADD_KRK_CMDID,
+    WMI_DELETE_KRK_CMDID,
+    WMI_SET_PMKID_CMDID,
+    WMI_SET_TX_PWR_CMDID,
+    WMI_GET_TX_PWR_CMDID,
+    WMI_SET_ASSOC_INFO_CMDID,
+    WMI_ADD_BAD_AP_CMDID,
+    WMI_DELETE_BAD_AP_CMDID,
+    WMI_SET_TKIP_COUNTERMEASURES_CMDID,
+    WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+    WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
+    WMI_SET_ACCESS_PARAMS_CMDID,
+    WMI_SET_RETRY_LIMITS_CMDID,
+    WMI_SET_OPT_MODE_CMDID,
+    WMI_OPT_TX_FRAME_CMDID,
+    WMI_SET_VOICE_PKT_SIZE_CMDID,
+    WMI_SET_MAX_SP_LEN_CMDID,
+    WMI_SET_ROAM_CTRL_CMDID,
+    WMI_GET_ROAM_TBL_CMDID,
+    WMI_GET_ROAM_DATA_CMDID,
+    WMI_ENABLE_RM_CMDID,
+    WMI_SET_MAX_OFFHOME_DURATION_CMDID,
+    WMI_EXTENSION_CMDID,                        /* Non-wireless extensions */
+    WMI_SNR_THRESHOLD_PARAMS_CMDID,
+    WMI_LQ_THRESHOLD_PARAMS_CMDID,
+    WMI_SET_LPREAMBLE_CMDID,
+    WMI_SET_RTS_CMDID,
+    WMI_CLR_RSSI_SNR_CMDID,
+    WMI_SET_FIXRATES_CMDID,
+    WMI_GET_FIXRATES_CMDID,
+    WMI_SET_AUTH_MODE_CMDID,
+    /*
+     * Developer commands starts at 0xF000
+     */
+    WMI_SET_BITRATE_CMDID = 0xF000,
+    WMI_GET_BITRATE_CMDID,
+} WMI_COMMAND_ID;
+
+/*
+ * Connect Command
+ */
+typedef enum {
+    INFRA_NETWORK       = 0x01,
+    ADHOC_NETWORK       = 0x02,
+} NETWORK_TYPE;
+
+typedef enum {
+    OPEN_AUTH           = 0x01,
+    SHARED_AUTH         = 0x02,
+    LEAP_AUTH           = 0x04,
+} DOT11_AUTH_MODE;
+
+typedef enum {
+    NONE_AUTH           = 0x01,
+    WPA_AUTH            = 0x02,
+    WPA_PSK_AUTH        = 0x03,
+    WPA2_AUTH           = 0x04,
+    WPA2_PSK_AUTH       = 0x05,
+    WPA_AUTH_CCKM       = 0x06,
+    WPA2_AUTH_CCKM      = 0x07,
+} AUTH_MODE;
+
+typedef enum {
+    NONE_CRYPT          = 0x01,
+    WEP_CRYPT           = 0x02,
+    TKIP_CRYPT          = 0x03,
+    AES_CRYPT           = 0x04,
+} CRYPTO_TYPE;
+
+#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
+#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
+
+#define WMI_MIN_KEY_INDEX   0
+#define WMI_MAX_KEY_INDEX   3
+
+#define WMI_MAX_KEY_LEN     32
+
+#define WMI_MAX_SSID_LEN    32
+
+typedef struct {
+    A_UINT8     networkType;
+    A_UINT8     dot11AuthMode;
+    A_UINT8     authMode;
+    A_UINT8     pairwiseCryptoType;
+    A_UINT8     pairwiseCryptoLen;
+    A_UINT8     groupCryptoType;
+    A_UINT8     groupCryptoLen;
+    A_UINT8     ssidLength;
+    A_UCHAR     ssid[WMI_MAX_SSID_LEN];
+    A_UINT16    channel;
+    A_UINT8     bssid[ATH_MAC_LEN];
+} __ATTRIB_PACK WMI_CONNECT_CMD;
+
+/*
+ * WMI_RECONNECT_CMDID
+ */
+typedef struct {
+    A_UINT16    channel;                    /* hint */
+    A_UINT8     bssid[ATH_MAC_LEN];         /* mandatory if set */
+} __ATTRIB_PACK WMI_RECONNECT_CMD;
+
+/*
+ * WMI_ADD_CIPHER_KEY_CMDID
+ */
+typedef enum {
+    PAIRWISE_USAGE      = 0x00,
+    GROUP_USAGE         = 0x01,
+    TX_USAGE            = 0x02,     /* default Tx Key - Static WEP only */
+} KEY_USAGE;
+
+typedef struct {
+    A_UINT8     keyIndex;
+    A_UINT8     keyType;
+    A_UINT8     keyUsage;           /* KEY_USAGE */
+    A_UINT8     keyLength;
+    A_UINT8     keyRSC[8];          /* key replay sequence counter */
+    A_UINT8     key[WMI_MAX_KEY_LEN];
+} __ATTRIB_PACK WMI_ADD_CIPHER_KEY_CMD;
+
+/*
+ * WMI_DELETE_CIPHER_KEY_CMDID
+ */
+typedef struct {
+    A_UINT8     keyIndex;
+} __ATTRIB_PACK WMI_DELETE_CIPHER_KEY_CMD;
+
+#define WMI_KRK_LEN     16
+/*
+ * WMI_ADD_KRK_CMDID
+ */
+typedef struct {
+    A_UINT8     krk[WMI_KRK_LEN];
+} __ATTRIB_PACK WMI_ADD_KRK_CMD;
+
+/*
+ * WMI_SET_TKIP_COUNTERMEASURES_CMDID
+ */
+typedef enum {
+    WMI_TKIP_CM_DISABLE = 0x0,
+    WMI_TKIP_CM_ENABLE  = 0x1,
+} WMI_TKIP_CM_CONTROL;
+
+typedef struct {
+    A_UINT8  cm_en;                     /* WMI_TKIP_CM_CONTROL */
+} __ATTRIB_PACK WMI_SET_TKIP_COUNTERMEASURES_CMD;
+
+/*
+ * WMI_SET_PMKID_CMDID
+ */
+typedef enum {
+   PMKID_DISABLE = 0,
+   PMKID_ENABLE  = 1,
+} PMKID_ENABLE_FLG;
+
+typedef struct {
+    A_UINT8     bssid[ATH_MAC_LEN];
+    A_UINT8     enable;                 /* PMKID_ENABLE_FLG */
+    A_UINT8     pmkid[16];
+} __ATTRIB_PACK WMI_SET_PMKID_CMD;
+
+/*
+ * WMI_START_SCAN_CMD
+ */
+typedef enum {
+    WMI_LONG_SCAN  = 0,
+    WMI_SHORT_SCAN = 1,
+} WMI_SCAN_TYPE;
+
+typedef struct {
+    A_UINT8 scanType;           /* WMI_SCAN_TYPE */
+} __ATTRIB_PACK WMI_START_SCAN_CMD;
+
+/*
+ * WMI_SET_SCAN_PARAMS_CMDID
+ */
+#define WMI_SHORTSCANRATIO_DEFAULT      3
+
+typedef struct {
+    A_UINT16    fg_start_period;        /* seconds */
+    A_UINT16    fg_end_period;          /* seconds */
+    A_UINT16    bg_period;              /* seconds */
+    A_UINT16    act_chdwell_time;       /* msec */
+    A_UINT16    pas_chdwell_time;       /* msec */
+    A_UINT8     shortScanRatio;         /* how many shorts scan for one long */
+} __ATTRIB_PACK WMI_SCAN_PARAMS_CMD;
+
+/*
+ * WMI_SET_BSS_FILTER_CMDID
+ */
+typedef enum {
+    NONE_BSS_FILTER = 0x0,              /* no beacons forwarded */
+    ALL_BSS_FILTER,                     /* all beacons forwarded */
+    PROFILE_FILTER,                     /* only beacons matching profile */
+    ALL_BUT_PROFILE_FILTER,             /* all but beacons matching profile */
+    CURRENT_BSS_FILTER,                 /* only beacons matching current BSS */
+    ALL_BUT_BSS_FILTER,                 /* all but beacons matching BSS */
+    PROBED_SSID_FILTER,                 /* beacons matching probed ssid */
+    LAST_BSS_FILTER,                    /* marker only */
+} WMI_BSS_FILTER;
+
+typedef struct {
+    A_UINT8    bssFilter;                      /* see WMI_BSS_FILTER */
+} __ATTRIB_PACK WMI_BSS_FILTER_CMD;
+
+/*
+ * WMI_SET_PROBED_SSID_CMDID
+ */
+#define MAX_PROBED_SSID_INDEX   5
+
+typedef enum {
+    DISABLE_SSID_FLAG  = 0,                  /* disables entry */
+    SPECIFIC_SSID_FLAG = 0x01,               /* probes specified ssid */
+    ANY_SSID_FLAG      = 0x02,               /* probes for any ssid */
+} WMI_SSID_FLAG;
+
+typedef struct {
+    A_UINT8     entryIndex;                     /* 0 to MAX_PROBED_SSID_INDEX */
+    A_UINT8     flag;                           /* WMI_SSID_FLG */
+    A_UINT8     ssidLength;
+    A_UINT8     ssid[32];
+} __ATTRIB_PACK WMI_PROBED_SSID_CMD;
+
+/*
+ * WMI_SET_LISTEN_INT_CMDID
+ * The Listen interval is between 100 and 1000 TUs
+ */
+#define MIN_LISTEN_INTERVAL 100
+#define MAX_LISTEN_INTERVAL 1000
+#define MIN_LISTEN_BEACONS 1
+#define MAX_LISTEN_BEACONS 50
+
+typedef struct {
+    A_UINT16     listenInterval;
+    A_UINT16     numBeacons;
+} __ATTRIB_PACK WMI_LISTEN_INT_CMD;
+
+/*
+ * WMI_SET_BEACON_INT_CMDID
+ */
+typedef struct {
+    A_UINT16     beaconInterval;
+} __ATTRIB_PACK WMI_BEACON_INT_CMD;
+
+/*
+ * WMI_SET_BMISS_TIME_CMDID
+ * valid values are between 1000 and 5000 TUs
+ */
+
+#define MIN_BMISS_TIME     1000
+#define MAX_BMISS_TIME     5000
+#define MIN_BMISS_BEACONS  5
+#define MAX_BMISS_BEACONS  50
+
+typedef struct {
+    A_UINT16     bmissTime;
+    A_UINT16     numBeacons;
+} __ATTRIB_PACK WMI_BMISS_TIME_CMD;
+
+/*
+ * WMI_SET_POWER_MODE_CMDID
+ */
+typedef enum {
+    REC_POWER = 0x01,
+    MAX_PERF_POWER,
+} WMI_POWER_MODE;
+
+typedef struct {
+    A_UINT8     powerMode;      /* WMI_POWER_MODE */
+} __ATTRIB_PACK WMI_POWER_MODE_CMD;
+
+/*
+ * WMI_SET_POWER_PARAMS_CMDID
+ */
+typedef enum {
+    IGNORE_DTIM = 0x01,
+    NORMAL_DTIM = 0x02,
+    STICK_DTIM  = 0x03,
+} WMI_DTIM_POLICY;
+
+typedef struct {
+    A_UINT16    idle_period;             /* msec */
+    A_UINT16    pspoll_number;
+    A_UINT16    dtim_policy;
+} __ATTRIB_PACK WMI_POWER_PARAMS_CMD;
+
+typedef struct {
+    A_UINT8    power_saving;
+    A_UINT8    ttl; /* number of beacon periods */
+    A_UINT16   atim_windows;          /* msec */
+    A_UINT16   timeout_value;         /* msec */
+} __ATTRIB_PACK WMI_IBSS_PM_CAPS_CMD;
+
+/*
+ * WMI_SET_POWERSAVE_TIMERS_CMDID
+ */
+typedef struct {
+    A_UINT16    psPollTimeout;          /* msec */
+    A_UINT16    eospTimeout;            /* msec */
+} __ATTRIB_PACK WMI_POWERSAVE_TIMERS_CMD;
+
+/*
+ * WMI_SET_VOICE_PKT_SIZE_CMDID
+ */
+typedef struct {
+    A_UINT16    voicePktSize;
+} __ATTRIB_PACK WMI_SET_VOICE_PKT_SIZE_CMD;
+
+/*
+ * WMI_SET_MAX_SP_LEN_CMDID
+ */
+typedef enum {
+    DELIVER_ALL_PKT = 0x0,
+    DELIVER_2_PKT = 0x1,
+    DELIVER_4_PKT = 0x2,
+    DELIVER_6_PKT = 0x3,
+} APSD_SP_LEN_TYPE;
+
+typedef struct {
+    A_UINT8    maxSPLen;
+} __ATTRIB_PACK WMI_SET_MAX_SP_LEN_CMD;
+
+/*
+ * WMI_SET_DISC_TIMEOUT_CMDID
+ */
+typedef struct {
+    A_UINT8     disconnectTimeout;          /* seconds */
+} __ATTRIB_PACK WMI_DISC_TIMEOUT_CMD;
+
+typedef enum {
+    UPLINK_TRAFFIC = 0,
+    DNLINK_TRAFFIC = 1,
+    BIDIR_TRAFFIC = 2,
+} DIR_TYPE;
+/*
+ * WMI_CREATE_PSTREAM_CMDID
+ */
+typedef enum {
+    DISABLE_FOR_THIS_AC = 0,
+    ENABLE_FOR_THIS_AC  = 1,
+    ENABLE_FOR_ALL_AC   = 2,
+} VOICEPS_CAP_TYPE;
+
+typedef enum {
+    TRAFFIC_TYPE_APERIODIC = 0,
+    TRAFFIC_TYPE_PERIODIC = 1,
+}TRAFFIC_TYPE;
+
+typedef struct {
+    A_UINT8         trafficClass;
+    A_UINT8         trafficDirection;        /* DIR_TYPE */
+    A_UINT8         rxQueueNum;
+    A_UINT8         trafficType;             /* TRAFFIC_TYPE */
+    A_UINT8         voicePSCapability;       /* VOICEPS_CAP_TYPE */
+    A_UINT8         tsid;
+    A_UINT8         userPriority;            /* 802.1D user priority */
+    A_UINT16        nominalMSDU;             /* in octects */
+    A_UINT16        maxMSDU;                 /* in octects */
+    A_UINT32        minServiceInt;           /* in milli-sec */
+    A_UINT32        maxServiceInt;           /* in milli-sec */
+    A_UINT32        inactivityInt;           /* in milli-sec */
+    A_UINT32        suspensionInt;           /* in milli-sec */
+    A_UINT32        serviceStartTime;
+    A_UINT32        minDataRate;             /* in bps */
+    A_UINT32        meanDataRate;            /* in bps */
+    A_UINT32        peakDataRate;            /* in bps */
+    A_UINT32        maxBurstSize;
+    A_UINT32        delayBound;
+    A_UINT32        minPhyRate;              /* in bps */
+    A_UINT32        sba;
+    A_UINT32        mediumTime;
+} __ATTRIB_PACK WMI_CREATE_PSTREAM_CMD;
+
+/*
+ * WMI_DELETE_PSTREAM_CMDID
+ */
+typedef struct {
+    A_UINT8     txQueueNumber;
+    A_UINT8     rxQueueNumber;
+    A_UINT8     trafficDirection;
+    A_UINT8     trafficClass;
+} __ATTRIB_PACK WMI_DELETE_PSTREAM_CMD;
+
+/*
+ * WMI_SET_CHANNEL_PARAMS_CMDID
+ */
+typedef enum {
+    WMI_11A_MODE  = 0x1,
+    WMI_11G_MODE  = 0x2,
+    WMI_11AG_MODE = 0x3,
+    WMI_11B_MODE  = 0x4,
+    WMI_11GONLY_MODE = 0x5,
+} WMI_PHY_MODE;
+
+#define WMI_MAX_CHANNELS        32
+
+typedef struct {
+    A_UINT8     phyMode;                /* see WMI_PHY_MODE */
+    A_UINT8     numChannels;            /* how many channels follow */
+    A_UINT16    channelList[1];         /* channels in Mhz */
+} __ATTRIB_PACK WMI_CHANNEL_PARAMS_CMD;
+
+
+/*
+ *  WMI_RSSI_THRESHOLD_PARAMS_CMDID
+ *  Setting the polltime to 0 would disable polling.
+ *  Threshold values are in the ascending order, and should agree to:
+ *  (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
+ *      < highThreshold_upperVal)
+ */
+
+typedef struct WMI_RSSI_THRESHOLD_PARAMS{
+    A_UINT8     highThreshold_upperVal;
+    A_UINT8     highThreshold_lowerVal;
+    A_UINT8     lowThreshold_upperVal;
+    A_UINT8     lowThreshold_lowerVal;
+    A_UINT32    pollTime;               /* Polling time in seconds */
+} __ATTRIB_PACK  WMI_RSSI_THRESHOLD_PARAMS_CMD;
+
+/*
+ *  WMI_TARGET_ERROR_REPORT_BITMASK_CMDID
+ *  Sets the error reporting event bitmask in target. Target clears it
+ *  upon an error. Subsequent errors are counted, but not reported
+ *  via event, unless the bitmask is set again.
+ */
+typedef struct {
+    A_UINT32    bitmask;
+} __ATTRIB_PACK  WMI_TARGET_ERROR_REPORT_BITMASK;
+
+/*
+ * WMI_SET_TX_PWR_CMDID
+ */
+typedef struct {
+    A_UINT8     dbM;                  /* in dbM units */
+} __ATTRIB_PACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY;
+
+/*
+ * WMI_SET_ASSOC_INFO_CMDID
+ *
+ * A maximum of 2 private IEs can be sent in the [Re]Assoc request.
+ * A 3rd one, the CCX version IE can also be set from the host.
+ */
+#define WMI_MAX_ASSOC_INFO_TYPE    2
+#define WMI_CCX_VER_IE             2 /* ieType to set CCX Version IE */
+
+#define WMI_MAX_ASSOC_INFO_LEN     240
+
+typedef struct {
+    A_UINT8     ieType;
+    A_UINT8     bufferSize;
+    A_UINT8     assocInfo[1];       /* up to WMI_MAX_ASSOC_INFO_LEN */
+} __ATTRIB_PACK WMI_SET_ASSOC_INFO_CMD;
+
+
+/*
+ * WMI_GET_TX_PWR_CMDID does not take any parameters
+ */
+
+/*
+ * WMI_ADD_BAD_AP_CMDID
+ */
+#define WMI_MAX_BAD_AP_INDEX      1
+
+typedef struct {
+    A_UINT8     badApIndex;         /* 0 to WMI_MAX_BAD_AP_INDEX */
+    A_UINT8     bssid[ATH_MAC_LEN];
+} __ATTRIB_PACK WMI_ADD_BAD_AP_CMD;
+
+/*
+ * WMI_DELETE_BAD_AP_CMDID
+ */
+typedef struct {
+    A_UINT8     badApIndex;         /* 0 to WMI_MAX_BAD_AP_INDEX */
+} __ATTRIB_PACK WMI_DELETE_BAD_AP_CMD;
+
+/*
+ * WMI_SET_ACCESS_PARAMS_CMDID
+ */
+#define WMI_DEFAULT_TXOP_ACPARAM    0       /* implies one MSDU */
+#define WMI_DEFAULT_ECWMIN_ACPARAM  4       /* corresponds to CWmin of 15 */
+#define WMI_DEFAULT_ECWMAX_ACPARAM  10      /* corresponds to CWmax of 1023 */
+#define WMI_MAX_CW_ACPARAM          15      /* maximum eCWmin or eCWmax */
+#define WMI_DEFAULT_AIFSN_ACPARAM   2
+#define WMI_MAX_AIFSN_ACPARAM       15
+typedef struct {
+    A_UINT16 txop;                      /* in units of 32 usec */
+    A_UINT8  eCWmin;
+    A_UINT8  eCWmax;
+    A_UINT8  aifsn;
+} __ATTRIB_PACK WMI_SET_ACCESS_PARAMS_CMD;
+
+
+/*
+ * WMI_SET_RETRY_LIMITS_CMDID
+ *
+ * This command is used to customize the number of retries the
+ * wlan device will perform on a given frame.
+ */
+#define WMI_MIN_RETRIES 2
+#define WMI_MAX_RETRIES 13
+typedef enum {
+    MGMT_FRAMETYPE    = 0,
+    CONTROL_FRAMETYPE = 1,
+    DATA_FRAMETYPE    = 2
+} WMI_FRAMETYPE;
+
+typedef struct {
+    A_UINT8 frameType;                      /* WMI_FRAMETYPE */
+    A_UINT8 trafficClass;                   /* applies only to DATA_FRAMETYPE */
+    A_UINT8 maxRetries;
+} __ATTRIB_PACK WMI_SET_RETRY_LIMITS_CMD;
+/*
+ * WMI_SET_ROAM_CTRL_CMDID
+ *
+ * This command is used to influence the Roaming behaviour
+ * Set the host biases of the BSSs before setting the roam mode as bias
+ * based.
+ */
+
+/*
+ * Different types of Roam Control
+ */
+
+typedef enum {
+        WMI_FORCE_ROAM          = 1,      /* Roam to the specified BSSID */
+        WMI_SET_ROAM_MODE       = 2,      /* default ,progd bias, no roam */
+        WMI_SET_HOST_BIAS       = 3,     /* Set the Host Bias */
+} WMI_ROAM_CTRL_TYPE;
+
+#define WMI_MIN_ROAM_CTRL_TYPE WMI_FORCE_ROAM
+#define WMI_MAX_ROAM_CTRL_TYPE WMI_SET_HOST_BIAS
+
+/*
+ * ROAM MODES
+ */
+
+typedef enum {
+        WMI_DEFAULT_ROAM_MODE   = 1,  /* RSSI based ROAM */
+        WMI_HOST_BIAS_ROAM_MODE = 2, /* HOST BIAS based ROAM */
+        WMI_LOCK_BSS_MODE  = 3,  /* Lock to the Current BSS - no Roam */
+        WMI_DISABLE_ROAM = 4    /* disables all auto-nomous roaming
+                                   behaviour */
+} WMI_ROAM_MODE;
+
+/*
+ * BSS HOST BIAS INFO
+ */
+
+typedef struct {
+        A_UINT8 bssid[ATH_MAC_LEN];
+        A_INT8  bias;
+} __ATTRIB_PACK WMI_BSS_BIAS;
+
+typedef struct {
+        A_UINT8 numBss;
+        WMI_BSS_BIAS bssBias[1];
+} __ATTRIB_PACK WMI_BSS_BIAS_INFO;
+
+typedef struct {
+    A_UINT8   roamCtrlType;
+    union {
+        A_UINT8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */
+        A_UINT8 roamMode;           /* WMI_SET_ROAM_MODE  */
+        WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */
+    } __ATTRIB_PACK info;
+} __ATTRIB_PACK WMI_SET_ROAM_CTRL_CMD;
+
+/*
+ * WMI_ENABLE_RM_CMDID
+ */
+typedef struct {
+        A_BOOL enable_radio_measurements;
+} __ATTRIB_PACK WMI_ENABLE_RM_CMD;
+
+/*
+ * WMI_SET_MAX_OFFHOME_DURATION_CMDID
+ */
+typedef struct {
+        A_UINT8 max_offhome_duration;
+} __ATTRIB_PACK WMI_SET_MAX_OFFHOME_DURATION_CMD;
+
+
+
+/*
+ * Command Replies
+ */
+
+/*
+ * WMI_GET_CHANNEL_LIST_CMDID reply
+ */
+typedef struct {
+    A_UINT8     reserved1;
+    A_UINT8     numChannels;            /* number of channels in reply */
+    A_UINT16    channelList[1];         /* channel in Mhz */
+} __ATTRIB_PACK WMI_CHANNEL_LIST_REPLY;
+
+typedef enum {
+    A_SUCCEEDED = A_OK,
+    A_MBOX1_OK = 1,
+    A_MBOX2_OK = 2,
+    A_MBOX3_OK = 3,
+    A_FAILED_DELETE_INVALID_MBOX = 253,
+    A_FAILED_CREATE_REMOVE_PSTREAM_FIRST = 254,
+} PSTREAM_REPLY_STATUS;
+
+typedef struct {
+    A_UINT8     status;                 /* PSTREAM_REPLY_STATUS */
+    A_UINT8     txQueueNumber;
+    A_UINT8     rxQueueNumber;
+    A_UINT8     trafficClass;
+    A_UINT8     trafficDirection;       /* DIR_TYPE */
+} __ATTRIB_PACK WMI_CRE_PRIORITY_STREAM_REPLY;
+
+typedef struct {
+    A_UINT8     status;                 /* PSTREAM_REPLY_STATUS */
+    A_UINT8     txQueueNumber;
+    A_UINT8     rxQueueNumber;
+    A_UINT8     trafficDirection;       /* DIR_TYPE */
+    A_UINT8     trafficClass;
+} __ATTRIB_PACK WMI_DEL_PRIORITY_STREAM_REPLY;
+
+
+/*
+ * List of Events (target to host)
+ */
+typedef enum {
+    WMI_READY_EVENTID           = 0x1001,
+    WMI_CONNECT_EVENTID,
+    WMI_DISCONNECT_EVENTID,
+    WMI_BSSINFO_EVENTID,
+    WMI_CMDERROR_EVENTID,
+    WMI_REGDOMAIN_EVENTID,
+    WMI_PSTREAM_TIMEOUT_EVENTID,
+    WMI_NEIGHBOR_REPORT_EVENTID,
+    WMI_TKIP_MICERR_EVENTID,
+    WMI_SCAN_COMPLETE_EVENTID,
+    WMI_REPORT_STATISTICS_EVENTID,
+    WMI_RSSI_THRESHOLD_EVENTID,
+    WMI_ERROR_REPORT_EVENTID,
+    WMI_OPT_RX_FRAME_EVENTID,
+    WMI_REPORT_ROAM_TBL_EVENTID,
+    WMI_EXTENSION_EVENTID,
+    WMI_CAC_EVENTID,
+    WMI_SNR_THRESHOLD_EVENTID,
+    WMI_LQ_THRESHOLD_EVENTID,
+    WMI_TX_RETRY_ERR_EVENTID,
+    WMI_REPORT_ROAM_DATA_EVENTID,
+} WMI_EVENT_ID;
+
+typedef enum {
+    WMI_11A_CAPABILITY   = 1,
+    WMI_11G_CAPABILITY   = 2,
+    WMI_11AG_CAPABILITY  = 3,
+} WMI_PHY_CAPABILITY;
+
+typedef struct {
+    A_UINT8     macaddr[ATH_MAC_LEN];
+    A_UINT8     phyCapability;              /* WMI_PHY_CAPABILITY */
+} __ATTRIB_PACK WMI_READY_EVENT;
+
+/*
+ * Connect Event
+ */
+typedef struct {
+    A_UINT16    channel;
+    A_UINT8     bssid[ATH_MAC_LEN];
+    A_UINT16    listenInterval;
+    A_UINT8     beaconIeLen;
+    A_UINT8     assocReqLen;
+    A_UINT8     assocRespLen;
+    A_UINT8     assocInfo[1];
+} __ATTRIB_PACK WMI_CONNECT_EVENT;
+
+/*
+ * Disconnect Event
+ */
+typedef enum {
+    NO_NETWORK_AVAIL   = 0x01,
+    LOST_LINK          = 0x02,     /* bmiss */
+    DISCONNECT_CMD     = 0x03,
+    BSS_DISCONNECTED   = 0x04,
+    AUTH_FAILED        = 0x05,
+    ASSOC_FAILED       = 0x06,
+    NO_RESOURCES_AVAIL = 0x07,
+    CSERV_DISCONNECT   = 0x08,
+    INVALID_PROFILE    = 0x0a,
+} WMI_DISCONNECT_REASON;
+
+typedef struct {
+    A_UINT8     disconnectReason;      /* see WMI_DISCONNECT_REASON */
+    A_UINT8     bssid[ATH_MAC_LEN];    /* set if known */
+    A_UINT8     assocRespLen;
+    A_UINT8     assocInfo[1];
+} __ATTRIB_PACK WMI_DISCONNECT_EVENT;
+
+/*
+ * BSS Info Event.
+ * Mechanism used to inform host of the presence and characteristic of
+ * wireless networks present.  Consists of bss info header followed by
+ * the beacon or probe-response frame body.  The 802.11 header is not included.
+ */
+typedef enum {
+    BEACON_FTYPE = 0x1,
+    PROBERESP_FTYPE,
+} WMI_BI_FTYPE;
+
+typedef struct {
+    A_UINT16    channel;
+    A_UINT8     frameType;          /* see WMI_BI_FTYPE */
+    A_INT8      rssi;
+    A_UINT8     bssid[ATH_MAC_LEN];
+} __ATTRIB_PACK WMI_BSS_INFO_HDR;
+
+/*
+ * Command Error Event
+ */
+typedef enum {
+    INVALID_PARAM  = 0x01,
+    ILLEGAL_STATE  = 0x02,
+    INTERNAL_ERROR = 0x03,
+} WMI_ERROR_CODE;
+
+typedef struct {
+    A_UINT16    commandId;
+    A_UINT8     errorCode;
+} __ATTRIB_PACK WMI_CMD_ERROR_EVENT;
+
+/*
+ * New Regulatory Domain Event
+ */
+typedef struct {
+    A_UINT32    regDomain;
+} __ATTRIB_PACK WMI_REG_DOMAIN_EVENT;
+
+typedef struct {
+    A_UINT8     txQueueNumber;
+    A_UINT8     rxQueueNumber;
+    A_UINT8     trafficDirection;
+} __ATTRIB_PACK WMI_PSTREAM_TIMEOUT_EVENT;
+
+/*
+ * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
+ * the host of BSS's it has found that matches the current profile.
+ * It can be used by the host to cache PMKs and/to initiate pre-authentication
+ * if the BSS supports it.  The first bssid is always the current associated
+ * BSS.
+ * The bssid and bssFlags information repeats according to the number
+ * or APs reported.
+ */
+typedef enum {
+    WMI_DEFAULT_BSS_FLAGS   = 0x00,
+    WMI_PREAUTH_CAPABLE_BSS = 0x01,
+    WMI_PMKID_VALID_BSS     = 0x02,
+} WMI_BSS_FLAGS;
+
+typedef struct {
+    A_UINT8     bssid[ATH_MAC_LEN];
+    A_UINT8     bssFlags;            /* see WMI_BSS_FLAGS */
+} __ATTRIB_PACK WMI_NEIGHBOR_INFO;
+
+typedef struct {
+    A_INT8      numberOfAps;
+    WMI_NEIGHBOR_INFO neighbor[1];
+} __ATTRIB_PACK WMI_NEIGHBOR_REPORT_EVENT;
+
+/*
+ * TKIP MIC Error Event
+ */
+typedef struct {
+    A_UINT8 keyid;
+    A_UINT8 ismcast;
+} __ATTRIB_PACK WMI_TKIP_MICERR_EVENT;
+
+/*
+ * WMI_SCAN_COMPLETE_EVENTID - no parameters
+ */
+
+#define MAX_OPT_DATA_LEN 1400
+
+/*
+ * WMI_SET_ADHOC_BSSID_CMDID
+ */
+typedef struct {
+    A_UINT8     bssid[ATH_MAC_LEN];
+} __ATTRIB_PACK WMI_SET_ADHOC_BSSID_CMD;
+
+/*
+ * WMI_SET_OPT_MODE_CMDID
+ */
+typedef enum {
+    SPECIAL_OFF,
+    SPECIAL_ON,
+} OPT_MODE_TYPE;
+
+typedef struct {
+    A_UINT8     optMode;
+} __ATTRIB_PACK WMI_SET_OPT_MODE_CMD;
+
+/*
+ * WMI_TX_OPT_FRAME_CMDID
+ */
+typedef enum {
+    OPT_PROBE_REQ   = 0x01,
+    OPT_PROBE_RESP  = 0x02,
+    OPT_CPPP_START  = 0x03,
+    OPT_CPPP_STOP   = 0x04,
+} __ATTRIB_PACK WMI_OPT_FTYPE;
+
+typedef struct {
+    A_UINT8     frmType;
+    A_UINT8     dstAddr[ATH_MAC_LEN];
+    A_UINT8     bssid[ATH_MAC_LEN];
+    A_UINT16    optIEDataLen;
+    A_UINT8     *optIEData;
+} __ATTRIB_PACK WMI_OPT_TX_FRAME_CMD;
+
+/*
+ * Special frame receive Event.
+ * Mechanism used to inform host of the receiption of the special frames.
+ * Consists of special frame info header followed by special frame body.
+ * The 802.11 header is not included.
+ */
+typedef struct {
+    A_UINT16    channel;
+    A_UINT8     frameType;          /* see WMI_OPT_FTYPE */
+    A_INT8      rssi;
+    A_UINT8     srcAddr[ATH_MAC_LEN];
+    A_UINT8     bssid[ATH_MAC_LEN];
+} __ATTRIB_PACK WMI_OPT_RX_INFO_HDR;
+
+/*
+ * Reporting statistics.
+ */
+typedef struct {
+    A_UINT32   tx_packets;
+    A_UINT32   tx_bytes;
+    A_UINT32   tx_unicast_pkts;
+    A_UINT32   tx_unicast_bytes;
+    A_UINT32   tx_multicast_pkts;
+    A_UINT32   tx_multicast_bytes;
+    A_UINT32   tx_broadcast_pkts;
+    A_UINT32   tx_broadcast_bytes;
+    A_UINT32   tx_rts_success_cnt;
+    A_UINT32   tx_packet_per_ac[4];
+
+    A_UINT32   tx_errors;
+    A_UINT32   tx_failed_cnt;
+    A_UINT32   tx_retry_cnt;
+    A_UINT32   tx_rts_fail_cnt;
+}__ATTRIB_PACK tx_stats_t;
+
+typedef struct {
+    A_UINT32   rx_packets;
+    A_UINT32   rx_bytes;
+    A_UINT32   rx_unicast_pkts;
+    A_UINT32   rx_unicast_bytes;
+    A_UINT32   rx_multicast_pkts;
+    A_UINT32   rx_multicast_bytes;
+    A_UINT32   rx_broadcast_pkts;
+    A_UINT32   rx_broadcast_bytes;
+    A_UINT32   rx_fragment_pkt;
+
+    A_UINT32   rx_errors;
+    A_UINT32   rx_crcerr;
+    A_UINT32   rx_key_cache_miss;
+    A_UINT32   rx_decrypt_err;
+    A_UINT32   rx_duplicate_frames;
+}__ATTRIB_PACK rx_stats_t;
+
+typedef struct {
+    A_UINT32   tkip_local_mic_failure;
+    A_UINT32   tkip_counter_measures_invoked;
+    A_UINT32   tkip_replays;
+    A_UINT32   tkip_format_errors;
+    A_UINT32   ccmp_format_errors;
+    A_UINT32   ccmp_replays;
+}__ATTRIB_PACK tkip_ccmp_stats_t;
+
+typedef struct {
+    A_UINT32   power_save_failure_cnt;
+}__ATTRIB_PACK pm_stats_t;
+
+typedef struct {
+    A_UINT32    cs_bmiss_cnt;
+    A_UINT32    cs_lowRssi_cnt;
+    A_UINT16    cs_connect_cnt;
+    A_UINT16    cs_disconnect_cnt;
+    A_UINT8     cs_aveBeacon_rssi;
+    A_UINT8     cs_lastRoam_msec;
+}__ATTRIB_PACK cserv_stats_t;
+
+typedef struct {
+    tx_stats_t          tx_stats;
+    rx_stats_t          rx_stats;
+    tkip_ccmp_stats_t   tkipCcmpStats;
+}__ATTRIB_PACK wlan_net_stats_t;
+
+typedef struct {
+    wlan_net_stats_t    txrxStats;
+    cserv_stats_t       cservStats;
+    pm_stats_t          pmStats;
+    A_INT16             noise_floor_calibation;
+}__ATTRIB_PACK WMI_TARGET_STATS;
+
+/*
+ * WMI_RSSI_THRESHOLD_EVENTID.
+ * Indicate the RSSI events to host. Events are indicated when we breach a
+ * thresold value.
+ */
+typedef enum{
+    WMI_RSSI_LOWTHRESHOLD_BELOW_LOWERVAL=1,
+    WMI_RSSI_LOWTHRESHOLD_LOWERVAL,
+    WMI_RSSI_LOWTHRESHOLD_UPPERVAL,
+    WMI_RSSI_HIGHTHRESHOLD_LOWERVAL,
+    WMI_RSSI_HIGHTHRESHOLD_HIGHERVAL
+}WMI_RSSI_THRESHOLD_VAL;
+
+typedef struct {
+    A_UINT8 range;
+}__ATTRIB_PACK WMI_RSSI_THRESHOLD_EVENT;
+
+/*
+ *  WMI_ERROR_REPORT_EVENTID
+ */
+typedef enum{
+    WMI_TARGET_PM_ERR_FAIL      = 0x00000001,
+    WMI_TARGET_KEY_NOT_FOUND    = 0x00000002,
+    WMI_TARGET_DECRYPTION_ERR   = 0x00000004,
+    WMI_TARGET_BMISS            = 0x00000008,
+    WMI_PSDISABLE_NODE_JOIN     = 0x00000010
+}__ATTRIB_PACK WMI_TARGET_ERROR_VAL;
+
+typedef struct {
+    A_UINT32 errorVal;
+}__ATTRIB_PACK  WMI_TARGET_ERROR_REPORT_EVENT;
+
+/*
+ * WMI_REPORT_ROAM_TBL_EVENTID
+ */
+#define MAX_ROAM_TBL_CAND   5
+
+typedef struct {
+    A_UINT8 bssid[ATH_MAC_LEN];
+    A_INT8  rssi;
+    A_INT8  rssidt;
+    A_INT8  last_rssi;
+    A_INT32 roam_util;
+    A_INT8  util;
+    A_INT8  bias;
+} __ATTRIB_PACK WMI_BSS_ROAM_INFO;
+
+
+typedef struct {
+    A_UINT8  roamMode;
+    A_UINT8  numEntries;
+    WMI_BSS_ROAM_INFO bssRoamInfo[1];
+} __ATTRIB_PACK WMI_TARGET_ROAM_TBL;
+
+/*
+ *  WMI_CAC_EVENTID
+ */
+typedef enum {
+    CAC_INDICATION_ADMISSION = 0x00,
+    CAC_INDICATION_ADMISSION_RESP = 0x01,
+    CAC_INDICATION_DELETE = 0x02,
+    CAC_INDICATION_NO_RESP = 0x03,
+}CAC_INDICATION;
+
+#define WMM_TSPEC_IE_LEN   63
+
+typedef struct {
+    A_UINT8 ac;
+    A_UINT8 cac_indication;
+    A_UINT8 statusCode;
+    A_UINT8 tspecSuggestion[WMM_TSPEC_IE_LEN];
+}__ATTRIB_PACK  WMI_CAC_EVENT;
+
+/*
+ * developer commands
+ */
+
+/*
+ * WMI_SET_BITRATE_CMDID
+ *
+ * Get bit rate cmd uses same definition as set bit rate cmd
+ */
+typedef enum {
+    RATE_AUTO   = -1,
+    RATE_1Mb    = 0,
+    RATE_2Mb    = 1,
+    RATE_5_5Mb  = 2,
+    RATE_11Mb   = 3,
+    RATE_6Mb    = 4,
+    RATE_9Mb    = 5,
+    RATE_12Mb   = 6,
+    RATE_18Mb   = 7,
+    RATE_24Mb   = 8,
+    RATE_36Mb   = 9,
+    RATE_48Mb   = 10,
+    RATE_54Mb   = 11,
+} WMI_BIT_RATE;
+
+typedef struct {
+    A_INT8      rateIndex;          /* see WMI_BIT_RATE */
+} __ATTRIB_PACK WMI_BIT_RATE_CMD, WMI_BIT_RATE_REPLY;
+
+typedef enum {
+    ROAM_DATA_TIME = 1,            /* Get The Roam Time Data */
+} ROAM_DATA_TYPE;
+
+typedef struct {
+    A_UINT32        disassoc_time;
+    A_UINT8         disassoc_bssid[ATH_MAC_LEN];
+    A_INT8          disassoc_bss_rssi;
+    A_UINT32        no_txrx_time;
+    A_UINT32        assoc_time;
+    A_UINT8         assoc_bssid[ATH_MAC_LEN];
+    A_INT8          assoc_bss_rssi;
+    A_UINT32        allow_txrx_time;
+    A_UINT32        last_data_txrx_time;
+    A_UINT32        first_data_txrx_time;
+} __ATTRIB_PACK WMI_TARGET_ROAM_TIME;
+
+typedef struct {
+    A_UINT8 roamDataType;
+    union {
+        WMI_TARGET_ROAM_TIME roamTime;
+    } u;
+} __ATTRIB_PACK WMI_TARGET_ROAM_DATA;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMI_H_ */

Added: developers/nbd/ar6k/include/wmi_api.h
===================================================================
--- developers/nbd/ar6k/include/wmi_api.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/wmi_api.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains the definitions for the Wireless Module Interface (WMI).
+ *
+ *
+ */
+
+#ifndef _WMI_API_H_
+#define _WMI_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WMI_HIGH_PRIORITY_MBOX  ENDPOINT4
+#define WMI_LOW_PRIORITY_MBOX   ENDPOINT3
+#define WMI_BEST_EFFORT_MBOX    ENDPOINT2
+#define WMI_CONTROL_MBOX        ENDPOINT1
+#define WMI_MBOX_COUNT          4
+#define WMI_MAX_NUM_PRI_STREAMS 2
+#define WMI_NOT_MAPPED          (-1)
+#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 /* 5 seconds */
+
+typedef enum {
+    CCX_V4_COMPLIANCE = 0x1,
+}TSPEC_PARAM_COMPLIANCE;
+
+struct wmi_t;
+
+void *wmi_init(void *devt);
+
+void wmi_qos_state_init(struct wmi_t *wmip);
+void wmi_shutdown(struct wmi_t *wmip);
+A_INT8 wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 dir, A_UINT8 trafficClass);
+A_STATUS wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf);
+A_STATUS wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType);
+A_STATUS wmi_dot3_2_dix(struct wmi_t *wmip, void *osbuf);
+A_STATUS wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf);
+A_STATUS wmi_syncpoint(struct wmi_t *wmip);
+A_STATUS wmi_syncpoint_reset(struct wmi_t *wmip);
+HTC_ENDPOINT_ID wmi_get_endpoint(struct wmi_t *wmip, A_UINT8 trafficClass);
+A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT8 dir);
+
+A_STATUS wmi_control_rx(struct wmi_t *wmip, void *osbuf);
+void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg);
+
+typedef enum {
+    NO_SYNC_WMIFLAG = 0,
+    SYNC_BEFORE_WMIFLAG,            /* transmit all queued data before cmd */
+    SYNC_AFTER_WMIFLAG,             /* any new data waits until cmd execs */
+    SYNC_BOTH_WMIFLAG,
+    END_WMIFLAG                     /* end marker */
+} WMI_SYNC_FLAG;
+
+A_STATUS wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
+                      WMI_SYNC_FLAG flag);
+A_STATUS wmi_connect_cmd(struct wmi_t *wmip,
+                         NETWORK_TYPE netType,
+                         DOT11_AUTH_MODE dot11AuthMode,
+                         AUTH_MODE authMode,
+                         CRYPTO_TYPE pairwiseCrypto,
+                         A_UINT8 pairwiseCryptoLen,
+                         CRYPTO_TYPE groupCrypto,
+                         A_UINT8 groupCryptoLen,
+                         int ssidLength,
+                         A_UCHAR *ssid,
+                         A_UINT8 *bssid,
+                         A_UINT16 channel);
+A_STATUS wmi_reconnect_cmd(struct wmi_t *wmip,
+                           A_UINT8 *bssid,
+                           A_UINT16 channel);
+A_STATUS wmi_disconnect_cmd(struct wmi_t *wmip);
+A_STATUS wmi_getrev_cmd(struct wmi_t *wmip);
+A_STATUS wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType);
+A_STATUS wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
+                            A_UINT16 fg_end_sec, A_UINT16 bg_sec,
+                            A_UINT16 act_chdw_msec, A_UINT16 pas_chdw_msec,
+                            A_UINT8 shScanRatio);
+A_STATUS wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter);
+A_STATUS wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag,
+                            A_UINT8 ssidLength, A_UCHAR *ssid);
+A_STATUS wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons);
+A_STATUS wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmisstime, A_UINT16 bmissbeacons);
+A_STATUS wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType,
+                           A_UINT8 ieLen, A_UINT8 *ieInfo);
+A_STATUS wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode);
+A_STATUS wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl,
+                            A_UINT16 atim_windows, A_UINT16 timeout_value);
+A_STATUS wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod,
+                           A_UINT16 psPollNum, A_UINT16 dtimPolicy);
+A_STATUS wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout);
+A_STATUS wmi_sync_cmd(struct wmi_t *wmip, A_UINT8 syncNumber);
+A_STATUS wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream);
+A_STATUS wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 txQueueNumber,
+                                A_UINT8 rxQueueNumber, A_UINT8 trafficDirection);
+A_STATUS wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 rate);
+A_STATUS wmi_get_bitrate_cmd(struct wmi_t *wmip);
+A_INT8   wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate);
+A_STATUS wmi_get_regDomain_cmd(struct wmi_t *wmip);
+A_STATUS wmi_get_channelList_cmd(struct wmi_t *wmip);
+A_STATUS wmi_set_channelParams_cmd(struct wmi_t *wmip, WMI_PHY_MODE mode,
+                                   A_INT8 numChan, A_UINT16 *channelList);
+A_STATUS wmi_set_link_threshold_params(struct wmi_t *wmip,
+                                A_UINT8 highThreshold_upperVal,
+                                A_UINT8 highThreshold_lowerVal,
+                                A_UINT8 lowThreshold_upperVal,
+                                A_UINT8 lowThreshold_lowerVal,
+                                A_UINT32 pollTime);
+A_STATUS wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask);
+
+A_STATUS wmi_get_stats_cmd(struct wmi_t *wmip);
+A_STATUS wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex,
+                        CRYPTO_TYPE keyType, A_UINT8 keyUsage,
+                        A_UINT8 keyLength,A_UINT8 *keyRSC,
+                        A_UINT8 *keyMaterial, WMI_SYNC_FLAG sync_flag);
+A_STATUS wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk);
+A_STATUS wmi_delete_krk_cmd(struct wmi_t *wmip);
+A_STATUS wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex);
+A_STATUS wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM);
+A_STATUS wmi_get_txPwr_cmd(struct wmi_t *wmip);
+A_STATUS wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid);
+A_STATUS wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex);
+A_STATUS wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en);
+A_STATUS wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
+                          A_BOOL set);
+A_STATUS wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT16 txop,
+                                   A_UINT8 eCWmin, A_UINT8 eCWmax,
+                                   A_UINT8 aifsn);
+A_STATUS wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
+                                  A_UINT8 trafficClass, A_UINT8 maxRetries);
+
+void wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid);
+
+A_STATUS wmi_get_roam_tbl_cmd(struct wmi_t *wmip);
+A_STATUS wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType);
+A_STATUS wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
+                               A_UINT8 size);
+A_STATUS wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
+                            WMI_POWERSAVE_TIMERS_CMD *pCmd,
+                            A_UINT8 size);
+
+A_STATUS wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode);
+A_STATUS wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
+                              A_UINT8 frmType,
+                              A_UINT8 *dstMacAddr,
+                              A_UINT8 *bssid,
+                              A_UINT16 optIEDataLen,
+                              A_UINT8 *optIEData);
+
+A_STATUS wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl);
+A_STATUS wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize);
+A_STATUS wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSpLen);
+A_UINT8  convert_userPriority_to_trafficClass(A_UINT8 userPriority);
+A_UINT8 wmi_get_power_mode_cmd(struct wmi_t *wmip);
+A_STATUS wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMI_API_H_ */

Added: developers/nbd/ar6k/include/wmi_host.h
===================================================================
--- developers/nbd/ar6k/include/wmi_host.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/wmi_host.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This file contains local definitios for the wmi host module.
+ *
+ */
+
+#ifndef _WMI_HOST_H_
+#define _WMI_HOST_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * IP QoS Field definitions according to 802.1p
+ */
+#define BEST_EFFORT_PRI         0
+#define BACKGROUND_PRI          1
+#define EXCELLENT_EFFORT_PRI    3
+#define CONTROLLED_LOAD_PRI     4
+#define VIDEO_PRI               5
+#define VOICE_PRI               6
+#define NETWORK_CONTROL_PRI     7
+
+struct wmi_stats {
+    A_UINT32    cmd_len_err;
+    A_UINT32    cmd_id_err;
+};
+
+struct wmi_priority_state {
+    A_UINT8     inUse;
+    A_UINT8     mbox;
+};
+
+struct wmi_mbox_state {
+    A_UINT8     trafficClass;
+    A_INT8      priorityNum;
+};
+
+struct wmi_t {
+    A_BOOL                          wmi_ready;
+    A_BOOL                          wmi_numQoSStream;
+    struct wmi_priority_state       wmi_priority[WMI_MAX_NUM_PRI_STREAMS];
+    struct wmi_mbox_state           wmi_mboxMap[2][WMI_MBOX_COUNT];
+    A_INT8                          wmi_trafficClassMap[2][WMM_NUM_AC];
+    A_UINT8                         wmi_olderPriRxMbox;
+    A_UINT8                         wmi_newerPriRxMbox;
+    void                           *wmi_devt;
+    struct wmi_stats                wmi_stats;
+    struct ieee80211_node_table     wmi_scan_table;
+    A_BOOL                          wmi_pstreamCmdInProgress[2][WMM_NUM_AC];
+    A_BOOL                          wmi_cpstreamCmdInProgress;
+    A_UINT8                         wmi_bssid[ATH_MAC_LEN];
+    A_UINT8                         wmi_powerMode;
+    A_UINT8                         wmi_phyMode;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMI_HOST_H_ */

Added: developers/nbd/ar6k/include/wmix.h
===================================================================
--- developers/nbd/ar6k/include/wmix.h	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/include/wmix.h	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2004-2005 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ * This file contains extensions of the WMI protocol specified in the
+ * Wireless Module Interface (WMI).  It includes definitions of all
+ * extended commands and events.  Extensions include useful commands
+ * that are not directly related to wireless activities.  They may
+ * be hardware-specific, and they might not be supported on all
+ * implementations.
+ *
+ * Extended WMIX commands are encapsulated in a WMI message with
+ * cmd=WMI_EXTENSION_CMD.
+ *
+ * $Id: //depot/sw/releases/etnaGPL1.1/include/wmix.h#1 $
+ *
+ */
+
+#ifndef _WMIX_H_
+#define _WMIX_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Extended WMI commands are those that are needed during wireless
+ * operation, but which are not really wireless commands.  This allows,
+ * for instance, platform-specific commands.  Extended WMI commands are
+ * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
+ * Extended WMI events are similarly embedded in a WMI event message with
+ * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
+ */
+typedef struct {
+    A_UINT16    commandId;
+} __ATTRIB_PACK WMIX_CMD_HDR;
+
+typedef enum {
+    WMIX_DSETOPEN_REPLY_CMDID           = 0x2001,
+    WMIX_DSETDATA_REPLY_CMDID,
+    WMIX_GPIO_OUTPUT_SET_CMDID,
+    WMIX_GPIO_INPUT_GET_CMDID,
+    WMIX_GPIO_REGISTER_SET_CMDID,
+    WMIX_GPIO_REGISTER_GET_CMDID,
+    WMIX_GPIO_INTR_ACK_CMDID,
+} WMIX_COMMAND_ID;
+
+typedef enum {
+    WMIX_DSETOPENREQ_EVENTID            = 0x3001,
+    WMIX_DSETCLOSE_EVENTID,
+    WMIX_DSETDATAREQ_EVENTID,
+    WMIX_GPIO_INTR_EVENTID,
+    WMIX_GPIO_DATA_EVENTID,
+    WMIX_GPIO_ACK_EVENTID,
+} WMIX_EVENT_ID;
+
+/*
+ * =============DataSet support=================
+ */
+
+/*
+ * WMIX_DSETOPENREQ_EVENTID
+ * DataSet Open Request Event
+ */
+typedef struct {
+    A_UINT32 dset_id;
+    A_UINT32 targ_dset_handle;  /* echo'ed, not used by Host, */
+    A_UINT32 targ_reply_fn;     /* echo'ed, not used by Host, */
+    A_UINT32 targ_reply_arg;    /* echo'ed, not used by Host, */
+} __ATTRIB_PACK WMIX_DSETOPENREQ_EVENT;
+
+/*
+ * WMIX_DSETCLOSE_EVENTID
+ * DataSet Close Event
+ */
+typedef struct {
+    A_UINT32 access_cookie;
+} __ATTRIB_PACK WMIX_DSETCLOSE_EVENT;
+
+/*
+ * WMIX_DSETDATAREQ_EVENTID
+ * DataSet Data Request Event
+ */
+typedef struct {
+    A_UINT32 access_cookie;
+    A_UINT32 offset;
+    A_UINT32 length;
+    A_UINT32 targ_buf;         /* echo'ed, not used by Host, */
+    A_UINT32 targ_reply_fn;    /* echo'ed, not used by Host, */
+    A_UINT32 targ_reply_arg;   /* echo'ed, not used by Host, */
+} __ATTRIB_PACK WMIX_DSETDATAREQ_EVENT;
+
+typedef struct {
+    A_UINT32              status;
+    A_UINT32              targ_dset_handle;
+    A_UINT32              targ_reply_fn;
+    A_UINT32              targ_reply_arg;
+    A_UINT32              access_cookie;
+    A_UINT32              size;
+    A_UINT32              version;
+} __ATTRIB_PACK WMIX_DSETOPEN_REPLY_CMD;
+
+typedef struct {
+    A_UINT32              status;
+    A_UINT32              targ_buf;
+    A_UINT32              targ_reply_fn;
+    A_UINT32              targ_reply_arg;
+    A_UINT32              length;
+    A_UINT8               buf[1];
+} __ATTRIB_PACK WMIX_DSETDATA_REPLY_CMD;
+
+
+/*
+ * =============GPIO support=================
+ * All masks are 18-bit masks with bit N operating on GPIO pin N.
+ */
+
+#if defined(AR6000)
+#include "AR6000/AR6000_gpio.h"
+#endif /* AR6000 */
+
+/*
+ * Set GPIO pin output state.
+ * In order for output to be driven, a pin must be enabled for output.
+ * This can be done during initialization through the GPIO Configuration
+ * DataSet, or during operation with the enable_mask.
+ *
+ * If a request is made to simultaneously set/clear or set/disable or
+ * clear/disable or disable/enable, results are undefined.
+ */
+typedef struct {
+    A_UINT32              set_mask;             /* pins to set */
+    A_UINT32              clear_mask;           /* pins to clear */
+    A_UINT32              enable_mask;          /* pins to enable for output */
+    A_UINT32              disable_mask;         /* pins to disable/tristate */
+} __ATTRIB_PACK WMIX_GPIO_OUTPUT_SET_CMD;
+
+/*
+ * Set a GPIO register.  For debug/exceptional cases.
+ * Values for gpioreg_id are GPIO_REGISTER_IDs, defined in a
+ * platform-dependent header.
+ */
+typedef struct {
+    A_UINT32              gpioreg_id;           /* GPIO register ID */
+    A_UINT32              value;                /* value to write */
+} __ATTRIB_PACK WMIX_GPIO_REGISTER_SET_CMD;
+
+/* Get a GPIO register.  For debug/exceptional cases. */
+typedef struct {
+    A_UINT32              gpioreg_id;           /* GPIO register to read */
+} __ATTRIB_PACK WMIX_GPIO_REGISTER_GET_CMD;
+
+/*
+ * Host acknowledges and re-arms GPIO interrupts.  A single
+ * message should be used to acknowledge all interrupts that
+ * were delivered in an earlier WMIX_GPIO_INTR_EVENT message.
+ */
+typedef struct {
+    A_UINT32              ack_mask;             /* interrupts to acknowledge */
+} __ATTRIB_PACK WMIX_GPIO_INTR_ACK_CMD;
+
+/*
+ * Target informs Host of GPIO interrupts that have ocurred since the
+ * last WMIX_GIPO_INTR_ACK_CMD was received.  Additional information --
+ * the current GPIO input values is provided -- in order to support
+ * use of a GPIO interrupt as a Data Valid signal for other GPIO pins.
+ */
+typedef struct {
+    A_UINT32              intr_mask;            /* pending GPIO interrupts */
+    A_UINT32              input_values;         /* recent GPIO input values */
+} __ATTRIB_PACK WMIX_GPIO_INTR_EVENT;
+
+/*
+ * Target responds to Host's earlier WMIX_GPIO_INPUT_GET_CMDID request
+ * using a GPIO_DATA_EVENT with
+ *   value set to the mask of GPIO pin inputs and
+ *   reg_id set to GPIO_ID_NONE
+ *
+ *
+ * Target responds to Hosts's earlier WMIX_GPIO_REGISTER_GET_CMDID request
+ * using a GPIO_DATA_EVENT with
+ *   value set to the value of the requested register and
+ *   reg_id identifying the register (reflects the original request)
+ * NB: reg_id supports the future possibility of unsolicited
+ * WMIX_GPIO_DATA_EVENTs (for polling GPIO input), and it may
+ * simplify Host GPIO support.
+ */
+typedef struct {
+    A_UINT32              value;
+    A_UINT32              reg_id;
+} __ATTRIB_PACK WMIX_GPIO_DATA_EVENT;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WMIX_H_ */

Added: developers/nbd/ar6k/wlan/Makefile
===================================================================
--- developers/nbd/ar6k/wlan/Makefile	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/wlan/Makefile	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,2 @@
+obj-$(CONFIG_SDIO_AR6000_WLAN) += wlan_node.o  wlan_recv_beacon.o  wlan_utils.o
+

Added: developers/nbd/ar6k/wlan/wlan_node.c
===================================================================
--- developers/nbd/ar6k/wlan/wlan_node.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/wlan/wlan_node.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2001 Atsushi Onoe
+ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2006 Atheros Communications
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ */
+/*
+ * IEEE 802.11 node handling support.
+ */
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/osapi.h"
+#include "../include/ieee80211.h"
+#include "../include/wlan_api.h"
+#include "../include/ieee80211_node.h"
+#include "../include/htc.h"
+#include "../include/wmi.h"
+#include "../include/wmi_api.h"
+
+#ifdef DEBUG
+static int wlan_node_debug= 1;
+#define ND_PRINTF      if (wlan_node_debug) A_PRINTF
+#else
+#define ND_PRINTF(args...)
+#endif
+
+static void wlan_node_timeout(unsigned long arg);
+static bss_t * _ieee80211_find_node(struct ieee80211_node_table *nt,
+                                    const A_UINT8 *macaddr);
+
+bss_t *
+wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size)
+{
+    bss_t *ni;
+
+    ni = A_MALLOC_NOWAIT(sizeof(bss_t));
+
+    if (ni != NULL) {
+        ni->ni_buf = A_MALLOC_NOWAIT(wh_size);
+        if (ni->ni_buf == NULL) {
+            A_FREE(ni);
+            ni = NULL;
+        }
+    }
+
+    /* Make sure our lists are clean */
+    ni->ni_list_next = NULL;
+    ni->ni_list_prev = NULL;
+    ni->ni_hash_next = NULL;
+    ni->ni_hash_prev = NULL;
+
+    return ni;
+}
+
+void
+wlan_node_free(bss_t *ni)
+{
+    if (ni->ni_buf != NULL) {
+        A_FREE(ni->ni_buf);
+    }
+
+    A_FREE(ni);
+}
+
+void
+wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni,
+                const A_UINT8 *macaddr)
+{
+    int hash;
+
+    A_MEMCPY(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN);
+    hash = IEEE80211_NODE_HASH(macaddr);
+    ieee80211_node_initref(ni);     /* mark referenced */
+
+    ni->ni_tstamp = jiffies + (WLAN_NODE_INACT_TIMEOUT_MSEC / 1000) * HZ;
+    IEEE80211_NODE_LOCK_BH(nt);
+
+    /* Insert at the end of the node list */
+    ni->ni_list_next = NULL;
+    ni->ni_list_prev = nt->nt_node_last;
+    if(nt->nt_node_last != NULL)
+    {
+        nt->nt_node_last->ni_list_next = ni;
+    }
+    nt->nt_node_last = ni;
+    if(nt->nt_node_first == NULL)
+    {
+        nt->nt_node_first = ni;
+    }
+
+    /* Insert into the hash list i.e. the bucket */
+    if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL)
+    {
+        nt->nt_hash[hash]->ni_hash_prev = ni;
+    }
+    ni->ni_hash_prev = NULL;
+    nt->nt_hash[hash] = ni;
+
+    IEEE80211_NODE_UNLOCK_BH(nt);
+}
+
+static bss_t *
+_ieee80211_find_node(struct ieee80211_node_table *nt,
+    const A_UINT8 *macaddr)
+{
+    bss_t *ni;
+    int hash;
+
+    IEEE80211_NODE_LOCK_ASSERT(nt);
+
+    hash = IEEE80211_NODE_HASH(macaddr);
+    for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
+        if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) {
+            ieee80211_node_incref(ni);  /* mark referenced */
+            return ni;
+        }
+    }
+    return NULL;
+}
+
+bss_t *
+wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr)
+{
+    bss_t *ni;
+
+    IEEE80211_NODE_LOCK(nt);
+    ni = _ieee80211_find_node(nt, macaddr);
+    IEEE80211_NODE_UNLOCK(nt);
+    return ni;
+}
+
+/*
+ * Reclaim a node.  If this is the last reference count then
+ * do the normal free work.  Otherwise remove it from the node
+ * table and mark it gone by clearing the back-reference.
+ */
+void
+wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni)
+{
+    IEEE80211_NODE_LOCK(nt);
+
+    if(ni->ni_list_prev == NULL)
+    {
+        /* First in list so fix the list head */
+        nt->nt_node_first = ni->ni_list_next;
+    }
+    else
+    {
+        ni->ni_list_prev->ni_list_next = ni->ni_list_next;
+    }
+
+    if(ni->ni_list_next == NULL)
+    {
+        /* Last in list so fix list tail */
+        nt->nt_node_last = ni->ni_list_prev;
+    }
+    else
+    {
+        ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
+    }
+
+    if(ni->ni_hash_prev == NULL)
+    {
+        /* First in list so fix the list head */
+        int hash;
+        hash = IEEE80211_NODE_HASH(ni->ni_macaddr);
+        nt->nt_hash[hash] = ni->ni_hash_next;
+    }
+    else
+    {
+        ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
+    }
+
+    if(ni->ni_hash_next != NULL)
+    {
+        ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
+    }
+    wlan_node_free(ni);
+
+    IEEE80211_NODE_UNLOCK(nt);
+}
+
+static void
+wlan_node_dec_free(bss_t *ni)
+{
+    if (ieee80211_node_dectestref(ni)) {
+        wlan_node_free(ni);
+    }
+}
+
+void
+wlan_free_allnodes(struct ieee80211_node_table *nt)
+{
+    bss_t *ni;
+
+    while ((ni = nt->nt_node_first) != NULL) {
+        wlan_node_reclaim(nt, ni);
+    }
+}
+
+void
+wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f,
+                   void *arg)
+{
+    bss_t *ni;
+    A_UINT32 gen;
+
+    gen = nt->nt_scangen++;
+    IEEE80211_NODE_LOCK(nt);
+    for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+        if (ni->ni_scangen != gen) {
+            ni->ni_scangen = gen;
+            (void) ieee80211_node_incref(ni);
+            (*f)(arg, ni);
+            wlan_node_dec_free(ni);
+        }
+    }
+    IEEE80211_NODE_UNLOCK(nt);
+}
+
+/*
+ * Node table support.
+ */
+void
+wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt)
+{
+    int i;
+    ND_PRINTF("node table = 0x%x\n", (A_UINT32)nt);
+    IEEE80211_NODE_LOCK_INIT(nt);
+
+    nt->nt_node_first = nt->nt_node_last = NULL;
+    for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++)
+    {
+        nt->nt_hash[i] = NULL;
+    }
+    A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt);
+    A_TIMEOUT_MS(&nt->nt_inact_timer, WLAN_NODE_INACT_TIMEOUT_MSEC, 0);
+    nt->nt_wmip = wmip;
+}
+
+static void
+wlan_node_timeout(unsigned long arg)
+{
+    struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;
+    bss_t *bss, *nextBss;
+    A_UINT8 myBssid[IEEE80211_ADDR_LEN];
+
+    wmi_get_current_bssid(nt->nt_wmip, myBssid);
+
+    bss = nt->nt_node_first;
+    while (bss != NULL) {
+        nextBss = bss->ni_list_next;
+        if ((A_MEMCMP(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) &&
+            (bss->ni_tstamp <= jiffies))
+        {
+            /*
+             * free up all but the current bss - if set
+             */
+            wlan_node_reclaim(nt, bss);
+        }
+        bss = nextBss;
+    }
+
+    A_TIMEOUT_MS(&nt->nt_inact_timer, WLAN_NODE_INACT_TIMEOUT_MSEC, 0);
+}
+
+void
+wlan_node_table_cleanup(struct ieee80211_node_table *nt)
+{
+    A_UNTIMEOUT(&nt->nt_inact_timer);
+    wlan_free_allnodes(nt);
+    IEEE80211_NODE_LOCK_DESTROY(nt);
+}

Added: developers/nbd/ar6k/wlan/wlan_recv_beacon.c
===================================================================
--- developers/nbd/ar6k/wlan/wlan_recv_beacon.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/wlan/wlan_recv_beacon.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2001 Atsushi Onoe
+ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
+ * Copyright 2006 Atheros Communications, Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ */
+/*
+ * IEEE 802.11 input handling.
+ */
+
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/osapi.h"
+#include "../include/wmi.h"
+#include "../include/ieee80211.h"
+#include "../include/wlan_api.h"
+
+#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do {         \
+    if ((_len) < (_minlen)) {                   \
+        return A_EINVAL;                         \
+    }                               \
+} while (0)
+
+#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do {         \
+    if ((__elem) == NULL) {                     \
+        return A_EINVAL;                         \
+    }                               \
+    if ((__elem)[1] > (__maxlen)) {                 \
+        return A_EINVAL;                         \
+    }                               \
+} while (0)
+
+
+/* unaligned little endian access */
+#define LE_READ_2(p)                            \
+    ((A_UINT16)                            \
+     ((((A_UINT8 *)(p))[0]      ) | (((A_UINT8 *)(p))[1] <<  8)))
+
+#define LE_READ_4(p)                            \
+    ((A_UINT32)                            \
+     ((((A_UINT8 *)(p))[0]      ) | (((A_UINT8 *)(p))[1] <<  8) | \
+      (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24)))
+
+
+static int __inline
+iswpaoui(const A_UINT8 *frm)
+{
+    return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
+}
+
+static int __inline
+iswmmoui(const A_UINT8 *frm)
+{
+    return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
+}
+
+static int __inline
+iswmmparam(const A_UINT8 *frm)
+{
+    return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
+}
+
+static int __inline
+iswmminfo(const A_UINT8 *frm)
+{
+    return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE;
+}
+
+static int __inline
+isatherosoui(const A_UINT8 *frm)
+{
+    return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI);
+}
+
+A_STATUS
+wlan_parse_beacon(A_UINT8 *buf, int framelen, struct ieee80211_common_ie *cie)
+{
+    A_UINT8 *frm, *efrm;
+
+    frm = buf;
+    efrm = (A_UINT8 *) (frm + framelen);
+
+    /*
+     * beacon/probe response frame format
+     *  [8] time stamp
+     *  [2] beacon interval
+     *  [2] capability information
+     *  [tlv] ssid
+     *  [tlv] supported rates
+     *  [tlv] country information
+     *  [tlv] parameter set (FH/DS)
+     *  [tlv] erp information
+     *  [tlv] extended supported rates
+     *  [tlv] WMM
+     *  [tlv] WPA or RSN
+     *  [tlv] Atheros Advanced Capabilities
+     */
+    IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
+    A_MEMZERO(cie, sizeof(*cie));
+
+    cie->ie_tstamp = frm; frm += 8;
+    cie->ie_beaconInt = A_LE2CPU16(*(A_UINT16 *)frm);  frm += 2;
+    cie->ie_capInfo = A_LE2CPU16(*(A_UINT16 *)frm);  frm += 2;
+    cie->ie_chan = 0;
+
+    while (frm < efrm) {
+        switch (*frm) {
+        case IEEE80211_ELEMID_SSID:
+            cie->ie_ssid = frm;
+            break;
+        case IEEE80211_ELEMID_RATES:
+            cie->ie_rates = frm;
+            break;
+        case IEEE80211_ELEMID_COUNTRY:
+            cie->ie_country = frm;
+            break;
+        case IEEE80211_ELEMID_FHPARMS:
+            break;
+        case IEEE80211_ELEMID_DSPARMS:
+            cie->ie_chan = frm[2];
+            break;
+        case IEEE80211_ELEMID_TIM:
+            cie->ie_tim = frm;
+            break;
+        case IEEE80211_ELEMID_IBSSPARMS:
+            break;
+        case IEEE80211_ELEMID_XRATES:
+            cie->ie_xrates = frm;
+            break;
+        case IEEE80211_ELEMID_ERP:
+            if (frm[1] != 1) {
+                A_PRINTF("Discarding ERP Element - Bad Len\n");
+                return A_EINVAL;
+            }
+            cie->ie_erp = frm[2];
+            break;
+        case IEEE80211_ELEMID_RSN:
+            cie->ie_wpa = frm;
+            break;
+        case IEEE80211_ELEMID_VENDOR:
+            if (iswpaoui(frm)) {
+                cie->ie_wpa = frm;
+            } else if (iswmmoui(frm)) {
+                cie->ie_wmm = frm;
+            } else if (isatherosoui(frm)) {
+                cie->ie_ath = frm;
+            }
+            break;
+        default:
+            break;
+        }
+        frm += frm[1] + 2;
+    }
+    IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE);
+    IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN);
+
+    return A_OK;
+}

Added: developers/nbd/ar6k/wlan/wlan_utils.c
===================================================================
--- developers/nbd/ar6k/wlan/wlan_utils.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/wlan/wlan_utils.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ * All rights reserved.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This module implements frequently used wlan utilies
+ *
+ */
+
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/osapi.h"
+
+/*
+ * converts ieee channel number to frequency
+ */
+A_UINT16
+wlan_ieee2freq(int chan)
+{
+    if (chan == 14) {
+        return 2484;
+    }
+    if (chan < 14) {    /* 0-13 */
+        return (2407 + (chan*5));
+    }
+    if (chan < 27) {    /* 15-26 */
+        return (2512 + ((chan-15)*20));
+    }
+    return (5000 + (chan*5));
+}
+
+/*
+ * Converts MHz frequency to IEEE channel number.
+ */
+A_UINT32
+wlan_freq2ieee(A_UINT16 freq)
+{
+    if (freq == 2484)
+        return 14;
+    if (freq < 2484)
+        return (freq - 2407) / 5;
+    if (freq < 5000)
+        return 15 + ((freq - 2512) / 20);
+    return (freq - 5000) / 5;
+}

Added: developers/nbd/ar6k/wmi/wmi.c
===================================================================
--- developers/nbd/ar6k/wmi/wmi.c	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/ar6k/wmi/wmi.c	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,2871 @@
+/*
+ * Copyright (c) 2004-2006 Atheros Communications Inc.
+ *
+ *  Wireless Network driver for Atheros AR6001
+ *
+ *  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;
+ *
+ *  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.
+ *
+ *
+ * This module implements the hardware independent layer of the
+ * Wireless Module Interface (WMI) protocol.
+ *
+ */
+
+#include "../include/athdefs.h"
+#include "../include/athtypes.h"
+#include "../include/osapi.h"
+#include "../include/htc.h"
+#include "../include/wmi.h"
+#include "../include/ieee80211.h"
+#include "../include/ieee80211_node.h"
+#include "../include/wlan_api.h"
+#include "../include/wmi_api.h"
+#include "../include/dset_api.h"
+#include "../include/gpio_api.h"
+#include "../include/wmi_host.h"
+#include "../include/athdrv.h"
+#include "../include/ar6000_api.h"
+
+#ifdef DEBUG
+int wmi_debug = 0;
+#define WMI_DEBUG_PRINTF(args...)        if (wmi_debug) printk(args);
+#define WMI_DEBUG_PRINTF2(args...)       if (wmi_debug > 1) printk(args);
+#else
+#define WMI_DEBUG_PRINTF(args...)
+#define WMI_DEBUG_PRINTF2(args...)
+#endif
+
+static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+
+static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                     int len);
+static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                        int len);
+static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                        int len);
+static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                     int len);
+static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                       int len);
+static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                     int len);
+static A_STATUS wmi_sync_point(struct wmi_t *wmip);
+
+static A_STATUS wmi_create_pstream_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                          int len);
+static A_STATUS wmi_delete_pstream_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                          int len);
+static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                     int len);
+static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                         int len);
+static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                       int len);
+static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                             int len);
+static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                     int len);
+#if CONFIG_HOST_DSET_SUPPORT
+static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                     int len);
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                     int len);
+static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                      int len);
+static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
+                                      int len);
+#if CONFIG_HOST_GPIO_SUPPORT
+static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+static A_STATUS wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+static const A_INT32 wmi_rateTable[] = {
+    1000,
+    2000,
+    5500,
+    11000,
+    6000,
+    9000,
+    12000,
+    18000,
+    24000,
+    36000,
+    48000,
+    54000,
+    0};
+
+#define MODE_A_SUPPORT_RATE_START       4
+#define MODE_A_SUPPORT_RATE_STOP        11
+
+#define MODE_GONLY_SUPPORT_RATE_START   MODE_A_SUPPORT_RATE_START
+#define MODE_GONLY_SUPPORT_RATE_STOP    MODE_A_SUPPORT_RATE_STOP
+
+#define MODE_B_SUPPORT_RATE_START       0
+#define MODE_B_SUPPORT_RATE_STOP        3
+
+
+/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
+const A_UINT8 up_to_ac[]= {
+                WMM_AC_BE,
+                WMM_AC_BK,
+                WMM_AC_BK,
+                WMM_AC_BE,
+                WMM_AC_VI,
+                WMM_AC_VI,
+                WMM_AC_VO,
+                WMM_AC_VO,
+            };
+void *
+wmi_init(void *devt)
+{
+    struct wmi_t *wmip;
+
+    A_UINT8 i;
+    wmip = A_MALLOC(sizeof(struct wmi_t));
+    if (wmip == NULL) {
+        return (NULL);
+    }
+    A_MEMZERO(wmip, sizeof(*wmip));
+
+    wmip->wmi_devt = devt;
+    wlan_node_table_init(wmip, &wmip->wmi_scan_table);
+    for (i = UPLINK_TRAFFIC; i < BIDIR_TRAFFIC; i++) {
+        wmip->wmi_pstreamCmdInProgress[i][WMM_AC_BE] = FALSE;
+        wmip->wmi_pstreamCmdInProgress[i][WMM_AC_BK] = FALSE;
+        wmip->wmi_pstreamCmdInProgress[i][WMM_AC_VI] = FALSE;
+        wmip->wmi_pstreamCmdInProgress[i][WMM_AC_VO] = FALSE;
+    }
+    wmip->wmi_cpstreamCmdInProgress = FALSE;
+    wmi_qos_state_init(wmip);
+    wmip->wmi_powerMode = REC_POWER;
+    wmip->wmi_phyMode = WMI_11G_MODE;
+
+    return (wmip);
+}
+
+void
+wmi_qos_state_init(struct wmi_t *wmip)
+{
+    A_UINT8 i;
+
+    if (wmip == NULL) {
+        return;
+    }
+
+    /* Initialize QoS States */
+    wmip->wmi_numQoSStream = 0;
+
+    for (i = 0; i < WMI_MAX_NUM_PRI_STREAMS; i++) {
+        wmip->wmi_priority[i].inUse = 0;
+        wmip->wmi_priority[i].mbox = WMI_BEST_EFFORT_MBOX;
+    }
+
+    for (i = 0; i < WMM_NUM_AC; i++) {
+        wmip->wmi_trafficClassMap[UPLINK_TRAFFIC][i] = WMI_NOT_MAPPED;
+        wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][i] = WMI_NOT_MAPPED;
+    }
+    wmip->wmi_trafficClassMap[UPLINK_TRAFFIC][WMM_AC_BE] = WMI_BEST_EFFORT_MBOX;
+    wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][WMM_AC_BE] = WMI_BEST_EFFORT_MBOX;
+
+    for (i = 0; i < WMI_MBOX_COUNT; i++) {
+        wmip->wmi_mboxMap[UPLINK_TRAFFIC][i].trafficClass = WMM_AC_BE;
+        wmip->wmi_mboxMap[UPLINK_TRAFFIC][i].priorityNum = WMI_NOT_MAPPED;
+        wmip->wmi_mboxMap[DNLINK_TRAFFIC][i].trafficClass = WMM_AC_BE;
+        wmip->wmi_mboxMap[DNLINK_TRAFFIC][i].priorityNum = WMI_NOT_MAPPED;
+    }
+
+    wmip->wmi_olderPriRxMbox = WMI_HIGH_PRIORITY_MBOX;
+    wmip->wmi_newerPriRxMbox = WMI_LOW_PRIORITY_MBOX;
+    ar6000_set_numdataendpts(wmip->wmi_devt, 1);
+}
+
+void
+wmi_shutdown(struct wmi_t *wmip)
+{
+    if (wmip != NULL) {
+        wlan_node_table_cleanup(&wmip->wmi_scan_table);
+        A_FREE(wmip);
+    }
+}
+
+/*
+ *  performs DIX to 802.3 encapsulation for transmit packets.
+ *  uses passed in buffer.  Returns buffer or NULL if failed.
+ *  Assumes the entire DIX header is contigous and that there is
+ *  enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
+ */
+A_STATUS
+wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
+{
+    A_UINT8          *datap;
+    A_UINT16         typeorlen;
+    ATH_MAC_HDR      macHdr;
+    ATH_LLC_SNAP_HDR *llcHdr;
+
+    A_ASSERT(osbuf != NULL);
+
+    if (a_netbuf_headroom(osbuf) <
+        (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
+    {
+        return A_NO_MEMORY;
+    }
+
+    datap = a_netbuf_to_data(osbuf);
+
+    typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
+
+    if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
+        /*
+         * packet is already in 802.3 format - return success
+         */
+        WMI_DEBUG_PRINTF("packet already 802.3\n");
+        return (A_OK);
+    }
+
+    /*
+     * Save mac fields and length to be inserted later
+     */
+    A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN);
+    A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
+    macHdr.typeOrLen = A_CPU2BE16(a_netbuf_to_len(osbuf) - sizeof(ATH_MAC_HDR) +
+                                  sizeof(ATH_LLC_SNAP_HDR));
+
+    /*
+     * Make room for LLC+SNAP headers
+     */
+    if (a_netbuf_push(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
+        return A_NO_MEMORY;
+    }
+
+    datap = a_netbuf_to_data(osbuf);
+
+    A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR));
+
+    llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
+    llcHdr->dsap      = 0xAA;
+    llcHdr->ssap      = 0xAA;
+    llcHdr->cntl      = 0x03;
+    llcHdr->orgCode[0] = 0x0;
+    llcHdr->orgCode[1] = 0x0;
+    llcHdr->orgCode[2] = 0x0;
+    llcHdr->etherType = typeorlen;
+
+    return (A_OK);
+}
+
+/*
+ * Adds a WMI data header
+ * Assumes there is enough room in the buffer to add header.
+ */
+A_STATUS
+wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType)
+{
+    WMI_DATA_HDR     *dtHdr;
+
+    A_ASSERT(osbuf != NULL);
+
+    if (a_netbuf_push(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
+        return A_NO_MEMORY;
+    }
+
+    dtHdr = (WMI_DATA_HDR *)a_netbuf_to_data(osbuf);
+    dtHdr->info = msgType;
+    dtHdr->rssi = 0;
+
+    return (A_OK);
+}
+A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT8 dir)
+{
+    A_UINT8         *datap;
+    A_UINT8         trafficClass, userPriority = 0;
+    ATH_LLC_SNAP_HDR *llcHdr;
+    A_UINT16        ipType = IP_ETHERTYPE;
+    WMI_DATA_HDR     *dtHdr;
+    WMI_CREATE_PSTREAM_CMD  cmd;
+
+    A_ASSERT(osbuf != NULL);
+    A_ASSERT(dir == DNLINK_TRAFFIC || dir == UPLINK_TRAFFIC);
+    datap = a_netbuf_to_data(osbuf);
+    llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) +
+                                  sizeof(ATH_MAC_HDR));
+
+    if (llcHdr->etherType == htons(ipType)) {
+        /* Extract the endpoint info from the TOS field in the IP header */
+        userPriority = ar6000_iptos_to_userPriority(((A_UINT8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR));
+        trafficClass = convert_userPriority_to_trafficClass(userPriority);
+    } else {
+        trafficClass = WMM_AC_BE;
+    }
+
+
+    dtHdr = (WMI_DATA_HDR *)datap;
+    if(dir==UPLINK_TRAFFIC)
+        dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;  /* lower 3-bits are 802.1d priority */
+
+    /* Implicitly determine whether a create_pstream_cmd is needed for this trafficClass */
+    if (!((trafficClass == WMM_AC_BE) || (wmip->wmi_trafficClassMap[dir][trafficClass] != WMI_NOT_MAPPED))) {
+        A_UINT8 reqMbox;
+        /*
+         * If the data pkt is tagged with a priority that doesn't have a MBOX created,
+         * we must first call create_pstream_cmd
+         * Originally, assume traffic goes to BE MBox,
+         * until the driver receives the reply from the create_pstream cmd
+         */
+        wmip->wmi_trafficClassMap[dir][trafficClass] = WMI_BEST_EFFORT_MBOX;
+        if (dir == DNLINK_TRAFFIC) {
+            /* determine which mailbox to use */
+            reqMbox = wmip->wmi_olderPriRxMbox;
+        } else {
+            reqMbox = WMI_BEST_EFFORT_MBOX;
+        }
+
+        A_MEMZERO(&cmd, sizeof(cmd));
+        cmd.trafficClass = trafficClass;
+        cmd.rxQueueNum = reqMbox;
+        cmd.userPriority = userPriority;
+        cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
+
+        if (wmi_create_pstream_cmd(wmip, &cmd) != A_OK) {
+            wmip->wmi_trafficClassMap[dir][trafficClass] = WMI_NOT_MAPPED;
+            trafficClass = WMM_AC_BE;
+        }
+
+    }
+    return trafficClass;
+}
+
+HTC_ENDPOINT_ID
+wmi_get_endpoint(struct wmi_t *wmip, A_UINT8 trafficClass)
+{
+    WMI_DEBUG_PRINTF2("1 pkt of traffic class(%d) to mbox(%d)\n",
+                      trafficClass, wmip->wmi_trafficClassMap[UPLINK_TRAFFIC][trafficClass]);
+    return wmip->wmi_trafficClassMap[UPLINK_TRAFFIC][trafficClass];
+}
+
+/*
+ *  performs 802.3 to DIX encapsulation for received packets.
+ *  Assumes the entire 802.3 header is contigous.
+ */
+A_STATUS
+wmi_dot3_2_dix(struct wmi_t *wmip, void *osbuf)
+{
+    A_UINT8          *datap;
+    ATH_MAC_HDR      macHdr;
+    ATH_LLC_SNAP_HDR *llcHdr;
+
+    A_ASSERT(osbuf != NULL);
+    datap = a_netbuf_to_data(osbuf);
+
+    A_MEMCPY(&macHdr, datap, sizeof(ATH_MAC_HDR));
+    llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
+    macHdr.typeOrLen = llcHdr->etherType;
+
+    if (a_netbuf_pull(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
+        return A_NO_MEMORY;
+    }
+
+    datap = a_netbuf_to_data(osbuf);
+
+    A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR));
+
+    return (A_OK);
+}
+
+/*
+ * Removes a WMI data header
+ */
+A_STATUS
+wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
+{
+    A_ASSERT(osbuf != NULL);
+
+    return (a_netbuf_pull(osbuf, sizeof(WMI_DATA_HDR)));
+}
+
+void
+wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
+{
+    wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
+}
+
+/*
+ * WMI Extended Event received from Target.
+ */
+A_STATUS
+wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
+{
+    WMIX_CMD_HDR *cmd;
+    A_UINT16 id;
+    A_UINT8 *datap;
+    A_UINT32 len;
+    A_STATUS status = A_OK;
+
+    if (a_netbuf_to_len(osbuf) < sizeof(WMIX_CMD_HDR)) {
+        WMI_DEBUG_PRINTF("wmi extended event rx: bad packet\n");
+        wmip->wmi_stats.cmd_len_err++;
+        a_netbuf_free(osbuf);
+        return A_ERROR;
+    }
+
+    cmd = (WMIX_CMD_HDR *)a_netbuf_to_data(osbuf);
+    id = cmd->commandId;
+
+    if (a_netbuf_pull(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
+        WMI_DEBUG_PRINTF("wmi extended event rx: bad packet\n");
+        wmip->wmi_stats.cmd_len_err++;
+        a_netbuf_free(osbuf);
+        return A_ERROR;
+    }
+
+    datap = a_netbuf_to_data(osbuf);
+    len = a_netbuf_to_len(osbuf);
+
+    switch (id) {
+    case (WMIX_DSETOPENREQ_EVENTID):
+        status = wmi_dset_open_req_rx(wmip, datap, len);
+        break;
+#if CONFIG_HOST_DSET_SUPPORT
+    case (WMIX_DSETCLOSE_EVENTID):
+        status = wmi_dset_close_rx(wmip, datap, len);
+        break;
+    case (WMIX_DSETDATAREQ_EVENTID):
+        status = wmi_dset_data_req_rx(wmip, datap, len);
+        break;
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+#if CONFIG_HOST_GPIO_SUPPORT
+    case (WMIX_GPIO_INTR_EVENTID):
+        wmi_gpio_intr_rx(wmip, datap, len);
+        break;
+    case (WMIX_GPIO_DATA_EVENTID):
+        wmi_gpio_data_rx(wmip, datap, len);
+        break;
+    case (WMIX_GPIO_ACK_EVENTID):
+        wmi_gpio_ack_rx(wmip, datap, len);
+        break;
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+    default:
+        WMI_DEBUG_PRINTF("Host received unknown extended reply/event with id 0x%x\n",
+                         id);
+        wmip->wmi_stats.cmd_id_err++;
+        status = A_ERROR;
+        break;
+    }
+
+    return status;
+}
+
+/*
+ * Control Path
+ */
+A_STATUS
+wmi_control_rx(struct wmi_t *wmip, void *osbuf)
+{
+    WMI_CMD_HDR *cmd;
+    A_UINT16 id;
+    A_UINT8 *datap;
+    A_UINT32 len;
+    A_STATUS status = A_OK;
+
+    A_ASSERT(osbuf != NULL);
+    if (a_netbuf_to_len(osbuf) < sizeof(WMI_CMD_HDR)) {
+        WMI_DEBUG_PRINTF("wmi event rx: bad packet\n");
+        wmip->wmi_stats.cmd_len_err++;
+        a_netbuf_free(osbuf);
+        return A_ERROR;
+    }
+
+    cmd = (WMI_CMD_HDR *)a_netbuf_to_data(osbuf);
+    id = cmd->commandId;
+
+    if (a_netbuf_pull(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
+        WMI_DEBUG_PRINTF("wmi event rx: bad packet\n");
+        wmip->wmi_stats.cmd_len_err++;
+        a_netbuf_free(osbuf);
+        return A_ERROR;
+    }
+
+    datap = a_netbuf_to_data(osbuf);
+    len = a_netbuf_to_len(osbuf);
+
+    switch (id) {
+    case (WMI_CREATE_PSTREAM_CMDID):
+        status = wmi_create_pstream_reply_rx(wmip, datap, len);
+        break;
+    case (WMI_DELETE_PSTREAM_CMDID):
+        status = wmi_delete_pstream_reply_rx(wmip, datap, len);
+        break;
+    case (WMI_GET_BITRATE_CMDID):
+        status = wmi_bitrate_reply_rx(wmip, datap, len);
+        break;
+    case (WMI_GET_CHANNEL_LIST_CMDID):
+        status = wmi_channelList_reply_rx(wmip, datap, len);
+        break;
+    case (WMI_GET_TX_PWR_CMDID):
+        status = wmi_txPwr_reply_rx(wmip, datap, len);
+        break;
+    case (WMI_READY_EVENTID):
+        status = wmi_ready_event_rx(wmip, datap, len);
+        break;
+    case (WMI_CONNECT_EVENTID):
+        status = wmi_connect_event_rx(wmip, datap, len);
+        break;
+    case (WMI_DISCONNECT_EVENTID):
+        status = wmi_disconnect_event_rx(wmip, datap, len);
+        break;
+    case (WMI_TKIP_MICERR_EVENTID):
+        status = wmi_tkip_micerr_event_rx(wmip, datap, len);
+        break;
+    case (WMI_BSSINFO_EVENTID):
+        status = wmi_bssInfo_event_rx(wmip, datap, len);
+        break;
+    case (WMI_REGDOMAIN_EVENTID):
+        status = wmi_regDomain_event_rx(wmip, datap, len);
+        break;
+    case (WMI_PSTREAM_TIMEOUT_EVENTID):
+        status = wmi_pstream_timeout_event_rx(wmip, datap, len);
+        break;
+    case (WMI_NEIGHBOR_REPORT_EVENTID):
+        status = wmi_neighborReport_event_rx(wmip, datap, len);
+        break;
+    case (WMI_SCAN_COMPLETE_EVENTID):
+        status = wmi_scanComplete_rx(wmip, datap, len);
+        break;
+    case (WMI_CMDERROR_EVENTID):
+        status = wmi_errorEvent_rx(wmip, datap, len);
+        break;
+    case (WMI_REPORT_STATISTICS_EVENTID):
+        status = wmi_statsEvent_rx(wmip, datap, len);
+        break;
+    case (WMI_RSSI_THRESHOLD_EVENTID):
+        status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
+        break;
+    case (WMI_ERROR_REPORT_EVENTID):
+        status = wmi_reportErrorEvent_rx(wmip, datap, len);
+        break;
+    case (WMI_OPT_RX_FRAME_EVENTID):
+        status = wmi_opt_frame_event_rx(wmip, datap, len);
+        break;
+    case (WMI_REPORT_ROAM_TBL_EVENTID):
+        status = wmi_roam_tbl_event_rx(wmip, datap, len);
+        break;
+    case (WMI_EXTENSION_EVENTID):
+        status = wmi_control_rx_xtnd(wmip, osbuf);
+        break;
+    case (WMI_CAC_EVENTID):
+        status = wmi_cac_event_rx(wmip, datap, len);
+        break;
+    case (WMI_REPORT_ROAM_DATA_EVENTID):
+        status = wmi_roam_data_event_rx(wmip, datap, len);
+        break;
+    default:
+        WMI_DEBUG_PRINTF("Host received unknown reply/event with id 0x%x\n",
+                         id);
+        wmip->wmi_stats.cmd_id_err++;
+        status = A_ERROR;
+        break;
+    }
+
+    a_netbuf_free(osbuf);
+
+    return status;
+}
+
+static A_STATUS
+wmi_create_pstream_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_CRE_PRIORITY_STREAM_REPLY *reply;
+    A_INT8 priNum = 0, i;
+    A_UINT8 dir;
+
+    if (len < sizeof(WMI_CRE_PRIORITY_STREAM_REPLY)) {
+        WMI_DEBUG_PRINTF ("wmi: create pstream reply too short (%d)!!\n", len);
+        return A_EINVAL;
+    }
+
+    reply = (WMI_CRE_PRIORITY_STREAM_REPLY *)datap;
+    WMI_DEBUG_PRINTF("wmi: create pstream reply: status = %d, tx mbox = %d rx mbox %d\n",
+            reply->status, reply->txQueueNumber, reply->rxQueueNumber);
+
+    dir = reply->trafficDirection;
+    if (dir == BIDIR_TRAFFIC) {
+        wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][reply->trafficClass] = FALSE;
+        wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][reply->trafficClass] = FALSE;
+    } else {
+        wmip->wmi_pstreamCmdInProgress[dir][reply->trafficClass] = FALSE;
+    }
+    wmip->wmi_cpstreamCmdInProgress = FALSE;
+
+    if (reply->status == A_FAILED_CREATE_REMOVE_PSTREAM_FIRST) {
+        /* do nothing */
+        return A_OK;
+    }
+
+    if (reply->status == A_SUCCEEDED) {
+        if (reply->trafficDirection == DNLINK_TRAFFIC ||
+            reply->trafficDirection == BIDIR_TRAFFIC) {
+            wmip->wmi_olderPriRxMbox = wmip->wmi_newerPriRxMbox;
+            wmip->wmi_newerPriRxMbox = reply->rxQueueNumber;
+            wmip->wmi_mboxMap[DNLINK_TRAFFIC][reply->rxQueueNumber].trafficClass = reply->trafficClass;
+            wmip->wmi_mboxMap[DNLINK_TRAFFIC][reply->rxQueueNumber].priorityNum = 0;
+            wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][reply->trafficClass] = reply->rxQueueNumber;
+        }
+
+        if (reply->trafficDirection == UPLINK_TRAFFIC ||
+            reply->trafficDirection == BIDIR_TRAFFIC) {
+            wmip->wmi_trafficClassMap[UPLINK_TRAFFIC][reply->trafficClass] = reply->txQueueNumber;
+            /* In case  of 3rd pstreams being created, target automatically deletes the old pstream
+             * and accomodates the this one. Though, the host does not know of this implicit
+             * deletion,
+             */
+            if (wmip->wmi_numQoSStream < WMI_MAX_NUM_PRI_STREAMS)
+                wmip->wmi_numQoSStream++;
+            for (i = 0; i < WMI_MAX_NUM_PRI_STREAMS; i++) {
+                if (!wmip->wmi_priority[i].inUse) {
+                    priNum = i;
+                    wmip->wmi_priority[i].inUse = 1;
+                    wmip->wmi_priority[i].mbox = reply->txQueueNumber;
+                    break;
+                }
+            }
+            wmip->wmi_mboxMap[UPLINK_TRAFFIC][reply->txQueueNumber].trafficClass = reply->trafficClass;
+            wmip->wmi_mboxMap[UPLINK_TRAFFIC][reply->txQueueNumber].priorityNum = priNum;
+            ar6000_set_numdataendpts(wmip->wmi_devt, wmip->wmi_numQoSStream+1);
+        }
+    }
+
+    return reply->status;
+}
+
+static A_STATUS
+wmi_delete_pstream_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_DEL_PRIORITY_STREAM_REPLY *reply;
+    A_UINT8 dir;
+
+    if (len < sizeof(WMI_DEL_PRIORITY_STREAM_REPLY)) {
+        return A_EINVAL;
+    }
+
+    reply = (WMI_DEL_PRIORITY_STREAM_REPLY *)datap;
+    WMI_DEBUG_PRINTF("wmi: delete pstream reply: status = %d, rx mbox = %d tx mbox = %d\n", reply->status,
+            reply->rxQueueNumber, reply->txQueueNumber);
+
+    dir = reply->trafficDirection;
+    if (dir == BIDIR_TRAFFIC) {
+        wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][reply->trafficClass] = FALSE;
+        wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][reply->trafficClass] = FALSE;
+    } else {
+        wmip->wmi_pstreamCmdInProgress[dir][reply->trafficClass] = FALSE;
+    }
+
+    if (reply->status == A_OK) {
+        /* update internal states for Rx Path */
+        if (reply->trafficDirection == DNLINK_TRAFFIC || reply->trafficDirection == BIDIR_TRAFFIC) {
+            A_UINT8 qNum = reply->rxQueueNumber;
+            A_UINT8 class = wmip->wmi_mboxMap[DNLINK_TRAFFIC][qNum].trafficClass;
+            wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][class] = WMI_NOT_MAPPED;
+            wmip->wmi_mboxMap[DNLINK_TRAFFIC][qNum].priorityNum = WMI_NOT_MAPPED;
+            wmip->wmi_mboxMap[DNLINK_TRAFFIC][qNum].trafficClass = WMM_AC_BE;
+            if (wmip->wmi_newerPriRxMbox == qNum) {
+                wmip->wmi_newerPriRxMbox = wmip->wmi_olderPriRxMbox;
+                wmip->wmi_olderPriRxMbox = qNum;
+            }
+        }
+    }
+
+    return reply->status;
+}
+
+static A_STATUS
+wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
+
+    if (len < sizeof(WMI_READY_EVENT)) {
+        return A_EINVAL;
+    }
+    WMI_DEBUG_PRINTF("wmi: ready event\n");
+    wmip->wmi_ready = TRUE;
+    ar6000_ready_event(wmip->wmi_devt, ev->macaddr, ev->phyCapability);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_CONNECT_EVENT *ev;
+
+    if (len < sizeof(WMI_CONNECT_EVENT)) {
+        return A_EINVAL;
+    }
+    ev = (WMI_CONNECT_EVENT *)datap;
+#ifdef DEBUG
+    WMI_DEBUG_PRINTF("wmi: connected event at freq %d ", ev->channel);
+    WMI_DEBUG_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+                     ev->bssid[0], ev->bssid[1], ev->bssid[2],
+                     ev->bssid[3], ev->bssid[4], ev->bssid[5]);
+#endif /* DEBUG */
+
+    A_MEMCPY(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
+
+    ar6000_connect_event(wmip->wmi_devt, ev->channel, ev->bssid,
+                         ev->listenInterval, ev->beaconIeLen, ev->assocReqLen,
+                         ev->assocRespLen, ev->assocInfo);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_REG_DOMAIN_EVENT *ev;
+
+    if (len < sizeof(*ev)) {
+        return A_EINVAL;
+    }
+    ev = (WMI_REG_DOMAIN_EVENT *)datap;
+
+    ar6000_regDomain_event(wmip->wmi_devt, ev->regDomain);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_NEIGHBOR_REPORT_EVENT *ev;
+    int numAps;
+
+    if (len < sizeof(*ev)) {
+        return A_EINVAL;
+    }
+    ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
+    numAps = ev->numberOfAps;
+
+    if (len < (sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
+        return A_EINVAL;
+    }
+
+    ar6000_neighborReport_event(wmip->wmi_devt, numAps, ev->neighbor);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_DISCONNECT_EVENT *ev;
+
+    if (len < sizeof(WMI_DISCONNECT_EVENT)) {
+        return A_EINVAL;
+    }
+    WMI_DEBUG_PRINTF("wmi: disconnected event\n");
+
+    ev = (WMI_DISCONNECT_EVENT *)datap;
+
+    A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
+
+    ar6000_disconnect_event(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
+                            ev->assocRespLen, ev->assocInfo);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_TKIP_MICERR_EVENT *ev;
+
+    if (len < sizeof(*ev)) {
+        return A_EINVAL;
+    }
+    WMI_DEBUG_PRINTF("wmi: tkip micerr event\n");
+
+    ev = (WMI_TKIP_MICERR_EVENT *)datap;
+    ar6000_tkip_micerr_event(wmip->wmi_devt, ev->keyid, ev->ismcast);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    bss_t *bss;
+    WMI_BSS_INFO_HDR *bih;
+    A_UINT8 *buf;
+
+    if (len <= sizeof(WMI_BSS_INFO_HDR)) {
+        return A_EINVAL;
+    }
+
+    bih = (WMI_BSS_INFO_HDR *)datap;
+    buf = datap + sizeof(WMI_BSS_INFO_HDR);
+    len -= sizeof(WMI_BSS_INFO_HDR);
+
+    WMI_DEBUG_PRINTF2("wmi: bssInfo event %2.2x:%2.2x\n",
+                      bih->bssid[4], bih->bssid[5]);
+
+    bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
+    if (bss != NULL) {
+        /*
+         * Free up the node.  Not the most efficient process given
+         * we are about to allocate a new node but it is simple and should be
+         * adequate.
+         */
+        wlan_node_reclaim(&wmip->wmi_scan_table, bss);
+    }
+
+    bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
+    if (bss == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    bss->ni_rssi        = bih->rssi;
+    A_ASSERT(bss->ni_buf != NULL);
+    A_MEMCPY(bss->ni_buf, buf, len);
+
+    if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) {
+        wlan_node_free(bss);
+        return A_EINVAL;
+    }
+
+    /*
+     * Update the frequency in ie_chan, overwriting of channel number
+     * which is done in wlan_parse_beacon
+     */
+    bss->ni_cie.ie_chan = bih->channel;
+    wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    bss_t *bss;
+    WMI_OPT_RX_INFO_HDR *bih;
+    A_UINT8 *buf;
+
+    if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
+        return A_EINVAL;
+    }
+
+    bih = (WMI_OPT_RX_INFO_HDR *)datap;
+    buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
+    len -= sizeof(WMI_OPT_RX_INFO_HDR);
+
+    WMI_DEBUG_PRINTF2("wmi: opt frame event %2.2x:%2.2x\n",
+                      bih->bssid[4], bih->bssid[5]);
+
+    bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
+    if (bss != NULL) {
+        /*
+         * Free up the node.  Not the most efficient process given
+         * we are about to allocate a new node but it is simple and should be
+         * adequate.
+         */
+        wlan_node_reclaim(&wmip->wmi_scan_table, bss);
+    }
+
+    bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
+    if (bss == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    bss->ni_rssi        = bih->rssi;
+    bss->ni_cie.ie_chan = bih->channel;
+    A_ASSERT(bss->ni_buf != NULL);
+    A_MEMCPY(bss->ni_buf, buf, len);
+    wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_PSTREAM_TIMEOUT_EVENT *ev;
+
+    if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
+        return A_EINVAL;
+    }
+
+    WMI_DEBUG_PRINTF("wmi: pstream timeout event\n");
+
+    ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
+
+    wmi_delete_pstream_cmd(wmip, ev->txQueueNumber, ev->rxQueueNumber, ev->trafficDirection);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_BIT_RATE_CMD *reply;
+    A_INT32 rate;
+
+    if (len < sizeof(WMI_BIT_RATE_CMD)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_BIT_RATE_CMD *)datap;
+    WMI_DEBUG_PRINTF("wmi: get bit rate reply %d\n", reply->rateIndex);
+
+    if (reply->rateIndex == RATE_AUTO) {
+        rate = RATE_AUTO;
+    } else {
+        rate = wmi_rateTable[reply->rateIndex];
+    }
+
+    ar6000_bitrate_rx(wmip->wmi_devt, rate);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_CHANNEL_LIST_REPLY *reply;
+
+    if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_CHANNEL_LIST_REPLY *)datap;
+    WMI_DEBUG_PRINTF("wmi: get channel list reply\n");
+
+    ar6000_channelList_rx(wmip->wmi_devt, reply->numChannels,
+                          reply->channelList);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_TX_PWR_REPLY *reply;
+
+    if (len < sizeof(*reply)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_TX_PWR_REPLY *)datap;
+    WMI_DEBUG_PRINTF("wmi: get tx pwr reply\n");
+
+    ar6000_txPwr_rx(wmip->wmi_devt, reply->dbM);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMIX_DSETOPENREQ_EVENT *dsetopenreq;
+
+    if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
+        return A_EINVAL;
+    }
+    WMI_DEBUG_PRINTF("wmi_dset_open_req_rx: DataSet Open Request event\n");
+
+    dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
+    WMI_DEBUG_PRINTF("wmi_dset_open_req_rx: dset_id=0x%x\n", dsetopenreq->dset_id);
+    ar6000_dset_open_req(wmip->wmi_devt,
+                        dsetopenreq->dset_id,
+                        dsetopenreq->targ_dset_handle,
+                        dsetopenreq->targ_reply_fn,
+                        dsetopenreq->targ_reply_arg);
+
+    return A_OK;
+}
+
+#if CONFIG_HOST_DSET_SUPPORT
+static A_STATUS
+wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMIX_DSETCLOSE_EVENT *dsetclose;
+
+    if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
+        return A_EINVAL;
+    }
+    WMI_DEBUG_PRINTF("wmi: DataSet Close event\n");
+
+    dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
+    ar6000_dset_close(wmip->wmi_devt, dsetclose->access_cookie);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMIX_DSETDATAREQ_EVENT *dsetdatareq;
+
+    if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
+        return A_EINVAL;
+    }
+    WMI_DEBUG_PRINTF("wmi: DataSet Data Request event\n");
+
+    dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
+    ar6000_dset_data_req(wmip->wmi_devt,
+                         dsetdatareq->access_cookie,
+                         dsetdatareq->offset,
+                         dsetdatareq->length,
+                         dsetdatareq->targ_buf,
+                         dsetdatareq->targ_reply_fn,
+                         dsetdatareq->targ_reply_arg);
+
+    return A_OK;
+}
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+static A_STATUS
+wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    ar6000_scanComplete_event(wmip->wmi_devt);
+
+    return A_OK;
+}
+
+/*
+ * Target is reporting a programming error.  This is for
+ * developer aid only.  Target only checks a few common violations
+ * and it is responsibility of host to do all error checking.
+ * Behavior of target after wmi error event is undefined.
+ * A reset is recommended.
+ */
+static A_STATUS
+wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_CMD_ERROR_EVENT *ev;
+
+    ev = (WMI_CMD_ERROR_EVENT *)datap;
+    A_PRINTF("Programming Error: cmd=%d ", ev->commandId);
+    switch (ev->errorCode) {
+    case (INVALID_PARAM):
+        A_PRINTF("Illegal Parameter\n");
+        break;
+    case (ILLEGAL_STATE):
+        A_PRINTF("Illegal State\n");
+        break;
+    case (INTERNAL_ERROR):
+        A_PRINTF("Internal Error\n");
+        break;
+    }
+
+    return A_OK;
+}
+
+
+static A_STATUS
+wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_TARGET_STATS *reply;
+
+    if (len < sizeof(*reply)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_TARGET_STATS *)datap;
+    WMI_DEBUG_PRINTF("wmi: target stats event\n");
+
+    ar6000_targetStats_event(wmip->wmi_devt, reply);
+
+    return A_OK;
+}
+
+
+
+static A_STATUS
+wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_RSSI_THRESHOLD_EVENT *reply;
+
+    if (len < sizeof(*reply)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
+    WMI_DEBUG_PRINTF("wmi: rssi threshold event\n");
+
+    ar6000_rssiThreshold_event(wmip->wmi_devt, reply->range);
+
+    return A_OK;
+}
+
+
+static A_STATUS
+wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_TARGET_ERROR_REPORT_EVENT *reply;
+
+    if (len < sizeof(*reply)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
+    WMI_DEBUG_PRINTF("wmi: report error event\n");
+
+    ar6000_reportError_event(wmip->wmi_devt, reply->errorVal);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_CAC_EVENT *reply;
+
+    if (len < sizeof(*reply)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_CAC_EVENT *)datap;
+    WMI_DEBUG_PRINTF("wmi: report CAC event\n");
+
+    ar6000_cac_event(wmip->wmi_devt, reply->ac,
+                reply->cac_indication, reply->statusCode,
+                reply->tspecSuggestion);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_TARGET_ROAM_TBL *reply;
+
+    if (len < sizeof(*reply)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_TARGET_ROAM_TBL *)datap;
+    WMI_DEBUG_PRINTF("wmi: target ROAM TABLE event\n");
+
+    ar6000_roam_tbl_event(wmip->wmi_devt, reply);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_TARGET_ROAM_DATA *reply;
+
+    if (len < sizeof(*reply)) {
+        return A_EINVAL;
+    }
+    reply = (WMI_TARGET_ROAM_DATA *)datap;
+    WMI_DEBUG_PRINTF("wmi: target ROAM DATA event\n");
+
+    ar6000_roam_data_event(wmip->wmi_devt, reply);
+
+    return A_OK;
+}
+
+#if CONFIG_HOST_GPIO_SUPPORT
+static A_STATUS
+wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap;
+
+    WMI_DEBUG_PRINTF("wmi GPIO interrupt received intrmask=0x%x input=0x%x.\n",
+                        gpio_intr->intr_mask, gpio_intr->input_values);
+
+    ar6000_gpio_intr_rx(gpio_intr->intr_mask, gpio_intr->input_values);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap;
+
+    WMI_DEBUG_PRINTF("wmi GPIO data received reg=%d value=0x%x.\n",
+                        gpio_data->reg_id, gpio_data->value);
+
+    ar6000_gpio_data_rx(gpio_data->reg_id, gpio_data->value);
+
+    return A_OK;
+}
+
+static A_STATUS
+wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
+{
+    WMI_DEBUG_PRINTF("wmi GPIO ACK received.\n");
+
+    ar6000_gpio_ack_rx();
+
+    return A_OK;
+}
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+/*
+ * Called to send a wmi command. Command specific data is already built
+ * on osbuf and current osbuf->data points to it.
+ */
+A_STATUS
+wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
+               WMI_SYNC_FLAG syncflag)
+{
+#define IS_LONG_CMD(cmdId) (cmdId == WMI_OPT_TX_FRAME_CMDID)
+    WMI_CMD_HDR     *cHdr;
+    A_UINT8         mbox = WMI_CONTROL_MBOX;
+
+    A_ASSERT(osbuf != NULL);
+
+    if (syncflag >= END_WMIFLAG) {
+        return A_EINVAL;
+    }
+
+    if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
+        /*
+         * We want to make sure all data currently queued is transmitted before
+         * the cmd execution.  Establish a new sync point.
+         */
+        wmi_sync_point(wmip);
+    }
+
+    if (a_netbuf_push(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
+        return A_NO_MEMORY;
+    }
+
+    cHdr = (WMI_CMD_HDR *)a_netbuf_to_data(osbuf);
+    cHdr->commandId = cmdId;
+
+    /*
+     * Send cmd, some via control pipe, others via data pipe
+     */
+    if (IS_LONG_CMD(cmdId)) {
+        wmi_data_hdr_add(wmip, osbuf, CNTL_MSGTYPE);
+        mbox = WMI_BEST_EFFORT_MBOX;
+    }
+    ar6000_control_tx(wmip->wmi_devt, osbuf, mbox);
+
+    if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
+        /*
+         * We want to make sure all new data queued waits for the command to
+         * execute. Establish a new sync point.
+         */
+        wmi_sync_point(wmip);
+    }
+
+    return (A_OK);
+#undef IS_LONG_CMD
+}
+
+A_STATUS
+wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
+                  WMI_SYNC_FLAG syncflag)
+{
+    WMIX_CMD_HDR     *cHdr;
+
+    if (a_netbuf_push(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
+        return A_NO_MEMORY;
+    }
+
+    cHdr = (WMIX_CMD_HDR *)a_netbuf_to_data(osbuf);
+    cHdr->commandId = cmdId;
+
+    return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
+}
+
+A_STATUS
+wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
+                DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
+                CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen,
+                CRYPTO_TYPE groupCrypto,A_UINT8 groupCryptoLen,
+                int ssidLength, A_UCHAR *ssid,
+                A_UINT8 *bssid, A_UINT16 channel)
+{
+    void *osbuf;
+    WMI_CONNECT_CMD *cc;
+
+    if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
+        return A_EINVAL;
+    }
+    if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(WMI_CONNECT_CMD));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(WMI_CONNECT_CMD));
+
+    cc = (WMI_CONNECT_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cc, sizeof(*cc));
+
+    A_MEMCPY(cc->ssid, ssid, ssidLength);
+    cc->ssidLength          = ssidLength;
+    cc->networkType         = netType;
+    cc->dot11AuthMode       = dot11AuthMode;
+    cc->authMode            = authMode;
+    cc->pairwiseCryptoType  = pairwiseCrypto;
+    cc->pairwiseCryptoLen   = pairwiseCryptoLen;
+    cc->groupCryptoType     = groupCrypto;
+    cc->groupCryptoLen      = groupCryptoLen;
+    cc->channel             = channel;
+
+    if (bssid != NULL) {
+        A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel)
+{
+    void *osbuf;
+    WMI_RECONNECT_CMD *cc;
+
+    osbuf = a_netbuf_alloc(sizeof(WMI_RECONNECT_CMD));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(WMI_RECONNECT_CMD));
+
+    cc = (WMI_RECONNECT_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cc, sizeof(*cc));
+
+    cc->channel = channel;
+
+    if (bssid != NULL) {
+        A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_disconnect_cmd(struct wmi_t *wmip)
+{
+    void *osbuf;
+    A_STATUS status;
+
+    osbuf = a_netbuf_alloc(0);      /* no payload */
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    status = (wmi_cmd_send(wmip, osbuf, WMI_DISCONNECT_CMDID,
+                         SYNC_BEFORE_WMIFLAG));
+    wmi_qos_state_init(wmip);
+    return status;
+}
+
+A_STATUS
+wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType)
+{
+    void *osbuf;
+    WMI_START_SCAN_CMD *sc;
+
+    if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*sc));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*sc));
+
+    sc = (WMI_START_SCAN_CMD *)(a_netbuf_to_data(osbuf));
+    sc->scanType = scanType;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
+                   A_UINT16 fg_end_sec, A_UINT16 bg_sec,
+                   A_UINT16 act_chdw_msec, A_UINT16 pas_chdw_msec,
+                   A_UINT8 shScanRatio)
+{
+    void *osbuf;
+    WMI_SCAN_PARAMS_CMD *sc;
+
+    osbuf = a_netbuf_alloc(sizeof(*sc));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*sc));
+
+    sc = (WMI_SCAN_PARAMS_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(sc, sizeof(*sc));
+    sc->fg_start_period  = fg_start_sec;
+    sc->fg_end_period    = fg_end_sec;
+    sc->bg_period        = bg_sec;
+    sc->act_chdwell_time = act_chdw_msec;
+    sc->pas_chdwell_time = pas_chdw_msec;
+    sc->shortScanRatio   = shScanRatio;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter)
+{
+    void *osbuf;
+    WMI_BSS_FILTER_CMD *cmd;
+
+    if (filter >= LAST_BSS_FILTER) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_BSS_FILTER_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->bssFilter = filter;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag,
+                   A_UINT8 ssidLength, A_UCHAR *ssid)
+{
+    void *osbuf;
+    WMI_PROBED_SSID_CMD *cmd;
+
+    if (index > MAX_PROBED_SSID_INDEX) {
+        return A_EINVAL;
+    }
+    if (ssidLength > sizeof(cmd->ssid)) {
+        return A_EINVAL;
+    }
+    if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
+        return A_EINVAL;
+    }
+    if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_PROBED_SSID_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->entryIndex = index;
+    cmd->flag       = flag;
+    cmd->ssidLength = ssidLength;
+    A_MEMCPY(cmd->ssid, ssid, ssidLength);
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons)
+{
+    void *osbuf;
+    WMI_LISTEN_INT_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_LISTEN_INT_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->listenInterval = listenInterval;
+    cmd->numBeacons = listenBeacons;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons)
+{
+    void *osbuf;
+    WMI_BMISS_TIME_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_BMISS_TIME_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->bmissTime = bmissTime;
+    cmd->numBeacons =  bmissBeacons;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType,
+                     A_UINT8 ieLen, A_UINT8 *ieInfo)
+{
+    void *osbuf;
+    WMI_SET_ASSOC_INFO_CMD *cmd;
+    A_UINT16 cmdLen;
+
+    cmdLen = sizeof(*cmd) + ieLen - 1;
+    osbuf = a_netbuf_alloc(cmdLen);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, cmdLen);
+
+    cmd = (WMI_SET_ASSOC_INFO_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, cmdLen);
+    cmd->ieType = ieType;
+    cmd->bufferSize = ieLen;
+    A_MEMCPY(cmd->assocInfo, ieInfo, ieLen);
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode)
+{
+    void *osbuf;
+    WMI_POWER_MODE_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_POWER_MODE_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->powerMode = powerMode;
+    wmip->wmi_powerMode = powerMode;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl,
+                   A_UINT16 atim_windows, A_UINT16 timeout_value)
+{
+    void *osbuf;
+    WMI_IBSS_PM_CAPS_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_IBSS_PM_CAPS_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->power_saving = pmEnable;
+    cmd->ttl = ttl;
+    cmd->atim_windows = atim_windows;
+    cmd->timeout_value = timeout_value;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod,
+                 A_UINT16 psPollNum, A_UINT16 dtimPolicy)
+{
+    void *osbuf;
+    WMI_POWER_PARAMS_CMD *pm;
+
+    osbuf = a_netbuf_alloc(sizeof(*pm));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*pm));
+
+    pm = (WMI_POWER_PARAMS_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(pm, sizeof(*pm));
+    pm->idle_period   = idlePeriod;
+    pm->pspoll_number = psPollNum;
+    pm->dtim_policy   = dtimPolicy;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout)
+{
+    void *osbuf;
+    WMI_DISC_TIMEOUT_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_DISC_TIMEOUT_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->disconnectTimeout = timeout;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType,
+               A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC,
+               A_UINT8 *keyMaterial, WMI_SYNC_FLAG sync_flag)
+{
+    void *osbuf;
+    WMI_ADD_CIPHER_KEY_CMD *cmd;
+
+    if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
+        (keyMaterial == NULL))
+    {
+        return A_EINVAL;
+    }
+
+    if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_ADD_CIPHER_KEY_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->keyIndex = keyIndex;
+    cmd->keyType  = keyType;
+    cmd->keyUsage = keyUsage;
+    cmd->keyLength = keyLength;
+    A_MEMCPY(cmd->key, keyMaterial, keyLength);
+    if (NULL != keyRSC) {
+        A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
+}
+
+A_STATUS
+wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk)
+{
+    void *osbuf;
+    WMI_ADD_KRK_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_ADD_KRK_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    A_MEMCPY(cmd->krk, krk, WMI_KRK_LEN);
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_delete_krk_cmd(struct wmi_t *wmip)
+{
+    void *osbuf;
+
+    osbuf = a_netbuf_alloc(0);
+
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_KRK_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex)
+{
+    void *osbuf;
+    WMI_DELETE_CIPHER_KEY_CMD *cmd;
+
+    if (keyIndex > WMI_MAX_KEY_INDEX) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->keyIndex = keyIndex;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
+                 A_BOOL set)
+{
+    void *osbuf;
+    WMI_SET_PMKID_CMD *cmd;
+
+    if (bssid == NULL) {
+        return A_EINVAL;
+    }
+
+    if ((set == TRUE) && (pmkId == NULL)) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_SET_PMKID_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
+    if (set == TRUE) {
+        A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
+        cmd->enable = PMKID_ENABLE;
+    } else {
+        A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
+        cmd->enable = PMKID_DISABLE;
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en)
+{
+    void *osbuf;
+    WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(a_netbuf_to_data(osbuf));
+    cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
+            NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, int endPoint)
+{
+    WMI_DATA_HDR     *dtHdr;
+
+    A_ASSERT(endPoint != WMI_CONTROL_MBOX);
+    A_ASSERT(osbuf != NULL);
+
+    if (a_netbuf_push(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
+        return A_NO_MEMORY;
+    }
+
+    dtHdr = (WMI_DATA_HDR *)a_netbuf_to_data(osbuf);
+    dtHdr->info =
+      (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
+
+    WMI_DEBUG_PRINTF("wmi sync pkt sent on mbox %d\n", endPoint);
+
+    return (ar6000_control_tx(wmip->wmi_devt, osbuf, endPoint));
+}
+
+static A_STATUS
+wmi_sync_point(struct wmi_t *wmip)
+{
+    void *cmd_osbuf, *be_osbuf, *pri_osbuf[WMI_MAX_NUM_PRI_STREAMS];
+    A_UINT8 i;
+    A_STATUS status;
+
+    WMI_DEBUG_PRINTF("wmi_sync_point\n");
+    /*
+     * We allocate all network buffers needed so we will be able to
+     * send all required frames.
+     */
+    cmd_osbuf = a_netbuf_alloc(0);      /* no payload */
+    if (cmd_osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+    be_osbuf = a_netbuf_alloc(0);      /* no payload */
+    if (be_osbuf == NULL) {
+        a_netbuf_free(cmd_osbuf);
+        return A_NO_MEMORY;
+    }
+
+    for (i = 0; i < wmip->wmi_numQoSStream; i++) {
+        pri_osbuf[i] = a_netbuf_alloc(0);      /* no payload */
+        if (pri_osbuf[i] == NULL) {
+            A_UINT8 j;
+            a_netbuf_free(be_osbuf);
+            a_netbuf_free(cmd_osbuf);
+            /* free previously allocated bufs */
+            for (j = 0; j < i; j++) {
+                a_netbuf_free(pri_osbuf[j]);
+            }
+            return A_NO_MEMORY;
+        }
+    }
+
+    /*
+     * Send sync cmd followed by sync data messages on all endpoints being
+     * used
+     */
+    status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
+                          NO_SYNC_WMIFLAG);
+
+    if (status == A_OK) {
+        status = wmi_dataSync_send(wmip, be_osbuf, WMI_BEST_EFFORT_MBOX);
+    }
+
+    if (status == A_OK) {
+        A_UINT8 priIndex = 0;
+        for (i = 0; i < wmip->wmi_numQoSStream; i++) {
+            while (priIndex < WMI_MAX_NUM_PRI_STREAMS &&
+                  (!wmip->wmi_priority[priIndex].inUse)) {
+                priIndex++;
+            }
+            if (priIndex >= WMI_MAX_NUM_PRI_STREAMS) {
+                break;
+            }
+            status = wmi_dataSync_send(wmip, pri_osbuf[i], wmip->wmi_priority[priIndex].mbox);
+            if (status != A_OK) {
+                break;
+            }
+            priIndex++;
+        }
+    }
+
+    return (status);
+}
+
+A_STATUS
+wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
+{
+    void *osbuf;
+    WMI_CREATE_PSTREAM_CMD *cmd;
+
+    /* Validate all the parameters. */
+    if( !((params->userPriority < 8) &&
+         (params->trafficDirection == BIDIR_TRAFFIC ||
+            params->trafficDirection == UPLINK_TRAFFIC ||
+            params->trafficDirection == DNLINK_TRAFFIC ) &&
+         (params->userPriority <= 0x7) &&
+         (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass)  &&
+         (params->trafficClass != WMM_AC_BE)  &&
+         (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
+            params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
+         (params->voicePSCapability == DISABLE_FOR_THIS_AC  ||
+            params->voicePSCapability == ENABLE_FOR_THIS_AC ||
+            params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
+         (params->tsid < 15)) )
+    {
+        return  A_EINVAL;
+    }
+
+
+    if (params->trafficDirection == BIDIR_TRAFFIC) {
+        if (wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][params->trafficClass]
+          || wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][params->trafficClass]
+          || wmip->wmi_cpstreamCmdInProgress) {
+            WMI_DEBUG_PRINTF("create %d too busy !\n",params->trafficClass);
+            return A_EBUSY;
+        }
+        wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][params->trafficClass] = TRUE;
+        wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][params->trafficClass] = TRUE;
+    } else {
+        if (wmip->wmi_pstreamCmdInProgress[params->trafficDirection][params->trafficClass]
+         || wmip->wmi_cpstreamCmdInProgress) {
+            WMI_DEBUG_PRINTF("create %d too busy !\n",params->trafficClass);
+            return A_EBUSY;
+        }
+        wmip->wmi_pstreamCmdInProgress[params->trafficDirection][params->trafficClass] = TRUE;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    wmip->wmi_cpstreamCmdInProgress = TRUE;
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    WMI_DEBUG_PRINTF("Sending create_pstream_cmd: ac=%d, rxQ=%d, dir=%d\n",
+                     params->trafficClass, params->rxQueueNum, params->trafficDirection);
+    cmd = (WMI_CREATE_PSTREAM_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    A_MEMCPY(cmd, params, sizeof(*cmd));
+
+    if (params->rxQueueNum == 0xFF) {
+        if(wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][params->trafficClass] != WMI_NOT_MAPPED)
+            cmd->rxQueueNum = wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][params->trafficClass];
+        else
+            cmd->rxQueueNum = wmip->wmi_olderPriRxMbox;
+    } else {
+        cmd->rxQueueNum = params->rxQueueNum;
+    }
+
+    /* mike: should be SYNC_BEFORE_WMIFLAG */
+    return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 txQueueNumber, A_UINT8 rxQueueNumber, A_UINT8 dir)
+{
+    void *osbuf;
+    WMI_DELETE_PSTREAM_CMD *cmd;
+    A_STATUS status;
+    A_UINT8 class;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    if (dir == BIDIR_TRAFFIC) {
+        class = wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].trafficClass;
+        if (wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][class]
+         || wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][class]) {
+            return A_EBUSY;
+        }
+        wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][class] = TRUE;
+        wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][class] = TRUE;
+    } else {
+        if (dir == UPLINK_TRAFFIC) {
+            class = wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].trafficClass;
+        } else {
+            class = wmip->wmi_mboxMap[DNLINK_TRAFFIC][rxQueueNumber].trafficClass;
+        }
+        if (wmip->wmi_pstreamCmdInProgress[dir][class]) {
+            return A_EBUSY;
+        }
+        wmip->wmi_pstreamCmdInProgress[dir][class] = TRUE;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_DELETE_PSTREAM_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->txQueueNumber = txQueueNumber;
+    cmd->rxQueueNumber = rxQueueNumber;
+    cmd->trafficDirection = dir;
+    cmd->trafficClass = class;
+    WMI_DEBUG_PRINTF("Sending delete_pstream_cmd: txQ=%d, rxQ=%d, dir=%d\n",
+                     txQueueNumber, rxQueueNumber, dir);
+    status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
+                         (dir == UPLINK_TRAFFIC || dir == BIDIR_TRAFFIC) ? SYNC_BEFORE_WMIFLAG : NO_SYNC_WMIFLAG));
+
+    if (class != WMM_AC_BE) {
+        /* Update internal states */
+        if (dir == UPLINK_TRAFFIC || dir == BIDIR_TRAFFIC) {
+            wmip->wmi_numQoSStream--;
+            ar6000_set_numdataendpts(wmip->wmi_devt, wmip->wmi_numQoSStream+1);
+            wmip->wmi_priority[wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].priorityNum].inUse = 0;
+            wmip->wmi_trafficClassMap[UPLINK_TRAFFIC][class] = WMI_NOT_MAPPED;
+            wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].priorityNum = WMI_NOT_MAPPED;
+            wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].trafficClass = WMM_AC_BE;
+        }
+    }
+
+    return status;
+}
+
+
+/*
+ * used to set the bit rate.  rate is in Kbps.  If rate == -1
+ * then auto selection is used.
+ */
+A_STATUS
+wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 rate)
+{
+    void *osbuf;
+    WMI_BIT_RATE_CMD *cmd;
+    A_INT8 index;
+
+    index = wmi_validate_bitrate(wmip, rate);
+    if(index == A_EINVAL){
+      return A_EINVAL;
+    }
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_BIT_RATE_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+
+    cmd->rateIndex = index;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_bitrate_cmd(struct wmi_t *wmip)
+{
+    void *osbuf;
+
+    osbuf = a_netbuf_alloc(0);      /* no payload */
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_GET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_INT8
+wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate)
+{
+    A_INT8 i;
+    if (rate != -1)
+    {
+        for (i=0;;i++)
+        {
+            if (wmi_rateTable[i] == 0) {
+                return A_EINVAL;
+            }
+            if (wmi_rateTable[i] == rate) {
+                break;
+            }
+        }
+    }
+    else{
+     i = -1;
+    }
+
+    if (wmip->wmi_phyMode == WMI_11A_MODE &&
+        (i < MODE_A_SUPPORT_RATE_START || i > MODE_A_SUPPORT_RATE_STOP))
+    {
+        return A_EINVAL;
+    } else if (wmip->wmi_phyMode == WMI_11B_MODE &&
+        (i < MODE_B_SUPPORT_RATE_START || i > MODE_B_SUPPORT_RATE_STOP))
+    {
+        return A_EINVAL;
+    } else if (wmip->wmi_phyMode == WMI_11GONLY_MODE &&
+        (i < MODE_GONLY_SUPPORT_RATE_START || i > MODE_GONLY_SUPPORT_RATE_STOP))
+    {
+        return A_EINVAL;
+    }
+
+    return i;
+ }
+
+A_STATUS
+wmi_get_channelList_cmd(struct wmi_t *wmip)
+{
+    void *osbuf;
+
+    osbuf = a_netbuf_alloc(0);      /* no payload */
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_GET_CHANNEL_LIST_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+/*
+ * used to generate a wmi sey channel Parameters cmd.
+ * mode should always be specified and corresponds to the phy mode of the
+ * wlan.
+ * numChan should alway sbe specified. If zero indicates that all available
+ * channels should be used.
+ * channelList is an array of channel frequencies (in Mhz) which the radio
+ * should limit its operation to.  It should be NULL if numChan == 0.  Size of
+ * array should correspond to numChan entries.
+ */
+A_STATUS
+wmi_set_channelParams_cmd(struct wmi_t *wmip, WMI_PHY_MODE mode, A_INT8 numChan,
+                          A_UINT16 *channelList)
+{
+    void *osbuf;
+    WMI_CHANNEL_PARAMS_CMD *cmd;
+    A_INT8 size;
+
+    size = sizeof (*cmd);
+
+    if (numChan) {
+        if (numChan > WMI_MAX_CHANNELS) {
+            return A_EINVAL;
+        }
+        size += sizeof(A_UINT16) * (numChan - 1);
+    }
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, size);
+
+    cmd = (WMI_CHANNEL_PARAMS_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, size);
+
+    wmip->wmi_phyMode = mode;
+    cmd->phyMode     = mode;
+    cmd->numChannels = numChan;
+    A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16));
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_link_threshold_params(struct wmi_t *wmip,
+                                A_UINT8     highThreshold_upperVal,
+                                A_UINT8     highThreshold_lowerVal,
+                                A_UINT8     lowThreshold_upperVal,
+                                A_UINT8     lowThreshold_lowerVal,
+                                A_UINT32    pollTime)
+{
+    void    *osbuf;
+    A_INT8  size;
+    WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
+
+    /* These values are in ascending order */
+    if( highThreshold_upperVal <= highThreshold_lowerVal ||
+        lowThreshold_upperVal  <= lowThreshold_lowerVal  ||
+        highThreshold_lowerVal <= lowThreshold_upperVal)
+        return A_EINVAL;
+
+    size = sizeof (*cmd);
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, size);
+
+    cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, size);
+
+    cmd->highThreshold_upperVal = highThreshold_upperVal;
+    cmd->highThreshold_lowerVal = highThreshold_lowerVal;
+    cmd->lowThreshold_upperVal  = lowThreshold_upperVal;
+    cmd->lowThreshold_lowerVal  = lowThreshold_lowerVal;
+    cmd->pollTime               = pollTime;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+                            NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask)
+{
+    void    *osbuf;
+    A_INT8  size;
+    WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
+
+    size = sizeof (*cmd);
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, size);
+
+    cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, size);
+
+    cmd->bitmask = mask;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
+                            NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_get_stats_cmd(struct wmi_t *wmip)
+{
+    void *osbuf;
+
+    osbuf = a_netbuf_alloc(0);      /* no payload */
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_GET_STATISTICS_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid)
+{
+    void *osbuf;
+    WMI_ADD_BAD_AP_CMD *cmd;
+
+    if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_ADD_BAD_AP_CMD *)(a_netbuf_to_data(osbuf));
+    cmd->badApIndex = apIndex;
+    A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex)
+{
+    void *osbuf;
+    WMI_DELETE_BAD_AP_CMD *cmd;
+
+    if (apIndex > WMI_MAX_BAD_AP_INDEX) {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_DELETE_BAD_AP_CMD *)(a_netbuf_to_data(osbuf));
+    cmd->badApIndex = apIndex;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM)
+{
+    void *osbuf;
+    WMI_SET_TX_PWR_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_SET_TX_PWR_CMD *)(a_netbuf_to_data(osbuf));
+    cmd->dbM = dbM;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_txPwr_cmd(struct wmi_t *wmip)
+{
+    void *osbuf;
+
+    osbuf = a_netbuf_alloc(0);      /* no payload */
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_GET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
+}
+
+A_INT8
+wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 dir, A_UINT8 trafficClass)
+{
+    if ((dir == UPLINK_TRAFFIC || dir == DNLINK_TRAFFIC) &&
+        (trafficClass <= WMM_AC_VO)) {
+        return wmip->wmi_trafficClassMap[dir][trafficClass];
+    } else {
+        return WMI_NOT_MAPPED;
+    }
+}
+
+A_STATUS
+wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
+{
+    void *osbuf;
+
+    osbuf = a_netbuf_alloc(0);      /* no payload */
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_TBL_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType)
+{
+    void *osbuf;
+    A_UINT32 size = sizeof(A_UINT8);
+    WMI_TARGET_ROAM_DATA *cmd;
+
+    osbuf = a_netbuf_alloc(size);      /* no payload */
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, size);
+
+    cmd = (WMI_TARGET_ROAM_DATA *)(a_netbuf_to_data(osbuf));
+    cmd->roamDataType = roamDataType;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
+                      A_UINT8 size)
+{
+    void *osbuf;
+    WMI_SET_ROAM_CTRL_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, size);
+
+    cmd = (WMI_SET_ROAM_CTRL_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, size);
+
+    A_MEMCPY(cmd, p, size);
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
+                            WMI_POWERSAVE_TIMERS_CMD *pCmd,
+                            A_UINT8 size)
+{
+    void *osbuf;
+    WMI_POWERSAVE_TIMERS_CMD *cmd;
+
+    /* These timers can't be zero */
+    if(!pCmd->psPollTimeout || !pCmd->eospTimeout)
+        return A_EINVAL;
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, size);
+
+    cmd = (WMI_POWERSAVE_TIMERS_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, size);
+
+    A_MEMCPY(cmd, pCmd, size);
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_dset_open_reply(struct wmi_t *wmip,
+                    A_UINT32 status,
+                    A_UINT32 access_cookie,
+                    A_UINT32 dset_size,
+                    A_UINT32 dset_version,
+                    A_UINT32 targ_handle,
+                    A_UINT32 targ_reply_fn,
+                    A_UINT32 targ_reply_arg)
+{
+    void *osbuf;
+    WMIX_DSETOPEN_REPLY_CMD *open_reply;
+
+    WMI_DEBUG_PRINTF("wmi_dset_open_reply: wmip=0x%x\n", (int)wmip);
+
+    osbuf = a_netbuf_alloc(sizeof(*open_reply));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*open_reply));
+    open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(a_netbuf_to_data(osbuf));
+
+    open_reply->status                   = status;
+    open_reply->targ_dset_handle         = targ_handle;
+    open_reply->targ_reply_fn            = targ_reply_fn;
+    open_reply->targ_reply_arg           = targ_reply_arg;
+    open_reply->access_cookie            = access_cookie;
+    open_reply->size                     = dset_size;
+    open_reply->version                  = dset_version;
+
+    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
+                             NO_SYNC_WMIFLAG));
+}
+
+#if CONFIG_HOST_DSET_SUPPORT
+A_STATUS
+wmi_dset_data_reply(struct wmi_t *wmip,
+                    A_UINT32 status,
+                    A_UINT8 *user_buf,
+                    A_UINT32 length,
+                    A_UINT32 targ_buf,
+                    A_UINT32 targ_reply_fn,
+                    A_UINT32 targ_reply_arg)
+{
+    void *osbuf;
+    WMIX_DSETDATA_REPLY_CMD *data_reply;
+    int size;
+
+    size = sizeof(*data_reply) + length;
+
+    WMI_DEBUG_PRINTF("wmi_dset_data_reply: length=%d status=%d\n", length, status);
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+    a_netbuf_put(osbuf, size);
+    data_reply = (WMIX_DSETDATA_REPLY_CMD *)(a_netbuf_to_data(osbuf));
+
+    data_reply->status                     = status;
+    data_reply->targ_buf                   = targ_buf;
+    data_reply->targ_reply_fn              = targ_reply_fn;
+    data_reply->targ_reply_arg             = targ_reply_arg;
+    data_reply->length                     = length;
+
+    if (status == A_OK) {
+        if (a_copy_from_user(data_reply->buf, user_buf, length)) {
+            return A_ERROR;
+        }
+    }
+
+    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
+                             NO_SYNC_WMIFLAG));
+}
+#endif /* CONFIG_HOST_DSET_SUPPORT */
+
+#if CONFIG_HOST_GPIO_SUPPORT
+/* Send a command to Target to change GPIO output pins. */
+A_STATUS
+wmi_gpio_output_set(struct wmi_t *wmip,
+                    A_UINT32 set_mask,
+                    A_UINT32 clear_mask,
+                    A_UINT32 enable_mask,
+                    A_UINT32 disable_mask)
+{
+    void *osbuf;
+    WMIX_GPIO_OUTPUT_SET_CMD *output_set;
+    int size;
+
+    size = sizeof(*output_set);
+
+    WMI_DEBUG_PRINTF("wmi_gpio_output_set: set=0x%x clear=0x%x enb=0x%x dis=0x%x\n",
+                set_mask, clear_mask, enable_mask, disable_mask);
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+    a_netbuf_put(osbuf, size);
+    output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(a_netbuf_to_data(osbuf));
+
+    output_set->set_mask                   = set_mask;
+    output_set->clear_mask                 = clear_mask;
+    output_set->enable_mask                = enable_mask;
+    output_set->disable_mask               = disable_mask;
+
+    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID,
+                             NO_SYNC_WMIFLAG));
+}
+
+/* Send a command to the Target requesting state of the GPIO input pins */
+A_STATUS
+wmi_gpio_input_get(struct wmi_t *wmip)
+{
+    void *osbuf;
+
+    WMI_DEBUG_PRINTF("wmi_gpio_input_get\n");
+
+    osbuf = a_netbuf_alloc(0);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INPUT_GET_CMDID,
+                             NO_SYNC_WMIFLAG));
+}
+
+/* Send a command to the Target that changes the value of a GPIO register. */
+A_STATUS
+wmi_gpio_register_set(struct wmi_t *wmip,
+                      A_UINT32 gpioreg_id,
+                      A_UINT32 value)
+{
+    void *osbuf;
+    WMIX_GPIO_REGISTER_SET_CMD *register_set;
+    int size;
+
+    size = sizeof(*register_set);
+
+    WMI_DEBUG_PRINTF("wmi_gpio_register_set: reg=%d value=0x%x\n",
+                gpioreg_id, value);
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+    a_netbuf_put(osbuf, size);
+    register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(a_netbuf_to_data(osbuf));
+
+    register_set->gpioreg_id               = gpioreg_id;
+    register_set->value                    = value;
+
+    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID,
+                             NO_SYNC_WMIFLAG));
+}
+
+/* Send a command to the Target to fetch the value of a GPIO register. */
+A_STATUS
+wmi_gpio_register_get(struct wmi_t *wmip,
+                      A_UINT32 gpioreg_id)
+{
+    void *osbuf;
+    WMIX_GPIO_REGISTER_GET_CMD *register_get;
+    int size;
+
+    size = sizeof(*register_get);
+
+    WMI_DEBUG_PRINTF("wmi_gpio_register_get: reg=%d\n", gpioreg_id);
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+    a_netbuf_put(osbuf, size);
+    register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(a_netbuf_to_data(osbuf));
+
+    register_get->gpioreg_id               = gpioreg_id;
+
+    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID,
+                             NO_SYNC_WMIFLAG));
+}
+
+/* Send a command to the Target acknowledging some GPIO interrupts. */
+A_STATUS
+wmi_gpio_intr_ack(struct wmi_t *wmip,
+                  A_UINT32 ack_mask)
+{
+    void *osbuf;
+    WMIX_GPIO_INTR_ACK_CMD *intr_ack;
+    int size;
+
+    size = sizeof(*intr_ack);
+
+    WMI_DEBUG_PRINTF("wmi_gpio_intr_ack: ack_mask=0x%x\n", ack_mask);
+
+    osbuf = a_netbuf_alloc(size);
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+    a_netbuf_put(osbuf, size);
+    intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(a_netbuf_to_data(osbuf));
+
+    intr_ack->ack_mask               = ack_mask;
+
+    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID,
+                             NO_SYNC_WMIFLAG));
+}
+#endif /* CONFIG_HOST_GPIO_SUPPORT */
+
+A_STATUS
+wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT16 txop, A_UINT8 eCWmin,
+                          A_UINT8 eCWmax, A_UINT8 aifsn)
+{
+    void *osbuf;
+    WMI_SET_ACCESS_PARAMS_CMD *cmd;
+
+    if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
+        (aifsn > WMI_MAX_AIFSN_ACPARAM))
+    {
+        return A_EINVAL;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(a_netbuf_to_data(osbuf));
+    cmd->txop   = txop;
+    cmd->eCWmin = eCWmin;
+    cmd->eCWmax = eCWmax;
+    cmd->aifsn  = aifsn;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
+                         A_UINT8 trafficClass, A_UINT8 maxRetries)
+{
+    void *osbuf;
+    WMI_SET_RETRY_LIMITS_CMD *cmd;
+
+    if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
+        (frameType != DATA_FRAMETYPE))
+    {
+        return A_EINVAL;
+    }
+
+    if (maxRetries > WMI_MAX_RETRIES) {
+        return A_EINVAL;
+    }
+
+    if (frameType != DATA_FRAMETYPE) {
+        trafficClass = 0;
+    }
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_SET_RETRY_LIMITS_CMD *)(a_netbuf_to_data(osbuf));
+    cmd->frameType    = frameType;
+    cmd->trafficClass = trafficClass;
+    cmd->maxRetries   = maxRetries;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+void
+wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid)
+{
+    if (bssid != NULL) {
+        A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
+    }
+}
+
+A_STATUS
+wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode)
+{
+    void *osbuf;
+    WMI_SET_OPT_MODE_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_SET_OPT_MODE_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->optMode = optMode;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
+                         SYNC_BOTH_WMIFLAG));
+}
+
+A_STATUS
+wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
+                      A_UINT8 frmType,
+                      A_UINT8 *dstMacAddr,
+                      A_UINT8 *bssid,
+                      A_UINT16 optIEDataLen,
+                      A_UINT8 *optIEData)
+{
+    void *osbuf;
+    WMI_OPT_TX_FRAME_CMD *cmd;
+    osbuf = a_netbuf_alloc(optIEDataLen + sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, (optIEDataLen + sizeof(*cmd)));
+
+    cmd = (WMI_OPT_TX_FRAME_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)));
+
+    cmd->frmType 	= frmType;
+    cmd->optIEDataLen 	= optIEDataLen;
+    cmd->optIEData     = (A_UINT8 *)((int)cmd + sizeof(*cmd));
+    A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
+    A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
+    A_MEMCPY(cmd->optIEData, optIEData, optIEDataLen);
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
+                         NO_SYNC_WMIFLAG));
+}
+
+A_STATUS
+wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl)
+{
+    void *osbuf;
+    WMI_BEACON_INT_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_BEACON_INT_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->beaconInterval = intvl;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
+            NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize)
+{
+    void *osbuf;
+    WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->voicePktSize = voicePktSize;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
+            NO_SYNC_WMIFLAG));
+}
+
+
+A_STATUS
+wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen)
+{
+    void *osbuf;
+    WMI_SET_MAX_SP_LEN_CMD *cmd;
+
+    /* maxSPLen is a two-bit value. If user trys to set anything
+     * other than this, then its invalid
+     */
+    if(maxSPLen & ~0x03)
+        return  A_EINVAL;
+
+    osbuf = a_netbuf_alloc(sizeof(*cmd));
+    if (osbuf == NULL) {
+        return A_NO_MEMORY;
+    }
+
+    a_netbuf_put(osbuf, sizeof(*cmd));
+
+    cmd = (WMI_SET_MAX_SP_LEN_CMD *)(a_netbuf_to_data(osbuf));
+    A_MEMZERO(cmd, sizeof(*cmd));
+    cmd->maxSPLen = maxSPLen;
+
+    return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
+            NO_SYNC_WMIFLAG));
+}
+
+A_UINT8
+convert_userPriority_to_trafficClass(A_UINT8 userPriority)
+{
+        return  (up_to_ac[userPriority & 0x7]);
+}
+
+A_UINT8
+wmi_get_power_mode_cmd(struct wmi_t *wmip)
+{
+    return wmip->wmi_powerMode;
+}
+
+A_STATUS
+wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance)
+{
+    A_STATUS ret = A_OK;
+
+#define TSPEC_SUSPENSION_INTERVAL_CCXV4_DEF (~0)
+#define TSPEC_SERVICE_START_TIME_CCXV4_DEF  0
+#define TSPEC_MAX_BURST_SIZE_CCXV4_DEF      0
+#define TSPEC_DELAY_BOUND_CCXV4_DEF         0
+#define TSPEC_MEDIUM_TIME_CCXV4_DEF         0
+#define TSPEC_SBA_CCXV4_DEF                 0x2000  /* factor is 1 */
+
+    /* Verify TSPEC params for CCX v4 compliance */
+    if(tspecCompliance == CCX_V4_COMPLIANCE) {
+        if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_CCXV4_DEF) ||
+            (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_CCXV4_DEF) ||
+            (pCmd->minDataRate != pCmd->meanDataRate) ||
+            (pCmd->minDataRate != pCmd->peakDataRate) ||
+            (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_CCXV4_DEF) ||
+            (pCmd->delayBound != TSPEC_DELAY_BOUND_CCXV4_DEF) ||
+            (pCmd->sba != TSPEC_SBA_CCXV4_DEF) ||
+            (pCmd->mediumTime != TSPEC_MEDIUM_TIME_CCXV4_DEF)) {
+
+            WMI_DEBUG_PRINTF("%s: Invalid TSPEC params\n", __FUNCTION__);
+            A_PRINTF("%s: Invalid TSPEC params\n", __FUNCTION__);
+            ret = A_EINVAL;
+        }
+    }
+
+    return ret;
+}

Added: developers/nbd/patches-2.6.22/100-asoc.patch
===================================================================
--- developers/nbd/patches-2.6.22/100-asoc.patch	2007-07-27 16:41:13 UTC (rev 2539)
+++ developers/nbd/patches-2.6.22/100-asoc.patch	2007-07-27 18:59:01 UTC (rev 2540)
@@ -0,0 +1,21306 @@
+Index: linux-2.6.22.1/sound/soc/codecs/ak4535.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/ak4535.c	2007-07-16 15:07:33.844265944 +0200
+@@ -0,0 +1,697 @@
++/*
++ * ak4535.c  --  AK4535 ALSA Soc Audio driver
++ *
++ * Copyright 2005 Openedhand Ltd.
++ *
++ * Author: Richard Purdie <richard at openedhand.com>
++ *
++ * Based on wm8753.c by Liam Girdwood
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++
++#include "ak4535.h"
++
++#define AUDIO_NAME "ak4535"
++#define AK4535_VERSION "0.3"
++
++struct snd_soc_codec_device soc_codec_dev_ak4535;
++
++/* codec private data */
++struct ak4535_priv {
++	unsigned int sysclk;
++};
++
++/*
++ * ak4535 register cache
++ */
++static const u16 ak4535_reg[AK4535_CACHEREGNUM] = {
++    0x0000, 0x0080, 0x0000, 0x0003,
++    0x0002, 0x0000, 0x0011, 0x0001,
++    0x0000, 0x0040, 0x0036, 0x0010,
++    0x0000, 0x0000, 0x0057, 0x0000,
++};
++
++/*
++ * read ak4535 register cache
++ */
++static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec,
++	unsigned int reg)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg >= AK4535_CACHEREGNUM)
++		return -1;
++	return cache[reg];
++}
++
++/*
++ * write ak4535 register cache
++ */
++static inline void ak4535_write_reg_cache(struct snd_soc_codec *codec,
++	u16 reg, unsigned int value)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg >= AK4535_CACHEREGNUM)
++		return;
++	cache[reg] = value;
++}
++
++/*
++ * write to the AK4535 register space
++ */
++static int ak4535_write(struct snd_soc_codec *codec, unsigned int reg,
++	unsigned int value)
++{
++	u8 data[2];
++
++	/* data is
++	 *   D15..D8 AK4535 register offset
++	 *   D7...D0 register data
++	 */
++	data[0] = reg & 0xff;
++	data[1] = value & 0xff;
++
++	ak4535_write_reg_cache (codec, reg, value);
++	if (codec->hw_write(codec->control_data, data, 2) == 2)
++		return 0;
++	else
++		return -EIO;
++}
++
++static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
++static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
++static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
++static const char *ak4535_deemp[] = {"44.1kHz", "Off", "48kHz", "32kHz"};
++static const char *ak4535_mic_select[] = {"Internal", "External"};
++
++static const struct soc_enum ak4535_enum[] = {
++	SOC_ENUM_SINGLE(AK4535_SIG1, 7, 2, ak4535_mono_gain),
++	SOC_ENUM_SINGLE(AK4535_SIG1, 6, 2, ak4535_mono_out),
++	SOC_ENUM_SINGLE(AK4535_MODE2, 2, 2, ak4535_hp_out),
++	SOC_ENUM_SINGLE(AK4535_DAC, 0, 4, ak4535_deemp),
++	SOC_ENUM_SINGLE(AK4535_MIC, 1, 2, ak4535_mic_select),
++};
++
++static const struct snd_kcontrol_new ak4535_snd_controls[] = {
++	SOC_SINGLE("ALC2 Switch", AK4535_SIG1, 1, 1, 0),
++	SOC_ENUM("Mono 1 Output", ak4535_enum[1]),
++	SOC_ENUM("Mono 1 Gain", ak4535_enum[0]),
++	SOC_ENUM("Headphone Output", ak4535_enum[2]),
++	SOC_ENUM("Playback Deemphasis", ak4535_enum[3]),
++	SOC_SINGLE("Bass Volume", AK4535_DAC, 2, 3, 0),
++	SOC_SINGLE("Mic Boost (+20dB) Switch", AK4535_MIC, 0, 1, 0),
++	SOC_ENUM("Mic Select", ak4535_enum[4]),
++	SOC_SINGLE("ALC Operation Time", AK4535_TIMER, 0, 3, 0),
++	SOC_SINGLE("ALC Recovery Time", AK4535_TIMER, 2, 3, 0),
++	SOC_SINGLE("ALC ZC Time", AK4535_TIMER, 4, 3, 0),
++	SOC_SINGLE("ALC 1 Switch", AK4535_ALC1, 5, 1, 0),
++	SOC_SINGLE("ALC 2 Switch", AK4535_ALC1, 6, 1, 0),
++	SOC_SINGLE("ALC Volume", AK4535_ALC2, 0, 127, 0),
++	SOC_SINGLE("Capture Volume", AK4535_PGA, 0, 127, 0),
++	SOC_SINGLE("Left Playback Volume", AK4535_LATT, 0, 127, 1),
++	SOC_SINGLE("Right Playback Volume", AK4535_RATT, 0, 127, 1),
++	SOC_SINGLE("AUX Bypass Volume", AK4535_VOL, 0, 15, 0),
++	SOC_SINGLE("Mic Sidetone Volume", AK4535_VOL, 4, 7, 0),
++};
++
++/* add non dapm controls */
++static int ak4535_add_controls(struct snd_soc_codec *codec)
++{
++	int err, i;
++
++	for (i = 0; i < ARRAY_SIZE(ak4535_snd_controls); i++) {
++		err = snd_ctl_add(codec->card,
++			snd_soc_cnew(&ak4535_snd_controls[i],codec, NULL));
++		if (err < 0)
++			return err;
++	}
++
++	return 0;
++}
++
++/* Mono 1 Mixer */
++static const struct snd_kcontrol_new ak4535_mono1_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG1, 4, 1, 0),
++	SOC_DAPM_SINGLE("Mono Playback Switch", AK4535_SIG1, 5, 1, 0),
++};
++
++/* Stereo Mixer */
++static const struct snd_kcontrol_new ak4535_stereo_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Mic Sidetone Switch", AK4535_SIG2, 4, 1, 0),
++	SOC_DAPM_SINGLE("Playback Switch", AK4535_SIG2, 7, 1, 0),
++	SOC_DAPM_SINGLE("Aux Bypass Switch", AK4535_SIG2, 5, 1, 0),
++};
++
++/* Input Mixer */
++static const struct snd_kcontrol_new ak4535_input_mixer_controls[] = {
++	SOC_DAPM_SINGLE("Mic Capture Switch", AK4535_MIC, 2, 1, 0),
++	SOC_DAPM_SINGLE("Aux Capture Switch", AK4535_MIC, 5, 1, 0),
++};
++
++/* Input mux */
++static const struct snd_kcontrol_new ak4535_input_mux_control =
++	SOC_DAPM_ENUM("Input Select", ak4535_enum[0]);
++
++/* HP L switch */
++static const struct snd_kcontrol_new ak4535_hpl_control =
++	SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 1, 1, 1);
++
++/* HP R switch */
++static const struct snd_kcontrol_new ak4535_hpr_control =
++	SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 0, 1, 1);
++
++/* Speaker switch */
++static const struct snd_kcontrol_new ak4535_spk_control =
++	SOC_DAPM_SINGLE("Switch", AK4535_MODE2, 0, 0, 0);
++
++/* mono 2 switch */
++static const struct snd_kcontrol_new ak4535_mono2_control =
++	SOC_DAPM_SINGLE("Switch", AK4535_SIG1, 0, 1, 0);
++
++/* Line out switch */
++static const struct snd_kcontrol_new ak4535_line_control =
++	SOC_DAPM_SINGLE("Switch", AK4535_SIG2, 6, 1, 0);
++
++/* ak4535 dapm widgets */
++static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = {
++	SND_SOC_DAPM_MIXER("Stereo Mixer", SND_SOC_NOPM, 0, 0,
++		&ak4535_stereo_mixer_controls[0],
++		ARRAY_SIZE(ak4535_stereo_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Mono1 Mixer", SND_SOC_NOPM, 0, 0,
++		&ak4535_mono1_mixer_controls[0],
++		ARRAY_SIZE(ak4535_mono1_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0,
++		&ak4535_input_mixer_controls[0],
++		ARRAY_SIZE(ak4535_mono1_mixer_controls)),
++	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
++		&ak4535_input_mux_control),
++	SND_SOC_DAPM_DAC("DAC", "Playback", AK4535_PM2, 0, 0),
++	SND_SOC_DAPM_SWITCH("Mono 2 Enable", SND_SOC_NOPM, 0, 0,
++		&ak4535_mono2_control),
++	SND_SOC_DAPM_SWITCH("Speaker Enable", SND_SOC_NOPM, 0, 0,
++		&ak4535_spk_control),
++	SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM, 0, 0,
++		&ak4535_line_control),
++	SND_SOC_DAPM_SWITCH("Left HP Enable", SND_SOC_NOPM, 0, 0,
++		&ak4535_hpl_control),
++	SND_SOC_DAPM_SWITCH("Right HP Enable", SND_SOC_NOPM, 0, 0,
++		&ak4535_hpr_control),
++	SND_SOC_DAPM_OUTPUT("LOUT"),
++	SND_SOC_DAPM_OUTPUT("HPL"),
++	SND_SOC_DAPM_OUTPUT("ROUT"),
++	SND_SOC_DAPM_OUTPUT("HPR"),
++	SND_SOC_DAPM_OUTPUT("SPP"),
++	SND_SOC_DAPM_OUTPUT("SPN"),
++	SND_SOC_DAPM_OUTPUT("MOUT1"),
++	SND_SOC_DAPM_OUTPUT("MOUT2"),
++	SND_SOC_DAPM_OUTPUT("MICOUT"),
++	SND_SOC_DAPM_ADC("ADC", "Capture", AK4535_PM1, 0, 1),
++	SND_SOC_DAPM_PGA("Spk Amp", AK4535_PM2, 3, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("HP R Amp", AK4535_PM2, 1, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("HP L Amp", AK4535_PM2, 2, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Mic", AK4535_PM1, 1, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Line Out", AK4535_PM1, 4, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Mono Out", AK4535_PM1, 3, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("AUX In", AK4535_PM1, 2, 0, NULL, 0),
++
++	SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4535_MIC, 3, 0),
++	SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4535_MIC, 4, 0),
++	SND_SOC_DAPM_INPUT("MICIN"),
++	SND_SOC_DAPM_INPUT("MICEXT"),
++	SND_SOC_DAPM_INPUT("AUX"),
++	SND_SOC_DAPM_INPUT("MIN"),
++	SND_SOC_DAPM_INPUT("AIN"),
++};
++
++static const char *audio_map[][3] = {
++	/*stereo mixer */
++	{"Stereo Mixer", "Playback Switch", "DAC"},
++	{"Stereo Mixer", "Mic Sidetone Switch", "Mic"},
++	{"Stereo Mixer", "Aux Bypass Switch", "AUX In"},
++
++	/* mono1 mixer */
++	{"Mono1 Mixer", "Mic Sidetone Switch", "Mic"},
++	{"Mono1 Mixer", "Mono Playback Switch", "DAC"},
++
++	/* mono2 mixer */
++	{"Mono2 Mixer", "Mono Playback Switch", "Stereo Mixer"},
++
++	/* Mic */
++	{"AIN", NULL, "Mic"},
++	{"Input Mux", "Internal", "Mic Int Bias"},
++	{"Input Mux", "External", "Mic Ext Bias"},
++	{"Mic Int Bias", NULL, "MICIN"},
++	{"Mic Ext Bias", NULL, "MICEXT"},
++	{"MICOUT", NULL, "Input Mux"},
++
++	/* line out */
++	{"LOUT", "Switch", "Line"},
++	{"ROUT", "Switch", "Line Out Enable"},
++	{"Line Out Enable", NULL, "Line Out"},
++	{"Line Out", NULL, "Stereo Mixer"},
++
++	/* mono1 out */
++	{"MOUT1", NULL, "Mono Out"},
++	{"Mono Out", NULL, "Mono Mixer"},
++
++	/* left HP */
++	{"HPL", "Switch", "Left HP Enable"},
++	{"Left HP Enable", NULL, "HP L Amp"},
++	{"HP L Amp", NULL, "Stereo Mixer"},
++
++	/* right HP */
++	{"HPR", "Switch", "Right HP Enable"},
++	{"Right HP Enable", NULL, "HP R Amp"},
++	{"HP R Amp", NULL, "Stereo Mixer"},
++
++	/* speaker */
++	{"SPP", "Switch", "Speaker Enable"},
++	{"SPN", "Switch", "Speaker Enable"},
++	{"Speaker Enable", NULL, "Spk Amp"},
++	{"Spk Amp", NULL, "MIN"},
++
++	/* mono 2 */
++	{"MOUT2", "Switch", "Mono 2 Enable"},
++	{"Mono 2 Enable", NULL, "Stereo Mixer"},
++
++	/* Aux In */
++	{"Aux In", NULL, "AUX"},
++
++	/* ADC */
++	{"ADC", NULL, "Input Mixer"},
++	{"Input Mixer", "Mic Capture Switch", "Mic"},
++	{"Input Mixer", "Aux Capture Switch", "Aux In"},
++
++	/* terminator */
++	{NULL, NULL, NULL},
++};
++
++static int ak4535_add_widgets(struct snd_soc_codec *codec)
++{
++	int i;
++
++	for(i = 0; i < ARRAY_SIZE(ak4535_dapm_widgets); i++) {
++		snd_soc_dapm_new_control(codec, &ak4535_dapm_widgets[i]);
++	}
++
++	/* set up audio path audio_mapnects */
++	for(i = 0; audio_map[i][0] != NULL; i++) {
++		snd_soc_dapm_connect_input(codec, audio_map[i][0],
++			audio_map[i][1], audio_map[i][2]);
++	}
++
++	snd_soc_dapm_new_widgets(codec);
++	return 0;
++}
++
++static int ak4535_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
++	int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct ak4535_priv *ak4535 = codec->private_data;
++
++	ak4535->sysclk = freq;
++	return 0;
++}
++
++static int ak4535_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	struct ak4535_priv *ak4535 = codec->private_data;
++	u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5);
++	int rate = params_rate(params), fs = 256;
++
++	if (rate)
++		fs = ak4535->sysclk / rate;
++
++	/* set fs */
++	switch (fs) {
++	case 1024:
++		mode2 |= (0x2 << 5);
++		break;
++	case 512:
++		mode2 |= (0x1 << 5);
++		break;
++	case 256:
++		break;
++	}
++
++	/* set rate */
++	ak4535_write(codec, AK4535_MODE2, mode2);
++	return 0;
++}
++
++static int ak4535_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u8 mode1 = 0;
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		mode1 = 0x0002;
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		mode1 = 0x0001;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* use 32 fs for BCLK to save power */
++	mode1 |= 0x4;
++
++	ak4535_write(codec, AK4535_MODE1, mode1);
++	return 0;
++}
++
++static int ak4535_mute(struct snd_soc_codec_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf;
++	if (mute)
++		ak4535_write(codec, AK4535_DAC, mute_reg);
++	else
++		ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
++	return 0;
++}
++
++static int ak4535_dapm_event(struct snd_soc_codec *codec, int event)
++{
++	switch (event) {
++	case SNDRV_CTL_POWER_D0: /* full On */
++	/* vref/mid, clk and osc on, dac unmute, active */
++	case SNDRV_CTL_POWER_D1: /* partial On */
++	case SNDRV_CTL_POWER_D2: /* partial On */
++		break;
++	case SNDRV_CTL_POWER_D3hot: /* Off, with power */
++		/* everything off except vref/vmid, dac mute, inactive */
++		ak4535_write(codec, AK4535_PM1, 0x80);
++		ak4535_write(codec, AK4535_PM2, 0x0);
++		break;
++	case SNDRV_CTL_POWER_D3cold: /* Off, without power */
++		/* everything off, inactive */
++		ak4535_write(codec, AK4535_PM1, 0x0);
++		ak4535_write(codec, AK4535_PM2, 0x80);
++		break;
++	}
++	codec->dapm_state = event;
++	return 0;
++}
++
++#define AK4535_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
++		SNDRV_PCM_RATE_48000)
++
++struct snd_soc_codec_dai ak4535_dai = {
++	.name = "AK4535",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = AK4535_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = AK4535_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.ops = {
++		.hw_params = ak4535_hw_params,
++	},
++	.dai_ops = {
++		.set_fmt = ak4535_set_dai_fmt,
++		.digital_mute = ak4535_mute,
++		.set_sysclk = ak4535_set_dai_sysclk,
++	},
++};
++EXPORT_SYMBOL_GPL(ak4535_dai);
++
++static int ak4535_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	ak4535_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++	return 0;
++}
++
++static int ak4535_resume(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++	int i;
++	u8 data[2];
++	u16 *cache = codec->reg_cache;
++
++	/* Sync reg_cache with the hardware */
++	for (i = 0; i < ARRAY_SIZE(ak4535_reg); i++) {
++		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
++		data[1] = cache[i] & 0x00ff;
++		codec->hw_write(codec->control_data, data, 2);
++	}
++	ak4535_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++	ak4535_dapm_event(codec, codec->suspend_dapm_state);
++	return 0;
++}
++
++/*
++ * initialise the AK4535 driver
++ * register the mixer and dsp interfaces with the kernel
++ */
++static int ak4535_init(struct snd_soc_device *socdev)
++{
++	struct snd_soc_codec *codec = socdev->codec;
++	int ret = 0;
++
++	codec->name = "AK4535";
++	codec->owner = THIS_MODULE;
++	codec->read = ak4535_read_reg_cache;
++	codec->write = ak4535_write;
++	codec->dapm_event = ak4535_dapm_event;
++	codec->dai = &ak4535_dai;
++	codec->num_dai = 1;
++	codec->reg_cache_size = ARRAY_SIZE(ak4535_reg);
++	codec->reg_cache =
++			kzalloc(sizeof(u16) * ARRAY_SIZE(ak4535_reg), GFP_KERNEL);
++	if (codec->reg_cache == NULL)
++		return -ENOMEM;
++	memcpy(codec->reg_cache, ak4535_reg,
++		sizeof(u16) * ARRAY_SIZE(ak4535_reg));
++	codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(ak4535_reg);
++
++	/* register pcms */
++	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++	if (ret < 0) {
++		printk(KERN_ERR "ak4535: failed to create pcms\n");
++		goto pcm_err;
++	}
++
++	/* power on device */
++	ak4535_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++
++	ak4535_add_controls(codec);
++	ak4535_add_widgets(codec);
++	ret = snd_soc_register_card(socdev);
++	if (ret < 0) {
++		printk(KERN_ERR "ak4535: failed to register card\n");
++		goto card_err;
++	}
++
++	return ret;
++
++card_err:
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++pcm_err:
++	kfree(codec->reg_cache);
++
++	return ret;
++}
++
++static struct snd_soc_device *ak4535_socdev;
++
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++
++#define I2C_DRIVERID_AK4535 0xfefe /* liam -  need a proper id */
++
++static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
++
++/* Magic definition of all other variables and things */
++I2C_CLIENT_INSMOD;
++
++static struct i2c_driver ak4535_i2c_driver;
++static struct i2c_client client_template;
++
++/* If the i2c layer weren't so broken, we could pass this kind of data
++   around */
++static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
++{
++	struct snd_soc_device *socdev = ak4535_socdev;
++	struct ak4535_setup_data *setup = socdev->codec_data;
++	struct snd_soc_codec *codec = socdev->codec;
++	struct i2c_client *i2c;
++	int ret;
++
++	if (addr != setup->i2c_address)
++		return -ENODEV;
++
++	client_template.adapter = adap;
++	client_template.addr = addr;
++
++	i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	if (i2c == NULL){
++		kfree(codec);
++		return -ENOMEM;
++	}
++	memcpy(i2c, &client_template, sizeof(struct i2c_client));
++	i2c_set_clientdata(i2c, codec);
++	codec->control_data = i2c;
++
++	ret = i2c_attach_client(i2c);
++	if (ret < 0) {
++		printk(KERN_ERR "failed to attach codec at addr %x\n", addr);
++		goto err;
++	}
++
++	ret = ak4535_init(socdev);
++	if (ret < 0) {
++		printk(KERN_ERR "failed to initialise AK4535\n");
++		goto err;
++	}
++	return ret;
++
++err:
++	kfree(codec);
++	kfree(i2c);
++	return ret;
++}
++
++static int ak4535_i2c_detach(struct i2c_client *client)
++{
++	struct snd_soc_codec* codec = i2c_get_clientdata(client);
++	i2c_detach_client(client);
++	kfree(codec->reg_cache);
++	kfree(client);
++	return 0;
++}
++
++static int ak4535_i2c_attach(struct i2c_adapter *adap)
++{
++	return i2c_probe(adap, &addr_data, ak4535_codec_probe);
++}
++
++/* corgi i2c codec control layer */
++static struct i2c_driver ak4535_i2c_driver = {
++	.driver = {
++		.name = "AK4535 I2C Codec",
++		.owner = THIS_MODULE,
++	},
++	.id =             I2C_DRIVERID_AK4535,
++	.attach_adapter = ak4535_i2c_attach,
++	.detach_client =  ak4535_i2c_detach,
++	.command =        NULL,
++};
++
++static struct i2c_client client_template = {
++	.name =   "AK4535",
++	.driver = &ak4535_i2c_driver,
++};
++#endif
++
++static int ak4535_probe(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct ak4535_setup_data *setup;
++	struct snd_soc_codec* codec;
++	struct ak4535_priv *ak4535;
++	int ret = 0;
++
++	printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
++
++	setup = socdev->codec_data;
++	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
++	if (codec == NULL)
++		return -ENOMEM;
++
++	ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL);
++	if (ak4535 == NULL) {
++		kfree(codec);
++		return -ENOMEM;
++	}
++
++	codec->private_data = ak4535;
++	socdev->codec = codec;
++	mutex_init(&codec->mutex);
++	INIT_LIST_HEAD(&codec->dapm_widgets);
++	INIT_LIST_HEAD(&codec->dapm_paths);
++
++	ak4535_socdev = socdev;
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	if (setup->i2c_address) {
++		normal_i2c[0] = setup->i2c_address;
++		codec->hw_write = (hw_write_t)i2c_master_send;
++		ret = i2c_add_driver(&ak4535_i2c_driver);
++		if (ret != 0)
++			printk(KERN_ERR "can't add i2c driver");
++	}
++#else
++	/* Add other interfaces here */
++#endif
++	return ret;
++}
++
++/* power down chip */
++static int ak4535_remove(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec* codec = socdev->codec;
++
++	if (codec->control_data)
++		ak4535_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	i2c_del_driver(&ak4535_i2c_driver);
++#endif
++	kfree(codec->private_data);
++	kfree(codec);
++
++	return 0;
++}
++
++struct snd_soc_codec_device soc_codec_dev_ak4535 = {
++	.probe = 	ak4535_probe,
++	.remove = 	ak4535_remove,
++	.suspend = 	ak4535_suspend,
++	.resume =	ak4535_resume,
++};
++
++EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
++
++MODULE_DESCRIPTION("Soc AK4535 driver");
++MODULE_AUTHOR("Richard Purdie");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.22.1/sound/soc/codecs/ak4535.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/ak4535.h	2007-07-16 15:07:33.848266172 +0200
+@@ -0,0 +1,46 @@
++/*
++ * ak4535.h  --  AK4535 Soc Audio driver
++ *
++ * Copyright 2005 Openedhand Ltd.
++ *
++ * Author: Richard Purdie <richard at openedhand.com>
++ *
++ * Based on wm8753.h
++ *
++ * 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.
++ */
++
++#ifndef _AK4535_H
++#define _AK4535_H
++
++/* AK4535 register space */
++
++#define AK4535_PM1		0x0
++#define AK4535_PM2		0x1
++#define AK4535_SIG1		0x2
++#define AK4535_SIG2		0x3
++#define AK4535_MODE1	0x4
++#define AK4535_MODE2	0x5
++#define AK4535_DAC		0x6
++#define AK4535_MIC		0x7
++#define AK4535_TIMER	0x8
++#define AK4535_ALC1		0x9
++#define AK4535_ALC2		0xa
++#define AK4535_PGA		0xb
++#define AK4535_LATT		0xc
++#define AK4535_RATT		0xd
++#define AK4535_VOL		0xe
++#define AK4535_STATUS	0xf
++
++#define AK4535_CACHEREGNUM 	0x10
++
++struct ak4535_setup_data {
++	unsigned short i2c_address;
++};
++
++extern struct snd_soc_codec_dai ak4535_dai;
++extern struct snd_soc_codec_device soc_codec_dev_ak4535;
++
++#endif
+Index: linux-2.6.22.1/sound/soc/codecs/uda1380.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/uda1380.c	2007-07-16 15:07:33.872267542 +0200
+@@ -0,0 +1,745 @@
++/*
++ * uda1380.c - Philips UDA1380 ALSA SoC audio driver
++ *
++ * 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.
++ *
++ * Modified by Richard Purdie <richard at openedhand.com> to fit into SoC
++ * codec model.
++ *
++ * Copyright (c) 2005 Giorgio Padrin <giorgio at mandarinlogiq.org>
++ * Copyright 2005 Openedhand Ltd.
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <linux/errno.h>
++#include <linux/ioctl.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/control.h>
++#include <sound/initval.h>
++#include <sound/info.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include "uda1380.h"
++
++#define UDA1380_VERSION "0.5"
++#define AUDIO_NAME "uda1380"
++/*
++ * Debug
++ */
++
++#define UDA1380_DEBUG 0
++
++#ifdef UDA1380_DEBUG
++#define dbg(format, arg...) \
++	printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
++#else
++#define dbg(format, arg...) do {} while (0)
++#endif
++
++/*
++ * uda1380 register cache
++ */
++static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = {
++	0x0502, 0x0000, 0x0000, 0x3f3f,
++	0x0202, 0x0000, 0x0000, 0x0000,
++	0x0000, 0x0000, 0x0000, 0x0000,
++	0x0000, 0x0000, 0x0000, 0x0000,
++	0x0000, 0xff00, 0x0000, 0x4800,
++	0x0000, 0x0000, 0x0000, 0x0000,
++	0x0000, 0x0000, 0x0000, 0x0000,
++	0x0000, 0x0000, 0x0000, 0x0000,
++	0x0000, 0x8000, 0x0002, 0x0000,
++};
++
++/*
++ * read uda1380 register cache
++ */
++static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec,
++	unsigned int reg)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg == UDA1380_RESET)
++		return 0;
++	if (reg >= UDA1380_CACHEREGNUM)
++		return -1;
++	return cache[reg];
++}
++
++/*
++ * write uda1380 register cache
++ */
++static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec,
++	u16 reg, unsigned int value)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg >= UDA1380_CACHEREGNUM)
++		return;
++	cache[reg] = value;
++}
++
++/*
++ * write to the UDA1380 register space
++ */
++static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg,
++	unsigned int value)
++{
++	u8 data[3];
++
++	/* data is
++	 *   data[0] is register offset
++	 *   data[1] is MS byte
++	 *   data[2] is LS byte
++	 */
++	data[0] = reg;
++	data[1] = (value & 0xff00) >> 8;
++	data[2] = value & 0x00ff;
++
++	uda1380_write_reg_cache (codec, reg, value);
++
++	/* the interpolator & decimator regs must only be written when the
++	 * codec DAI is active.
++	 */
++	if (!codec->active && (reg >= UDA1380_MVOL))
++		return 0;
++	dbg("uda hw write %x val %x\n", reg, value);
++	if (codec->hw_write(codec->control_data, data, 3) == 3) {
++		unsigned int val;
++		i2c_master_send(codec->control_data, data, 1);
++		i2c_master_recv(codec->control_data, data, 2);
++		val = (data[0]<<8) | data[1];
++		if (val != value) {
++			dbg("READ BACK VAL %x\n", (data[0]<<8) | data[1]);
++			return -EIO;
++		}
++		return 0;
++	} else
++		return -EIO;
++}
++
++#define uda1380_reset(c)	uda1380_write(c, UDA1380_RESET, 0)
++
++/* declarations of ALSA reg_elem_REAL controls */
++static const char *uda1380_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz",
++				      "96kHz"};
++static const char *uda1380_input_sel[] = {"Line", "Mic"};
++static const char *uda1380_output_sel[] = {"Direct", "Mixer"};
++static const char *uda1380_spf_mode[] = {"Flat", "Minimum1", "Minimum2",
++					 "Maximum"};
++
++static const struct soc_enum uda1380_enum[] = {
++	SOC_ENUM_DOUBLE(UDA1380_DEEMP, 0, 8, 5, uda1380_deemp),
++	SOC_ENUM_SINGLE(UDA1380_ADC, 3, 2, uda1380_input_sel),
++	SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode),
++	SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel), /* R02_EN_AVC */
++};
++
++static const struct snd_kcontrol_new uda1380_snd_controls[] = {
++	SOC_DOUBLE("Playback Volume", UDA1380_MVOL, 0, 8, 255, 1),
++	SOC_DOUBLE("Mixer Volume", UDA1380_MIXVOL, 0, 8, 255, 1),
++	SOC_ENUM("Sound Processing Filter Mode", uda1380_enum[2]),
++	SOC_DOUBLE("Treble Volume", UDA1380_MODE, 4, 12, 3, 0),
++	SOC_DOUBLE("Bass Volume", UDA1380_MODE, 0, 8, 15, 0),
++	SOC_ENUM("Playback De-emphasis", uda1380_enum[0]),
++	SOC_DOUBLE("Capture Volume", UDA1380_DEC, 0, 8, 127, 0),
++	SOC_DOUBLE("Line Capture Volume", UDA1380_PGA, 0, 8, 15, 0),
++	SOC_SINGLE("Mic Capture Volume", UDA1380_PGA, 8, 11, 0),
++	SOC_DOUBLE("Playback Switch", UDA1380_DEEMP, 3, 11, 1, 1),
++	SOC_SINGLE("Capture Switch", UDA1380_PGA, 15, 1, 0),
++	SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0),
++	SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1),
++	SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0),
++	SOC_SINGLE("Silence", UDA1380_MIXER, 7, 1, 0),
++	SOC_SINGLE("Silence Detection", UDA1380_MIXER, 6, 1, 0),
++};
++
++/* add non dapm controls */
++static int uda1380_add_controls(struct snd_soc_codec *codec)
++{
++	int err, i;
++
++	for (i = 0; i < ARRAY_SIZE(uda1380_snd_controls); i++) {
++		err = snd_ctl_add(codec->card,
++			snd_soc_cnew(&uda1380_snd_controls[i],codec, NULL));
++		if (err < 0)
++			return err;
++	}
++
++	return 0;
++}
++
++/* Input mux */
++static const struct snd_kcontrol_new uda1380_input_mux_control =
++	SOC_DAPM_ENUM("Input Select", uda1380_enum[1]);
++
++/* Output mux */
++static const struct snd_kcontrol_new uda1380_output_mux_control =
++	SOC_DAPM_ENUM("Output Select", uda1380_enum[3]);
++
++static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
++	SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
++		&uda1380_input_mux_control),
++	SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0,
++		&uda1380_output_mux_control),
++	SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0),
++	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0),
++	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0),
++	SND_SOC_DAPM_INPUT("VINM"),
++	SND_SOC_DAPM_INPUT("VINL"),
++	SND_SOC_DAPM_INPUT("VINR"),
++	SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0),
++	SND_SOC_DAPM_OUTPUT("VOUTLHP"),
++	SND_SOC_DAPM_OUTPUT("VOUTRHP"),
++	SND_SOC_DAPM_OUTPUT("VOUTL"),
++	SND_SOC_DAPM_OUTPUT("VOUTR"),
++	SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0),
++	SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0),
++};
++
++static const char *audio_map[][3] = {
++
++	/* output mux */
++	{"HeadPhone Driver", NULL, "Output Mux"},
++	{"VOUTR", NULL, "Output Mux"},
++	{"VOUTL", NULL, "Output Mux"},
++
++	{"Analog Mixer", NULL, "VINR"},
++	{"Analog Mixer", NULL, "VINL"},
++	{"Analog Mixer", NULL, "DAC"},
++
++	{"Output Mux", "Direct", "DAC"},
++	{"Output Mux", "Mixer", "Analog Mixer"},
++
++	/* headphone driver */
++	{"VOUTLHP", NULL, "HeadPhone Driver"},
++	{"VOUTRHP", NULL, "HeadPhone Driver"},
++
++	/* input mux */
++	{"Left ADC", NULL, "Input Mux"},
++	{"Input Mux", "Mic", "Mic LNA"},
++	{"Input Mux", "Line", "Left PGA"},
++
++	/* right input */
++	{"Right ADC", NULL, "Right PGA"},
++
++	/* inputs */
++	{"Mic LNA", NULL, "VINM"},
++	{"Left PGA", NULL, "VINL"},
++	{"Right PGA", NULL, "VINR"},
++
++	/* terminator */
++	{NULL, NULL, NULL},
++};
++
++static int uda1380_add_widgets(struct snd_soc_codec *codec)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(uda1380_dapm_widgets); i++)
++		snd_soc_dapm_new_control(codec, &uda1380_dapm_widgets[i]);
++
++	/* set up audio path interconnects */
++	for (i = 0; audio_map[i][0] != NULL; i++)
++		snd_soc_dapm_connect_input(codec, audio_map[i][0],
++			audio_map[i][1], audio_map[i][2]);
++
++	snd_soc_dapm_new_widgets(codec);
++	return 0;
++}
++
++static int uda1380_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	int iface;
++	/* set up DAI based upon fmt */
++
++	iface = uda1380_read_reg_cache (codec, UDA1380_IFACE);
++	iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK);
++
++	/* FIXME: how to select I2S for DATAO and MSB for DATAI correctly? */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		iface |= R01_SFORI_I2S | R01_SFORO_I2S;
++		break;
++	case SND_SOC_DAIFMT_LSB:
++		iface |= R01_SFORI_LSB16 | R01_SFORO_I2S;
++		break;
++	case SND_SOC_DAIFMT_MSB:
++		iface |= R01_SFORI_MSB | R01_SFORO_I2S;
++	}
++
++	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM)
++		iface |= R01_SIM;
++
++	uda1380_write(codec, UDA1380_IFACE, iface);
++
++	return 0;
++}
++
++/*
++ * Flush reg cache
++ * We can only write the interpolator and decimator registers
++ * when the DAI is being clocked by the CPU DAI. It's up to the
++ * machine and cpu DAI driver to do this before we are called.
++ */
++static int uda1380_pcm_prepare(struct snd_pcm_substream *substream)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	int reg, reg_start, reg_end, clk;
++
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++		reg_start = UDA1380_MVOL;
++		reg_end = UDA1380_MIXER;
++	} else {
++		reg_start = UDA1380_DEC;
++		reg_end = UDA1380_AGC;
++	}
++
++	/* FIXME disable DAC_CLK */
++	clk = uda1380_read_reg_cache (codec, 00);
++	uda1380_write(codec, UDA1380_CLK, clk & ~R00_DAC_CLK);
++
++	for (reg = reg_start; reg <= reg_end; reg++ ) {
++		dbg("reg %x val %x\n",reg, uda1380_read_reg_cache (codec, reg));
++		uda1380_write(codec, reg, uda1380_read_reg_cache (codec, reg));
++	}
++
++	/* FIXME enable DAC_CLK */
++	uda1380_write(codec, UDA1380_CLK, clk | R00_DAC_CLK);
++
++	return 0;
++}
++
++static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
++
++	/* set WSPLL power and divider if running from this clock */
++	if (clk & R00_DAC_CLK) {
++		int rate = params_rate(params);
++		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
++		clk &= ~0x3; /* clear SEL_LOOP_DIV */
++		switch (rate) {
++		case 6250 ... 12500:
++			clk |= 0x0;
++			break;
++		case 12501 ... 25000:
++			clk |= 0x1;
++			break;
++		case 25001 ... 50000:
++			clk |= 0x2;
++			break;
++		case 50001 ... 100000:
++			clk |= 0x3;
++			break;
++		}
++		uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm);
++	}
++
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++		clk |= R00_EN_DAC | R00_EN_INT;
++	else
++		clk |= R00_EN_ADC | R00_EN_DEC;
++
++	uda1380_write(codec, UDA1380_CLK, clk);
++	return 0;
++}
++
++static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
++
++	/* shut down WSPLL power if running from this clock */
++	if (clk & R00_DAC_CLK) {
++		u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM);
++		uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm);
++	}
++
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++		clk &= ~(R00_EN_DAC | R00_EN_INT);
++	else
++		clk &= ~(R00_EN_ADC | R00_EN_DEC);
++
++	uda1380_write(codec, UDA1380_CLK, clk);
++}
++
++static int uda1380_mute(struct snd_soc_codec_dai *codec_dai, int mute)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 mute_reg = uda1380_read_reg_cache(codec, UDA1380_DEEMP) & 0xbfff;
++
++	/* FIXME: mute(codec,0) is called when the magician clock is already
++	 * set to WSPLL, but for some unknown reason writing to interpolator
++	 * registers works only when clocked by SYSCLK */
++	u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
++	uda1380_write(codec, UDA1380_CLK, ~R00_DAC_CLK & clk);
++	if (mute)
++		uda1380_write(codec, UDA1380_DEEMP, mute_reg | 0x4000);
++	else
++		uda1380_write(codec, UDA1380_DEEMP, mute_reg);
++	uda1380_write(codec, UDA1380_CLK, clk);
++	return 0;
++}
++
++static int uda1380_dapm_event(struct snd_soc_codec *codec, int event)
++{
++	int pm = uda1380_read_reg_cache(codec, UDA1380_PM);
++
++	switch (event) {
++	case SNDRV_CTL_POWER_D0: /* full On */
++	case SNDRV_CTL_POWER_D1: /* partial On */
++	case SNDRV_CTL_POWER_D2: /* partial On */
++		/* enable internal bias */
++		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
++		break;
++	case SNDRV_CTL_POWER_D3hot: /* Off, with power */
++		/* everything off except internal bias */
++		uda1380_write(codec, UDA1380_PM, R02_PON_BIAS);
++		break;
++	case SNDRV_CTL_POWER_D3cold: /* Off, without power */
++		/* everything off, inactive */
++		uda1380_write(codec, UDA1380_PM, 0x0);
++		break;
++	}
++	codec->dapm_state = event;
++	return 0;
++}
++
++#define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++		       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
++		       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
++
++struct snd_soc_codec_dai uda1380_dai[] = {
++{
++	.name = "UDA1380",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = UDA1380_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = UDA1380_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.ops = {
++		.hw_params = uda1380_pcm_hw_params,
++		.shutdown = uda1380_pcm_shutdown,
++		.prepare = uda1380_pcm_prepare,
++	},
++	.dai_ops = {
++		.digital_mute = uda1380_mute,
++		.set_fmt = uda1380_set_dai_fmt,
++	},
++},
++{/* playback only  - dual interface */
++	.name = "UDA1380",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = UDA1380_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,
++	},
++	.ops = {
++		.hw_params = uda1380_pcm_hw_params,
++		.shutdown = uda1380_pcm_shutdown,
++		.prepare = uda1380_pcm_prepare,
++	},
++	.dai_ops = {
++		.digital_mute = uda1380_mute,
++		.set_fmt = uda1380_set_dai_fmt,
++	},
++},
++{ /* capture only - dual interface*/
++	.name = "UDA1380",
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = UDA1380_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,
++	},
++	.ops = {
++		.hw_params = uda1380_pcm_hw_params,
++		.shutdown = uda1380_pcm_shutdown,
++		.prepare = uda1380_pcm_prepare,
++	},
++	.dai_ops = {
++		.set_fmt = uda1380_set_dai_fmt,
++	},
++},
++};
++EXPORT_SYMBOL_GPL(uda1380_dai);
++
++static int uda1380_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	uda1380_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++	return 0;
++}
++
++static int uda1380_resume(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++	int i;
++	u8 data[2];
++	u16 *cache = codec->reg_cache;
++
++	/* Sync reg_cache with the hardware */
++	for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) {
++		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
++		data[1] = cache[i] & 0x00ff;
++		codec->hw_write(codec->control_data, data, 2);
++	}
++	uda1380_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++	uda1380_dapm_event(codec, codec->suspend_dapm_state);
++	return 0;
++}
++
++/*
++ * initialise the UDA1380 driver
++ * register the mixer and dsp interfaces with the kernel
++ */
++static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
++{
++	struct snd_soc_codec *codec = socdev->codec;
++	int ret = 0;
++
++	codec->name = "UDA1380";
++	codec->owner = THIS_MODULE;
++	codec->read = uda1380_read_reg_cache;
++	codec->write = uda1380_write;
++	codec->dapm_event = uda1380_dapm_event;
++	codec->dai = uda1380_dai;
++	codec->num_dai = ARRAY_SIZE(uda1380_dai);
++	codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
++	codec->reg_cache =
++		kcalloc(ARRAY_SIZE(uda1380_reg), sizeof(u16), GFP_KERNEL);
++	if (codec->reg_cache == NULL)
++		return -ENOMEM;
++	memcpy(codec->reg_cache, uda1380_reg,
++	       sizeof(u16) * ARRAY_SIZE(uda1380_reg));
++	codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(uda1380_reg);
++	uda1380_reset(codec);
++
++	/* register pcms */
++	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++	if(ret < 0) {
++		printk(KERN_ERR "uda1380: failed to create pcms\n");
++		goto pcm_err;
++	}
++
++	/* power on device */
++	uda1380_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++	/* set clock input */
++	switch (dac_clk) {
++	case UDA1380_DAC_CLK_SYSCLK:
++		uda1380_write(codec, UDA1380_CLK, 0);
++		break;
++	case UDA1380_DAC_CLK_WSPLL:
++		uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK);
++		break;
++	}
++
++	/* uda1380 init */
++	uda1380_add_controls(codec);
++	uda1380_add_widgets(codec);
++	ret = snd_soc_register_card(socdev);
++	if (ret < 0) {
++		printk(KERN_ERR "uda1380: failed to register card\n");
++		goto card_err;
++	}
++
++	return ret;
++
++card_err:
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++pcm_err:
++	kfree(codec->reg_cache);
++	return ret;
++}
++
++static struct snd_soc_device *uda1380_socdev;
++
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++
++#define I2C_DRIVERID_UDA1380 0xfefe /* liam -  need a proper id */
++
++static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
++
++/* Magic definition of all other variables and things */
++I2C_CLIENT_INSMOD;
++
++static struct i2c_driver uda1380_i2c_driver;
++static struct i2c_client client_template;
++
++/* If the i2c layer weren't so broken, we could pass this kind of data
++   around */
++
++static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
++{
++	struct snd_soc_device *socdev = uda1380_socdev;
++	struct uda1380_setup_data *setup = socdev->codec_data;
++	struct snd_soc_codec *codec = socdev->codec;
++	struct i2c_client *i2c;
++	int ret;
++
++	if (addr != setup->i2c_address)
++		return -ENODEV;
++
++	client_template.adapter = adap;
++	client_template.addr = addr;
++
++	i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	if (i2c == NULL){
++		kfree(codec);
++		return -ENOMEM;
++	}
++	memcpy(i2c, &client_template, sizeof(struct i2c_client));
++	i2c_set_clientdata(i2c, codec);
++	codec->control_data = i2c;
++
++	ret = i2c_attach_client(i2c);
++	if (ret < 0) {
++		printk(KERN_ERR "failed to attach codec at addr %x\n", addr);
++		goto err;
++	}
++
++	ret = uda1380_init(socdev, setup->dac_clk);
++	if (ret < 0) {
++		printk(KERN_ERR "failed to initialise UDA1380\n");
++		goto err;
++	}
++	return ret;
++
++err:
++	kfree(codec);
++	kfree(i2c);
++	return ret;
++}
++
++static int uda1380_i2c_detach(struct i2c_client *client)
++{
++	struct snd_soc_codec* codec = i2c_get_clientdata(client);
++	i2c_detach_client(client);
++	kfree(codec->reg_cache);
++	kfree(client);
++	return 0;
++}
++
++static int uda1380_i2c_attach(struct i2c_adapter *adap)
++{
++	return i2c_probe(adap, &addr_data, uda1380_codec_probe);
++}
++
++/* corgi i2c codec control layer */
++static struct i2c_driver uda1380_i2c_driver = {
++	.driver = {
++		.name =  "UDA1380 I2C Codec",
++		.owner = THIS_MODULE,
++	},
++	.id =             I2C_DRIVERID_UDA1380,
++	.attach_adapter = uda1380_i2c_attach,
++	.detach_client =  uda1380_i2c_detach,
++	.command =        NULL,
++};
++
++static struct i2c_client client_template = {
++	.name =   "UDA1380",
++	.driver = &uda1380_i2c_driver,
++};
++#endif
++
++static int uda1380_probe(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct uda1380_setup_data *setup;
++	struct snd_soc_codec* codec;
++	int ret = 0;
++
++	printk(KERN_INFO "UDA1380 Audio Codec %s", UDA1380_VERSION);
++
++	setup = socdev->codec_data;
++	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
++	if (codec == NULL)
++		return -ENOMEM;
++
++	socdev->codec = codec;
++	mutex_init(&codec->mutex);
++	INIT_LIST_HEAD(&codec->dapm_widgets);
++	INIT_LIST_HEAD(&codec->dapm_paths);
++
++	uda1380_socdev = socdev;
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	if (setup->i2c_address) {
++		normal_i2c[0] = setup->i2c_address;
++		codec->hw_write = (hw_write_t)i2c_master_send;
++		ret = i2c_add_driver(&uda1380_i2c_driver);
++		if (ret != 0)
++			printk(KERN_ERR "can't add i2c driver");
++	}
++#else
++	/* Add other interfaces here */
++#endif
++	return ret;
++}
++
++/* power down chip */
++static int uda1380_remove(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec* codec = socdev->codec;
++
++	if (codec->control_data)
++		uda1380_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	i2c_del_driver(&uda1380_i2c_driver);
++#endif
++	kfree(codec);
++
++	return 0;
++}
++
++struct snd_soc_codec_device soc_codec_dev_uda1380 = {
++	.probe = 	uda1380_probe,
++	.remove = 	uda1380_remove,
++	.suspend = 	uda1380_suspend,
++	.resume =	uda1380_resume,
++};
++
++EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
++
++MODULE_AUTHOR("Giorgio Padrin");
++MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.22.1/sound/soc/codecs/uda1380.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/uda1380.h	2007-07-16 15:07:33.892268682 +0200
+@@ -0,0 +1,89 @@
++/*
++ * Audio support for Philips UDA1380
++ *
++ * 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) 2005 Giorgio Padrin <giorgio at mandarinlogiq.org>
++ */
++
++#ifndef _UDA1380_H
++#define _UDA1380_H
++
++#define UDA1380_CLK	0x00
++#define UDA1380_IFACE	0x01
++#define UDA1380_PM	0x02
++#define UDA1380_AMIX	0x03
++#define UDA1380_HP	0x04
++#define UDA1380_MVOL	0x10
++#define UDA1380_MIXVOL	0x11
++#define UDA1380_MODE	0x12
++#define UDA1380_DEEMP	0x13
++#define UDA1380_MIXER	0x14
++#define UDA1380_INTSTAT	0x18
++#define UDA1380_DEC	0x20
++#define UDA1380_PGA	0x21
++#define UDA1380_ADC	0x22
++#define UDA1380_AGC	0x23
++#define UDA1380_DECSTAT	0x28
++#define UDA1380_RESET	0x7f
++
++#define UDA1380_CACHEREGNUM 0x24
++
++/* Register flags */
++#define R00_EN_ADC	0x0800
++#define R00_EN_DEC	0x0400
++#define R00_EN_DAC	0x0200
++#define R00_EN_INT	0x0100
++#define R00_DAC_CLK	0x0010
++#define R01_SFORI_I2S   0x0000
++#define R01_SFORI_LSB16 0x0100
++#define R01_SFORI_LSB18 0x0200
++#define R01_SFORI_LSB20 0x0300
++#define R01_SFORI_MSB   0x0500
++#define R01_SFORI_MASK  0x0700
++#define R01_SFORO_I2S   0x0000
++#define R01_SFORO_LSB16 0x0001
++#define R01_SFORO_LSB18 0x0002
++#define R01_SFORO_LSB20 0x0003
++#define R01_SFORO_LSB24 0x0004
++#define R01_SFORO_MSB   0x0005
++#define R01_SFORO_MASK  0x0007
++#define R01_SEL_SOURCE  0x0040
++#define R01_SIM		0x0010
++#define R02_PON_PLL	0x8000
++#define R02_PON_HP	0x2000
++#define R02_PON_DAC	0x0400
++#define R02_PON_BIAS	0x0100
++#define R02_EN_AVC	0x0080
++#define R02_PON_AVC	0x0040
++#define R02_PON_LNA	0x0010
++#define R02_PON_PGAL	0x0008
++#define R02_PON_ADCL	0x0004
++#define R02_PON_PGAR	0x0002
++#define R02_PON_ADCR	0x0001
++#define R13_MTM		0x4000
++#define R14_SILENCE	0x0080
++#define R14_SDET_ON	0x0040
++#define R21_MT_ADC	0x8000
++#define R22_SEL_LNA	0x0008
++#define R22_SEL_MIC	0x0004
++#define R22_SKIP_DCFIL	0x0002
++#define R23_AGC_EN	0x0001
++
++struct uda1380_setup_data {
++	unsigned short i2c_address;
++	int            dac_clk;
++#define UDA1380_DAC_CLK_SYSCLK 0
++#define UDA1380_DAC_CLK_WSPLL  1
++};
++
++#define UDA1380_DAI_DUPLEX	0 /* playback and capture on single DAI */
++#define UDA1380_DAI_PLAYBACK	1 /* playback DAI */
++#define UDA1380_DAI_CAPTURE	2 /* capture DAI */
++
++extern struct snd_soc_codec_dai uda1380_dai[3];
++extern struct snd_soc_codec_device soc_codec_dev_uda1380;
++
++#endif /* _UDA1380_H */
+Index: linux-2.6.22.1/sound/soc/codecs/wm8772.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/wm8772.c	2007-07-16 15:07:33.996274607 +0200
+@@ -0,0 +1,603 @@
++/*
++ * wm8772.c  --  WM8772 ALSA Soc Audio driver
++ *
++ * Copyright 2005 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ *         liam.girdwood at wolfsonmicro.com or linux at wolfsonmicro.com
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++
++#include "wm8772.h"
++
++#define AUDIO_NAME "WM8772"
++#define WM8772_VERSION "0.4"
++
++/* codec private data */
++struct wm8772_priv {
++	unsigned int adcclk;
++	unsigned int dacclk;
++};
++
++/*
++ * wm8772 register cache
++ * We can't read the WM8772 register space when we
++ * are using 2 wire for device control, so we cache them instead.
++ */
++static const u16 wm8772_reg[] = {
++	0x00ff, 0x00ff, 0x0120, 0x0000,  /*  0 */
++	0x00ff, 0x00ff, 0x00ff, 0x00ff,  /*  4 */
++	0x00ff, 0x0000, 0x0080, 0x0040,  /*  8 */
++	0x0000
++};
++
++/*
++ * read wm8772 register cache
++ */
++static inline unsigned int wm8772_read_reg_cache(struct snd_soc_codec * codec,
++	unsigned int reg)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg > WM8772_CACHE_REGNUM)
++		return -1;
++	return cache[reg];
++}
++
++/*
++ * write wm8772 register cache
++ */
++static inline void wm8772_write_reg_cache(struct snd_soc_codec * codec,
++	unsigned int reg, unsigned int value)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg > WM8772_CACHE_REGNUM)
++		return;
++	cache[reg] = value;
++}
++
++static int wm8772_write(struct snd_soc_codec * codec, unsigned int reg,
++	unsigned int value)
++{
++	u8 data[2];
++
++	/* data is
++	 *   D15..D9 WM8772 register offset
++	 *   D8...D0 register data
++	 */
++	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
++	data[1] = value & 0x00ff;
++
++	wm8772_write_reg_cache (codec, reg, value);
++	if (codec->hw_write(codec->control_data, data, 2) == 2)
++		return 0;
++	else
++		return -1;
++}
++
++#define wm8772_reset(c)	wm8772_write(c, WM8772_RESET, 0)
++
++/*
++ * WM8772 Controls
++ */
++static const char *wm8772_zero_flag[] = {"All Ch", "Ch 1", "Ch 2", "Ch3"};
++
++static const struct soc_enum wm8772_enum[] = {
++SOC_ENUM_SINGLE(WM8772_DACCTRL, 0, 4, wm8772_zero_flag),
++};
++
++static const struct snd_kcontrol_new wm8772_snd_controls[] = {
++
++SOC_SINGLE("Left1 Playback Volume", WM8772_LDAC1VOL, 0, 255, 0),
++SOC_SINGLE("Left2 Playback Volume", WM8772_LDAC2VOL, 0, 255, 0),
++SOC_SINGLE("Left3 Playback Volume", WM8772_LDAC3VOL, 0, 255, 0),
++SOC_SINGLE("Right1 Playback Volume", WM8772_RDAC1VOL, 0, 255, 0),
++SOC_SINGLE("Right1 Playback Volume", WM8772_RDAC2VOL, 0, 255, 0),
++SOC_SINGLE("Right1 Playback Volume", WM8772_RDAC3VOL, 0, 255, 0),
++SOC_SINGLE("Master Playback Volume", WM8772_MDACVOL, 0, 255, 0),
++
++SOC_SINGLE("Playback Switch", WM8772_DACCH, 0, 1, 0),
++SOC_SINGLE("Capture Switch", WM8772_ADCCTRL, 2, 1, 0),
++
++SOC_SINGLE("Demp1 Playback Switch", WM8772_DACCTRL, 6, 1, 0),
++SOC_SINGLE("Demp2 Playback Switch", WM8772_DACCTRL, 7, 1, 0),
++SOC_SINGLE("Demp3 Playback Switch", WM8772_DACCTRL, 8, 1, 0),
++
++SOC_SINGLE("Phase Invert 1 Switch", WM8772_IFACE, 6, 1, 0),
++SOC_SINGLE("Phase Invert 2 Switch", WM8772_IFACE, 7, 1, 0),
++SOC_SINGLE("Phase Invert 3 Switch", WM8772_IFACE, 8, 1, 0),
++
++SOC_SINGLE("Playback ZC Switch", WM8772_DACCTRL, 0, 1, 0),
++
++SOC_SINGLE("Capture High Pass Switch", WM8772_ADCCTRL, 3, 1, 0),
++};
++
++/* add non dapm controls */
++static int wm8772_add_controls(struct snd_soc_codec *codec)
++{
++	int err, i;
++
++	for (i = 0; i < ARRAY_SIZE(wm8772_snd_controls); i++) {
++		err = snd_ctl_add(codec->card,
++				snd_soc_cnew(&wm8772_snd_controls[i],codec, NULL));
++		if (err < 0)
++			return err;
++	}
++	return 0;
++}
++
++static int wm8772_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
++		int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct wm8772_priv *wm8772 = codec->private_data;
++
++	switch (freq) {
++	case 4096000:
++	case 5644800:
++	case 6144000:
++	case 8192000:
++	case 8467000:
++	case 9216000:
++	case 11289600:
++	case 12000000:
++	case 12288000:
++	case 16934400:
++	case 18432000:
++	case 22579200:
++	case 24576000:
++	case 33868800:
++	case 36864000:
++		if (clk_id == WM8772_DACCLK) {
++			wm8772->dacclk = freq;
++			return 0;
++		} else if (clk_id == WM8772_ADCCLK) {
++			wm8772->adcclk = freq;
++			return 0;
++		}
++	}
++	return -EINVAL;
++}
++
++static int wm8772_set_dac_dai_fmt(struct snd_soc_codec_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 diface = wm8772_read_reg_cache(codec, WM8772_IFACE) & 0x1f0;
++	u16 diface_ctrl = wm8772_read_reg_cache(codec, WM8772_DACRATE) & 0x1ef;
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		diface_ctrl |= 0x0010;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		diface |= 0x0002;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		diface |= 0x0001;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		diface |= 0x0003;
++		break;
++	case SND_SOC_DAIFMT_DSP_B:
++		diface |= 0x0007;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		diface |= 0x0008;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	wm8772_write(codec, WM8772_DACRATE, diface_ctrl);
++	wm8772_write(codec, WM8772_IFACE, diface);
++	return 0;
++}
++
++static int wm8772_set_adc_dai_fmt(struct snd_soc_codec_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 aiface = 0;
++	u16 aiface_ctrl = wm8772_read_reg_cache(codec, WM8772_ADCCTRL) & 0x1cf;
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		aiface |= 0x0010;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		aiface |= 0x0002;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		aiface |= 0x0001;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		aiface |= 0x0003;
++		break;
++	case SND_SOC_DAIFMT_DSP_B:
++		aiface |= 0x0003;
++		aiface_ctrl |= 0x0010;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		aiface_ctrl |= 0x0020;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	wm8772_write(codec, WM8772_ADCCTRL, aiface_ctrl);
++	wm8772_write(codec, WM8772_ADCRATE, aiface);
++	return 0;
++}
++
++static int wm8772_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	struct wm8772_priv *wm8772 = codec->private_data;
++
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
++
++		u16 diface = wm8772_read_reg_cache(codec, WM8772_IFACE) & 0x1cf;
++		u16 diface_ctrl = wm8772_read_reg_cache(codec, WM8772_DACRATE) & 0x3f;
++
++		/* bit size */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			diface |= 0x0010;
++			break;
++		case SNDRV_PCM_FORMAT_S24_3LE:
++			diface |= 0x0020;
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			diface |= 0x0030;
++			break;
++		}
++
++		/* set rate */
++		switch (wm8772->dacclk / params_rate(params)) {
++		case 768:
++			diface_ctrl |= (0x5 << 6);
++			break;
++		case 512:
++			diface_ctrl |= (0x4 << 6);
++			break;
++		case 384:
++			diface_ctrl |= (0x3 << 6);
++			break;
++		case 256:
++			diface_ctrl |= (0x2 << 6);
++			break;
++		case 192:
++			diface_ctrl |= (0x1 << 6);
++			break;
++		}
++
++		wm8772_write(codec, WM8772_DACRATE, diface_ctrl);
++		wm8772_write(codec, WM8772_IFACE, diface);
++
++	} else {
++
++		u16 aiface = wm8772_read_reg_cache(codec, WM8772_ADCRATE) & 0x113;
++
++		/* bit size */
++		switch (params_format(params)) {
++		case SNDRV_PCM_FORMAT_S16_LE:
++			break;
++		case SNDRV_PCM_FORMAT_S20_3LE:
++			aiface |= 0x0004;
++			break;
++		case SNDRV_PCM_FORMAT_S24_LE:
++			aiface |= 0x0008;
++			break;
++		case SNDRV_PCM_FORMAT_S32_LE:
++			aiface |= 0x000c;
++			break;
++		}
++
++		/* set rate */
++		switch (wm8772->adcclk / params_rate(params)) {
++		case 768:
++			aiface |= (0x5 << 5);
++			break;
++		case 512:
++			aiface |= (0x4 << 5);
++			break;
++		case 384:
++			aiface |= (0x3 << 5);
++			break;
++		case 256:
++			aiface |= (0x2 << 5);
++			break;
++		}
++
++		wm8772_write(codec, WM8772_ADCRATE, aiface);
++	}
++
++	return 0;
++}
++
++static int wm8772_dapm_event(struct snd_soc_codec *codec, int event)
++{
++	u16 master = wm8772_read_reg_cache(codec, WM8772_DACRATE) & 0xffe0;
++
++	switch (event) {
++		case SNDRV_CTL_POWER_D0: /* full On */
++			/* vref/mid, clk and osc on, dac unmute, active */
++			wm8772_write(codec, WM8772_DACRATE, master);
++			break;
++		case SNDRV_CTL_POWER_D1: /* partial On */
++		case SNDRV_CTL_POWER_D2: /* partial On */
++			break;
++		case SNDRV_CTL_POWER_D3hot: /* Off, with power */
++			/* everything off except vref/vmid, dac mute, inactive */
++			wm8772_write(codec, WM8772_DACRATE, master | 0x0f);
++			break;
++		case SNDRV_CTL_POWER_D3cold: /* Off, without power */
++			/* everything off, dac mute, inactive */
++			wm8772_write(codec, WM8772_DACRATE, master | 0x1f);
++			break;
++	}
++	codec->dapm_state = event;
++	return 0;
++}
++
++struct snd_soc_codec_dai wm8772_dai[] = {
++{
++	.name = "WM8772",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 2,
++		.channels_max = 6,
++	},
++	.ops = {
++		.hw_params = wm8772_hw_params,
++	},
++	.dai_ops = {
++		.set_fmt = wm8772_set_dac_dai_fmt,
++		.set_sysclk = wm8772_set_dai_sysclk,
++	},
++},
++{
++	.name = "WM8772",
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 2,
++		.channels_max = 2,
++	},
++	.ops = {
++		.hw_params = wm8772_hw_params,
++	},
++	.dai_ops = {
++		.set_fmt = wm8772_set_adc_dai_fmt,
++		.set_sysclk = wm8772_set_dai_sysclk,
++	},
++},
++};
++EXPORT_SYMBOL_GPL(wm8772_dai);
++
++static int wm8772_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	wm8772_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++	return 0;
++}
++
++static int wm8772_resume(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++	int i;
++	u8 data[2];
++	u16 *cache = codec->reg_cache;
++
++	/* Sync reg_cache with the hardware */
++	for (i = 0; i < ARRAY_SIZE(wm8772_reg); i++) {
++		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
++		data[1] = cache[i] & 0x00ff;
++		codec->hw_write(codec->control_data, data, 2);
++	}
++	wm8772_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++	wm8772_dapm_event(codec, codec->suspend_dapm_state);
++	return 0;
++}
++
++/*
++ * initialise the WM8772 driver
++ * register the mixer and dsp interfaces with the kernel
++ */
++static int wm8772_init(struct snd_soc_device *socdev)
++{
++	struct snd_soc_codec *codec = socdev->codec;
++	int reg, ret = 0;
++
++	codec->name = "WM8772";
++	codec->owner = THIS_MODULE;
++	codec->read = wm8772_read_reg_cache;
++	codec->write = wm8772_write;
++	codec->dapm_event = wm8772_dapm_event;
++	codec->dai = wm8772_dai;
++	codec->num_dai = 1;
++	codec->reg_cache_size = ARRAY_SIZE(wm8772_reg);
++	codec->reg_cache =
++			kzalloc(sizeof(u16) * ARRAY_SIZE(wm8772_reg), GFP_KERNEL);
++	if (codec->reg_cache == NULL)
++		return -ENOMEM;
++	memcpy(codec->reg_cache, wm8772_reg,
++		sizeof(u16) * ARRAY_SIZE(wm8772_reg));
++	codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm8772_reg);
++
++	wm8772_reset(codec);
++
++	/* register pcms */
++	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++	if(ret < 0) {
++		printk(KERN_ERR "wm8772: failed to create pcms\n");
++		goto pcm_err;
++	}
++
++	/* power on device */
++	wm8772_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++
++	/* set the update bits */
++	reg = wm8772_read_reg_cache(codec, WM8772_MDACVOL);
++	wm8772_write(codec, WM8772_MDACVOL, reg | 0x0100);
++	reg = wm8772_read_reg_cache(codec, WM8772_LDAC1VOL);
++	wm8772_write(codec, WM8772_LDAC1VOL, reg | 0x0100);
++	reg = wm8772_read_reg_cache(codec, WM8772_LDAC2VOL);
++	wm8772_write(codec, WM8772_LDAC2VOL, reg | 0x0100);
++	reg = wm8772_read_reg_cache(codec, WM8772_LDAC3VOL);
++	wm8772_write(codec, WM8772_LDAC3VOL, reg | 0x0100);
++	reg = wm8772_read_reg_cache(codec, WM8772_RDAC1VOL);
++	wm8772_write(codec, WM8772_RDAC1VOL, reg | 0x0100);
++	reg = wm8772_read_reg_cache(codec, WM8772_RDAC2VOL);
++	wm8772_write(codec, WM8772_RDAC2VOL, reg | 0x0100);
++	reg = wm8772_read_reg_cache(codec, WM8772_RDAC3VOL);
++	wm8772_write(codec, WM8772_RDAC3VOL, reg | 0x0100);
++
++	wm8772_add_controls(codec);
++	ret = snd_soc_register_card(socdev);
++	if (ret < 0) {
++      	printk(KERN_ERR "wm8772: failed to register card\n");
++		goto card_err;
++    }
++	return ret;
++
++card_err:
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++pcm_err:
++	kfree(codec->reg_cache);
++	return ret;
++}
++
++static struct snd_soc_device *wm8772_socdev;
++
++static int wm8772_probe(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct wm8772_setup_data *setup;
++	struct snd_soc_codec *codec;
++	struct wm8772_priv *wm8772;
++	int ret = 0;
++
++	printk(KERN_INFO "WM8772 Audio Codec %s", WM8772_VERSION);
++
++	setup = socdev->codec_data;
++	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
++	if (codec == NULL)
++		return -ENOMEM;
++
++	wm8772 = kzalloc(sizeof(struct wm8772_priv), GFP_KERNEL);
++	if (wm8772 == NULL) {
++		kfree(codec);
++		return -ENOMEM;
++	}
++
++	codec->private_data = wm8772;
++	socdev->codec = codec;
++	mutex_init(&codec->mutex);
++	INIT_LIST_HEAD(&codec->dapm_widgets);
++	INIT_LIST_HEAD(&codec->dapm_paths);
++
++	wm8772_socdev = socdev;
++
++	/* Add other interfaces here */
++#warning do SPI device probe here and then call wm8772_init()
++
++	return ret;
++}
++
++/* power down chip */
++static int wm8772_remove(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	if (codec->control_data)
++		wm8772_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++
++	snd_soc_free_pcms(socdev);
++	kfree(codec->private_data);
++	kfree(codec->reg_cache);
++	kfree(codec);
++
++	return 0;
++}
++
++struct snd_soc_codec_device soc_codec_dev_wm8772 = {
++	.probe = 	wm8772_probe,
++	.remove = 	wm8772_remove,
++	.suspend = 	wm8772_suspend,
++	.resume =	wm8772_resume,
++};
++
++EXPORT_SYMBOL_GPL(soc_codec_dev_wm8772);
++
++MODULE_DESCRIPTION("ASoC WM8772 driver");
++MODULE_AUTHOR("Liam Girdwood");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.22.1/sound/soc/codecs/wm8772.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/wm8772.h	2007-07-16 15:07:34.016275747 +0200
+@@ -0,0 +1,46 @@
++/*
++ * wm8772.h  --  audio driver for WM8772
++ *
++ * Copyright 2005 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ *         liam.girdwood at wolfsonmicro.com or linux at wolfsonmicro.com
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ */
++
++#ifndef _WM8772_H
++#define _WM8772_H
++
++/* WM8772 register space */
++
++#define WM8772_LDAC1VOL   0x00
++#define WM8772_RDAC1VOL   0x01
++#define WM8772_DACCH      0x02
++#define WM8772_IFACE      0x03
++#define WM8772_LDAC2VOL   0x04
++#define WM8772_RDAC2VOL   0x05
++#define WM8772_LDAC3VOL   0x06
++#define WM8772_RDAC3VOL   0x07
++#define WM8772_MDACVOL    0x08
++#define WM8772_DACCTRL    0x09
++#define WM8772_DACRATE    0x0a
++#define WM8772_ADCRATE    0x0b
++#define WM8772_ADCCTRL    0x0c
++#define WM8772_RESET	  0x1f
++
++#define WM8772_CACHE_REGNUM 	10
++
++#define WM8772_DACCLK	0
++#define WM8772_ADCCLK	1
++
++#define WM8753_DAI_DAC		0
++#define WM8753_DAI_ADC		1
++
++extern struct snd_soc_codec_dai wm8772_dai[2];
++extern struct snd_soc_codec_device soc_codec_dev_wm8772;
++
++#endif
+Index: linux-2.6.22.1/sound/soc/codecs/wm8971.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/wm8971.c	2007-07-16 15:07:34.028276432 +0200
+@@ -0,0 +1,971 @@
++/*
++ * wm8971.c  --  WM8971 ALSA SoC Audio driver
++ *
++ * Copyright 2005 Lab126, Inc.
++ *
++ * Author: Kenneth Kiraly <kiraly at lab126.com>
++ *
++ * Based on wm8753.c by Liam Girdwood
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++
++#include "wm8971.h"
++
++#define AUDIO_NAME "wm8971"
++#define WM8971_VERSION "0.9"
++
++#undef	WM8971_DEBUG
++
++#ifdef WM8971_DEBUG
++#define dbg(format, arg...) \
++	printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
++#else
++#define dbg(format, arg...) do {} while (0)
++#endif
++#define err(format, arg...) \
++	printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
++#define info(format, arg...) \
++	printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
++#define warn(format, arg...) \
++	printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
++
++#define	WM8971_REG_COUNT		43
++
++static struct workqueue_struct *wm8971_workq = NULL;
++
++/* codec private data */
++struct wm8971_priv {
++	unsigned int sysclk;
++};
++
++/*
++ * wm8971 register cache
++ * We can't read the WM8971 register space when we
++ * are using 2 wire for device control, so we cache them instead.
++ */
++static const u16 wm8971_reg[] = {
++	0x0097, 0x0097, 0x0079, 0x0079,  /*  0 */
++	0x0000, 0x0008, 0x0000, 0x000a,  /*  4 */
++	0x0000, 0x0000, 0x00ff, 0x00ff,  /*  8 */
++	0x000f, 0x000f, 0x0000, 0x0000,  /* 12 */
++	0x0000, 0x007b, 0x0000, 0x0032,  /* 16 */
++	0x0000, 0x00c3, 0x00c3, 0x00c0,  /* 20 */
++	0x0000, 0x0000, 0x0000, 0x0000,  /* 24 */
++	0x0000, 0x0000, 0x0000, 0x0000,  /* 28 */
++	0x0000, 0x0000, 0x0050, 0x0050,  /* 32 */
++	0x0050, 0x0050, 0x0050, 0x0050,  /* 36 */
++	0x0079, 0x0079, 0x0079,          /* 40 */
++};
++
++static inline unsigned int wm8971_read_reg_cache(struct snd_soc_codec *codec,
++	unsigned int reg)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg < WM8971_REG_COUNT)
++		return cache[reg];
++
++	return -1;
++}
++
++static inline void wm8971_write_reg_cache(struct snd_soc_codec *codec,
++	unsigned int reg, unsigned int value)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg < WM8971_REG_COUNT)
++		cache[reg] = value;
++}
++
++static int wm8971_write(struct snd_soc_codec *codec, unsigned int reg,
++	unsigned int value)
++{
++	u8 data[2];
++
++	/* data is
++	 *   D15..D9 WM8753 register offset
++	 *   D8...D0 register data
++	 */
++	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
++	data[1] = value & 0x00ff;
++
++	wm8971_write_reg_cache (codec, reg, value);
++	if (codec->hw_write(codec->control_data, data, 2) == 2)
++		return 0;
++	else
++		return -EIO;
++}
++
++#define wm8971_reset(c)	wm8971_write(c, WM8971_RESET, 0)
++
++/* WM8971 Controls */
++static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
++static const char *wm8971_bass_filter[] = { "130Hz @ 48kHz",
++	"200Hz @ 48kHz" };
++static const char *wm8971_treble[] = { "8kHz", "4kHz" };
++static const char *wm8971_alc_func[] = { "Off", "Right", "Left", "Stereo" };
++static const char *wm8971_ng_type[] = { "Constant PGA Gain",
++	"Mute ADC Output" };
++static const char *wm8971_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
++static const char *wm8971_mono_mux[] = {"Stereo", "Mono (Left)",
++	"Mono (Right)", "Digital Mono"};
++static const char *wm8971_dac_phase[] = { "Non Inverted", "Inverted" };
++static const char *wm8971_lline_mux[] = {"Line", "NC", "NC", "PGA",
++	"Differential"};
++static const char *wm8971_rline_mux[] = {"Line", "Mic", "NC", "PGA",
++	"Differential"};
++static const char *wm8971_lpga_sel[] = {"Line", "NC", "NC", "Differential"};
++static const char *wm8971_rpga_sel[] = {"Line", "Mic", "NC", "Differential"};
++static const char *wm8971_adcpol[] = {"Normal", "L Invert", "R Invert",
++	"L + R Invert"};
++
++static const struct soc_enum wm8971_enum[] = {
++	SOC_ENUM_SINGLE(WM8971_BASS, 7, 2, wm8971_bass),			/* 0 */
++	SOC_ENUM_SINGLE(WM8971_BASS, 6, 2, wm8971_bass_filter),
++	SOC_ENUM_SINGLE(WM8971_TREBLE, 6, 2, wm8971_treble),
++	SOC_ENUM_SINGLE(WM8971_ALC1, 7, 4, wm8971_alc_func),
++	SOC_ENUM_SINGLE(WM8971_NGATE, 1, 2, wm8971_ng_type),        /* 4 */
++	SOC_ENUM_SINGLE(WM8971_ADCDAC, 1, 4, wm8971_deemp),
++	SOC_ENUM_SINGLE(WM8971_ADCTL1, 4, 4, wm8971_mono_mux),
++	SOC_ENUM_SINGLE(WM8971_ADCTL1, 1, 2, wm8971_dac_phase),
++	SOC_ENUM_SINGLE(WM8971_LOUTM1, 0, 5, wm8971_lline_mux),     /* 8 */
++	SOC_ENUM_SINGLE(WM8971_ROUTM1, 0, 5, wm8971_rline_mux),
++	SOC_ENUM_SINGLE(WM8971_LADCIN, 6, 4, wm8971_lpga_sel),
++	SOC_ENUM_SINGLE(WM8971_RADCIN, 6, 4, wm8971_rpga_sel),
++	SOC_ENUM_SINGLE(WM8971_ADCDAC, 5, 4, wm8971_adcpol),        /* 12 */
++	SOC_ENUM_SINGLE(WM8971_ADCIN, 6, 4, wm8971_mono_mux),
++};
++
++static const struct snd_kcontrol_new wm8971_snd_controls[] = {
++	SOC_DOUBLE_R("Capture Volume", WM8971_LINVOL, WM8971_RINVOL, 0, 63, 0),
++	SOC_DOUBLE_R("Capture ZC Switch", WM8971_LINVOL, WM8971_RINVOL, 6, 1, 0),
++	SOC_DOUBLE_R("Capture Switch", WM8971_LINVOL, WM8971_RINVOL, 7, 1, 1),
++
++	SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8971_LOUT1V,
++		WM8971_ROUT1V, 7, 1, 0),
++	SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8971_LOUT2V,
++		WM8971_ROUT2V, 7, 1, 0),
++	SOC_SINGLE("Mono Playback ZC Switch", WM8971_MOUTV, 7, 1, 0),
++
++	SOC_DOUBLE_R("PCM Volume", WM8971_LDAC, WM8971_RDAC, 0, 255, 0),
++
++	SOC_DOUBLE_R("Bypass Left Playback Volume", WM8971_LOUTM1,
++		WM8971_LOUTM2, 4, 7, 1),
++	SOC_DOUBLE_R("Bypass Right Playback Volume", WM8971_ROUTM1,
++		WM8971_ROUTM2, 4, 7, 1),
++	SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8971_MOUTM1,
++		WM8971_MOUTM2, 4, 7, 1),
++
++	SOC_DOUBLE_R("Headphone Playback Volume", WM8971_LOUT1V,
++		WM8971_ROUT1V, 0, 127, 0),
++	SOC_DOUBLE_R("Speaker Playback Volume", WM8971_LOUT2V,
++		WM8971_ROUT2V, 0, 127, 0),
++
++	SOC_ENUM("Bass Boost", wm8971_enum[0]),
++	SOC_ENUM("Bass Filter", wm8971_enum[1]),
++	SOC_SINGLE("Bass Volume", WM8971_BASS, 0, 7, 1),
++
++	SOC_SINGLE("Treble Volume", WM8971_TREBLE, 0, 7, 0),
++	SOC_ENUM("Treble Cut-off", wm8971_enum[2]),
++
++	SOC_SINGLE("Capture Filter Switch", WM8971_ADCDAC, 0, 1, 1),
++
++	SOC_SINGLE("ALC Target Volume", WM8971_ALC1, 0, 7, 0),
++	SOC_SINGLE("ALC Max Volume", WM8971_ALC1, 4, 7, 0),
++
++	SOC_SINGLE("ALC Capture Target Volume", WM8971_ALC1, 0, 7, 0),
++	SOC_SINGLE("ALC Capture Max Volume", WM8971_ALC1, 4, 7, 0),
++	SOC_ENUM("ALC Capture Function", wm8971_enum[3]),
++	SOC_SINGLE("ALC Capture ZC Switch", WM8971_ALC2, 7, 1, 0),
++	SOC_SINGLE("ALC Capture Hold Time", WM8971_ALC2, 0, 15, 0),
++	SOC_SINGLE("ALC Capture Decay Time", WM8971_ALC3, 4, 15, 0),
++	SOC_SINGLE("ALC Capture Attack Time", WM8971_ALC3, 0, 15, 0),
++	SOC_SINGLE("ALC Capture NG Threshold", WM8971_NGATE, 3, 31, 0),
++	SOC_ENUM("ALC Capture NG Type", wm8971_enum[4]),
++	SOC_SINGLE("ALC Capture NG Switch", WM8971_NGATE, 0, 1, 0),
++
++	SOC_SINGLE("Capture 6dB Attenuate", WM8971_ADCDAC, 8, 1, 0),
++	SOC_SINGLE("Playback 6dB Attenuate", WM8971_ADCDAC, 7, 1, 0),
++
++    SOC_ENUM("Playback De-emphasis", wm8971_enum[5]),
++	SOC_ENUM("Playback Function", wm8971_enum[6]),
++	SOC_ENUM("Playback Phase", wm8971_enum[7]),
++
++	SOC_DOUBLE_R("Mic Boost", WM8971_LADCIN, WM8971_RADCIN, 4, 3, 0),
++};
++
++/* add non-DAPM controls */
++static int wm8971_add_controls(struct snd_soc_codec *codec)
++{
++	int err, i;
++
++	for (i = 0; i < ARRAY_SIZE(wm8971_snd_controls); i++) {
++		err = snd_ctl_add(codec->card,
++				snd_soc_cnew(&wm8971_snd_controls[i],codec, NULL));
++		if (err < 0)
++			return err;
++	}
++	return 0;
++}
++
++/*
++ * DAPM Controls
++ */
++
++/* Left Mixer */
++static const struct snd_kcontrol_new wm8971_left_mixer_controls[] = {
++SOC_DAPM_SINGLE("Playback Switch", WM8971_LOUTM1, 8, 1, 0),
++SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_LOUTM1, 7, 1, 0),
++SOC_DAPM_SINGLE("Right Playback Switch", WM8971_LOUTM2, 8, 1, 0),
++SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_LOUTM2, 7, 1, 0),
++};
++
++/* Right Mixer */
++static const struct snd_kcontrol_new wm8971_right_mixer_controls[] = {
++SOC_DAPM_SINGLE("Left Playback Switch", WM8971_ROUTM1, 8, 1, 0),
++SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_ROUTM1, 7, 1, 0),
++SOC_DAPM_SINGLE("Playback Switch", WM8971_ROUTM2, 8, 1, 0),
++SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_ROUTM2, 7, 1, 0),
++};
++
++/* Mono Mixer */
++static const struct snd_kcontrol_new wm8971_mono_mixer_controls[] = {
++SOC_DAPM_SINGLE("Left Playback Switch", WM8971_MOUTM1, 8, 1, 0),
++SOC_DAPM_SINGLE("Left Bypass Switch", WM8971_MOUTM1, 7, 1, 0),
++SOC_DAPM_SINGLE("Right Playback Switch", WM8971_MOUTM2, 8, 1, 0),
++SOC_DAPM_SINGLE("Right Bypass Switch", WM8971_MOUTM2, 7, 1, 0),
++};
++
++/* Left Line Mux */
++static const struct snd_kcontrol_new wm8971_left_line_controls =
++SOC_DAPM_ENUM("Route", wm8971_enum[8]);
++
++/* Right Line Mux */
++static const struct snd_kcontrol_new wm8971_right_line_controls =
++SOC_DAPM_ENUM("Route", wm8971_enum[9]);
++
++/* Left PGA Mux */
++static const struct snd_kcontrol_new wm8971_left_pga_controls =
++SOC_DAPM_ENUM("Route", wm8971_enum[10]);
++
++/* Right PGA Mux */
++static const struct snd_kcontrol_new wm8971_right_pga_controls =
++SOC_DAPM_ENUM("Route", wm8971_enum[11]);
++
++/* Mono ADC Mux */
++static const struct snd_kcontrol_new wm8971_monomux_controls =
++SOC_DAPM_ENUM("Route", wm8971_enum[13]);
++
++static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
++	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
++		&wm8971_left_mixer_controls[0],
++		ARRAY_SIZE(wm8971_left_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
++		&wm8971_right_mixer_controls[0],
++		ARRAY_SIZE(wm8971_right_mixer_controls)),
++	SND_SOC_DAPM_MIXER("Mono Mixer", WM8971_PWR2, 2, 0,
++		&wm8971_mono_mixer_controls[0],
++		ARRAY_SIZE(wm8971_mono_mixer_controls)),
++
++	SND_SOC_DAPM_PGA("Right Out 2", WM8971_PWR2, 3, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Left Out 2", WM8971_PWR2, 4, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Right Out 1", WM8971_PWR2, 5, 0, NULL, 0),
++	SND_SOC_DAPM_PGA("Left Out 1", WM8971_PWR2, 6, 0, NULL, 0),
++	SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8971_PWR2, 7, 0),
++	SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8971_PWR2, 8, 0),
++	SND_SOC_DAPM_PGA("Mono Out 1", WM8971_PWR2, 2, 0, NULL, 0),
++
++	SND_SOC_DAPM_MICBIAS("Mic Bias", WM8971_PWR1, 1, 0),
++	SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8971_PWR1, 2, 0),
++	SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8971_PWR1, 3, 0),
++
++	SND_SOC_DAPM_MUX("Left PGA Mux", WM8971_PWR1, 5, 0,
++		&wm8971_left_pga_controls),
++	SND_SOC_DAPM_MUX("Right PGA Mux", WM8971_PWR1, 4, 0,
++		&wm8971_right_pga_controls),
++	SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
++		&wm8971_left_line_controls),
++	SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
++		&wm8971_right_line_controls),
++
++	SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
++		&wm8971_monomux_controls),
++	SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
++		&wm8971_monomux_controls),
++
++	SND_SOC_DAPM_OUTPUT("LOUT1"),
++	SND_SOC_DAPM_OUTPUT("ROUT1"),
++	SND_SOC_DAPM_OUTPUT("LOUT2"),
++	SND_SOC_DAPM_OUTPUT("ROUT2"),
++	SND_SOC_DAPM_OUTPUT("MONO"),
++
++	SND_SOC_DAPM_INPUT("LINPUT1"),
++	SND_SOC_DAPM_INPUT("RINPUT1"),
++	SND_SOC_DAPM_INPUT("MIC"),
++};
++
++static const char *audio_map[][3] = {
++	/* left mixer */
++	{"Left Mixer", "Playback Switch", "Left DAC"},
++	{"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
++	{"Left Mixer", "Right Playback Switch", "Right DAC"},
++	{"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
++
++	/* right mixer */
++	{"Right Mixer", "Left Playback Switch", "Left DAC"},
++	{"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
++	{"Right Mixer", "Playback Switch", "Right DAC"},
++	{"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
++
++	/* left out 1 */
++	{"Left Out 1", NULL, "Left Mixer"},
++	{"LOUT1", NULL, "Left Out 1"},
++
++	/* left out 2 */
++	{"Left Out 2", NULL, "Left Mixer"},
++	{"LOUT2", NULL, "Left Out 2"},
++
++	/* right out 1 */
++	{"Right Out 1", NULL, "Right Mixer"},
++	{"ROUT1", NULL, "Right Out 1"},
++
++	/* right out 2 */
++	{"Right Out 2", NULL, "Right Mixer"},
++	{"ROUT2", NULL, "Right Out 2"},
++
++	/* mono mixer */
++	{"Mono Mixer", "Left Playback Switch", "Left DAC"},
++	{"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
++	{"Mono Mixer", "Right Playback Switch", "Right DAC"},
++	{"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
++
++	/* mono out */
++	{"Mono Out", NULL, "Mono Mixer"},
++	{"MONO1", NULL, "Mono Out"},
++
++	/* Left Line Mux */
++	{"Left Line Mux", "Line", "LINPUT1"},
++	{"Left Line Mux", "PGA", "Left PGA Mux"},
++	{"Left Line Mux", "Differential", "Differential Mux"},
++
++	/* Right Line Mux */
++	{"Right Line Mux", "Line", "RINPUT1"},
++	{"Right Line Mux", "Mic", "MIC"},
++	{"Right Line Mux", "PGA", "Right PGA Mux"},
++	{"Right Line Mux", "Differential", "Differential Mux"},
++
++	/* Left PGA Mux */
++	{"Left PGA Mux", "Line", "LINPUT1"},
++	{"Left PGA Mux", "Differential", "Differential Mux"},
++
++	/* Right PGA Mux */
++	{"Right PGA Mux", "Line", "RINPUT1"},
++	{"Right PGA Mux", "Differential", "Differential Mux"},
++
++	/* Differential Mux */
++	{"Differential Mux", "Line", "LINPUT1"},
++	{"Differential Mux", "Line", "RINPUT1"},
++
++	/* Left ADC Mux */
++	{"Left ADC Mux", "Stereo", "Left PGA Mux"},
++	{"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
++	{"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
++
++	/* Right ADC Mux */
++	{"Right ADC Mux", "Stereo", "Right PGA Mux"},
++	{"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
++	{"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
++
++	/* ADC */
++	{"Left ADC", NULL, "Left ADC Mux"},
++	{"Right ADC", NULL, "Right ADC Mux"},
++
++	/* terminator */
++	{NULL, NULL, NULL},
++};
++
++static int wm8971_add_widgets(struct snd_soc_codec *codec)
++{
++	int i;
++
++	for(i = 0; i < ARRAY_SIZE(wm8971_dapm_widgets); i++) {
++		snd_soc_dapm_new_control(codec, &wm8971_dapm_widgets[i]);
++	}
++
++	/* set up audio path audio_mapnects */
++	for(i = 0; audio_map[i][0] != NULL; i++) {
++		snd_soc_dapm_connect_input(codec, audio_map[i][0],
++			audio_map[i][1], audio_map[i][2]);
++	}
++
++	snd_soc_dapm_new_widgets(codec);
++	return 0;
++}
++
++struct _coeff_div {
++	u32 mclk;
++	u32 rate;
++	u16 fs;
++	u8 sr:5;
++	u8 usb:1;
++};
++
++/* codec hifi mclk clock divider coefficients */
++static const struct _coeff_div coeff_div[] = {
++	/* 8k */
++	{12288000, 8000, 1536, 0x6, 0x0},
++	{11289600, 8000, 1408, 0x16, 0x0},
++	{18432000, 8000, 2304, 0x7, 0x0},
++	{16934400, 8000, 2112, 0x17, 0x0},
++	{12000000, 8000, 1500, 0x6, 0x1},
++
++	/* 11.025k */
++	{11289600, 11025, 1024, 0x18, 0x0},
++	{16934400, 11025, 1536, 0x19, 0x0},
++	{12000000, 11025, 1088, 0x19, 0x1},
++
++	/* 16k */
++	{12288000, 16000, 768, 0xa, 0x0},
++	{18432000, 16000, 1152, 0xb, 0x0},
++	{12000000, 16000, 750, 0xa, 0x1},
++
++	/* 22.05k */
++	{11289600, 22050, 512, 0x1a, 0x0},
++	{16934400, 22050, 768, 0x1b, 0x0},
++	{12000000, 22050, 544, 0x1b, 0x1},
++
++	/* 32k */
++	{12288000, 32000, 384, 0xc, 0x0},
++	{18432000, 32000, 576, 0xd, 0x0},
++	{12000000, 32000, 375, 0xa, 0x1},
++
++	/* 44.1k */
++	{11289600, 44100, 256, 0x10, 0x0},
++	{16934400, 44100, 384, 0x11, 0x0},
++	{12000000, 44100, 272, 0x11, 0x1},
++
++	/* 48k */
++	{12288000, 48000, 256, 0x0, 0x0},
++	{18432000, 48000, 384, 0x1, 0x0},
++	{12000000, 48000, 250, 0x0, 0x1},
++
++	/* 88.2k */
++	{11289600, 88200, 128, 0x1e, 0x0},
++	{16934400, 88200, 192, 0x1f, 0x0},
++	{12000000, 88200, 136, 0x1f, 0x1},
++
++	/* 96k */
++	{12288000, 96000, 128, 0xe, 0x0},
++	{18432000, 96000, 192, 0xf, 0x0},
++	{12000000, 96000, 125, 0xe, 0x1},
++};
++
++static int get_coeff(int mclk, int rate)
++{
++	int i;
++
++	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
++		if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
++			return i;
++	}
++	return -EINVAL;
++}
++
++static int wm8971_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
++		int clk_id, unsigned int freq, int dir)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	struct wm8971_priv *wm8971 = codec->private_data;
++
++	switch (freq) {
++	case 11289600:
++	case 12000000:
++	case 12288000:
++	case 16934400:
++	case 18432000:
++		wm8971->sysclk = freq;
++		return 0;
++	}
++	return -EINVAL;
++}
++
++static int wm8971_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 iface = 0;
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		iface = 0x0040;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		iface |= 0x0002;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		iface |= 0x0001;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		iface |= 0x0003;
++		break;
++	case SND_SOC_DAIFMT_DSP_B:
++		iface |= 0x0013;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		break;
++	case SND_SOC_DAIFMT_IB_IF:
++		iface |= 0x0090;
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		iface |= 0x0080;
++		break;
++	case SND_SOC_DAIFMT_NB_IF:
++		iface |= 0x0010;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	wm8971_write(codec, WM8971_IFACE, iface);
++	return 0;
++}
++
++static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	struct wm8971_priv *wm8971 = codec->private_data;
++	u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3;
++	u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0;
++	int coeff = get_coeff(wm8971->sysclk, params_rate(params));
++
++	/* bit size */
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S16_LE:
++		break;
++	case SNDRV_PCM_FORMAT_S20_3LE:
++		iface |= 0x0004;
++		break;
++	case SNDRV_PCM_FORMAT_S24_LE:
++		iface |= 0x0008;
++		break;
++	case SNDRV_PCM_FORMAT_S32_LE:
++		iface |= 0x000c;
++		break;
++	}
++
++	/* set iface & srate */
++	wm8971_write(codec, WM8971_IFACE, iface);
++	if (coeff >= 0)
++		wm8971_write(codec, WM8971_SRATE, srate |
++			(coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
++
++	return 0;
++}
++
++static int wm8971_mute(struct snd_soc_codec_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u16 mute_reg = wm8971_read_reg_cache(codec, WM8971_ADCDAC) & 0xfff7;
++
++	if (mute)
++		wm8971_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
++	else
++		wm8971_write(codec, WM8971_ADCDAC, mute_reg);
++	return 0;
++}
++
++static int wm8971_dapm_event(struct snd_soc_codec *codec, int event)
++{
++	u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e;
++
++	switch (event) {
++	case SNDRV_CTL_POWER_D0: /* full On */
++		/* set vmid to 50k and unmute dac */
++		wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
++		break;
++	case SNDRV_CTL_POWER_D1: /* partial On */
++	case SNDRV_CTL_POWER_D2: /* partial On */
++		/* set vmid to 5k for quick power up */
++		wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x01c0);
++		break;
++	case SNDRV_CTL_POWER_D3hot: /* Off, with power */
++		/* mute dac and set vmid to 500k, enable VREF */
++		wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
++		break;
++	case SNDRV_CTL_POWER_D3cold: /* Off, without power */
++		wm8971_write(codec, WM8971_PWR1, 0x0001);
++		break;
++	}
++	codec->dapm_state = event;
++	return 0;
++}
++
++#define WM8971_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
++		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
++
++#define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
++	SNDRV_PCM_FMTBIT_S24_LE)
++
++struct snd_soc_codec_dai wm8971_dai = {
++	.name = "WM8971",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = WM8971_RATES,
++		.formats = WM8971_FORMATS,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = WM8971_RATES,
++		.formats = WM8971_FORMATS,},
++	.ops = {
++		.hw_params = wm8971_pcm_hw_params,
++	},
++	.dai_ops = {
++		.digital_mute = wm8971_mute,
++		.set_fmt = wm8971_set_dai_fmt,
++		.set_sysclk = wm8971_set_dai_sysclk,
++	},
++};
++EXPORT_SYMBOL_GPL(wm8971_dai);
++
++static void wm8971_work(struct work_struct *work)
++{
++	struct snd_soc_codec *codec =
++		container_of(work, struct snd_soc_codec, delayed_work.work);
++	wm8971_dapm_event(codec, codec->dapm_state);
++}
++
++static int wm8971_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	wm8971_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++	return 0;
++}
++
++static int wm8971_resume(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++	int i;
++	u8 data[2];
++	u16 *cache = codec->reg_cache;
++
++	/* Sync reg_cache with the hardware */
++	for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) {
++		if (i + 1 == WM8971_RESET)
++			continue;
++		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
++		data[1] = cache[i] & 0x00ff;
++		codec->hw_write(codec->control_data, data, 2);
++	}
++
++	wm8971_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++
++	/* charge wm8971 caps */
++	if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) {
++		wm8971_dapm_event(codec, SNDRV_CTL_POWER_D2);
++		codec->dapm_state = SNDRV_CTL_POWER_D0;
++		queue_delayed_work(wm8971_workq, &codec->delayed_work,
++			msecs_to_jiffies(1000));
++	}
++
++	return 0;
++}
++
++static int wm8971_init(struct snd_soc_device *socdev)
++{
++	struct snd_soc_codec *codec = socdev->codec;
++	int reg, ret = 0;
++
++	codec->name = "WM8971";
++	codec->owner = THIS_MODULE;
++	codec->read = wm8971_read_reg_cache;
++	codec->write = wm8971_write;
++	codec->dapm_event = wm8971_dapm_event;
++	codec->dai = &wm8971_dai;
++	codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
++	codec->num_dai = 1;
++	codec->reg_cache =
++			kzalloc(sizeof(u16) * ARRAY_SIZE(wm8971_reg), GFP_KERNEL);
++	if (codec->reg_cache == NULL)
++		return -ENOMEM;
++	memcpy(codec->reg_cache, wm8971_reg,
++		sizeof(u16) * ARRAY_SIZE(wm8971_reg));
++	codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm8971_reg);
++
++	wm8971_reset(codec);
++
++	/* register pcms */
++	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++	if (ret < 0) {
++		printk(KERN_ERR "wm8971: failed to create pcms\n");
++		goto pcm_err;
++	}
++
++	/* charge output caps */
++	wm8971_dapm_event(codec, SNDRV_CTL_POWER_D2);
++	codec->dapm_state = SNDRV_CTL_POWER_D3hot;
++	queue_delayed_work(wm8971_workq, &codec->delayed_work,
++		msecs_to_jiffies(1000));
++
++	/* set the update bits */
++	reg = wm8971_read_reg_cache(codec, WM8971_LDAC);
++	wm8971_write(codec, WM8971_LDAC, reg | 0x0100);
++	reg = wm8971_read_reg_cache(codec, WM8971_RDAC);
++	wm8971_write(codec, WM8971_RDAC, reg | 0x0100);
++
++	reg = wm8971_read_reg_cache(codec, WM8971_LOUT1V);
++	wm8971_write(codec, WM8971_LOUT1V, reg | 0x0100);
++	reg = wm8971_read_reg_cache(codec, WM8971_ROUT1V);
++	wm8971_write(codec, WM8971_ROUT1V, reg | 0x0100);
++
++	reg = wm8971_read_reg_cache(codec, WM8971_LOUT2V);
++	wm8971_write(codec, WM8971_LOUT2V, reg | 0x0100);
++	reg = wm8971_read_reg_cache(codec, WM8971_ROUT2V);
++	wm8971_write(codec, WM8971_ROUT2V, reg | 0x0100);
++
++	reg = wm8971_read_reg_cache(codec, WM8971_LINVOL);
++	wm8971_write(codec, WM8971_LINVOL, reg | 0x0100);
++	reg = wm8971_read_reg_cache(codec, WM8971_RINVOL);
++	wm8971_write(codec, WM8971_RINVOL, reg | 0x0100);
++
++	wm8971_add_controls(codec);
++	wm8971_add_widgets(codec);
++	ret = snd_soc_register_card(socdev);
++	if (ret < 0) {
++      	printk(KERN_ERR "wm8971: failed to register card\n");
++		goto card_err;
++    }
++	return ret;
++
++card_err:
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++pcm_err:
++	kfree(codec->reg_cache);
++	return ret;
++}
++
++/* If the i2c layer weren't so broken, we could pass this kind of data
++   around */
++static struct snd_soc_device *wm8971_socdev;
++
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++
++/*
++ * WM8731 2 wire address is determined by GPIO5
++ * state during powerup.
++ *    low  = 0x1a
++ *    high = 0x1b
++ */
++#define I2C_DRIVERID_WM8971 0xfefe /* liam -  need a proper id */
++
++static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
++
++/* Magic definition of all other variables and things */
++I2C_CLIENT_INSMOD;
++
++static struct i2c_driver wm8971_i2c_driver;
++static struct i2c_client client_template;
++
++static int wm8971_codec_probe(struct i2c_adapter *adap, int addr, int kind)
++{
++	struct snd_soc_device *socdev = wm8971_socdev;
++	struct wm8971_setup_data *setup = socdev->codec_data;
++	struct snd_soc_codec *codec = socdev->codec;
++	struct i2c_client *i2c;
++	int ret;
++
++	if (addr != setup->i2c_address)
++		return -ENODEV;
++
++	client_template.adapter = adap;
++	client_template.addr = addr;
++
++	i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	if (i2c == NULL) {
++		kfree(codec);
++		return -ENOMEM;
++	}
++	memcpy(i2c, &client_template, sizeof(struct i2c_client));
++
++	i2c_set_clientdata(i2c, codec);
++
++	codec->control_data = i2c;
++
++	ret = i2c_attach_client(i2c);
++	if (ret < 0) {
++		err("failed to attach codec at addr %x\n", addr);
++		goto err;
++	}
++
++	ret = wm8971_init(socdev);
++	if (ret < 0) {
++		err("failed to initialise WM8971\n");
++		goto err;
++	}
++	return ret;
++
++err:
++	kfree(codec);
++	kfree(i2c);
++	return ret;
++}
++
++static int wm8971_i2c_detach(struct i2c_client *client)
++{
++	struct snd_soc_codec* codec = i2c_get_clientdata(client);
++	i2c_detach_client(client);
++	kfree(codec->reg_cache);
++	kfree(client);
++	return 0;
++}
++
++static int wm8971_i2c_attach(struct i2c_adapter *adap)
++{
++	return i2c_probe(adap, &addr_data, wm8971_codec_probe);
++}
++
++/* corgi i2c codec control layer */
++static struct i2c_driver wm8971_i2c_driver = {
++	.driver = {
++		.name = "WM8971 I2C Codec",
++		.owner = THIS_MODULE,
++	},
++	.id =             I2C_DRIVERID_WM8971,
++	.attach_adapter = wm8971_i2c_attach,
++	.detach_client =  wm8971_i2c_detach,
++	.command =        NULL,
++};
++
++static struct i2c_client client_template = {
++	.name =   "WM8971",
++	.driver = &wm8971_i2c_driver,
++};
++#endif
++
++static int wm8971_probe(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct wm8971_setup_data *setup;
++	struct snd_soc_codec *codec;
++	struct wm8971_priv *wm8971;
++	int ret = 0;
++
++	info("WM8971 Audio Codec %s", WM8971_VERSION);
++
++	setup = socdev->codec_data;
++	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
++	if (codec == NULL)
++		return -ENOMEM;
++
++	wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
++	if (wm8971 == NULL) {
++		kfree(codec);
++		return -ENOMEM;
++	}
++
++	codec->private_data = wm8971;
++	socdev->codec = codec;
++	mutex_init(&codec->mutex);
++	INIT_LIST_HEAD(&codec->dapm_widgets);
++	INIT_LIST_HEAD(&codec->dapm_paths);
++	wm8971_socdev = socdev;
++
++	INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work);
++	wm8971_workq = create_workqueue("wm8971");
++	if (wm8971_workq == NULL) {
++		kfree(codec);
++		return -ENOMEM;
++	}
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	if (setup->i2c_address) {
++		normal_i2c[0] = setup->i2c_address;
++		codec->hw_write = (hw_write_t)i2c_master_send;
++		ret = i2c_add_driver(&wm8971_i2c_driver);
++		if (ret != 0)
++			printk(KERN_ERR "can't add i2c driver");
++	}
++#else
++		/* Add other interfaces here */
++#endif
++
++	return ret;
++}
++
++/* power down chip */
++static int wm8971_remove(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	if (codec->control_data)
++		wm8971_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++	if (wm8971_workq)
++		destroy_workqueue(wm8971_workq);
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	i2c_del_driver(&wm8971_i2c_driver);
++#endif
++	kfree(codec->private_data);
++	kfree(codec);
++
++	return 0;
++}
++
++struct snd_soc_codec_device soc_codec_dev_wm8971 = {
++	.probe = 	wm8971_probe,
++	.remove = 	wm8971_remove,
++	.suspend = 	wm8971_suspend,
++	.resume =	wm8971_resume,
++};
++
++EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
++
++MODULE_DESCRIPTION("ASoC WM8971 driver");
++MODULE_AUTHOR("Lab126");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.22.1/sound/soc/codecs/wm8971.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/wm8971.h	2007-07-16 15:07:34.076279166 +0200
+@@ -0,0 +1,63 @@
++/*
++ * wm8971.h  --  audio driver for WM8971
++ *
++ * Copyright 2005 Lab126, Inc.
++ *
++ * Author: Kenneth Kiraly <kiraly at lab126.com>
++ *
++ * This program is free software; you can redistribute  it and/or modify it
++ * under  the terms of  the GNU General  Public License as published by the
++ * Free Software Foundation;  either version 2 of the  License, or (at your
++ * option) any later version.
++ *
++ */
++
++#ifndef _WM8971_H
++#define _WM8971_H
++
++#define WM8971_LINVOL	0x00
++#define WM8971_RINVOL	0x01
++#define WM8971_LOUT1V	0x02
++#define WM8971_ROUT1V	0x03
++#define WM8971_ADCDAC	0x05
++#define WM8971_IFACE	0x07
++#define WM8971_SRATE	0x08
++#define WM8971_LDAC		0x0a
++#define WM8971_RDAC		0x0b
++#define WM8971_BASS		0x0c
++#define WM8971_TREBLE	0x0d
++#define WM8971_RESET	0x0f
++#define WM8971_ALC1		0x11
++#define	WM8971_ALC2		0x12
++#define	WM8971_ALC3		0x13
++#define WM8971_NGATE	0x14
++#define WM8971_LADC		0x15
++#define WM8971_RADC		0x16
++#define	WM8971_ADCTL1	0x17
++#define	WM8971_ADCTL2	0x18
++#define WM8971_PWR1		0x19
++#define WM8971_PWR2		0x1a
++#define	WM8971_ADCTL3	0x1b
++#define WM8971_ADCIN	0x1f
++#define	WM8971_LADCIN	0x20
++#define	WM8971_RADCIN	0x21
++#define WM8971_LOUTM1	0x22
++#define WM8971_LOUTM2	0x23
++#define WM8971_ROUTM1	0x24
++#define WM8971_ROUTM2	0x25
++#define WM8971_MOUTM1	0x26
++#define WM8971_MOUTM2	0x27
++#define WM8971_LOUT2V	0x28
++#define WM8971_ROUT2V	0x29
++#define WM8971_MOUTV	0x2A
++
++#define WM8971_SYSCLK	0
++
++struct wm8971_setup_data {
++	unsigned short i2c_address;
++};
++
++extern struct snd_soc_codec_dai wm8971_dai;
++extern struct snd_soc_codec_device soc_codec_dev_wm8971;
++
++#endif
+Index: linux-2.6.22.1/sound/soc/codecs/wm8974.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/wm8974.c	2007-07-16 15:07:34.104280762 +0200
+@@ -0,0 +1,873 @@
++/*
++ * wm8974.c  --  WM8974 ALSA Soc Audio driver
++ *
++ * Copyright 2006 Wolfson Microelectronics PLC.
++ *
++ * Author: Liam Girdwood <liam.girdwood at wolfsonmicro.com>
++ *
++ * 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.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/i2c.h>
++#include <linux/platform_device.h>
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++#include <sound/initval.h>
++
++#include "wm8974.h"
++
++#define AUDIO_NAME "wm8974"
++#define WM8974_VERSION "0.6"
++
++/*
++ * Debug
++ */
++
++#define WM8974_DEBUG 0
++
++#ifdef WM8974_DEBUG
++#define dbg(format, arg...) \
++	printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
++#else
++#define dbg(format, arg...) do {} while (0)
++#endif
++#define err(format, arg...) \
++	printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
++#define info(format, arg...) \
++	printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
++#define warn(format, arg...) \
++	printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
++
++struct snd_soc_codec_device soc_codec_dev_wm8974;
++
++/*
++ * wm8974 register cache
++ * We can't read the WM8974 register space when we are
++ * using 2 wire for device control, so we cache them instead.
++ */
++static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
++    0x0000, 0x0000, 0x0000, 0x0000,
++    0x0050, 0x0000, 0x0140, 0x0000,
++    0x0000, 0x0000, 0x0000, 0x00ff,
++    0x0000, 0x0000, 0x0100, 0x00ff,
++    0x0000, 0x0000, 0x012c, 0x002c,
++    0x002c, 0x002c, 0x002c, 0x0000,
++    0x0032, 0x0000, 0x0000, 0x0000,
++    0x0000, 0x0000, 0x0000, 0x0000,
++    0x0038, 0x000b, 0x0032, 0x0000,
++    0x0008, 0x000c, 0x0093, 0x00e9,
++    0x0000, 0x0000, 0x0000, 0x0000,
++    0x0003, 0x0010, 0x0000, 0x0000,
++    0x0000, 0x0002, 0x0000, 0x0000,
++    0x0000, 0x0000, 0x0039, 0x0000,
++    0x0000,
++};
++
++/*
++ * read wm8974 register cache
++ */
++static inline unsigned int wm8974_read_reg_cache(struct snd_soc_codec * codec,
++	unsigned int reg)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg == WM8974_RESET)
++		return 0;
++	if (reg >= WM8974_CACHEREGNUM)
++		return -1;
++	return cache[reg];
++}
++
++/*
++ * write wm8974 register cache
++ */
++static inline void wm8974_write_reg_cache(struct snd_soc_codec *codec,
++	u16 reg, unsigned int value)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg >= WM8974_CACHEREGNUM)
++		return;
++	cache[reg] = value;
++}
++
++/*
++ * write to the WM8974 register space
++ */
++static int wm8974_write(struct snd_soc_codec *codec, unsigned int reg,
++	unsigned int value)
++{
++	u8 data[2];
++
++	/* data is
++	 *   D15..D9 WM8974 register offset
++	 *   D8...D0 register data
++	 */
++	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
++	data[1] = value & 0x00ff;
++
++	wm8974_write_reg_cache (codec, reg, value);
++	if (codec->hw_write(codec->control_data, data, 2) == 2)
++		return 0;
++	else
++		return -EIO;
++}
++
++#define wm8974_reset(c)	wm8974_write(c, WM8974_RESET, 0)
++
++static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
++static const char *wm8974_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz" };
++static const char *wm8974_eqmode[] = {"Capture", "Playback" };
++static const char *wm8974_bw[] = {"Narrow", "Wide" };
++static const char *wm8974_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz" };
++static const char *wm8974_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz" };
++static const char *wm8974_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz" };
++static const char *wm8974_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" };
++static const char *wm8974_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz" };
++static const char *wm8974_alc[] = {"ALC", "Limiter" };
++
++static const struct soc_enum wm8974_enum[] = {
++	SOC_ENUM_SINGLE(WM8974_COMP, 1, 4, wm8974_companding), /* adc */
++	SOC_ENUM_SINGLE(WM8974_COMP, 3, 4, wm8974_companding), /* dac */
++	SOC_ENUM_SINGLE(WM8974_DAC,  4, 4, wm8974_deemp),
++	SOC_ENUM_SINGLE(WM8974_EQ1,  8, 2, wm8974_eqmode),
++
++	SOC_ENUM_SINGLE(WM8974_EQ1,  5, 4, wm8974_eq1),
++	SOC_ENUM_SINGLE(WM8974_EQ2,  8, 2, wm8974_bw),
++	SOC_ENUM_SINGLE(WM8974_EQ2,  5, 4, wm8974_eq2),
++	SOC_ENUM_SINGLE(WM8974_EQ3,  8, 2, wm8974_bw),
++
++	SOC_ENUM_SINGLE(WM8974_EQ3,  5, 4, wm8974_eq3),
++	SOC_ENUM_SINGLE(WM8974_EQ4,  8, 2, wm8974_bw),
++	SOC_ENUM_SINGLE(WM8974_EQ4,  5, 4, wm8974_eq4),
++	SOC_ENUM_SINGLE(WM8974_EQ5,  8, 2, wm8974_bw),
++
++	SOC_ENUM_SINGLE(WM8974_EQ5,  5, 4, wm8974_eq5),
++	SOC_ENUM_SINGLE(WM8974_ALC3,  8, 2, wm8974_alc),
++};
++
++static const struct snd_kcontrol_new wm8974_snd_controls[] = {
++
++SOC_SINGLE("Digital Loopback Switch", WM8974_COMP, 0, 1, 0),
++
++SOC_ENUM("DAC Companding", wm8974_enum[1]),
++SOC_ENUM("ADC Companding", wm8974_enum[0]),
++
++SOC_ENUM("Playback De-emphasis", wm8974_enum[2]),
++SOC_SINGLE("DAC Inversion Switch", WM8974_DAC, 0, 1, 0),
++
++SOC_SINGLE("PCM Volume", WM8974_DACVOL, 0, 127, 0),
++
++SOC_SINGLE("High Pass Filter Switch", WM8974_ADC, 8, 1, 0),
++SOC_SINGLE("High Pass Cut Off", WM8974_ADC, 4, 7, 0),
++SOC_SINGLE("ADC Inversion Switch", WM8974_COMP, 0, 1, 0),
++
++SOC_SINGLE("Capture Volume", WM8974_ADCVOL,  0, 127, 0),
++
++SOC_ENUM("Equaliser Function", wm8974_enum[3]),
++SOC_ENUM("EQ1 Cut Off", wm8974_enum[4]),
++SOC_SINGLE("EQ1 Volume", WM8974_EQ1,  0, 31, 1),
++
++SOC_ENUM("Equaliser EQ2 Bandwith", wm8974_enum[5]),
++SOC_ENUM("EQ2 Cut Off", wm8974_enum[6]),
++SOC_SINGLE("EQ2 Volume", WM8974_EQ2,  0, 31, 1),
++
++SOC_ENUM("Equaliser EQ3 Bandwith", wm8974_enum[7]),
++SOC_ENUM("EQ3 Cut Off", wm8974_enum[8]),
++SOC_SINGLE("EQ3 Volume", WM8974_EQ3,  0, 31, 1),
++
++SOC_ENUM("Equaliser EQ4 Bandwith", wm8974_enum[9]),
++SOC_ENUM("EQ4 Cut Off", wm8974_enum[10]),
++SOC_SINGLE("EQ4 Volume", WM8974_EQ4,  0, 31, 1),
++
++SOC_ENUM("Equaliser EQ5 Bandwith", wm8974_enum[11]),
++SOC_ENUM("EQ5 Cut Off", wm8974_enum[12]),
++SOC_SINGLE("EQ5 Volume", WM8974_EQ5,  0, 31, 1),
++
++SOC_SINGLE("DAC Playback Limiter Switch", WM8974_DACLIM1,  8, 1, 0),
++SOC_SINGLE("DAC Playback Limiter Decay", WM8974_DACLIM1,  4, 15, 0),
++SOC_SINGLE("DAC Playback Limiter Attack", WM8974_DACLIM1,  0, 15, 0),
++
++SOC_SINGLE("DAC Playback Limiter Threshold", WM8974_DACLIM2,  4, 7, 0),
++SOC_SINGLE("DAC Playback Limiter Boost", WM8974_DACLIM2,  0, 15, 0),
++
++SOC_SINGLE("ALC Enable Switch", WM8974_ALC1,  8, 1, 0),
++SOC_SINGLE("ALC Capture Max Gain", WM8974_ALC1,  3, 7, 0),
++SOC_SINGLE("ALC Capture Min Gain", WM8974_ALC1,  0, 7, 0),
++
++SOC_SINGLE("ALC Capture ZC Switch", WM8974_ALC2,  8, 1, 0),
++SOC_SINGLE("ALC Capture Hold", WM8974_ALC2,  4, 7, 0),
++SOC_SINGLE("ALC Capture Target", WM8974_ALC2,  0, 15, 0),
++
++SOC_ENUM("ALC Capture Mode", wm8974_enum[13]),
++SOC_SINGLE("ALC Capture Decay", WM8974_ALC3,  4, 15, 0),
++SOC_SINGLE("ALC Capture Attack", WM8974_ALC3,  0, 15, 0),
++
++SOC_SINGLE("ALC Capture Noise Gate Switch", WM8974_NGATE,  3, 1, 0),
++SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8974_NGATE,  0, 7, 0),
++
++SOC_SINGLE("Capture PGA ZC Switch", WM8974_INPPGA,  7, 1, 0),
++SOC_SINGLE("Capture PGA Volume", WM8974_INPPGA,  0, 63, 0),
++
++SOC_SINGLE("Speaker Playback ZC Switch", WM8974_SPKVOL,  7, 1, 0),
++SOC_SINGLE("Speaker Playback Switch", WM8974_SPKVOL,  6, 1, 1),
++SOC_SINGLE("Speaker Playback Volume", WM8974_SPKVOL,  0, 63, 0),
++
++SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST,  8, 1, 0),
++SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 0),
++};
++
++/* add non dapm controls */
++static int wm8974_add_controls(struct snd_soc_codec *codec)
++{
++	int err, i;
++
++	for (i = 0; i < ARRAY_SIZE(wm8974_snd_controls); i++) {
++		err = snd_ctl_add(codec->card,
++				snd_soc_cnew(&wm8974_snd_controls[i],codec, NULL));
++		if (err < 0)
++			return err;
++	}
++
++	return 0;
++}
++
++/* Speaker Output Mixer */
++static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = {
++SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0),
++SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0),
++SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 1),
++};
++
++/* Mono Output Mixer */
++static const struct snd_kcontrol_new wm8974_mono_mixer_controls[] = {
++SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_MONOMIX, 1, 1, 0),
++SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_MONOMIX, 2, 1, 0),
++SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 1),
++};
++
++/* AUX Input boost vol */
++static const struct snd_kcontrol_new wm8974_aux_boost_controls =
++SOC_DAPM_SINGLE("Aux Volume", WM8974_ADCBOOST, 0, 7, 0);
++
++/* Mic Input boost vol */
++static const struct snd_kcontrol_new wm8974_mic_boost_controls =
++SOC_DAPM_SINGLE("Mic Volume", WM8974_ADCBOOST, 4, 7, 0);
++
++/* Capture boost switch */
++static const struct snd_kcontrol_new wm8974_capture_boost_controls =
++SOC_DAPM_SINGLE("Capture Boost Switch", WM8974_INPPGA,  6, 1, 0);
++
++/* Aux In to PGA */
++static const struct snd_kcontrol_new wm8974_aux_capture_boost_controls =
++SOC_DAPM_SINGLE("Aux Capture Boost Switch", WM8974_INPPGA,  2, 1, 0);
++
++/* Mic P In to PGA */
++static const struct snd_kcontrol_new wm8974_micp_capture_boost_controls =
++SOC_DAPM_SINGLE("Mic P Capture Boost Switch", WM8974_INPPGA,  0, 1, 0);
++
++/* Mic N In to PGA */
++static const struct snd_kcontrol_new wm8974_micn_capture_boost_controls =
++SOC_DAPM_SINGLE("Mic N Capture Boost Switch", WM8974_INPPGA,  1, 1, 0);
++
++static const struct snd_soc_dapm_widget wm8974_dapm_widgets[] = {
++SND_SOC_DAPM_MIXER("Speaker Mixer", WM8974_POWER3, 2, 0,
++	&wm8974_speaker_mixer_controls[0],
++	ARRAY_SIZE(wm8974_speaker_mixer_controls)),
++SND_SOC_DAPM_MIXER("Mono Mixer", WM8974_POWER3, 3, 0,
++	&wm8974_mono_mixer_controls[0],
++	ARRAY_SIZE(wm8974_mono_mixer_controls)),
++SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8974_POWER3, 0, 0),
++SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8974_POWER3, 0, 0),
++SND_SOC_DAPM_PGA("Aux Input", WM8974_POWER1, 6, 0, NULL, 0),
++SND_SOC_DAPM_PGA("SpkN Out", WM8974_POWER3, 5, 0, NULL, 0),
++SND_SOC_DAPM_PGA("SpkP Out", WM8974_POWER3, 6, 0, NULL, 0),
++SND_SOC_DAPM_PGA("Mono Out", WM8974_POWER3, 7, 0, NULL, 0),
++SND_SOC_DAPM_PGA("Mic PGA", WM8974_POWER2, 2, 0, NULL, 0),
++
++SND_SOC_DAPM_PGA("Aux Boost", SND_SOC_NOPM, 0, 0,
++	&wm8974_aux_boost_controls, 1),
++SND_SOC_DAPM_PGA("Mic Boost", SND_SOC_NOPM, 0, 0,
++	&wm8974_mic_boost_controls, 1),
++SND_SOC_DAPM_SWITCH("Capture Boost", SND_SOC_NOPM, 0, 0,
++	&wm8974_capture_boost_controls),
++
++SND_SOC_DAPM_MIXER("Boost Mixer", WM8974_POWER2, 4, 0, NULL, 0),
++
++SND_SOC_DAPM_MICBIAS("Mic Bias", WM8974_POWER1, 4, 0),
++
++SND_SOC_DAPM_INPUT("MICN"),
++SND_SOC_DAPM_INPUT("MICP"),
++SND_SOC_DAPM_INPUT("AUX"),
++SND_SOC_DAPM_OUTPUT("MONOOUT"),
++SND_SOC_DAPM_OUTPUT("SPKOUTP"),
++SND_SOC_DAPM_OUTPUT("SPKOUTN"),
++};
++
++static const char *audio_map[][3] = {
++	/* Mono output mixer */
++	{"Mono Mixer", "PCM Playback Switch", "DAC"},
++	{"Mono Mixer", "Aux Playback Switch", "Aux Input"},
++	{"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
++
++	/* Speaker output mixer */
++	{"Speaker Mixer", "PCM Playback Switch", "DAC"},
++	{"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
++	{"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
++
++	/* Outputs */
++	{"Mono Out", NULL, "Mono Mixer"},
++	{"MONOOUT", NULL, "Mono Out"},
++	{"SpkN Out", NULL, "Speaker Mixer"},
++	{"SpkP Out", NULL, "Speaker Mixer"},
++	{"SPKOUTN", NULL, "SpkN Out"},
++	{"SPKOUTP", NULL, "SpkP Out"},
++
++	/* Boost Mixer */
++	{"Boost Mixer", NULL, "ADC"},
++    {"Capture Boost Switch", "Aux Capture Boost Switch", "AUX"},
++	{"Aux Boost", "Aux Volume", "Boost Mixer"},
++    {"Capture Boost", "Capture Switch", "Boost Mixer"},
++	{"Mic Boost", "Mic Volume", "Boost Mixer"},
++
++	/* Inputs */
++	{"MICP", NULL, "Mic Boost"},
++	{"MICN", NULL, "Mic PGA"},
++	{"Mic PGA", NULL, "Capture Boost"},
++	{"AUX", NULL, "Aux Input"},
++
++	/* terminator */
++	{NULL, NULL, NULL},
++};
++
++static int wm8974_add_widgets(struct snd_soc_codec *codec)
++{
++	int i;
++
++	for(i = 0; i < ARRAY_SIZE(wm8974_dapm_widgets); i++) {
++		snd_soc_dapm_new_control(codec, &wm8974_dapm_widgets[i]);
++	}
++
++	/* set up audio path audio_mapnects */
++	for(i = 0; audio_map[i][0] != NULL; i++) {
++		snd_soc_dapm_connect_input(codec, audio_map[i][0],
++			audio_map[i][1], audio_map[i][2]);
++	}
++
++	snd_soc_dapm_new_widgets(codec);
++	return 0;
++}
++
++struct pll_ {
++	unsigned int in_hz, out_hz;
++	unsigned int pre:4; /* prescale - 1 */
++	unsigned int n:4;
++	unsigned int k;
++};
++
++struct pll_ pll[] = {
++	{12000000, 11289600, 0, 7, 0x86c220},
++	{12000000, 12288000, 0, 8, 0x3126e8},
++	{13000000, 11289600, 0, 6, 0xf28bd4},
++	{13000000, 12288000, 0, 7, 0x8fd525},
++	{12288000, 11289600, 0, 7, 0x59999a},
++	{11289600, 12288000, 0, 8, 0x80dee9},
++	/* liam - add more entries */
++};
++
++static int wm8974_set_dai_pll(struct snd_soc_codec_dai *codec_dai,
++		int pll_id, unsigned int freq_in, unsigned int freq_out)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	int i;
++	u16 reg;
++
++	if(freq_in == 0 || freq_out == 0) {
++		reg = wm8974_read_reg_cache(codec, WM8974_POWER1);
++		wm8974_write(codec, WM8974_POWER1, reg & 0x1df);
++		return 0;
++	}
++
++	for(i = 0; i < ARRAY_SIZE(pll); i++) {
++		if (freq_in == pll[i].in_hz && freq_out == pll[i].out_hz) {
++			wm8974_write(codec, WM8974_PLLN, (pll[i].pre << 4) | pll[i].n);
++			wm8974_write(codec, WM8974_PLLK1, pll[i].k >> 18);
++			wm8974_write(codec, WM8974_PLLK1, (pll[i].k >> 9) && 0x1ff);
++			wm8974_write(codec, WM8974_PLLK1, pll[i].k && 0x1ff);
++			reg = wm8974_read_reg_cache(codec, WM8974_POWER1);
++			wm8974_write(codec, WM8974_POWER1, reg | 0x020);
++			return 0;
++		}
++	}
++	return -EINVAL;
++}
++
++/*
++ * Configure WM8974 clock dividers.
++ */
++static int wm8974_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai,
++		int div_id, int div)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 reg;
++
++	switch (div_id) {
++	case WM8974_OPCLKDIV:
++		reg = wm8974_read_reg_cache(codec, WM8974_GPIO & 0x1cf);
++		wm8974_write(codec, WM8974_GPIO, reg | div);
++		break;
++	case WM8974_MCLKDIV:
++		reg = wm8974_read_reg_cache(codec, WM8974_CLOCK & 0x1f);
++		wm8974_write(codec, WM8974_CLOCK, reg | div);
++		break;
++	case WM8974_ADCCLK:
++		reg = wm8974_read_reg_cache(codec, WM8974_ADC & 0x1f7);
++		wm8974_write(codec, WM8974_ADC, reg | div);
++		break;
++	case WM8974_DACCLK:
++		reg = wm8974_read_reg_cache(codec, WM8974_DAC & 0x1f7);
++		wm8974_write(codec, WM8974_DAC, reg | div);
++		break;
++	case WM8974_BCLKDIV:
++		reg = wm8974_read_reg_cache(codec, WM8974_CLOCK & 0x1e3);
++		wm8974_write(codec, WM8974_CLOCK, reg | div);
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static int wm8974_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 iface = 0;
++	u16 clk = wm8974_read_reg_cache(codec, WM8974_CLOCK) & 0x1fe;
++
++	/* set master/slave audio interface */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
++	case SND_SOC_DAIFMT_CBM_CFM:
++		clk |= 0x0001;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* interface format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		iface |= 0x0010;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		iface |= 0x0008;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		iface |= 0x00018;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_NB_NF:
++		break;
++	case SND_SOC_DAIFMT_IB_IF:
++		iface |= 0x0180;
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		iface |= 0x0100;
++		break;
++	case SND_SOC_DAIFMT_NB_IF:
++		iface |= 0x0080;
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	wm8974_write(codec, WM8974_IFACE, iface);
++	wm8974_write(codec, WM8974_CLOCK, clk);
++	return 0;
++}
++
++static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	u16 iface = wm8974_read_reg_cache(codec, WM8974_ADD) & 0x19f;
++	u16 adn = wm8974_read_reg_cache(codec, WM8974_ADD) & 0x1f1;
++
++	/* bit size */
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S16_LE:
++		break;
++	case SNDRV_PCM_FORMAT_S20_3LE:
++		iface |= 0x0020;
++		break;
++	case SNDRV_PCM_FORMAT_S24_LE:
++		iface |= 0x0040;
++		break;
++	case SNDRV_PCM_FORMAT_S32_LE:
++		iface |= 0x0060;
++		break;
++	}
++
++	/* filter coefficient */
++	switch (params_rate(params)) {
++	case SNDRV_PCM_RATE_8000:
++		adn |= 0x5 << 1;
++		break;
++	case SNDRV_PCM_RATE_11025:
++		adn |= 0x4 << 1;
++		break;
++	case SNDRV_PCM_RATE_16000:
++		adn |= 0x3 << 1;
++		break;
++	case SNDRV_PCM_RATE_22050:
++		adn |= 0x2 << 1;
++		break;
++	case SNDRV_PCM_RATE_32000:
++		adn |= 0x1 << 1;
++		break;
++	case SNDRV_PCM_RATE_44100:
++		break;
++	}
++
++	wm8974_write(codec, WM8974_IFACE, iface);
++	wm8974_write(codec, WM8974_ADD, adn);
++	return 0;
++}
++
++static int wm8974_mute(struct snd_soc_codec_dai *dai, int mute)
++{
++	struct snd_soc_codec *codec = dai->codec;
++	u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf;
++
++	if(mute)
++		wm8974_write(codec, WM8974_DAC, mute_reg | 0x40);
++	else
++		wm8974_write(codec, WM8974_DAC, mute_reg);
++	return 0;
++}
++
++/* liam need to make this lower power with dapm */
++static int wm8974_dapm_event(struct snd_soc_codec *codec, int event)
++{
++
++	switch (event) {
++	case SNDRV_CTL_POWER_D0: /* full On */
++		/* vref/mid, clk and osc on, dac unmute, active */
++		wm8974_write(codec, WM8974_POWER1, 0x1ff);
++		wm8974_write(codec, WM8974_POWER2, 0x1ff);
++		wm8974_write(codec, WM8974_POWER3, 0x1ff);
++		break;
++	case SNDRV_CTL_POWER_D1: /* partial On */
++	case SNDRV_CTL_POWER_D2: /* partial On */
++		break;
++	case SNDRV_CTL_POWER_D3hot: /* Off, with power */
++		/* everything off except vref/vmid, dac mute, inactive */
++
++		break;
++	case SNDRV_CTL_POWER_D3cold: /* Off, without power */
++		/* everything off, dac mute, inactive */
++		wm8974_write(codec, WM8974_POWER1, 0x0);
++		wm8974_write(codec, WM8974_POWER2, 0x0);
++		wm8974_write(codec, WM8974_POWER3, 0x0);
++		break;
++	}
++	codec->dapm_state = event;
++	return 0;
++}
++
++#define WM8974_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
++		SNDRV_PCM_RATE_48000)
++
++#define WM8974_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
++	SNDRV_PCM_FMTBIT_S24_LE)
++
++struct snd_soc_codec_dai wm8974_dai = {
++	.name = "WM8974 HiFi",
++	.playback = {
++		.stream_name = "Playback",
++		.channels_min = 1,
++		.channels_max = 1,
++		.rates = WM8974_RATES,
++		.formats = WM8974_FORMATS,},
++	.capture = {
++		.stream_name = "Capture",
++		.channels_min = 1,
++		.channels_max = 1,
++		.rates = WM8974_RATES,
++		.formats = WM8974_FORMATS,},
++	.ops = {
++		.hw_params = wm8974_pcm_hw_params,
++	},
++	.dai_ops = {
++		.digital_mute = wm8974_mute,
++		.set_fmt = wm8974_set_dai_fmt,
++		.set_clkdiv = wm8974_set_dai_clkdiv,
++		.set_pll = wm8974_set_dai_pll,
++	},
++};
++EXPORT_SYMBOL_GPL(wm8974_dai);
++
++static int wm8974_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	wm8974_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++	return 0;
++}
++
++static int wm8974_resume(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++	int i;
++	u8 data[2];
++	u16 *cache = codec->reg_cache;
++
++	/* Sync reg_cache with the hardware */
++	for (i = 0; i < ARRAY_SIZE(wm8974_reg); i++) {
++		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
++		data[1] = cache[i] & 0x00ff;
++		codec->hw_write(codec->control_data, data, 2);
++	}
++	wm8974_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++	wm8974_dapm_event(codec, codec->suspend_dapm_state);
++	return 0;
++}
++
++/*
++ * initialise the WM8974 driver
++ * register the mixer and dsp interfaces with the kernel
++ */
++static int wm8974_init(struct snd_soc_device *socdev)
++{
++	struct snd_soc_codec *codec = socdev->codec;
++	int ret = 0;
++
++	codec->name = "WM8974";
++	codec->owner = THIS_MODULE;
++	codec->read = wm8974_read_reg_cache;
++	codec->write = wm8974_write;
++	codec->dapm_event = wm8974_dapm_event;
++	codec->dai = &wm8974_dai;
++	codec->num_dai = 1;
++	codec->reg_cache_size = ARRAY_SIZE(wm8974_reg);
++	codec->reg_cache =
++			kzalloc(sizeof(u16) * ARRAY_SIZE(wm8974_reg), GFP_KERNEL);
++	if (codec->reg_cache == NULL)
++		return -ENOMEM;
++	memcpy(codec->reg_cache, wm8974_reg,
++		sizeof(u16) * ARRAY_SIZE(wm8974_reg));
++	codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm8974_reg);
++
++	wm8974_reset(codec);
++
++	/* register pcms */
++	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++	if(ret < 0) {
++		printk(KERN_ERR "wm8974: failed to create pcms\n");
++		goto pcm_err;
++	}
++
++	/* power on device */
++	wm8974_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++	wm8974_add_controls(codec);
++	wm8974_add_widgets(codec);
++	ret = snd_soc_register_card(socdev);
++	if (ret < 0) {
++      	printk(KERN_ERR "wm8974: failed to register card\n");
++		goto card_err;
++    }
++	return ret;
++
++card_err:
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++pcm_err:
++	kfree(codec->reg_cache);
++	return ret;
++}
++
++static struct snd_soc_device *wm8974_socdev;
++
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++
++/*
++ * WM8974 2 wire address is 0x1a
++ */
++#define I2C_DRIVERID_WM8974 0xfefe /* liam -  need a proper id */
++
++static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
++
++/* Magic definition of all other variables and things */
++I2C_CLIENT_INSMOD;
++
++static struct i2c_driver wm8974_i2c_driver;
++static struct i2c_client client_template;
++
++/* If the i2c layer weren't so broken, we could pass this kind of data
++   around */
++
++static int wm8974_codec_probe(struct i2c_adapter *adap, int addr, int kind)
++{
++	struct snd_soc_device *socdev = wm8974_socdev;
++	struct wm8974_setup_data *setup = socdev->codec_data;
++	struct snd_soc_codec *codec = socdev->codec;
++	struct i2c_client *i2c;
++	int ret;
++
++	if (addr != setup->i2c_address)
++		return -ENODEV;
++
++	client_template.adapter = adap;
++	client_template.addr = addr;
++
++	i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
++	if (i2c == NULL) {
++		kfree(codec);
++		return -ENOMEM;
++	}
++	memcpy(i2c, &client_template, sizeof(struct i2c_client));
++	i2c_set_clientdata(i2c, codec);
++	codec->control_data = i2c;
++
++	ret = i2c_attach_client(i2c);
++	if(ret < 0) {
++		err("failed to attach codec at addr %x\n", addr);
++		goto err;
++	}
++
++	ret = wm8974_init(socdev);
++	if(ret < 0) {
++		err("failed to initialise WM8974\n");
++		goto err;
++	}
++	return ret;
++
++err:
++	kfree(codec);
++	kfree(i2c);
++	return ret;
++}
++
++static int wm8974_i2c_detach(struct i2c_client *client)
++{
++	struct snd_soc_codec *codec = i2c_get_clientdata(client);
++	i2c_detach_client(client);
++	kfree(codec->reg_cache);
++	kfree(client);
++	return 0;
++}
++
++static int wm8974_i2c_attach(struct i2c_adapter *adap)
++{
++	return i2c_probe(adap, &addr_data, wm8974_codec_probe);
++}
++
++/* corgi i2c codec control layer */
++static struct i2c_driver wm8974_i2c_driver = {
++	.driver = {
++		.name = "WM8974 I2C Codec",
++		.owner = THIS_MODULE,
++	},
++	.id =             I2C_DRIVERID_WM8974,
++	.attach_adapter = wm8974_i2c_attach,
++	.detach_client =  wm8974_i2c_detach,
++	.command =        NULL,
++};
++
++static struct i2c_client client_template = {
++	.name =   "WM8974",
++	.driver = &wm8974_i2c_driver,
++};
++#endif
++
++static int wm8974_probe(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct wm8974_setup_data *setup;
++	struct snd_soc_codec *codec;
++	int ret = 0;
++
++	info("WM8974 Audio Codec %s", WM8974_VERSION);
++
++	setup = socdev->codec_data;
++	codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
++	if (codec == NULL)
++		return -ENOMEM;
++
++	socdev->codec = codec;
++	mutex_init(&codec->mutex);
++	INIT_LIST_HEAD(&codec->dapm_widgets);
++	INIT_LIST_HEAD(&codec->dapm_paths);
++
++	wm8974_socdev = socdev;
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	if (setup->i2c_address) {
++		normal_i2c[0] = setup->i2c_address;
++		codec->hw_write = (hw_write_t)i2c_master_send;
++		ret = i2c_add_driver(&wm8974_i2c_driver);
++		if (ret != 0)
++			printk(KERN_ERR "can't add i2c driver");
++	}
++#else
++	/* Add other interfaces here */
++#endif
++	return ret;
++}
++
++/* power down chip */
++static int wm8974_remove(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	if (codec->control_data)
++		wm8974_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++
++	snd_soc_free_pcms(socdev);
++	snd_soc_dapm_free(socdev);
++#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
++	i2c_del_driver(&wm8974_i2c_driver);
++#endif
++	kfree(codec);
++
++	return 0;
++}
++
++struct snd_soc_codec_device soc_codec_dev_wm8974 = {
++	.probe = 	wm8974_probe,
++	.remove = 	wm8974_remove,
++	.suspend = 	wm8974_suspend,
++	.resume =	wm8974_resume,
++};
++
++EXPORT_SYMBOL_GPL(soc_codec_dev_wm8974);
++
++MODULE_DESCRIPTION("ASoC WM8974 driver");
++MODULE_AUTHOR("Liam Girdwood");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.22.1/sound/soc/codecs/wm8974.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/wm8974.h	2007-07-16 15:07:34.124281902 +0200
+@@ -0,0 +1,104 @@
++/*
++ * wm8974.h  --  WM8974 Soc Audio driver
++ *
++ * 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.
++ */
++
++#ifndef _WM8974_H
++#define _WM8974_H
++
++/* WM8974 register space */
++
++#define WM8974_RESET		0x0
++#define WM8974_POWER1		0x1
++#define WM8974_POWER2		0x2
++#define WM8974_POWER3		0x3
++#define WM8974_IFACE		0x4
++#define WM8974_COMP			0x5
++#define WM8974_CLOCK		0x6
++#define WM8974_ADD			0x7
++#define WM8974_GPIO			0x8
++#define WM8974_DAC			0xa
++#define WM8974_DACVOL		0xb
++#define WM8974_ADC			0xe
++#define WM8974_ADCVOL		0xf
++#define WM8974_EQ1			0x12
++#define WM8974_EQ2			0x13
++#define WM8974_EQ3			0x14
++#define WM8974_EQ4			0x15
++#define WM8974_EQ5			0x16
++#define WM8974_DACLIM1		0x18
++#define WM8974_DACLIM2		0x19
++#define WM8974_NOTCH1		0x1b
++#define WM8974_NOTCH2		0x1c
++#define WM8974_NOTCH3		0x1d
++#define WM8974_NOTCH4		0x1e
++#define WM8974_ALC1			0x20
++#define WM8974_ALC2			0x21
++#define WM8974_ALC3			0x22
++#define WM8974_NGATE		0x23
++#define WM8974_PLLN			0x24
++#define WM8974_PLLK1		0x25
++#define WM8974_PLLK2		0x26
++#define WM8974_PLLK3		0x27
++#define WM8974_ATTEN		0x28
++#define WM8974_INPUT		0x2c
++#define WM8974_INPPGA		0x2d
++#define WM8974_ADCBOOST		0x2f
++#define WM8974_OUTPUT		0x31
++#define WM8974_SPKMIX		0x32
++#define WM8974_SPKVOL		0x36
++#define WM8974_MONOMIX		0x38
++
++#define WM8974_CACHEREGNUM 	57
++
++/* Clock divider Id's */
++#define WM8974_OPCLKDIV		0
++#define WM8974_MCLKDIV		1
++#define WM8974_ADCCLK		2
++#define WM8974_DACCLK		3
++#define WM8974_BCLKDIV		4
++
++/* DAC clock dividers */
++#define WM8974_DACCLK_F2	(1 << 3)
++#define WM8974_DACCLK_F4	(0 << 3)
++
++/* ADC clock dividers */
++#define WM8974_ADCCLK_F2	(1 << 3)
++#define WM8974_ADCCLK_F4	(0 << 3)
++
++/* PLL Out dividers */
++#define WM8974_OPCLKDIV_1	(0 << 4)
++#define WM8974_OPCLKDIV_2	(1 << 4)
++#define WM8974_OPCLKDIV_3	(2 << 4)
++#define WM8974_OPCLKDIV_4	(3 << 4)
++
++/* BCLK clock dividers */
++#define WM8974_BCLKDIV_1	(0 << 2)
++#define WM8974_BCLKDIV_2	(1 << 2)
++#define WM8974_BCLKDIV_4	(2 << 2)
++#define WM8974_BCLKDIV_8	(3 << 2)
++#define WM8974_BCLKDIV_16	(4 << 2)
++#define WM8974_BCLKDIV_32	(5 << 2)
++
++/* MCLK clock dividers */
++#define WM8974_MCLKDIV_1	(0 << 5)
++#define WM8974_MCLKDIV_1_5	(1 << 5)
++#define WM8974_MCLKDIV_2	(2 << 5)
++#define WM8974_MCLKDIV_3	(3 << 5)
++#define WM8974_MCLKDIV_4	(4 << 5)
++#define WM8974_MCLKDIV_6	(5 << 5)
++#define WM8974_MCLKDIV_8	(6 << 5)
++#define WM8974_MCLKDIV_12	(7 << 5)
++
++
++struct wm8974_setup_data {
++	unsigned short i2c_address;
++};
++
++extern struct snd_soc_codec_dai wm8974_dai;
++extern struct snd_soc_codec_device soc_codec_dev_wm8974;
++
++#endif
+Index: linux-2.6.22.1/sound/soc/codecs/wm9713.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/wm9713.c	2007-07-16 15:07:34.148283271 +0200
+@@ -0,0 +1,1220 @@
++/*
++ * wm9713.c  --  ALSA Soc WM9713 codec support
++ *
++ * Copyright 2006 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ *         liam.girdwood at wolfsonmicro.com or linux at wolfsonmicro.com
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ *  Revision history
++ *    4th Feb 2006   Initial version.
++ *
++ *  Features:-
++ *
++ *   o Support for AC97 Codec, Voice DAC and Aux DAC
++ *   o Support for DAPM
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/device.h>
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/ac97_codec.h>
++#include <sound/initval.h>
++#include <sound/pcm_params.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include "wm9713.h"
++
++#define WM9713_VERSION "0.12"
++
++struct wm9713_priv {
++	u32 pll_in; /* PLL input frequency */
++	u32 pll_out; /* PLL output frequency */
++};
++
++static unsigned int ac97_read(struct snd_soc_codec *codec,
++	unsigned int reg);
++static int ac97_write(struct snd_soc_codec *codec,
++	unsigned int reg, unsigned int val);
++
++/*
++ * WM9713 register cache
++ * Reg 0x3c bit 15 is used by touch driver.
++ */
++static const u16 wm9713_reg[] = {
++	0x6174, 0x8080, 0x8080, 0x8080, // 6
++	0xc880, 0xe808, 0xe808, 0x0808, // e
++	0x00da, 0x8000, 0xd600, 0xaaa0, // 16
++	0xaaa0, 0xaaa0, 0x0000, 0x0000, // 1e
++	0x0f0f, 0x0040, 0x0000, 0x7f00, // 26
++	0x0405, 0x0410, 0xbb80, 0xbb80, // 2e
++	0x0000, 0xbb80, 0x0000, 0x4523, // 36
++	0x0000, 0x2000, 0x7eff, 0xffff, // 3e
++	0x0000, 0x0000, 0x0080, 0x0000, // 46
++	0x0000, 0x0000, 0xfffe, 0xffff, // 4e
++	0x0000, 0x0000, 0x0000, 0xfffe, // 56
++	0x4000, 0x0000, 0x0000, 0x0000, // 5e
++	0xb032, 0x3e00, 0x0000, 0x0000, // 66
++	0x0000, 0x0000, 0x0000, 0x0000, // 6e
++	0x0000, 0x0000, 0x0000, 0x0006, // 76
++	0x0001, 0x0000, 0x574d, 0x4c13, // 7e
++	0x0000, 0x0000, 0x0000 // virtual hp & mic mixers
++};
++
++/* virtual HP mixers regs */
++#define HPL_MIXER	0x80
++#define HPR_MIXER	0x82
++#define MICB_MUX	0x82
++
++static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
++static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
++static const char *wm9713_rec_src[] =
++	{"Mic 1", "Mic 2", "Line", "Mono In", "Headphone", "Speaker",
++	"Mono Out", "Zh"};
++static const char *wm9713_rec_gain[] = {"+1.5dB Steps", "+0.75dB Steps"};
++static const char *wm9713_alc_select[] = {"None", "Left", "Right", "Stereo"};
++static const char *wm9713_mono_pga[] = {"Vmid", "Zh", "Mono", "Inv",
++	"Mono Vmid", "Inv Vmid"};
++static const char *wm9713_spk_pga[] =
++	{"Vmid", "Zh", "Headphone", "Speaker", "Inv", "Headphone Vmid",
++	"Speaker Vmid", "Inv Vmid"};
++static const char *wm9713_hp_pga[] = {"Vmid", "Zh", "Headphone",
++	"Headphone Vmid"};
++static const char *wm9713_out3_pga[] = {"Vmid", "Zh", "Inv 1", "Inv 1 Vmid"};
++static const char *wm9713_out4_pga[] = {"Vmid", "Zh", "Inv 2", "Inv 2 Vmid"};
++static const char *wm9713_dac_inv[] =
++	{"Off", "Mono", "Speaker", "Left Headphone", "Right Headphone",
++	"Headphone Mono", "NC", "Vmid"};
++static const char *wm9713_bass[] = {"Linear Control", "Adaptive Boost"};
++static const char *wm9713_ng_type[] = {"Constant Gain", "Mute"};
++static const char *wm9713_mic_select[] = {"Mic 1", "Mic 2 A", "Mic 2 B"};
++static const char *wm9713_micb_select[] = {"MPB", "MPA"};
++
++static const struct soc_enum wm9713_enum[] = {
++SOC_ENUM_SINGLE(AC97_LINE, 3, 4, wm9713_mic_mixer), /* record mic mixer 0 */
++SOC_ENUM_SINGLE(AC97_VIDEO, 14, 4, wm9713_rec_mux), /* record mux hp 1 */
++SOC_ENUM_SINGLE(AC97_VIDEO, 9, 4, wm9713_rec_mux),  /* record mux mono 2 */
++SOC_ENUM_SINGLE(AC97_VIDEO, 3, 8, wm9713_rec_src),  /* record mux left 3 */
++SOC_ENUM_SINGLE(AC97_VIDEO, 0, 8, wm9713_rec_src),  /* record mux right 4*/
++SOC_ENUM_DOUBLE(AC97_CD, 14, 6, 2, wm9713_rec_gain), /* record step size 5 */
++SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9713_alc_select), /* alc source select 6*/
++SOC_ENUM_SINGLE(AC97_REC_GAIN, 14, 4, wm9713_mono_pga), /* mono input select 7 */
++SOC_ENUM_SINGLE(AC97_REC_GAIN, 11, 8, wm9713_spk_pga), /* speaker left input select 8 */
++SOC_ENUM_SINGLE(AC97_REC_GAIN, 8, 8, wm9713_spk_pga), /* speaker right input select 9 */
++SOC_ENUM_SINGLE(AC97_REC_GAIN, 6, 3, wm9713_hp_pga), /* headphone left input 10 */
++SOC_ENUM_SINGLE(AC97_REC_GAIN, 4, 3, wm9713_hp_pga), /* headphone right input 11 */
++SOC_ENUM_SINGLE(AC97_REC_GAIN, 2, 4, wm9713_out3_pga), /* out 3 source 12 */
++SOC_ENUM_SINGLE(AC97_REC_GAIN, 0, 4, wm9713_out4_pga), /* out 4 source 13 */
++SOC_ENUM_SINGLE(AC97_REC_GAIN_MIC, 13, 8, wm9713_dac_inv), /* dac invert 1 14 */
++SOC_ENUM_SINGLE(AC97_REC_GAIN_MIC, 10, 8, wm9713_dac_inv), /* dac invert 2 15 */
++SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, wm9713_bass), /* bass control 16 */
++SOC_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type), /* noise gate type 17 */
++SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18 */
++SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */
++};
++
++static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = {
++SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1),
++SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1),
++SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1),
++SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE,15, 7, 1, 1),
++SOC_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1),
++SOC_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1),
++SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
++SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
++
++SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
++SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
++
++SOC_SINGLE("Capture Switch", AC97_CD, 15, 1, 1),
++SOC_ENUM("Capture Volume Steps", wm9713_enum[5]),
++SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0),
++SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
++
++SOC_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1),
++SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
++SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
++
++SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
++SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
++SOC_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0),
++SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
++SOC_ENUM("ALC Function", wm9713_enum[6]),
++SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
++SOC_SINGLE("ALC ZC Timeout", AC97_PCI_SVID, 9, 3, 0),
++SOC_SINGLE("ALC ZC Switch", AC97_PCI_SVID, 8, 1, 0),
++SOC_SINGLE("ALC NG Switch", AC97_PCI_SVID, 7, 1, 0),
++SOC_ENUM("ALC NG Type", wm9713_enum[17]),
++SOC_SINGLE("ALC NG Threshold", AC97_PCI_SVID, 0, 31, 0),
++
++SOC_DOUBLE("Speaker Playback ZC Switch", AC97_MASTER, 14, 6, 1, 0),
++SOC_DOUBLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
++
++SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
++SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0),
++SOC_SINGLE("Out4 Playback Volume", AC97_MASTER_MONO, 8, 63, 1),
++
++SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1),
++SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0),
++SOC_SINGLE("Out3 Playback Volume", AC97_MASTER_MONO, 0, 63, 1),
++
++SOC_SINGLE("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1),
++SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
++SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
++SOC_SINGLE("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1),
++
++SOC_SINGLE("PC Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1),
++SOC_SINGLE("PC Beep Playback Speaker Volume", AC97_AUX, 8, 7, 1),
++SOC_SINGLE("PC Beep Playback Mono Volume", AC97_AUX, 4, 7, 1),
++
++SOC_SINGLE("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1),
++SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
++SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1),
++
++SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1),
++SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1),
++SOC_SINGLE("Aux Playback Mono Volume", AC97_REC_SEL, 4, 7, 1),
++
++SOC_ENUM("Bass Control", wm9713_enum[16]),
++SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
++SOC_SINGLE("Tone Cut-off Switch", AC97_GENERAL_PURPOSE, 4, 1, 1),
++SOC_SINGLE("Playback Attenuate (-6dB) Switch", AC97_GENERAL_PURPOSE, 6, 1, 0),
++SOC_SINGLE("Bass Volume", AC97_GENERAL_PURPOSE, 8, 15, 1),
++SOC_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1),
++
++SOC_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
++SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
++SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
++};
++
++/* add non dapm controls */
++static int wm9713_add_controls(struct snd_soc_codec *codec)
++{
++	int err, i;
++
++	for (i = 0; i < ARRAY_SIZE(wm9713_snd_ac97_controls); i++) {
++		err = snd_ctl_add(codec->card,
++				snd_soc_cnew(&wm9713_snd_ac97_controls[i],codec, NULL));
++		if (err < 0)
++			return err;
++	}
++	return 0;
++}
++
++/* We have to create a fake left and right HP mixers because
++ * the codec only has a single control that is shared by both channels.
++ * This makes it impossible to determine the audio path using the current
++ * register map, thus we add a new (virtual) register to help determine the
++ * audio route within the device.
++ */
++static int mixer_event (struct snd_soc_dapm_widget *w, int event)
++{
++	u16 l, r, beep, tone, phone, rec, pcm, aux;
++
++	l = ac97_read(w->codec, HPL_MIXER);
++	r = ac97_read(w->codec, HPR_MIXER);
++	beep = ac97_read(w->codec, AC97_PC_BEEP);
++	tone = ac97_read(w->codec, AC97_MASTER_TONE);
++	phone = ac97_read(w->codec, AC97_PHONE);
++	rec = ac97_read(w->codec, AC97_REC_SEL);
++	pcm = ac97_read(w->codec, AC97_PCM);
++	aux = ac97_read(w->codec, AC97_AUX);
++
++	if (event & SND_SOC_DAPM_PRE_REG)
++		return 0;
++	if (l & 0x1 || r & 0x1)
++		ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff);
++	else
++		ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000);
++
++	if (l & 0x2 || r & 0x2)
++		ac97_write(w->codec, AC97_MASTER_TONE, tone & 0x7fff);
++	else
++		ac97_write(w->codec, AC97_MASTER_TONE, tone | 0x8000);
++
++	if (l & 0x4 || r & 0x4)
++		ac97_write(w->codec, AC97_PHONE, phone & 0x7fff);
++	else
++		ac97_write(w->codec, AC97_PHONE, phone | 0x8000);
++
++	if (l & 0x8 || r & 0x8)
++		ac97_write(w->codec, AC97_REC_SEL, rec & 0x7fff);
++	else
++		ac97_write(w->codec, AC97_REC_SEL, rec | 0x8000);
++
++	if (l & 0x10 || r & 0x10)
++		ac97_write(w->codec, AC97_PCM, pcm & 0x7fff);
++	else
++		ac97_write(w->codec, AC97_PCM, pcm | 0x8000);
++
++	if (l & 0x20 || r & 0x20)
++		ac97_write(w->codec, AC97_AUX, aux & 0x7fff);
++	else
++		ac97_write(w->codec, AC97_AUX, aux | 0x8000);
++
++	return 0;
++}
++
++/* Left Headphone Mixers */
++static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = {
++SOC_DAPM_SINGLE("PC Beep Playback Switch", HPL_MIXER, 5, 1, 0),
++SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0),
++SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0),
++SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0),
++SOC_DAPM_SINGLE("MonoIn Playback Switch", HPL_MIXER, 1, 1, 0),
++SOC_DAPM_SINGLE("Bypass Playback Switch", HPL_MIXER, 0, 1, 0),
++};
++
++/* Right Headphone Mixers */
++static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = {
++SOC_DAPM_SINGLE("PC Beep Playback Switch", HPR_MIXER, 5, 1, 0),
++SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0),
++SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0),
++SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0),
++SOC_DAPM_SINGLE("MonoIn Playback Switch", HPR_MIXER, 1, 1, 0),
++SOC_DAPM_SINGLE("Bypass Playback Switch", HPR_MIXER, 0, 1, 0),
++};
++
++/* headphone capture mux */
++static const struct snd_kcontrol_new wm9713_hp_rec_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[1]);
++
++/* headphone mic mux */
++static const struct snd_kcontrol_new wm9713_hp_mic_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[0]);
++
++/* Speaker Mixer */
++static const struct snd_kcontrol_new wm9713_speaker_mixer_controls[] = {
++SOC_DAPM_SINGLE("PC Beep Playback Switch", AC97_AUX, 11, 1, 1),
++SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 11, 1, 1),
++SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 11, 1, 1),
++SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 14, 1, 1),
++SOC_DAPM_SINGLE("MonoIn Playback Switch", AC97_MASTER_TONE, 14, 1, 1),
++SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 14, 1, 1),
++};
++
++/* Mono Mixer */
++static const struct snd_kcontrol_new wm9713_mono_mixer_controls[] = {
++SOC_DAPM_SINGLE("PC Beep Playback Switch", AC97_AUX, 7, 1, 1),
++SOC_DAPM_SINGLE("Voice Playback Switch", AC97_PCM, 7, 1, 1),
++SOC_DAPM_SINGLE("Aux Playback Switch", AC97_REC_SEL, 7, 1, 1),
++SOC_DAPM_SINGLE("PCM Playback Switch", AC97_PHONE, 13, 1, 1),
++SOC_DAPM_SINGLE("MonoIn Playback Switch", AC97_MASTER_TONE, 13, 1, 1),
++SOC_DAPM_SINGLE("Bypass Playback Switch", AC97_PC_BEEP, 13, 1, 1),
++SOC_DAPM_SINGLE("Mic 1 Sidetone Switch", AC97_LINE, 7, 1, 1),
++SOC_DAPM_SINGLE("Mic 2 Sidetone Switch", AC97_LINE, 6, 1, 1),
++};
++
++/* mono mic mux */
++static const struct snd_kcontrol_new wm9713_mono_mic_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[2]);
++
++/* mono output mux */
++static const struct snd_kcontrol_new wm9713_mono_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[7]);
++
++/* speaker left output mux */
++static const struct snd_kcontrol_new wm9713_hp_spkl_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[8]);
++
++/* speaker right output mux */
++static const struct snd_kcontrol_new wm9713_hp_spkr_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[9]);
++
++/* headphone left output mux */
++static const struct snd_kcontrol_new wm9713_hpl_out_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[10]);
++
++/* headphone right output mux */
++static const struct snd_kcontrol_new wm9713_hpr_out_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[11]);
++
++/* Out3 mux */
++static const struct snd_kcontrol_new wm9713_out3_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[12]);
++
++/* Out4 mux */
++static const struct snd_kcontrol_new wm9713_out4_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[13]);
++
++/* DAC inv mux 1 */
++static const struct snd_kcontrol_new wm9713_dac_inv1_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[14]);
++
++/* DAC inv mux 2 */
++static const struct snd_kcontrol_new wm9713_dac_inv2_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[15]);
++
++/* Capture source left */
++static const struct snd_kcontrol_new wm9713_rec_srcl_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[3]);
++
++/* Capture source right */
++static const struct snd_kcontrol_new wm9713_rec_srcr_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[4]);
++
++/* mic source */
++static const struct snd_kcontrol_new wm9713_mic_sel_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[18]);
++
++/* mic source B virtual control */
++static const struct snd_kcontrol_new wm9713_micb_sel_mux_controls =
++SOC_DAPM_ENUM("Route", wm9713_enum[19]);
++
++static const struct snd_soc_dapm_widget wm9713_dapm_widgets[] = {
++SND_SOC_DAPM_MUX("Capture Headphone Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_hp_rec_mux_controls),
++SND_SOC_DAPM_MUX("Sidetone Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_hp_mic_mux_controls),
++SND_SOC_DAPM_MUX("Capture Mono Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_mono_mic_mux_controls),
++SND_SOC_DAPM_MUX("Mono Out Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_mono_mux_controls),
++SND_SOC_DAPM_MUX("Left Speaker Out Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_hp_spkl_mux_controls),
++SND_SOC_DAPM_MUX("Right Speaker Out Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_hp_spkr_mux_controls),
++SND_SOC_DAPM_MUX("Left Headphone Out Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_hpl_out_mux_controls),
++SND_SOC_DAPM_MUX("Right Headphone Out Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_hpr_out_mux_controls),
++SND_SOC_DAPM_MUX("Out 3 Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_out3_mux_controls),
++SND_SOC_DAPM_MUX("Out 4 Mux", SND_SOC_NOPM, 0, 0,
++	&wm9713_out4_mux_controls),
++SND_SOC_DAPM_MUX("DAC Inv Mux 1", SND_SOC_NOPM, 0, 0,
++	&wm9713_dac_inv1_mux_controls),
++SND_SOC_DAPM_MUX("DAC Inv Mux 2", SND_SOC_NOPM, 0, 0,
++	&wm9713_dac_inv2_mux_controls),
++SND_SOC_DAPM_MUX("Left Capture Source", SND_SOC_NOPM, 0, 0,
++	&wm9713_rec_srcl_mux_controls),
++SND_SOC_DAPM_MUX("Right Capture Source", SND_SOC_NOPM, 0, 0,
++	&wm9713_rec_srcr_mux_controls),
++SND_SOC_DAPM_MUX("Mic A Source", SND_SOC_NOPM, 0, 0,
++	&wm9713_mic_sel_mux_controls ),
++SND_SOC_DAPM_MUX("Mic B Source", SND_SOC_NOPM, 0, 0,
++	&wm9713_micb_sel_mux_controls ),
++SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_EXTENDED_MID, 3, 1,
++	&wm9713_hpl_mixer_controls[0], ARRAY_SIZE(wm9713_hpl_mixer_controls),
++	mixer_event, SND_SOC_DAPM_POST_REG),
++SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_EXTENDED_MID, 2, 1,
++	&wm9713_hpr_mixer_controls[0], ARRAY_SIZE(wm9713_hpr_mixer_controls),
++	mixer_event, SND_SOC_DAPM_POST_REG),
++SND_SOC_DAPM_MIXER("Mono Mixer", AC97_EXTENDED_MID, 0, 1,
++	&wm9713_mono_mixer_controls[0], ARRAY_SIZE(wm9713_mono_mixer_controls)),
++SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_EXTENDED_MID, 1, 1,
++	&wm9713_speaker_mixer_controls[0],
++	ARRAY_SIZE(wm9713_speaker_mixer_controls)),
++SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", AC97_EXTENDED_MID, 7, 1),
++SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", AC97_EXTENDED_MID, 6, 1),
++SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
++SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
++SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
++SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1),
++SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1),
++SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", AC97_EXTENDED_MID, 5, 1),
++SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", AC97_EXTENDED_MID, 4, 1),
++SND_SOC_DAPM_PGA("Left Headphone", AC97_EXTENDED_MSTATUS, 10, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Right Headphone", AC97_EXTENDED_MSTATUS, 9, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Left Speaker", AC97_EXTENDED_MSTATUS, 8, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Right Speaker", AC97_EXTENDED_MSTATUS, 7, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Out 3", AC97_EXTENDED_MSTATUS, 11, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Out 4", AC97_EXTENDED_MSTATUS, 12, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Mono Out", AC97_EXTENDED_MSTATUS, 13, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Left Line In", AC97_EXTENDED_MSTATUS, 6, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Right Line In", AC97_EXTENDED_MSTATUS, 5, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Mono In", AC97_EXTENDED_MSTATUS, 4, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Mic A PGA", AC97_EXTENDED_MSTATUS, 3, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Mic B PGA", AC97_EXTENDED_MSTATUS, 2, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Mic A Pre Amp", AC97_EXTENDED_MSTATUS, 1, 1, NULL, 0),
++SND_SOC_DAPM_PGA("Mic B Pre Amp", AC97_EXTENDED_MSTATUS, 0, 1, NULL, 0),
++SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_EXTENDED_MSTATUS, 14, 1),
++SND_SOC_DAPM_OUTPUT("MONO"),
++SND_SOC_DAPM_OUTPUT("HPL"),
++SND_SOC_DAPM_OUTPUT("HPR"),
++SND_SOC_DAPM_OUTPUT("SPKL"),
++SND_SOC_DAPM_OUTPUT("SPKR"),
++SND_SOC_DAPM_OUTPUT("OUT3"),
++SND_SOC_DAPM_OUTPUT("OUT4"),
++SND_SOC_DAPM_INPUT("LINEL"),
++SND_SOC_DAPM_INPUT("LINER"),
++SND_SOC_DAPM_INPUT("MONOIN"),
++SND_SOC_DAPM_INPUT("PCBEEP"),
++SND_SOC_DAPM_INPUT("MIC1"),
++SND_SOC_DAPM_INPUT("MIC2A"),
++SND_SOC_DAPM_INPUT("MIC2B"),
++SND_SOC_DAPM_VMID("VMID"),
++};
++
++static const char *audio_map[][3] = {
++	/* left HP mixer */
++	{"Left HP Mixer", "PC Beep Playback Switch", "PCBEEP"},
++	{"Left HP Mixer", "Voice Playback Switch",   "Voice DAC"},
++	{"Left HP Mixer", "Aux Playback Switch",     "Aux DAC"},
++	{"Left HP Mixer", "Bypass Playback Switch",  "Left Line In"},
++	{"Left HP Mixer", "PCM Playback Switch",     "Left DAC"},
++	{"Left HP Mixer", "MonoIn Playback Switch",  "Mono In"},
++	{"Left HP Mixer", NULL,  "Capture Headphone Mux"},
++
++	/* right HP mixer */
++	{"Right HP Mixer", "PC Beep Playback Switch", "PCBEEP"},
++	{"Right HP Mixer", "Voice Playback Switch",   "Voice DAC"},
++	{"Right HP Mixer", "Aux Playback Switch",     "Aux DAC"},
++	{"Right HP Mixer", "Bypass Playback Switch",  "Right Line In"},
++	{"Right HP Mixer", "PCM Playback Switch",     "Right DAC"},
++	{"Right HP Mixer", "MonoIn Playback Switch",  "Mono In"},
++	{"Right HP Mixer", NULL,  "Capture Headphone Mux"},
++
++	/* virtual mixer - mixes left & right channels for spk and mono */
++	{"AC97 Mixer", NULL, "Left DAC"},
++	{"AC97 Mixer", NULL, "Right DAC"},
++	{"Line Mixer", NULL, "Right Line In"},
++	{"Line Mixer", NULL, "Left Line In"},
++	{"HP Mixer", NULL, "Left HP Mixer"},
++	{"HP Mixer", NULL, "Right HP Mixer"},
++	{"Capture Mixer", NULL, "Left Capture Source"},
++	{"Capture Mixer", NULL, "Right Capture Source"},
++
++	/* speaker mixer */
++	{"Speaker Mixer", "PC Beep Playback Switch", "PCBEEP"},
++	{"Speaker Mixer", "Voice Playback Switch",   "Voice DAC"},
++	{"Speaker Mixer", "Aux Playback Switch",     "Aux DAC"},
++	{"Speaker Mixer", "Bypass Playback Switch",  "Line Mixer"},
++	{"Speaker Mixer", "PCM Playback Switch",     "AC97 Mixer"},
++	{"Speaker Mixer", "MonoIn Playback Switch",  "Mono In"},
++
++	/* mono mixer */
++	{"Mono Mixer", "PC Beep Playback Switch", "PCBEEP"},
++	{"Mono Mixer", "Voice Playback Switch",   "Voice DAC"},
++	{"Mono Mixer", "Aux Playback Switch",     "Aux DAC"},
++	{"Mono Mixer", "Bypass Playback Switch",  "Line Mixer"},
++	{"Mono Mixer", "PCM Playback Switch",     "AC97 Mixer"},
++	{"Mono Mixer", NULL,  "Capture Mono Mux"},
++
++	/* DAC inv mux 1 */
++	{"DAC Inv Mux 1", "Mono", "Mono Mixer"},
++	{"DAC Inv Mux 1", "Speaker", "Speaker Mixer"},
++	{"DAC Inv Mux 1", "Left Headphone", "Left HP Mixer"},
++	{"DAC Inv Mux 1", "Right Headphone", "Right HP Mixer"},
++	{"DAC Inv Mux 1", "Headphone Mono", "HP Mixer"},
++
++	/* DAC inv mux 2 */
++	{"DAC Inv Mux 2", "Mono", "Mono Mixer"},
++	{"DAC Inv Mux 2", "Speaker", "Speaker Mixer"},
++	{"DAC Inv Mux 2", "Left Headphone", "Left HP Mixer"},
++	{"DAC Inv Mux 2", "Right Headphone", "Right HP Mixer"},
++	{"DAC Inv Mux 2", "Headphone Mono", "HP Mixer"},
++
++	/* headphone left mux */
++	{"Left Headphone Out Mux", "Headphone", "Left HP Mixer"},
++
++	/* headphone right mux */
++	{"Right Headphone Out Mux", "Headphone", "Right HP Mixer"},
++
++	/* speaker left mux */
++	{"Left Speaker Out Mux", "Headphone", "Left HP Mixer"},
++	{"Left Speaker Out Mux", "Speaker", "Speaker Mixer"},
++	{"Left Speaker Out Mux", "Inv", "DAC Inv Mux 1"},
++
++	/* speaker right mux */
++	{"Right Speaker Out Mux", "Headphone", "Right HP Mixer"},
++	{"Right Speaker Out Mux", "Speaker", "Speaker Mixer"},
++	{"Right Speaker Out Mux", "Inv", "DAC Inv Mux 2"},
++
++	/* mono mux */
++	{"Mono Out Mux", "Mono", "Mono Mixer"},
++	{"Mono Out Mux", "Inv", "DAC Inv Mux 1"},
++
++	/* out 3 mux */
++	{"Out 3 Mux", "Inv 1", "DAC Inv Mux 1"},
++
++	/* out 4 mux */
++	{"Out 4 Mux", "Inv 2", "DAC Inv Mux 2"},
++
++	/* output pga */
++	{"HPL", NULL, "Left Headphone"},
++	{"Left Headphone", NULL, "Left Headphone Out Mux"},
++	{"HPR", NULL, "Right Headphone"},
++	{"Right Headphone", NULL, "Right Headphone Out Mux"},
++	{"OUT3", NULL, "Out 3"},
++	{"Out 3", NULL, "Out 3 Mux"},
++	{"OUT4", NULL, "Out 4"},
++	{"Out 4", NULL, "Out 4 Mux"},
++	{"SPKL", NULL, "Left Speaker"},
++	{"Left Speaker", NULL, "Left Speaker Out Mux"},
++	{"SPKR", NULL, "Right Speaker"},
++	{"Right Speaker", NULL, "Right Speaker Out Mux"},
++	{"MONO", NULL, "Mono Out"},
++	{"Mono Out", NULL, "Mono Out Mux"},
++
++	/* input pga */
++	{"Left Line In", NULL, "LINEL"},
++	{"Right Line In", NULL, "LINER"},
++	{"Mono In", NULL, "MONOIN"},
++	{"Mic A PGA", NULL, "Mic A Pre Amp"},
++	{"Mic B PGA", NULL, "Mic B Pre Amp"},
++
++	/* left capture select */
++	{"Left Capture Source", "Mic 1", "Mic A Pre Amp"},
++	{"Left Capture Source", "Mic 2", "Mic B Pre Amp"},
++	{"Left Capture Source", "Line", "LINEL"},
++	{"Left Capture Source", "Mono In", "MONOIN"},
++	{"Left Capture Source", "Headphone", "Left HP Mixer"},
++	{"Left Capture Source", "Speaker", "Speaker Mixer"},
++	{"Left Capture Source", "Mono Out", "Mono Mixer"},
++
++	/* right capture select */
++	{"Right Capture Source", "Mic 1", "Mic A Pre Amp"},
++	{"Right Capture Source", "Mic 2", "Mic B Pre Amp"},
++	{"Right Capture Source", "Line", "LINER"},
++	{"Right Capture Source", "Mono In", "MONOIN"},
++	{"Right Capture Source", "Headphone", "Right HP Mixer"},
++	{"Right Capture Source", "Speaker", "Speaker Mixer"},
++	{"Right Capture Source", "Mono Out", "Mono Mixer"},
++
++	/* left ADC */
++	{"Left ADC", NULL, "Left Capture Source"},
++
++	/* right ADC */
++	{"Right ADC", NULL, "Right Capture Source"},
++
++	/* mic */
++	{"Mic A Pre Amp", NULL, "Mic A Source"},
++	{"Mic A Source", "Mic 1", "MIC1"},
++	{"Mic A Source", "Mic 2 A", "MIC2A"},
++	{"Mic A Source", "Mic 2 B", "Mic B Source"},
++	{"Mic B Pre Amp", "MPB", "Mic B Source"},
++	{"Mic B Source", NULL, "MIC2B"},
++
++	/* headphone capture */
++	{"Capture Headphone Mux", "Stereo", "Capture Mixer"},
++	{"Capture Headphone Mux", "Left", "Left Capture Source"},
++	{"Capture Headphone Mux", "Right", "Right Capture Source"},
++
++	/* mono capture */
++	{"Capture Mono Mux", "Stereo", "Capture Mixer"},
++	{"Capture Mono Mux", "Left", "Left Capture Source"},
++	{"Capture Mono Mux", "Right", "Right Capture Source"},
++
++	{NULL, NULL, NULL},
++};
++
++static int wm9713_add_widgets(struct snd_soc_codec *codec)
++{
++	int i;
++
++	for(i = 0; i < ARRAY_SIZE(wm9713_dapm_widgets); i++) {
++		snd_soc_dapm_new_control(codec, &wm9713_dapm_widgets[i]);
++	}
++
++	/* set up audio path audio_mapnects */
++	for(i = 0; audio_map[i][0] != NULL; i++) {
++		snd_soc_dapm_connect_input(codec, audio_map[i][0],
++			audio_map[i][1], audio_map[i][2]);
++	}
++
++	snd_soc_dapm_new_widgets(codec);
++	return 0;
++}
++
++static unsigned int ac97_read(struct snd_soc_codec *codec,
++	unsigned int reg)
++{
++	u16 *cache = codec->reg_cache;
++
++	if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
++		reg == AC97_VENDOR_ID1 || reg == AC97_VENDOR_ID2 ||
++		reg == AC97_CD)
++		return soc_ac97_ops.read(codec->ac97, reg);
++	else {
++		reg = reg >> 1;
++
++		if (reg > (ARRAY_SIZE(wm9713_reg)))
++			return -EIO;
++
++		return cache[reg];
++	}
++}
++
++static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
++	unsigned int val)
++{
++	u16 *cache = codec->reg_cache;
++	if (reg < 0x7c)
++		soc_ac97_ops.write(codec->ac97, reg, val);
++	reg = reg >> 1;
++	if (reg <= (ARRAY_SIZE(wm9713_reg)))
++		cache[reg] = val;
++
++	return 0;
++}
++
++struct pll_ {
++	unsigned int in_hz;
++	unsigned int lf:1; /* allows low frequency use */
++	unsigned int sdm:1; /* allows fraction n div */
++	unsigned int divsel:1; /* enables input clock div */
++	unsigned int divctl:1; /* input clock divider */
++	unsigned int n:4;
++	unsigned int k;
++};
++
++struct pll_ pll[] = {
++	{13000000, 0, 1, 0, 0, 7, 0x23f488},
++	{2048000,  1, 0, 0, 0, 12, 0x0},
++	{4096000,  1, 0, 0, 0, 6, 0x0},
++	{12288000, 0, 0, 0, 0, 8, 0x0},
++	/* liam - add more entries */
++};
++
++static int wm9713_set_pll(struct snd_soc_codec *codec,
++	int pll_id, unsigned int freq_in, unsigned int freq_out)
++{
++	struct wm9713_priv *wm9713 = codec->private_data;
++	int i;
++	u16 reg, reg2;
++
++	/* turn PLL off ? */
++	if (freq_in == 0 || freq_out == 0) {
++		/* disable PLL power and select ext source */
++		reg = ac97_read(codec, AC97_HANDSET_RATE);
++		ac97_write(codec, AC97_HANDSET_RATE, reg | 0x0080);
++		reg = ac97_read(codec, AC97_EXTENDED_MID);
++		ac97_write(codec, AC97_EXTENDED_MID, reg | 0x0200);
++		wm9713->pll_out = 0;
++		return 0;
++	}
++
++	for (i = 0; i < ARRAY_SIZE(pll); i++) {
++		if (pll[i].in_hz == freq_in)
++			goto found;
++	}
++	return -EINVAL;
++
++found:
++	if (pll[i].sdm == 0) {
++		reg = (pll[i].n << 12) | (pll[i].lf << 11) |
++			(pll[i].divsel << 9) | (pll[i].divctl << 8);
++		ac97_write(codec, AC97_LINE1_LEVEL, reg);
++	} else {
++		/* write the fractional k to the reg 0x46 pages */
++		reg2 = (pll[i].n << 12) | (pll[i].lf << 11) | (pll[i].sdm << 10) |
++			(pll[i].divsel << 9) | (pll[i].divctl << 8);
++
++		reg = reg2 | (0x5 << 4) | (pll[i].k >> 20); /* K [21:20] */
++		ac97_write(codec, AC97_LINE1_LEVEL, reg);
++
++		reg = reg2 | (0x4 << 4) | ((pll[i].k >> 16) & 0xf); /* K [19:16] */
++		ac97_write(codec, AC97_LINE1_LEVEL, reg);
++
++		reg = reg2 | (0x3 << 4) | ((pll[i].k >> 12) & 0xf); /* K [15:12] */
++		ac97_write(codec, AC97_LINE1_LEVEL, reg);
++
++		reg = reg2 | (0x2 << 4) | ((pll[i].k >> 8) & 0xf); /* K [11:8] */
++		ac97_write(codec, AC97_LINE1_LEVEL, reg);
++
++		reg = reg2 | (0x1 << 4) | ((pll[i].k >> 4) & 0xf); /* K [7:4] */
++		ac97_write(codec, AC97_LINE1_LEVEL, reg);
++
++		reg = reg2 | (0x0 << 4) | (pll[i].k & 0xf); /* K [3:0] */
++		ac97_write(codec, AC97_LINE1_LEVEL, reg);
++	}
++
++	/* turn PLL on and select as source */
++	reg = ac97_read(codec, AC97_EXTENDED_MID);
++	ac97_write(codec, AC97_EXTENDED_MID, reg & 0xfdff);
++	reg = ac97_read(codec, AC97_HANDSET_RATE);
++	ac97_write(codec, AC97_HANDSET_RATE, reg & 0xff7f);
++	wm9713->pll_out = freq_out;
++	wm9713->pll_in = freq_in;
++
++	/* wait 10ms AC97 link frames for the link to stabilise */
++	schedule_timeout_interruptible(msecs_to_jiffies(10));
++	return 0;
++}
++
++static int wm9713_set_dai_pll(struct snd_soc_codec_dai *codec_dai,
++		int pll_id, unsigned int freq_in, unsigned int freq_out)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
++}
++
++/*
++ * Tristate the PCM DAI lines, tristate can be disabled by calling
++ * wm9713_set_dai_fmt()
++ */
++static int wm9713_set_dai_tristate(struct snd_soc_codec_dai *codec_dai,
++	int tristate)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0x9fff;
++
++	if (tristate)
++		ac97_write(codec, AC97_CENTER_LFE_MASTER, reg);
++
++	return 0;
++}
++
++/*
++ * Configure WM9713 clock dividers.
++ * Voice DAC needs 256 FS
++ */
++static int wm9713_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai,
++		int div_id, int div)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 reg;
++
++	switch (div_id) {
++	case WM9713_PCMCLK_DIV:
++		reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xf0ff;
++		ac97_write(codec, AC97_HANDSET_RATE, reg | div);
++		break;
++	case WM9713_CLKA_MULT:
++		reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xfffd;
++		ac97_write(codec, AC97_HANDSET_RATE, reg | div);
++		break;
++	case WM9713_CLKB_MULT:
++		reg = ac97_read(codec, AC97_HANDSET_RATE) & 0xfffb;
++		ac97_write(codec, AC97_HANDSET_RATE, reg | div);
++		break;
++	case WM9713_HIFI_DIV:
++		reg = ac97_read(codec, AC97_HANDSET_RATE) & 0x8fff;
++		ac97_write(codec, AC97_HANDSET_RATE, reg | div);
++		break;
++	case WM9713_PCMBCLK_DIV:
++		reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xf1ff;
++		ac97_write(codec, AC97_CENTER_LFE_MASTER, reg | div);
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++};
++
++static int wm9713_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
++		unsigned int fmt)
++{
++	struct snd_soc_codec *codec = codec_dai->codec;
++	u16 gpio = ac97_read(codec, AC97_GPIO_CFG) & 0xffe2;
++	u16 reg = 0x8000;
++
++	/* clock masters */
++	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK){
++	case SND_SOC_DAIFMT_CBM_CFM:
++		reg |= 0x4000;
++		gpio |= 0x0008;
++		break;
++	case SND_SOC_DAIFMT_CBM_CFS:
++		reg |= 0x6000;
++		gpio |= 0x000c;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFS:
++		reg |= 0x0200;
++		gpio |= 0x000d;
++		break;
++	case SND_SOC_DAIFMT_CBS_CFM:
++		gpio |= 0x0009;
++		break;
++	}
++
++	/* clock inversion */
++	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
++	case SND_SOC_DAIFMT_IB_IF:
++		reg |= 0x00c0;
++		break;
++	case SND_SOC_DAIFMT_IB_NF:
++		reg |= 0x0080;
++		break;
++	case SND_SOC_DAIFMT_NB_IF:
++		reg |= 0x0040;
++		break;
++	}
++
++	/* DAI format */
++	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
++	case SND_SOC_DAIFMT_I2S:
++		reg |= 0x0002;
++		break;
++	case SND_SOC_DAIFMT_RIGHT_J:
++		break;
++	case SND_SOC_DAIFMT_LEFT_J:
++		reg |= 0x0001;
++		break;
++	case SND_SOC_DAIFMT_DSP_A:
++		reg |= 0x0003;
++		break;
++	case SND_SOC_DAIFMT_DSP_B:
++		reg |= 0x0043;
++		break;
++	}
++
++	ac97_write(codec, AC97_GPIO_CFG, gpio);
++	ac97_write(codec, AC97_CENTER_LFE_MASTER, reg);
++	return 0;
++}
++
++static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3;
++
++	switch (params_format(params)) {
++	case SNDRV_PCM_FORMAT_S16_LE:
++		break;
++	case SNDRV_PCM_FORMAT_S20_3LE:
++		reg |= 0x0004;
++		break;
++	case SNDRV_PCM_FORMAT_S24_LE:
++		reg |= 0x0008;
++		break;
++	case SNDRV_PCM_FORMAT_S32_LE:
++		reg |= 0x000c;
++		break;
++	}
++
++	/* enable PCM interface in master mode */
++	ac97_write(codec, AC97_CENTER_LFE_MASTER, reg);
++	return 0;
++}
++
++static void wm9713_voiceshutdown(snd_pcm_substream_t *substream)
++{
++    struct snd_soc_pcm_runtime *rtd = substream->private_data;
++    struct snd_soc_device *socdev = rtd->socdev;
++    struct snd_soc_codec *codec = socdev->codec;
++    u16 status;
++
++    /* Gracefully shut down the voice interface. */
++    status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000;
++    ac97_write(codec,AC97_HANDSET_RATE,0x0280);
++    schedule_timeout_interruptible(msecs_to_jiffies(1));
++    ac97_write(codec,AC97_HANDSET_RATE,0x0F80);
++    ac97_write(codec,AC97_EXTENDED_MID,status);
++}
++
++static int ac97_hifi_prepare(struct snd_pcm_substream *substream)
++{
++	struct snd_pcm_runtime *runtime = substream->runtime;
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	int reg;
++	u16 vra;
++
++	vra = ac97_read(codec, AC97_EXTENDED_STATUS);
++	ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
++
++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++		reg = AC97_PCM_FRONT_DAC_RATE;
++	else
++		reg = AC97_PCM_LR_ADC_RATE;
++
++	return ac97_write(codec, reg, runtime->rate);
++}
++
++static int ac97_aux_prepare(struct snd_pcm_substream *substream)
++{
++	struct snd_pcm_runtime *runtime = substream->runtime;
++	struct snd_soc_pcm_runtime *rtd = substream->private_data;
++	struct snd_soc_device *socdev = rtd->socdev;
++	struct snd_soc_codec *codec = socdev->codec;
++	u16 vra, xsle;
++
++	vra = ac97_read(codec, AC97_EXTENDED_STATUS);
++	ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
++	xsle = ac97_read(codec, AC97_PCI_SID);
++	ac97_write(codec, AC97_PCI_SID, xsle | 0x8000);
++
++	if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
++		return -ENODEV;
++
++	return ac97_write(codec, AC97_PCM_SURR_DAC_RATE, runtime->rate);
++}
++
++#define WM9713_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
++		SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
++
++#define WM9713_PCM_FORMATS \
++	(SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \
++	 SNDRV_PCM_FORMAT_S24_LE)
++
++struct snd_soc_codec_dai wm9713_dai[] = {
++{
++	.name = "AC97 HiFi",
++	.playback = {
++		.stream_name = "HiFi Playback",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = WM9713_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.capture = {
++		.stream_name = "HiFi Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = WM9713_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.ops = {
++		.prepare = ac97_hifi_prepare,},
++	},
++	{
++	.name = "AC97 Aux",
++	.playback = {
++		.stream_name = "Aux Playback",
++		.channels_min = 1,
++		.channels_max = 1,
++		.rates = WM9713_RATES,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.ops = {
++		.prepare = ac97_aux_prepare,},
++	},
++	{
++	.name = "WM9713 Voice",
++	.playback = {
++		.stream_name = "Voice Playback",
++		.channels_min = 1,
++		.channels_max = 1,
++		.rates = WM9713_RATES,
++		.formats = WM9713_PCM_FORMATS,},
++	.capture = {
++		.stream_name = "Voice Capture",
++		.channels_min = 1,
++		.channels_max = 2,
++		.rates = WM9713_RATES,
++		.formats = WM9713_PCM_FORMATS,},
++	.ops = {
++		.hw_params = wm9713_pcm_hw_params,
++		.shutdown = wm9713_voiceshutdown,},
++	.dai_ops = {
++		.set_clkdiv = wm9713_set_dai_clkdiv,
++		.set_pll = wm9713_set_dai_pll,
++		.set_fmt = wm9713_set_dai_fmt,
++		.set_tristate = wm9713_set_dai_tristate,
++	},
++	},
++};
++EXPORT_SYMBOL_GPL(wm9713_dai);
++
++int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
++{
++	if (try_warm && soc_ac97_ops.warm_reset) {
++		soc_ac97_ops.warm_reset(codec->ac97);
++		if (!(ac97_read(codec, 0) & 0x8000))
++			return 1;
++	}
++
++	soc_ac97_ops.reset(codec->ac97);
++	if (ac97_read(codec, 0) & 0x8000)
++		return -EIO;
++	return 0;
++}
++EXPORT_SYMBOL_GPL(wm9713_reset);
++
++static int wm9713_dapm_event(struct snd_soc_codec *codec, int event)
++{
++	u16 reg;
++
++	switch (event) {
++	case SNDRV_CTL_POWER_D0: /* full On */
++		/* enable thermal shutdown */
++		reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x1bff;
++		ac97_write(codec, AC97_EXTENDED_MID, reg);
++		break;
++	case SNDRV_CTL_POWER_D1: /* partial On */
++	case SNDRV_CTL_POWER_D2: /* partial On */
++		break;
++	case SNDRV_CTL_POWER_D3hot: /* Off, with power */
++		/* enable master bias and vmid */
++		reg = ac97_read(codec, AC97_EXTENDED_MID) & 0x3bff;
++		ac97_write(codec, AC97_EXTENDED_MID, reg);
++		ac97_write(codec, AC97_POWERDOWN, 0x0000);
++		break;
++	case SNDRV_CTL_POWER_D3cold: /* Off, without power */
++		/* disable everything including AC link */
++		ac97_write(codec, AC97_EXTENDED_MID, 0xffff);
++		ac97_write(codec, AC97_EXTENDED_MSTATUS, 0xffff);
++		ac97_write(codec, AC97_POWERDOWN, 0xffff);
++		break;
++	}
++	codec->dapm_state = event;
++	return 0;
++}
++
++static int wm9713_soc_suspend(struct platform_device *pdev,
++	pm_message_t state)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	wm9713_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
++	return 0;
++}
++
++static int wm9713_soc_resume(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++	struct wm9713_priv *wm9713 = codec->private_data;
++	int i, ret;
++	u16 *cache = codec->reg_cache;
++
++	if ((ret = wm9713_reset(codec, 1)) < 0){
++		printk(KERN_ERR "could not reset AC97 codec\n");
++		return ret;
++	}
++
++	wm9713_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++
++	/* do we need to re-start the PLL ? */
++	if (wm9713->pll_out)
++		wm9713_set_pll(codec, 0, wm9713->pll_in, wm9713->pll_out);
++
++	/* only synchronise the codec if warm reset failed */
++	if (ret == 0) {
++		for (i = 2; i < ARRAY_SIZE(wm9713_reg) << 1; i+=2) {
++			if (i == AC97_POWERDOWN || i == AC97_EXTENDED_MID ||
++				i == AC97_EXTENDED_MSTATUS || i > 0x66)
++				continue;
++			soc_ac97_ops.write(codec->ac97, i, cache[i>>1]);
++		}
++	}
++
++	if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0)
++		wm9713_dapm_event(codec, SNDRV_CTL_POWER_D0);
++
++	return ret;
++}
++
++static int wm9713_soc_probe(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec;
++	int ret = 0, reg;
++
++	printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION);
++
++	socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
++	if (socdev->codec == NULL)
++		return -ENOMEM;
++	codec = socdev->codec;
++	mutex_init(&codec->mutex);
++
++	codec->reg_cache =
++			kzalloc(sizeof(u16) * ARRAY_SIZE(wm9713_reg), GFP_KERNEL);
++	if (codec->reg_cache == NULL){
++		ret = -ENOMEM;
++		goto cache_err;
++	}
++	memcpy(codec->reg_cache, wm9713_reg,
++		sizeof(u16) * ARRAY_SIZE(wm9713_reg));
++	codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm9713_reg);
++	codec->reg_cache_step = 2;
++
++	codec->private_data = kzalloc(sizeof(struct wm9713_priv), GFP_KERNEL);
++	if (codec->private_data == NULL) {
++		ret = -ENOMEM;
++		goto priv_err;
++	}
++
++	codec->name = "WM9713";
++	codec->owner = THIS_MODULE;
++	codec->dai = wm9713_dai;
++	codec->num_dai = ARRAY_SIZE(wm9713_dai);
++	codec->write = ac97_write;
++	codec->read = ac97_read;
++	codec->dapm_event = wm9713_dapm_event;
++	INIT_LIST_HEAD(&codec->dapm_widgets);
++	INIT_LIST_HEAD(&codec->dapm_paths);
++
++	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
++	if (ret < 0)
++		goto codec_err;
++
++	/* register pcms */
++	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
++	if (ret < 0)
++		goto pcm_err;
++
++	/* do a cold reset for the controller and then try
++	 * a warm reset followed by an optional cold reset for codec */
++	wm9713_reset(codec, 0);
++	ret = wm9713_reset(codec, 1);
++	if (ret < 0) {
++		printk(KERN_ERR "AC97 link error\n");
++		goto reset_err;
++	}
++
++	wm9713_dapm_event(codec, SNDRV_CTL_POWER_D3hot);
++
++	/* unmute the adc - move to kcontrol */
++	reg = ac97_read(codec, AC97_CD) & 0x7fff;
++	ac97_write(codec, AC97_CD, reg);
++
++	wm9713_add_controls(codec);
++	wm9713_add_widgets(codec);
++	ret = snd_soc_register_card(socdev);
++	if (ret < 0)
++		goto reset_err;
++	return 0;
++
++reset_err:
++	snd_soc_free_pcms(socdev);
++
++pcm_err:
++	snd_soc_free_ac97_codec(codec);
++
++codec_err:
++	kfree(codec->private_data);
++
++priv_err:
++	kfree(codec->reg_cache);
++
++cache_err:
++	kfree(socdev->codec);
++	socdev->codec = NULL;
++	return ret;
++}
++
++static int wm9713_soc_remove(struct platform_device *pdev)
++{
++	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
++	struct snd_soc_codec *codec = socdev->codec;
++
++	if (codec == NULL)
++		return 0;
++
++	snd_soc_dapm_free(socdev);
++	snd_soc_free_pcms(socdev);
++	snd_soc_free_ac97_codec(codec);
++	kfree(codec->private_data);
++	kfree(codec->reg_cache);
++	kfree(codec->dai);
++	kfree(codec);
++	return 0;
++}
++
++struct snd_soc_codec_device soc_codec_dev_wm9713 = {
++	.probe = 	wm9713_soc_probe,
++	.remove = 	wm9713_soc_remove,
++	.suspend =	wm9713_soc_suspend,
++	.resume = 	wm9713_soc_resume,
++};
++
++EXPORT_SYMBOL_GPL(soc_codec_dev_wm9713);
++
++MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver");
++MODULE_AUTHOR("Liam Girdwood");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.22.1/sound/soc/codecs/wm9713.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/codecs/wm9713.h	2007-07-16 15:07:34.168284411 +0200
+@@ -0,0 +1,51 @@
++/*
++ * wm9713.h  --  WM9713 Soc Audio driver
++ */
++
++#ifndef _WM9713_H
++#define _WM9713_H
++
++/* clock inputs */
++#define WM9713_CLKA_PIN			0
++#define WM9713_CLKB_PIN			1
++
++/* clock divider ID's */
++#define WM9713_PCMCLK_DIV		0
++#define WM9713_CLKA_MULT		1
++#define WM9713_CLKB_MULT		2
++#define WM9713_HIFI_DIV			3
++#define WM9713_PCMBCLK_DIV		4
++
++/* PCM clk div */
++#define WM9713_PCMDIV(x)	((x - 1) << 8)
++
++/* HiFi Div */
++#define WM9713_HIFIDIV(x)	((x - 1) << 12)
++
++/* MCLK clock mulitipliers */
++#define WM9713_CLKA_X1		(0 << 1)
++#define WM9713_CLKA_X2		(1 << 1)
++#define WM9713_CLKB_X1		(0 << 2)
++#define WM9713_CLKB_X2		(1 << 2)
++
++/* MCLK clock MUX */
++#define WM9713_CLK_MUX_A		(0 << 0)
++#define WM9713_CLK_MUX_B		(1 << 0)
++
++/* Voice DAI BCLK divider */
++#define WM9713_PCMBCLK_DIV_1	(0 << 9)
++#define WM9713_PCMBCLK_DIV_2	(1 << 9)
++#define WM9713_PCMBCLK_DIV_4	(2 << 9)
++#define WM9713_PCMBCLK_DIV_8	(3 << 9)
++#define WM9713_PCMBCLK_DIV_16	(4 << 9)
++
++#define WM9713_DAI_AC97_HIFI	0
++#define WM9713_DAI_AC97_AUX		1
++#define WM9713_DAI_PCM_VOICE	2
++
++extern struct snd_soc_codec_device soc_codec_dev_wm9713;
++extern struct snd_soc_codec_dai wm9713_dai[3];
++
++int wm9713_reset(struct snd_soc_codec *codec,  int try_warm);
++
++#endif
+Index: linux-2.6.22.1/sound/soc/pxa/mainstone.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/pxa/mainstone.c	2007-07-16 15:07:34.192285777 +0200
+@@ -0,0 +1,127 @@
++/*
++ * mainstone.c  --  SoC audio for Mainstone
++ *
++ * Copyright 2005 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ *         liam.girdwood at wolfsonmicro.com or linux at wolfsonmicro.com
++ *
++ *  Mainstone audio amplifier code taken from arch/arm/mach-pxa/mainstone.c
++ *  Copyright:	MontaVista Software Inc.
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ *  Revision history
++ *    30th Oct 2005   Initial version.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/device.h>
++#include <linux/i2c.h>
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include <asm/arch/pxa-regs.h>
++#include <asm/arch/mainstone.h>
++#include <asm/arch/audio.h>
++
++#include "../codecs/ac97.h"
++#include "pxa2xx-pcm.h"
++#include "pxa2xx-ac97.h"
++
++static struct snd_soc_machine mainstone;
++static long mst_audio_suspend_mask;
++
++static int mainstone_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	mst_audio_suspend_mask = MST_MSCWR2;
++	MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
++	return 0;
++}
++
++static int mainstone_resume(struct platform_device *pdev)
++{
++	MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
++	return 0;
++}
++
++static int mainstone_probe(struct platform_device *pdev)
++{
++	MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
++	return 0;
++}
++
++static int mainstone_remove(struct platform_device *pdev)
++{
++	MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
++	return 0;
++}
++
++static struct snd_soc_machine_config codecs[] = {
++{
++	.name = "AC97",
++	.sname = "AC97 HiFi",
++	.iface = &pxa_ac97_interface[0],
++},
++{
++	.name = "AC97 Aux",
++	.sname = "AC97 Aux",
++	.iface = &pxa_ac97_interface[1],
++},
++};
++
++static struct snd_soc_machine mainstone = {
++	.name = "Mainstone",
++	.probe = mainstone_probe,
++	.remove = mainstone_remove,
++	.suspend_pre = mainstone_suspend,
++	.resume_post = mainstone_resume,
++	.config = codecs,
++	.nconfigs = ARRAY_SIZE(codecs),
++};
++
++static struct snd_soc_device mainstone_snd_devdata = {
++	.machine = &mainstone,
++	.platform = &pxa2xx_soc_platform,
++	.codec_dev = &soc_codec_dev_ac97,
++};
++
++static struct platform_device *mainstone_snd_device;
++
++static int __init mainstone_init(void)
++{
++	int ret;
++
++	mainstone_snd_device = platform_device_alloc("soc-audio", -1);
++	if (!mainstone_snd_device)
++		return -ENOMEM;
++
++	platform_set_drvdata(mainstone_snd_device, &mainstone_snd_devdata);
++	mainstone_snd_devdata.dev = &mainstone_snd_device->dev;
++	ret = platform_device_add(mainstone_snd_device);
++
++	if (ret)
++		platform_device_put(mainstone_snd_device);
++
++	return ret;
++}
++
++static void __exit mainstone_exit(void)
++{
++	platform_device_unregister(mainstone_snd_device);
++}
++
++module_init(mainstone_init);
++module_exit(mainstone_exit);
++
++/* Module information */
++MODULE_AUTHOR("Liam Girdwood, liam.girdwood at wolfsonmicro.com, www.wolfsonmicro.com");
++MODULE_DESCRIPTION("ALSA SoC Mainstone");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.22.1/sound/soc/pxa/mainstone_baseband.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.22.1/sound/soc/pxa/mainstone_baseband.c	2007-07-16 15:07:34.232288057 +0200
+@@ -0,0 +1,212 @@
++/*
++ * mainstone_baseband.c
++ * Mainstone Example Baseband modem  --  ALSA Soc Audio Layer
++ *
++ * Copyright 2006 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ *         liam.girdwood at wolfsonmicro.com or linux at wolfsonmicro.com
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ *  Revision history
++ *    15th Apr 2006   Initial version.
++ *
++ * This is example code to demonstrate connecting a baseband modem to the PCM
++ * DAI on the WM9713 codec on the Intel Mainstone platform. It is by no means
++ * complete as it requires code to control the modem.
++ *
++ * The architecture consists of the WM9713 AC97 DAI connected to the PXA27x
++ * AC97 controller and the WM9713 PCM DAI connected to the basebands DAI. The
++ * baseband is controlled via a serial port. Audio is routed between the PXA27x
++ * and the baseband via internal WM9713 analog paths.
++ *
++ * This driver is not the baseband modem driver. This driver only calls
++ * functions from the Baseband driver to set up it's PCM DAI.
++ *
++ * It's intended to use this driver as follows:-
++ *
++ *  1. open() WM9713 PCM audio device.
++ *  2. open() serial device (for AT commands).
++ *  3. configure PCM audio device (rate etc) - sets up WM9713 PCM DAI,
++ *      this will also set up the baseband PCM DAI (via calling baseband driver).
++ *  4. send any further AT commands to set up baseband.
++ *  5. configure codec audio mixer paths.
++ *  6. open(), configure and read/write AC97 audio device - to Tx/Rx voice
++ *
++ * The PCM audio device is opened but IO is never performed on it as the IO is
++ * directly between the codec and the baseband (and not the CPU).
++ *
++ * TODO:
++ *  o Implement callbacks
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/soc.h>
++#include <sound/soc-dapm.h>
++
++#include <asm/hardware.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/arch/audio.h>
++#include <asm/arch/ssp.h>
++
++#include "../codecs/wm9713.h"
++#include "pxa2xx-pcm.h"
++#include "pxa2xx-ac97.h"
++#include "pxa2xx-ssp.h"
++
++static struct snd_soc_machine mainstone;
++
++/* Do specific baseband PCM voice startup here */
++static int baseband_startup(struct snd_pcm_substream *substream)
++{
++	return 0;
++}
++
++/* Do specific baseband PCM voice shutdown here */
++static void baseband_shutdown (struct snd_pcm_substream *substream)
++{
++}
++
++/* Do specific baseband modem PCM voice hw params init here */
++static int baseband_hw_params(struct snd_pcm_substream *substream,
++	struct snd_pcm_hw_params *params)
++{
++	return 0;
++}
++
++/* Do specific baseband modem PCM voice hw params free here */
++static int baseband_hw_free(struct snd_pcm_substream *substream)
++{
++	return 0;
++}
++
++/*
++ * Baseband Processor DAI
++ */
++static struct snd_soc_cpu_dai baseband_dai =
++{	.name = "Baseband",
++	.id = 0,
++	.type = SND_SOC_DAI_PCM,
++	.playback = {
++		.channels_min = 1,
++		.channels_max = 1,
++		.rates = SNDRV_PCM_RATE_8000,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.capture = {
++		.channels_min = 1,
++		.channels_max = 1,
++		.rates = SNDRV_PCM_RATE_8000,
++		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
++	.ops = {
++		.startup = baseband_startup,
++		.shutdown = baseband_shutdown,
++		.hw_params = baseband_hw_params,
++		.hw_free = baseband_hw_free,
++		},
++};
++
++/* PM */
++static int mainstone_suspend(struct platform_device *pdev, pm_message_t state)
++{
++	return 0;
++}
++
++static int mainstone_resume(struct platform_device *pdev)
++{
++	return 0;
++}
++
++static int mainstone_probe(struct platform_device *pdev)
++{
++	return 0;
++}
++
++static int mainstone_remove(struct platform_device *pdev)
++{
++	return 0;
++}
++
++static int mainstone_wm9713_init(struct snd_soc_codec *codec)
++{
++	return 0;
++}
++
++/* the physical audio connections between the WM9713, Baseband and pxa2xx */
++static struct snd_soc_dai_link mainstone_dai[] = {
++{
++	.name = "AC97",
++	.stream_name = "AC97 HiFi",
++	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
++	.codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
++	.init = mainstone_wm9713_init,
++},
++{
++	.name = "AC97 Aux",
++	.stream_name = "AC97 Aux",
++	.cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
++	.codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX],
++},
++{
++	.name = "Baseband",
++	.stream_name = "Voice",
++	.cpu_dai = &baseband_dai,
++	.codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE],
++},
++};
++
++static struct snd_soc_machine mainstone = {
++	.name = "Mainstone",
++	.probe = mainstone_probe,
++	.remove = mainstone_remove,
++	.suspend_pre = mainstone_suspend,
++	.resume_post = mainstone_resume,
++	.dai_link = mainstone_dai,
++	.num_links = ARRAY_SI