changeset 9999:d5e89571de4e

6814300 Need support for Atheros AR9280 and AR9281 6834736 Need support for new wireless chipset AR9285
author lin wang - Sun Microsystems - Beijing China <Wang.Lin@Sun.COM>
date Tue, 30 Jun 2009 15:05:56 +0800
parents 5f6596ec3328
children 241a51d8720c
files usr/src/pkgdefs/Makefile usr/src/pkgdefs/SUNWarn/Makefile usr/src/pkgdefs/SUNWarn/pkginfo.tmpl usr/src/pkgdefs/SUNWarn/postinstall usr/src/pkgdefs/SUNWarn/postremove usr/src/pkgdefs/SUNWarn/prototype_com usr/src/pkgdefs/SUNWarn/prototype_i386 usr/src/pkgdefs/common_files/i.minorperm_i386 usr/src/tools/opensolaris/license-list usr/src/uts/common/Makefile.files usr/src/uts/common/Makefile.rules usr/src/uts/common/io/arn/LICENSE usr/src/uts/common/io/arn/LICENSE.descrip usr/src/uts/common/io/arn/arn_ani.c usr/src/uts/common/io/arn/arn_ath9k.h usr/src/uts/common/io/arn/arn_beacon.c usr/src/uts/common/io/arn/arn_calib.c usr/src/uts/common/io/arn/arn_core.h usr/src/uts/common/io/arn/arn_eeprom.c usr/src/uts/common/io/arn/arn_hw.c usr/src/uts/common/io/arn/arn_hw.h usr/src/uts/common/io/arn/arn_initvals.h usr/src/uts/common/io/arn/arn_mac.c usr/src/uts/common/io/arn/arn_main.c usr/src/uts/common/io/arn/arn_phy.c usr/src/uts/common/io/arn/arn_phy.h usr/src/uts/common/io/arn/arn_rc.c usr/src/uts/common/io/arn/arn_rc.h usr/src/uts/common/io/arn/arn_recv.c usr/src/uts/common/io/arn/arn_reg.h usr/src/uts/common/io/arn/arn_regd.c usr/src/uts/common/io/arn/arn_regd.h usr/src/uts/common/io/arn/arn_regd_common.h usr/src/uts/common/io/arn/arn_xmit.c usr/src/uts/intel/Makefile.intel.shared usr/src/uts/intel/arn/Makefile usr/src/uts/intel/os/minor_perm
diffstat 37 files changed, 32202 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/pkgdefs/Makefile	Tue Jun 30 07:41:21 2009 +0100
+++ b/usr/src/pkgdefs/Makefile	Tue Jun 30 15:05:56 2009 +0800
@@ -115,6 +115,7 @@
 	SUNWamt \
 	SUNWamt-lms \
 	SUNWarcmsr \
+	SUNWarn \
 	SUNWatheros \
 	SUNWatigfx \
 	SUNWatu \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWarn/Makefile	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,39 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+include ../Makefile.com
+
+DATAFILES += depend
+LICENSEFILES += ../../uts/common/io/arn/LICENSE
+CDDL=
+
+.KEEP_STATE:
+
+all: $(FILES) postinstall postremove
+install: all pkg
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWarn/pkginfo.tmpl	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PKG="SUNWarn"
+NAME="Atheros IEEE 802.11 Wireless NIC Driver"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="SunOS"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGVERS="1.0"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY="system"
+VENDOR="Sun Microsystems, Inc."
+DESC="Atheros AR9xxx 802.11 Wireless NIC Driver"
+CLASSES="none"
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+BASEDIR=/
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="true"
+SUNW_PKG_THISZONE="false"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWarn/postinstall	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,91 @@
+#! /usr/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+# Driver info
+DRV=arn
+DRVALIAS='"pciex168c,2a" "pciex168c,2b"'
+
+BASEDIR=${BASEDIR:-/}
+
+# Function: check_add_drv()
+#
+# This function will check if add_drv has been executed.
+# If not simply calls add_drv. Otherwise adds entries to
+# driver_aliases, driver_classes and minor_perm if necessary.
+# The syntax of this function is the same as add_drv. 
+
+check_add_drv()
+{
+	CMD="add_drv"
+
+	ALIAS=""
+	ALIASDIR="${BASEDIR}"/etc/driver_aliases
+	while getopts i:b: opt 2>/dev/null; do
+		case "$opt" in
+		i)	CMD="${CMD} -i ${OPTARG}"
+			ALIAS=`echo ${OPTARG} | /usr/bin/sed -e "s/'//g"`
+			;;
+		b)	if [ "${OPTARG}" != "/" ]; then
+				# On a client
+				# modify the sytem files and touch
+				# /reconfigure for reconfigure reboot
+				CMD="${CMD} -b \"${OPTARG}\""
+			fi
+			;;
+		\?)	echo "check_add_drv(): Unknown option $opt"
+			return
+			;;
+		esac
+	done
+	shift `/usr/bin/expr ${OPTIND} - 1`
+	DRIVER=$1
+	CMD="${CMD} ${DRIVER}"
+
+	# Make sure add_drv has not been previously executed
+	# before attempting to add the driver
+	/usr/bin/egrep -s "^${DRIVER}[ 	]" "$BASEDIR"/etc/name_to_major
+
+	if [ $? -ne 0 ]; then
+		eval ${CMD}
+		if [ $? -ne 0 ]; then
+			echo "Failed add_drv ${DRIVER}!\n" >&2
+			exit 1
+		fi
+	else
+		# Add driver entry if necessary
+		if [ -n "${ALIAS}" ]; then
+			for i in ${ALIAS}; do
+				/usr/bin/egrep -s "^${DRIVER}[ 	]+$i" ${ALIASDIR}
+				if [ $? -ne 0 ]; then
+					echo "${DRIVER} $i" >> ${ALIASDIR}
+				fi
+			done
+		fi
+	fi
+}
+
+check_add_drv -b "${BASEDIR}" -i "'${DRVALIAS}'" ${DRV}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWarn/postremove	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,50 @@
+#! /usr/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+DRV=arn
+BASEDIR=${BASEDIR:-/}
+
+# Select the correct rem_drv options to execute.
+# Only attempt to unload the driver on a running system
+if [ "$BASEDIR" = "/" ]; then
+	REM_DRV="rem_drv"
+else
+	REM_DRV="rem_drv -b ${BASEDIR}"
+fi
+
+# Make sure rem_drv has not been previously executed
+# before attempting to remove the driver
+/usr/bin/egrep -s "^${DRV}[ 	]" $BASEDIR/etc/name_to_major
+if [ $? -eq 0 ]; then
+	${REM_DRV} ${DRV}
+        if [ $? -ne 0 ]; then
+		echo "Failed rem_drv ${DRV}!\n" >&2
+                exit 1
+        fi
+fi
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWarn/prototype_com	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,45 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>        # where to find pkg objects
+#!include <filename>                    # include another 'prototype' file
+#!default <mode> <owner> <group>        # default used if not specified on entry
+#!<param>=<value>                       # puts parameter in pkg environment
+
+#
+# SUNWarn
+#
+
+i pkginfo
+i copyright
+i depend
+i postinstall
+i postremove
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/pkgdefs/SUNWarn/prototype_i386	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,51 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>        # where to find pkg objects
+#!include <filename>                    # include another 'prototype' file
+#!default <mode> <owner> <group>        # default used if not specified on entry
+#!<param>=<value>                       # puts parameter in pkg environment
+
+#
+# SUNWarn
+#
+
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+
+# Atheros IEEE 80211n NIC driver
+d none kernel 0755 root sys
+d none kernel/drv 0755 root sys
+f none kernel/drv/arn 0755 root sys
+d none kernel/drv/amd64 0755 root sys
+f none kernel/drv/amd64/arn 0755 root sys
--- a/usr/src/pkgdefs/common_files/i.minorperm_i386	Tue Jun 30 07:41:21 2009 +0100
+++ b/usr/src/pkgdefs/common_files/i.minorperm_i386	Tue Jun 30 15:05:56 2009 +0800
@@ -109,6 +109,7 @@
 clone:chxge		0600 root sys 0666 root sys	/dev/chxge
 clone:pcn		0600 root sys 0666 root sys	/dev/pcn
 clone:rtls		0600 root sys 0666 root sys	/dev/rtls
+clone:arn               0600 root sys 0666 root sys     /dev/arn
 clone:ath		0600 root sys 0666 root sys	/dev/ath
 clone:atu		0600 root sys 0666 root sys	/dev/atu
 clone:ipw               0600 root sys 0666 root sys     /dev/ipw
@@ -139,6 +140,7 @@
 chxge:*			0600 root sys 0666 root sys	/dev/chxge*
 pcn:*			0600 root sys 0666 root sys	/dev/pcn*
 rtls:*			0600 root sys 0666 root sys	/dev/rtls*
+arn:*                   0600 root sys 0666 root sys     /dev/arn*
 ath:*			0600 root sys 0666 root sys	/dev/ath*
 atu:*			0600 root sys 0666 root sys	/dev/atu*
 ipw:*                   0600 root sys 0666 root sys     /dev/ipw*
@@ -296,6 +298,7 @@
 clone:chxge
 clone:pcn
 clone:rtls
+clone:arn
 clone:ath
 clone:atu
 clone:ipw
@@ -326,6 +329,7 @@
 chxge:*
 pcn:*
 rtls:*
+arn:*
 ath:*
 atu:*
 ipw:*
--- a/usr/src/tools/opensolaris/license-list	Tue Jun 30 07:41:21 2009 +0100
+++ b/usr/src/tools/opensolaris/license-list	Tue Jun 30 15:05:56 2009 +0800
@@ -139,6 +139,7 @@
 usr/src/uts/common/io/THIRDPARTYLICENSE.etheraddr
 usr/src/uts/common/io/aac/THIRDPARTYLICENSE
 usr/src/uts/common/io/afe/THIRDPARTYLICENSE
+usr/src/uts/common/io/arn/LICENSE
 usr/src/uts/common/io/ath/LICENSE
 usr/src/uts/common/io/atu/THIRDPARTYLICENSE
 usr/src/uts/common/io/chxge/com/THIRDPARTYLICENSE
--- a/usr/src/uts/common/Makefile.files	Tue Jun 30 07:41:21 2009 +0100
+++ b/usr/src/uts/common/Makefile.files	Tue Jun 30 15:05:56 2009 +0800
@@ -1702,6 +1702,9 @@
 
 URTW_OBJS += urtw.o
 
+ARN_OBJS += arn_hw.o arn_eeprom.o arn_mac.o arn_calib.o arn_ani.o arn_phy.o arn_regd.o arn_beacon.o \
+		arn_main.o arn_recv.o arn_xmit.o arn_rc.o
+
 ATH_OBJS += ath_aux.o ath_main.o ath_osdep.o ath_rate.o
 
 ATU_OBJS += atu.o
--- a/usr/src/uts/common/Makefile.rules	Tue Jun 30 07:41:21 2009 +0100
+++ b/usr/src/uts/common/Makefile.rules	Tue Jun 30 15:05:56 2009 +0800
@@ -528,6 +528,10 @@
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
 
+$(OBJS_DIR)/%.o:                $(UTSBASE)/common/io/arn/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
 $(OBJS_DIR)/%.o:               $(UTSBASE)/common/io/ath/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -1763,6 +1767,9 @@
 $(LINTS_DIR)/%.ln:              $(UTSBASE)/common/io/afe/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:              $(UTSBASE)/common/io/arn/%.c
+	@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:              $(UTSBASE)/common/io/ath/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/LICENSE	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+ /*
+ * Copyright (c) 2004 Video54 Technologies, Inc.
+ * Copyright (c) 2004-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+ /*
+ * Copyright (c) 2004 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004 Video54 Technologies, Inc.
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/LICENSE.descrip	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,1 @@
+Atheros AR5416/5418/9280/9281/9285 IEEE802.11 a/b/g/n Wireless Network Driver
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_ani.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,891 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "arn_core.h"
+#include "arn_hw.h"
+#include "arn_reg.h"
+#include "arn_phy.h"
+
+static int
+ath9k_hw_get_ani_channel_idx(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
+		if (ahp->ah_ani[i].c.channel == chan->channel)
+			return (i);
+		if (ahp->ah_ani[i].c.channel == 0) {
+			ahp->ah_ani[i].c.channel = chan->channel;
+			ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
+			return (i);
+		}
+	}
+
+	ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_get_ani_channel_idx(): "
+	    "No more channel states left. Using channel 0\n"));
+
+	return (0);
+}
+
+static boolean_t
+ath9k_hw_ani_control(struct ath_hal *ah, enum ath9k_ani_cmd cmd, int param)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416AniState *aniState = ahp->ah_curani;
+
+	switch (cmd & ahp->ah_ani_function) {
+	case ATH9K_ANI_NOISE_IMMUNITY_LEVEL: {
+		uint32_t level = param;
+
+		if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
+			ARN_DBG((ARN_DBG_ANI, "arn: "
+			    "ah->ah_sc, ATH_DBG_ANI",
+			    "%s: level out of range (%u > %u)\n",
+			    __func__, level,
+			    (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired)));
+
+			return (B_FALSE);
+		}
+
+		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+		    AR_PHY_DESIRED_SZ_TOT_DES,
+		    ahp->ah_totalSizeDesired[level]);
+		REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+		    AR_PHY_AGC_CTL1_COARSE_LOW,
+		    ahp->ah_coarseLow[level]);
+		REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+		    AR_PHY_AGC_CTL1_COARSE_HIGH,
+		    ahp->ah_coarseHigh[level]);
+		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+		    AR_PHY_FIND_SIG_FIRPWR,
+		    ahp->ah_firpwr[level]);
+
+		if (level > aniState->noiseImmunityLevel)
+			ahp->ah_stats.ast_ani_niup++;
+		else if (level < aniState->noiseImmunityLevel)
+			ahp->ah_stats.ast_ani_nidown++;
+		aniState->noiseImmunityLevel = (uint8_t)level; /* LINT */
+		break;
+	}
+	case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION: {
+		const int m1ThreshLow[] = { 127, 50 };
+		const int m2ThreshLow[] = { 127, 40 };
+		const int m1Thresh[] = { 127, 0x4d };
+		const int m2Thresh[] = { 127, 0x40 };
+		const int m2CountThr[] = { 31, 16 };
+		const int m2CountThrLow[] = { 63, 48 };
+		uint32_t on = param ? 1 : 0;
+
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+		    AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+		    m1ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+		    AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+		    m2ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+		    AR_PHY_SFCORR_M1_THRESH,
+		    m1Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+		    AR_PHY_SFCORR_M2_THRESH,
+		    m2Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+		    AR_PHY_SFCORR_M2COUNT_THR,
+		    m2CountThr[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+		    AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+		    m2CountThrLow[on]);
+
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+		    AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
+		    m1ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+		    AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
+		    m2ThreshLow[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+		    AR_PHY_SFCORR_EXT_M1_THRESH,
+		    m1Thresh[on]);
+		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+		    AR_PHY_SFCORR_EXT_M2_THRESH,
+		    m2Thresh[on]);
+
+		if (on)
+			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+			    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+		else
+			REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
+			    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+
+		if (!on != aniState->ofdmWeakSigDetectOff) {
+			if (on)
+				ahp->ah_stats.ast_ani_ofdmon++;
+			else
+				ahp->ah_stats.ast_ani_ofdmoff++;
+			aniState->ofdmWeakSigDetectOff = !on;
+		}
+		break;
+	}
+	case ATH9K_ANI_CCK_WEAK_SIGNAL_THR: {
+		const int weakSigThrCck[] = { 8, 6 };
+		uint32_t high = param ? 1 : 0;
+
+		REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
+		    AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
+		    weakSigThrCck[high]);
+		if (high != aniState->cckWeakSigThreshold) {
+			if (high)
+				ahp->ah_stats.ast_ani_cckhigh++;
+			else
+				ahp->ah_stats.ast_ani_ccklow++;
+			/* LINT */
+			aniState->cckWeakSigThreshold = (uint8_t)high;
+		}
+		break;
+	}
+	case ATH9K_ANI_FIRSTEP_LEVEL: {
+		const int firstep[] = { 0, 4, 8 };
+		uint32_t level = param;
+
+		if (level >= ARRAY_SIZE(firstep)) {
+			ARN_DBG((ARN_DBG_ANI, "arn: "
+			    "%s: level out of range (%u > %u)\n",
+			    __func__, level,
+			    (unsigned)ARRAY_SIZE(firstep)));
+
+			return (B_FALSE);
+		}
+		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+		    AR_PHY_FIND_SIG_FIRSTEP, firstep[level]);
+		if (level > aniState->firstepLevel)
+			ahp->ah_stats.ast_ani_stepup++;
+		else if (level < aniState->firstepLevel)
+			ahp->ah_stats.ast_ani_stepdown++;
+		aniState->firstepLevel = (uint8_t)level; /* LINT */
+		break;
+	}
+	case ATH9K_ANI_SPUR_IMMUNITY_LEVEL: {
+		const int cycpwrThr1[] =
+			{ 2, 4, 6, 8, 10, 12, 14, 16 };
+		uint32_t level = param;
+
+		if (level >= ARRAY_SIZE(cycpwrThr1)) {
+			ARN_DBG((ARN_DBG_ANI, "arn: "
+			    "%s: level out of range (%u > %u)\n",
+			    __func__, level,
+			    (unsigned)ARRAY_SIZE(cycpwrThr1)));
+
+			return (B_FALSE);
+		}
+		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+		    AR_PHY_TIMING5_CYCPWR_THR1, cycpwrThr1[level]);
+		if (level > aniState->spurImmunityLevel)
+			ahp->ah_stats.ast_ani_spurup++;
+		else if (level < aniState->spurImmunityLevel)
+			ahp->ah_stats.ast_ani_spurdown++;
+		aniState->spurImmunityLevel = (uint8_t)level; /* LINT */
+		break;
+	}
+	case ATH9K_ANI_PRESENT:
+		break;
+	default:
+		ARN_DBG((ARN_DBG_ANI, "arn: "
+		    "%s: invalid cmd %u\n", __func__, cmd));
+		return (B_FALSE);
+	}
+
+	ARN_DBG((ARN_DBG_ANI, "arn: "
+	    "%s: ANI parameters:\n", __func__));
+	ARN_DBG((ARN_DBG_ANI, "arn: "
+	    "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+	    "ofdmWeakSigDetectOff=%d\n",
+	    aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
+	    !aniState->ofdmWeakSigDetectOff));
+	ARN_DBG((ARN_DBG_ANI, "arn: "
+	    "cckWeakSigThreshold=%d, "
+	    "firstepLevel=%d, listenTime=%d\n",
+	    aniState->cckWeakSigThreshold, aniState->firstepLevel,
+	    aniState->listenTime));
+	ARN_DBG((ARN_DBG_ANI, "arn: "
+	    "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+	    aniState->cycleCount, aniState->ofdmPhyErrCount,
+	    aniState->cckPhyErrCount));
+
+	return (B_TRUE);
+}
+
+static void
+ath9k_hw_update_mibstats(struct ath_hal *ah, struct ath9k_mib_stats *stats)
+{
+	stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
+	stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
+	stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
+	stats->rts_good += REG_READ(ah, AR_RTS_OK);
+	stats->beacons += REG_READ(ah, AR_BEACON_CNT);
+}
+
+static void
+ath9k_ani_restart(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416AniState *aniState;
+
+	if (!DO_ANI(ah))
+		return;
+
+	aniState = ahp->ah_curani;
+
+	aniState->listenTime = 0;
+	if (ahp->ah_hasHwPhyCounters) {
+		if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
+			aniState->ofdmPhyErrBase = 0;
+			ARN_DBG((ARN_DBG_ANI, "arn: "
+			    "OFDM Trigger is too high for hw counters\n"));
+		} else {
+			aniState->ofdmPhyErrBase =
+			    AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
+		}
+		if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
+			aniState->cckPhyErrBase = 0;
+			ARN_DBG((ARN_DBG_ANI, "arn: "
+			    "CCK Trigger is too high for hw counters\n"));
+		} else {
+			aniState->cckPhyErrBase =
+			    AR_PHY_COUNTMAX - aniState->cckTrigHigh;
+		}
+
+		ARN_DBG((ARN_DBG_ANI, "arn: "
+		    "%s: Writing ofdmbase=%u   cckbase=%u\n",
+		    __func__, aniState->ofdmPhyErrBase,
+		    aniState->cckPhyErrBase));
+
+		REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
+		REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
+		REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+		REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+		ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+	}
+	aniState->ofdmPhyErrCount = 0;
+	aniState->cckPhyErrCount = 0;
+}
+
+static void
+ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ar5416AniState *aniState;
+	enum wireless_mode mode;
+	int32_t rssi;
+
+	if (!DO_ANI(ah))
+		return;
+
+	aniState = ahp->ah_curani;
+
+	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
+		if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+		    aniState->noiseImmunityLevel + 1)) {
+			return;
+		}
+	}
+
+	if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
+		if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+		    aniState->spurImmunityLevel + 1)) {
+			return;
+		}
+	}
+
+	if (ah->ah_opmode == ATH9K_M_HOSTAP) {
+		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+			(void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+			    aniState->firstepLevel + 1);
+		}
+		return;
+	}
+	rssi = BEACON_RSSI(ahp);
+	if (rssi > aniState->rssiThrHigh) {
+		if (!aniState->ofdmWeakSigDetectOff) {
+			if (ath9k_hw_ani_control(ah,
+			    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+			    B_FALSE)) {
+				(void) ath9k_hw_ani_control(ah,
+				    ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+				return;
+			}
+		}
+		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+			(void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+			    aniState->firstepLevel + 1);
+			return;
+		}
+	} else if (rssi > aniState->rssiThrLow) {
+		if (aniState->ofdmWeakSigDetectOff)
+			(void) ath9k_hw_ani_control(ah,
+			    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+			    B_TRUE);
+		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+			(void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+			    aniState->firstepLevel + 1);
+		return;
+	} else {
+		mode = ath9k_hw_chan2wmode(ah, chan);
+		if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+			if (!aniState->ofdmWeakSigDetectOff)
+				(void) ath9k_hw_ani_control(ah,
+				    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+				    B_FALSE);
+			if (aniState->firstepLevel > 0)
+				(void) ath9k_hw_ani_control(ah,
+				    ATH9K_ANI_FIRSTEP_LEVEL, 0);
+			return;
+		}
+	}
+}
+
+static void
+ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ar5416AniState *aniState;
+	enum wireless_mode mode;
+	int32_t rssi;
+
+	if (!DO_ANI(ah))
+		return;
+
+	aniState = ahp->ah_curani;
+	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
+		if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+		    aniState->noiseImmunityLevel + 1)) {
+			return;
+		}
+	}
+	if (ah->ah_opmode == ATH9K_M_HOSTAP) {
+		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+			(void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+			    aniState->firstepLevel + 1);
+		}
+		return;
+	}
+	rssi = BEACON_RSSI(ahp);
+	if (rssi > aniState->rssiThrLow) {
+		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+			(void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+			    aniState->firstepLevel + 1);
+	} else {
+		mode = ath9k_hw_chan2wmode(ah, chan);
+		if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+			if (aniState->firstepLevel > 0)
+				(void) ath9k_hw_ani_control(ah,
+				    ATH9K_ANI_FIRSTEP_LEVEL, 0);
+		}
+	}
+}
+
+static void
+ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416AniState *aniState;
+	int32_t rssi;
+
+	aniState = ahp->ah_curani;
+
+	if (ah->ah_opmode == ATH9K_M_HOSTAP) {
+		if (aniState->firstepLevel > 0) {
+			if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+			    aniState->firstepLevel - 1))
+				return;
+		}
+	} else {
+		rssi = BEACON_RSSI(ahp);
+		if (rssi > aniState->rssiThrHigh) {
+			/* XXX: Handle me */
+			ARN_DBG((ARN_DBG_ANI, "arn: ath9k_ani_reset():\n"));
+		} else if (rssi > aniState->rssiThrLow) {
+			if (aniState->ofdmWeakSigDetectOff) {
+				if (ath9k_hw_ani_control(ah,
+				    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+				    B_TRUE) == B_TRUE)
+					return;
+			}
+			if (aniState->firstepLevel > 0) {
+				if (ath9k_hw_ani_control(ah,
+				    ATH9K_ANI_FIRSTEP_LEVEL,
+				    aniState->firstepLevel - 1) == B_TRUE)
+					return;
+			}
+		} else {
+			if (aniState->firstepLevel > 0) {
+				if (ath9k_hw_ani_control(ah,
+				    ATH9K_ANI_FIRSTEP_LEVEL,
+				    aniState->firstepLevel - 1) == B_TRUE)
+					return;
+			}
+		}
+	}
+
+	if (aniState->spurImmunityLevel > 0) {
+		if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+		    aniState->spurImmunityLevel - 1))
+			return;
+	}
+
+	if (aniState->noiseImmunityLevel > 0) {
+		(void) ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+		    aniState->noiseImmunityLevel - 1);
+		return;
+	}
+}
+
+static int32_t
+ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416AniState *aniState;
+	uint32_t txFrameCount, rxFrameCount, cycleCount;
+	int32_t listenTime;
+
+	txFrameCount = REG_READ(ah, AR_TFCNT);
+	rxFrameCount = REG_READ(ah, AR_RFCNT);
+	cycleCount = REG_READ(ah, AR_CCCNT);
+
+	aniState = ahp->ah_curani;
+	if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
+
+		listenTime = 0;
+		ahp->ah_stats.ast_ani_lzero++;
+	} else {
+		int32_t ccdelta = cycleCount - aniState->cycleCount;
+		int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
+		int32_t tfdelta = txFrameCount - aniState->txFrameCount;
+		listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
+	}
+	aniState->cycleCount = cycleCount;
+	aniState->txFrameCount = txFrameCount;
+	aniState->rxFrameCount = rxFrameCount;
+
+	return (listenTime);
+}
+
+void
+ath9k_ani_reset(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416AniState *aniState;
+	struct ath9k_channel *chan = ah->ah_curchan;
+	int index;
+
+	/* For Lint Reasons */
+	boolean_t ANI_USE_OFDM_WEAK_SIG = ATH9K_ANI_USE_OFDM_WEAK_SIG;
+
+	if (!DO_ANI(ah))
+		return;
+
+	index = ath9k_hw_get_ani_channel_idx(ah, chan);
+	aniState = &ahp->ah_ani[index];
+	ahp->ah_curani = aniState;
+
+	if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA &&
+	    ah->ah_opmode != ATH9K_M_IBSS) {
+		ARN_DBG((ARN_DBG_ANI, "arn: ath9k_ani_reset(): "
+		    "Reset ANI state opmode %u\n", ah->ah_opmode));
+		ahp->ah_stats.ast_ani_reset++;
+
+		(void) ath9k_hw_ani_control(ah,
+		    ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
+		(void) ath9k_hw_ani_control(ah,
+		    ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+		(void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
+		(void) ath9k_hw_ani_control
+		    (ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+		    !ANI_USE_OFDM_WEAK_SIG /* !ATH9K_ANI_USE_OFDM_WEAK_SIG */);
+		(void) ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
+		    ATH9K_ANI_CCK_WEAK_SIG_THR);
+
+		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
+		    ATH9K_RX_FILTER_PHYERR);
+
+		if (ah->ah_opmode == ATH9K_M_HOSTAP) {
+			ahp->ah_curani->ofdmTrigHigh =
+			    ah->ah_config.ofdm_trig_high;
+			ahp->ah_curani->ofdmTrigLow =
+			    ah->ah_config.ofdm_trig_low;
+			ahp->ah_curani->cckTrigHigh =
+			    ah->ah_config.cck_trig_high;
+			ahp->ah_curani->cckTrigLow =
+			    ah->ah_config.cck_trig_low;
+		}
+		ath9k_ani_restart(ah);
+		return;
+	}
+
+	if (aniState->noiseImmunityLevel != 0)
+		(void) ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+		    aniState->noiseImmunityLevel);
+	if (aniState->spurImmunityLevel != 0)
+		(void) ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+		    aniState->spurImmunityLevel);
+	if (aniState->ofdmWeakSigDetectOff)
+		(void) ath9k_hw_ani_control
+		    (ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+		    !aniState->ofdmWeakSigDetectOff);
+	if (aniState->cckWeakSigThreshold)
+		(void) ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
+		    aniState->cckWeakSigThreshold);
+	if (aniState->firstepLevel != 0)
+		(void) ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+		    aniState->firstepLevel);
+	if (ahp->ah_hasHwPhyCounters) {
+		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
+		    ~ATH9K_RX_FILTER_PHYERR);
+		ath9k_ani_restart(ah);
+		REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+		REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+	} else {
+		ath9k_ani_restart(ah);
+		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
+		    ATH9K_RX_FILTER_PHYERR);
+	}
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_ani_monitor(struct ath_hal *ah, const struct ath9k_node_stats *stats,
+    struct ath9k_channel *chan)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416AniState *aniState;
+	int32_t listenTime;
+
+	aniState = ahp->ah_curani;
+	ahp->ah_stats.ast_nodestats = *stats;
+
+	listenTime = ath9k_hw_ani_get_listen_time(ah);
+	if (listenTime < 0) {
+		ahp->ah_stats.ast_ani_lneg++;
+		ath9k_ani_restart(ah);
+		return;
+	}
+
+	aniState->listenTime += listenTime;
+
+	if (ahp->ah_hasHwPhyCounters) {
+		uint32_t phyCnt1, phyCnt2;
+		uint32_t ofdmPhyErrCnt, cckPhyErrCnt;
+
+		ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+
+		phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
+		phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
+
+		if (phyCnt1 < aniState->ofdmPhyErrBase ||
+		    phyCnt2 < aniState->cckPhyErrBase) {
+			if (phyCnt1 < aniState->ofdmPhyErrBase) {
+				ARN_DBG((ARN_DBG_ANI, "arn: "
+				    "%s: phyCnt1 0x%x, resetting "
+				    "counter value to 0x%x\n",
+				    __func__, phyCnt1,
+				    aniState->ofdmPhyErrBase));
+				REG_WRITE(ah, AR_PHY_ERR_1,
+				    aniState->ofdmPhyErrBase);
+				REG_WRITE(ah, AR_PHY_ERR_MASK_1,
+				    AR_PHY_ERR_OFDM_TIMING);
+			}
+			if (phyCnt2 < aniState->cckPhyErrBase) {
+				ARN_DBG((ARN_DBG_ANI, "arn: "
+				    "%s: phyCnt2 0x%x, resetting "
+				    "counter value to 0x%x\n",
+				    __func__, phyCnt2,
+				    aniState->cckPhyErrBase));
+				REG_WRITE(ah, AR_PHY_ERR_2,
+				    aniState->cckPhyErrBase);
+				REG_WRITE(ah, AR_PHY_ERR_MASK_2,
+				    AR_PHY_ERR_CCK_TIMING);
+			}
+			return;
+		}
+
+		ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
+		ahp->ah_stats.ast_ani_ofdmerrs +=
+		    ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+		aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+		cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+		ahp->ah_stats.ast_ani_cckerrs +=
+		    cckPhyErrCnt - aniState->cckPhyErrCount;
+		aniState->cckPhyErrCount = cckPhyErrCnt;
+	}
+
+	if (!DO_ANI(ah))
+		return;
+
+	if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
+		if (aniState->ofdmPhyErrCount <= aniState->listenTime *
+		    aniState->ofdmTrigLow / 1000 &&
+		    aniState->cckPhyErrCount <= aniState->listenTime *
+		    aniState->cckTrigLow / 1000)
+			ath9k_hw_ani_lower_immunity(ah);
+		ath9k_ani_restart(ah);
+	} else if (aniState->listenTime > ahp->ah_aniPeriod) {
+		if (aniState->ofdmPhyErrCount > aniState->listenTime *
+		    aniState->ofdmTrigHigh / 1000) {
+			ath9k_hw_ani_ofdm_err_trigger(ah);
+			ath9k_ani_restart(ah);
+		} else if (aniState->cckPhyErrCount >
+		    aniState->listenTime * aniState->cckTrigHigh / 1000) {
+			ath9k_hw_ani_cck_err_trigger(ah);
+			ath9k_ani_restart(ah);
+		}
+	}
+}
+
+boolean_t
+ath9k_hw_phycounters(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	return (ahp->ah_hasHwPhyCounters ? B_TRUE : B_FALSE);
+}
+
+void
+ath9k_enable_mib_counters(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	ARN_DBG((ARN_DBG_ANI, "arn: ath9k_enable_mib_counters(): "
+	    "Enable MIB counters\n"));
+
+	ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+
+	REG_WRITE(ah, AR_FILT_OFDM, 0);
+	REG_WRITE(ah, AR_FILT_CCK, 0);
+	REG_WRITE(ah, AR_MIBC,
+	    ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) & 0x0f);
+	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+}
+
+void
+ath9k_hw_disable_mib_counters(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	ARN_DBG((ARN_DBG_ANI,
+	    "arn: ath9k_hw_disable_mib_counters(): "
+	    "Disable MIB counters\n"));
+
+	REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
+
+	ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+
+	REG_WRITE(ah, AR_FILT_OFDM, 0);
+	REG_WRITE(ah, AR_FILT_CCK, 0);
+}
+
+uint32_t
+ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah, uint32_t *rxc_pcnt,
+    uint32_t *rxf_pcnt, uint32_t *txf_pcnt)
+{
+	static uint32_t cycles, rx_clear, rx_frame, tx_frame;
+	uint32_t good = 1;
+
+	uint32_t rc = REG_READ(ah, AR_RCCNT);
+	uint32_t rf = REG_READ(ah, AR_RFCNT);
+	uint32_t tf = REG_READ(ah, AR_TFCNT);
+	uint32_t cc = REG_READ(ah, AR_CCCNT);
+
+	if (cycles == 0 || cycles > cc) {
+		ARN_DBG((ARN_DBG_CHANNEL,
+		    "arn: ath9k_hw_GetMibCycleCountsPct(): "
+		    "cycle counter wrap. ExtBusy = 0\n"));
+		good = 0;
+	} else {
+		uint32_t cc_d = cc - cycles;
+		uint32_t rc_d = rc - rx_clear;
+		uint32_t rf_d = rf - rx_frame;
+		uint32_t tf_d = tf - tx_frame;
+
+		if (cc_d != 0) {
+			*rxc_pcnt = rc_d * 100 / cc_d;
+			*rxf_pcnt = rf_d * 100 / cc_d;
+			*txf_pcnt = tf_d * 100 / cc_d;
+		} else {
+			good = 0;
+		}
+	}
+
+	cycles = cc;
+	rx_frame = rf;
+	rx_clear = rc;
+	tx_frame = tf;
+
+	return (good);
+}
+
+/*
+ * Process a MIB interrupt.  We may potentially be invoked because
+ * any of the MIB counters overflow/trigger so don't assume we're
+ * here because a PHY error counter triggered.
+ */
+void
+ath9k_hw_procmibevent(struct ath_hal *ah,
+    const struct ath9k_node_stats *stats)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t phyCnt1, phyCnt2;
+
+	/* Reset these counters regardless */
+	REG_WRITE(ah, AR_FILT_OFDM, 0);
+	REG_WRITE(ah, AR_FILT_CCK, 0);
+	if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
+		REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
+
+	/* Clear the mib counters and save them in the stats */
+	ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+	ahp->ah_stats.ast_nodestats = *stats;
+
+	if (!DO_ANI(ah))
+		return;
+
+	/* NB: these are not reset-on-read */
+	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
+	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
+	if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
+	    ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
+		struct ar5416AniState *aniState = ahp->ah_curani;
+		uint32_t ofdmPhyErrCnt, cckPhyErrCnt;
+
+		/* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
+		ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
+		ahp->ah_stats.ast_ani_ofdmerrs +=
+		    ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+		aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+		cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+		ahp->ah_stats.ast_ani_cckerrs +=
+		    cckPhyErrCnt - aniState->cckPhyErrCount;
+		aniState->cckPhyErrCount = cckPhyErrCnt;
+
+		/*
+		 * NB: figure out which counter triggered.  If both
+		 * trigger we'll only deal with one as the processing
+		 * clobbers the error counter so the trigger threshold
+		 * check will never be true.
+		 */
+		if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
+			ath9k_hw_ani_ofdm_err_trigger(ah);
+		if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
+			ath9k_hw_ani_cck_err_trigger(ah);
+		/* NB: always restart to insure the h/w counters are reset */
+		ath9k_ani_restart(ah);
+	}
+}
+
+void
+ath9k_hw_ani_setup(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int i;
+
+	const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
+	const int coarseHigh[] = { -14, -14, -14, -14, -12 };
+	const int coarseLow[] = { -64, -64, -64, -64, -70 };
+	const int firpwr[] = { -78, -78, -78, -78, -80 };
+
+	for (i = 0; i < 5; i++) {
+		ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
+		ahp->ah_coarseHigh[i] = coarseHigh[i];
+		ahp->ah_coarseLow[i] = coarseLow[i];
+		ahp->ah_firpwr[i] = firpwr[i];
+	}
+}
+
+void
+ath9k_hw_ani_attach(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int i;
+
+	/* For Lint Reasons */
+	boolean_t ANI_USE_OFDM_WEAK_SIG = ATH9K_ANI_USE_OFDM_WEAK_SIG;
+
+	ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_ani_attach(): "
+	    "Attach ANI\n"));
+
+	ahp->ah_hasHwPhyCounters = 1;
+
+	(void) memset(ahp->ah_ani, 0, sizeof (ahp->ah_ani));
+	for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
+		ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
+		ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
+		ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
+		ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
+		ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+		ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+		ahp->ah_ani[i].ofdmWeakSigDetectOff =
+		    !ANI_USE_OFDM_WEAK_SIG /* !ATH9K_ANI_USE_OFDM_WEAK_SIG */;
+		ahp->ah_ani[i].cckWeakSigThreshold =
+		    ATH9K_ANI_CCK_WEAK_SIG_THR;
+		ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+		ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+		if (ahp->ah_hasHwPhyCounters) {
+			ahp->ah_ani[i].ofdmPhyErrBase =
+			    AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
+			ahp->ah_ani[i].cckPhyErrBase =
+			    AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
+		}
+	}
+	if (ahp->ah_hasHwPhyCounters) {
+		ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_ani_attach(): "
+		    "Setting OfdmErrBase = 0x%08x\n",
+		    ahp->ah_ani[0].ofdmPhyErrBase));
+		ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_ani_attach(): "
+		    "Setting cckErrBase = 0x%08x\n",
+		    ahp->ah_ani[0].cckPhyErrBase));
+
+		REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
+		REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
+		ath9k_enable_mib_counters(ah);
+	}
+	ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
+	if (ah->ah_config.enable_ani)
+		ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
+}
+
+void
+ath9k_hw_ani_detach(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	ARN_DBG((ARN_DBG_ANI, "arn: ath9k_hw_ani_detach(): "
+	    "Detach ANI\n"));
+
+	if (ahp->ah_hasHwPhyCounters) {
+		ath9k_hw_disable_mib_counters(ah);
+		REG_WRITE(ah, AR_PHY_ERR_1, 0);
+		REG_WRITE(ah, AR_PHY_ERR_2, 0);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_ath9k.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,1100 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_ARN_ATH9K_H
+#define	_ARN_ATH9K_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum ath9k_band {
+	ATH9K_BAND_2GHZ,
+	ATH9K_BAND_5GHZ,
+	ATH9K_NUM_BANDS
+};
+
+#define	ATHEROS_VENDOR_ID	0x168c
+
+#define	AR5416_DEVID_PCI	0x0023
+#define	AR5416_DEVID_PCIE	0x0024
+#define	AR9160_DEVID_PCI	0x0027
+#define	AR9280_DEVID_PCI	0x0029
+#define	AR9280_DEVID_PCIE	0x002a
+#define	AR9285_DEVID_PCIE	0x002b
+
+#define	AR5416_AR9100_DEVID	0x000b
+
+#define	AR_SUBVENDOR_ID_NOG	0x0e11
+#define	AR_SUBVENDOR_ID_NEW_A	0x7065
+
+#define	ATH9K_TXERR_XRETRY		0x01
+#define	ATH9K_TXERR_FILT		0x02
+#define	ATH9K_TXERR_FIFO		0x04
+#define	ATH9K_TXERR_XTXOP		0x08
+#define	ATH9K_TXERR_TIMER_EXPIRED	0x10
+
+#define	ATH9K_TX_BA		0x01
+#define	ATH9K_TX_PWRMGMT	0x02
+#define	ATH9K_TX_DESC_CFG_ERR	0x04
+#define	ATH9K_TX_DATA_UNDERRUN	0x08
+#define	ATH9K_TX_DELIM_UNDERRUN	0x10
+#define	ATH9K_TX_SW_ABORTED	0x40
+#define	ATH9K_TX_SW_FILTERED	0x80
+
+/* should be changed later */
+#define	BIT(n)	(1UL << (n))
+
+struct ath_tx_status {
+	uint32_t ts_tstamp;
+	uint16_t ts_seqnum;
+	uint8_t ts_status;
+	uint8_t ts_ratecode;
+	uint8_t ts_rateindex;
+	int8_t ts_rssi;
+	uint8_t ts_shortretry;
+	uint8_t ts_longretry;
+	uint8_t ts_virtcol;
+	uint8_t ts_antenna;
+	uint8_t ts_flags;
+	int8_t ts_rssi_ctl0;
+	int8_t ts_rssi_ctl1;
+	int8_t ts_rssi_ctl2;
+	int8_t ts_rssi_ext0;
+	int8_t ts_rssi_ext1;
+	int8_t ts_rssi_ext2;
+	uint8_t pad[3];
+	uint32_t ba_low;
+	uint32_t ba_high;
+	uint32_t evm0;
+	uint32_t evm1;
+	uint32_t evm2;
+};
+
+struct ath_rx_status {
+	uint32_t rs_tstamp;
+	uint16_t rs_datalen;
+	uint8_t rs_status;
+	uint8_t rs_phyerr;
+	int8_t rs_rssi;
+	uint8_t rs_keyix;
+	uint8_t rs_rate;
+	uint8_t rs_antenna;
+	uint8_t rs_more;
+	int8_t rs_rssi_ctl0;
+	int8_t rs_rssi_ctl1;
+	int8_t rs_rssi_ctl2;
+	int8_t rs_rssi_ext0;
+	int8_t rs_rssi_ext1;
+	int8_t rs_rssi_ext2;
+	uint8_t rs_isaggr;
+	uint8_t rs_moreaggr;
+	uint8_t rs_num_delims;
+	uint8_t rs_flags;
+	uint32_t evm0;
+	uint32_t evm1;
+	uint32_t evm2;
+};
+
+#define	ATH9K_RXERR_CRC		0x01
+#define	ATH9K_RXERR_PHY		0x02
+#define	ATH9K_RXERR_FIFO	0x04
+#define	ATH9K_RXERR_DECRYPT	0x08
+#define	ATH9K_RXERR_MIC		0x10
+
+#define	ATH9K_RX_MORE		0x01
+#define	ATH9K_RX_MORE_AGGR	0x02
+#define	ATH9K_RX_GI		0x04
+#define	ATH9K_RX_2040		0x08
+#define	ATH9K_RX_DELIM_CRC_PRE	0x10
+#define	ATH9K_RX_DELIM_CRC_POST	0x20
+#define	ATH9K_RX_DECRYPT_BUSY	0x40
+
+#define	ATH9K_RXKEYIX_INVALID	((uint8_t)-1)
+#define	ATH9K_TXKEYIX_INVALID	((uint32_t)-1)
+
+#pragma pack(1)
+struct ath_desc {
+	uint32_t ds_link;
+	uint32_t ds_data;
+	uint32_t ds_ctl0;
+	uint32_t ds_ctl1;
+	uint32_t ds_hw[20];
+	union {
+		struct ath_tx_status tx;
+		struct ath_rx_status rx;
+		void *stats;
+	} ds_us;
+	void *ds_vdata;
+};
+#pragma pack()
+
+#define	ds_txstat	ds_us.tx
+#define	ds_rxstat	ds_us.rx
+#define	ds_stat		ds_us.stats
+
+#define	ATH9K_TXDESC_CLRDMASK		0x0001
+#define	ATH9K_TXDESC_NOACK		0x0002
+#define	ATH9K_TXDESC_RTSENA		0x0004
+#define	ATH9K_TXDESC_CTSENA		0x0008
+/*
+ * ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
+ * the descriptor its marked on.  We take a tx interrupt to reap
+ * descriptors when the h/w hits an EOL condition or
+ * when the descriptor is specifically marked to generate
+ * an interrupt with this flag. Descriptors should be
+ * marked periodically to insure timely replenishing of the
+ * supply needed for sending frames. Defering interrupts
+ * reduces system load and potentially allows more concurrent
+ * work to be done but if done to aggressively can cause
+ * senders to backup. When the hardware queue is left too
+ * large rate control information may also be too out of
+ * date. An Alternative for this is TX interrupt mitigation
+ * but this needs more testing.
+ */
+#define	ATH9K_TXDESC_INTREQ		0x0010
+#define	ATH9K_TXDESC_VEOL		0x0020
+#define	ATH9K_TXDESC_EXT_ONLY		0x0040
+#define	ATH9K_TXDESC_EXT_AND_CTL	0x0080
+#define	ATH9K_TXDESC_VMF		0x0100
+#define	ATH9K_TXDESC_FRAG_IS_ON 	0x0200
+#define	ATH9K_TXDESC_CAB		0x0400
+
+#define	ATH9K_RXDESC_INTREQ		0x0020
+
+enum wireless_mode {
+	ATH9K_MODE_11A = 0,
+	ATH9K_MODE_11B = 2,
+	ATH9K_MODE_11G = 3,
+	ATH9K_MODE_11NA_HT20 = 6,
+	ATH9K_MODE_11NG_HT20 = 7,
+	ATH9K_MODE_11NA_HT40PLUS = 8,
+	ATH9K_MODE_11NA_HT40MINUS = 9,
+	ATH9K_MODE_11NG_HT40PLUS = 10,
+	ATH9K_MODE_11NG_HT40MINUS = 11,
+	ATH9K_MODE_MAX
+};
+
+enum ath9k_hw_caps {
+	ATH9K_HW_CAP_CHAN_SPREAD		= BIT(0),
+	ATH9K_HW_CAP_MIC_AESCCM			= BIT(1),
+	ATH9K_HW_CAP_MIC_CKIP			= BIT(2),
+	ATH9K_HW_CAP_MIC_TKIP			= BIT(3),
+	ATH9K_HW_CAP_CIPHER_AESCCM		= BIT(4),
+	ATH9K_HW_CAP_CIPHER_CKIP		= BIT(5),
+	ATH9K_HW_CAP_CIPHER_TKIP		= BIT(6),
+	ATH9K_HW_CAP_VEOL			= BIT(7),
+	ATH9K_HW_CAP_BSSIDMASK			= BIT(8),
+	ATH9K_HW_CAP_MCAST_KEYSEARCH		= BIT(9),
+	ATH9K_HW_CAP_CHAN_HALFRATE		= BIT(10),
+	ATH9K_HW_CAP_CHAN_QUARTERRATE		= BIT(11),
+	ATH9K_HW_CAP_HT				= BIT(12),
+	ATH9K_HW_CAP_GTT			= BIT(13),
+	ATH9K_HW_CAP_FASTCC			= BIT(14),
+	ATH9K_HW_CAP_RFSILENT			= BIT(15),
+	ATH9K_HW_CAP_WOW			= BIT(16),
+	ATH9K_HW_CAP_CST			= BIT(17),
+	ATH9K_HW_CAP_ENHANCEDPM			= BIT(18),
+	ATH9K_HW_CAP_AUTOSLEEP			= BIT(19),
+	ATH9K_HW_CAP_4KB_SPLITTRANS		= BIT(20),
+	ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT	= BIT(21),
+};
+
+enum ath9k_capability_type {
+	ATH9K_CAP_CIPHER = 0,
+	ATH9K_CAP_TKIP_MIC,
+	ATH9K_CAP_TKIP_SPLIT,
+	ATH9K_CAP_PHYCOUNTERS,
+	ATH9K_CAP_DIVERSITY,
+	ATH9K_CAP_TXPOW,
+	ATH9K_CAP_PHYDIAG,
+	ATH9K_CAP_MCAST_KEYSRCH,
+	ATH9K_CAP_TSF_ADJUST,
+	ATH9K_CAP_WME_TKIPMIC,
+	ATH9K_CAP_RFSILENT,
+	ATH9K_CAP_ANT_CFG_2GHZ,
+	ATH9K_CAP_ANT_CFG_5GHZ
+};
+
+struct ath9k_hw_capabilities {
+	uint32_t hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
+	uint8_t	 wireless_modes[4]; /* ATH9K_MODE_* */
+	uint16_t total_queues;
+	uint16_t keycache_size;
+	uint16_t low_5ghz_chan, high_5ghz_chan;
+	uint16_t low_2ghz_chan, high_2ghz_chan;
+	uint16_t num_mr_retries;
+	uint16_t rts_aggr_limit;
+	uint8_t tx_chainmask;
+	uint8_t rx_chainmask;
+	uint16_t tx_triglevel_max;
+	uint16_t reg_cap;
+	uint8_t num_gpio_pins;
+	uint8_t num_antcfg_2ghz;
+	uint8_t num_antcfg_5ghz;
+};
+
+struct ath9k_ops_config {
+	int dma_beacon_response_time;
+	int sw_beacon_response_time;
+	int additional_swba_backoff;
+	int ack_6mb;
+	int cwm_ignore_extcca;
+	uint8_t pcie_powersave_enable;
+	uint8_t pcie_l1skp_enable;
+	uint8_t pcie_clock_req;
+	uint32_t pcie_waen;
+	int pcie_power_reset;
+	uint8_t pcie_restore;
+	uint8_t analog_shiftreg;
+	uint8_t ht_enable;
+	uint32_t ofdm_trig_low;
+	uint32_t ofdm_trig_high;
+	uint32_t cck_trig_high;
+	uint32_t cck_trig_low;
+	uint32_t enable_ani;
+	uint8_t noise_immunity_level;
+	uint32_t ofdm_weaksignal_det;
+	uint32_t cck_weaksignal_thr;
+	uint8_t spur_immunity_level;
+	uint8_t firstep_level;
+	int8_t rssi_thr_high;
+	int8_t rssi_thr_low;
+	uint16_t diversity_control;
+	uint16_t antenna_switch_swap;
+	int serialize_regmode;
+	int intr_mitigation;
+#define	SPUR_DISABLE		0
+#define	SPUR_ENABLE_IOCTL	1
+#define	SPUR_ENABLE_EEPROM	2
+#define	AR_EEPROM_MODAL_SPURS	5
+#define	AR_SPUR_5413_1		1640
+#define	AR_SPUR_5413_2		1200
+#define	AR_NO_SPUR		0x8000
+#define	AR_BASE_FREQ_2GHZ	2300
+#define	AR_BASE_FREQ_5GHZ	4900
+#define	AR_SPUR_FEEQ_BOUND_HT40	19
+#define	AR_SPUR_FEEQ_BOUND_HT20	10
+	int spurmode;
+	uint16_t spurchans[AR_EEPROM_MODAL_SPURS][2];
+};
+
+enum ath9k_tx_queue {
+	ATH9K_TX_QUEUE_INACTIVE = 0,
+	ATH9K_TX_QUEUE_DATA,
+	ATH9K_TX_QUEUE_BEACON,
+	ATH9K_TX_QUEUE_CAB,
+	ATH9K_TX_QUEUE_UAPSD,
+	ATH9K_TX_QUEUE_PSPOLL
+};
+
+#define	ATH9K_NUM_TX_QUEUES 10
+
+enum ath9k_tx_queue_subtype {
+	ATH9K_WME_AC_BK = 0,
+	ATH9K_WME_AC_BE,
+	ATH9K_WME_AC_VI,
+	ATH9K_WME_AC_VO,
+	ATH9K_WME_UPSD
+};
+
+enum ath9k_tx_queue_flags {
+	TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
+	TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
+	TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
+	TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
+	TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
+	TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
+	TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
+	TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
+	TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
+};
+
+#define	ATH9K_TXQ_USEDEFAULT	((uint32_t)(-1))
+
+#define	ATH9K_DECOMP_MASK_SIZE		128
+#define	ATH9K_READY_TIME_LO_BOUND	50
+#define	ATH9K_READY_TIME_HI_BOUND	96
+
+enum ath9k_pkt_type {
+	ATH9K_PKT_TYPE_NORMAL = 0,
+	ATH9K_PKT_TYPE_ATIM,
+	ATH9K_PKT_TYPE_PSPOLL,
+	ATH9K_PKT_TYPE_BEACON,
+	ATH9K_PKT_TYPE_PROBE_RESP,
+	ATH9K_PKT_TYPE_CHIRP,
+	ATH9K_PKT_TYPE_GRP_POLL,
+};
+
+struct ath9k_tx_queue_info {
+	uint32_t tqi_ver;
+	enum ath9k_tx_queue tqi_type;
+	enum ath9k_tx_queue_subtype tqi_subtype;
+	enum ath9k_tx_queue_flags tqi_qflags;
+	uint32_t tqi_priority;
+	uint32_t tqi_aifs;
+	uint32_t tqi_cwmin;
+	uint32_t tqi_cwmax;
+	uint16_t tqi_shretry;
+	uint16_t tqi_lgretry;
+	uint32_t tqi_cbrPeriod;
+	uint32_t tqi_cbrOverflowLimit;
+	uint32_t tqi_burstTime;
+	uint32_t tqi_readyTime;
+	uint32_t tqi_physCompBuf;
+	uint32_t tqi_intFlags;
+};
+
+enum ath9k_rx_filter {
+	ATH9K_RX_FILTER_UCAST = 0x00000001,
+	ATH9K_RX_FILTER_MCAST = 0x00000002,
+	ATH9K_RX_FILTER_BCAST = 0x00000004,
+	ATH9K_RX_FILTER_CONTROL = 0x00000008,
+	ATH9K_RX_FILTER_BEACON = 0x00000010,
+	ATH9K_RX_FILTER_PROM = 0x00000020,
+	ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
+	ATH9K_RX_FILTER_PSPOLL = 0x00004000,
+	ATH9K_RX_FILTER_PHYERR = 0x00000100,
+	ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+};
+
+enum ath9k_int {
+	ATH9K_INT_RX = 0x00000001,
+	ATH9K_INT_RXDESC = 0x00000002,
+	ATH9K_INT_RXNOFRM = 0x00000008,
+	ATH9K_INT_RXEOL = 0x00000010,
+	ATH9K_INT_RXORN = 0x00000020,
+	ATH9K_INT_TX = 0x00000040,
+	ATH9K_INT_TXDESC = 0x00000080,
+	ATH9K_INT_TIM_TIMER = 0x00000100,
+	ATH9K_INT_TXURN = 0x00000800,
+	ATH9K_INT_MIB = 0x00001000,
+	ATH9K_INT_RXPHY = 0x00004000,
+	ATH9K_INT_RXKCM = 0x00008000,
+	ATH9K_INT_SWBA = 0x00010000,
+	ATH9K_INT_BMISS = 0x00040000,
+	ATH9K_INT_BNR = 0x00100000,
+	ATH9K_INT_TIM = 0x00200000,
+	ATH9K_INT_DTIM = 0x00400000,
+	ATH9K_INT_DTIMSYNC = 0x00800000,
+	ATH9K_INT_GPIO = 0x01000000,
+	ATH9K_INT_CABEND = 0x02000000,
+	ATH9K_INT_CST = 0x10000000,
+	ATH9K_INT_GTT = 0x20000000,
+	ATH9K_INT_FATAL = 0x40000000,
+	ATH9K_INT_GLOBAL = INT_MIN,
+	ATH9K_INT_BMISC = ATH9K_INT_TIM |
+		ATH9K_INT_DTIM |
+		ATH9K_INT_DTIMSYNC |
+		ATH9K_INT_CABEND,
+	ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
+		ATH9K_INT_RXDESC |
+		ATH9K_INT_RXEOL |
+		ATH9K_INT_RXORN |
+		ATH9K_INT_TXURN |
+		ATH9K_INT_TXDESC |
+		ATH9K_INT_MIB |
+		ATH9K_INT_RXPHY |
+		ATH9K_INT_RXKCM |
+		ATH9K_INT_SWBA |
+		ATH9K_INT_BMISS |
+		ATH9K_INT_GPIO,
+	ATH9K_INT_NOCARD = -1
+};
+
+#define	ATH9K_RATESERIES_RTS_CTS	0x0001
+#define	ATH9K_RATESERIES_2040		0x0002
+#define	ATH9K_RATESERIES_HALFGI		0x0004
+
+struct ath9k_11n_rate_series {
+	uint32_t Tries;
+	uint32_t Rate;
+	uint32_t PktDuration;
+	uint32_t ChSel;
+	uint32_t RateFlags;
+};
+
+#define	CHANNEL_CW_INT		0x00002
+#define	CHANNEL_CCK		0x00020
+#define	CHANNEL_OFDM		0x00040
+#define	CHANNEL_2GHZ		0x00080
+#define	CHANNEL_5GHZ		0x00100
+#define	CHANNEL_PASSIVE		0x00200
+#define	CHANNEL_DYN		0x00400
+#define	CHANNEL_HALF		0x04000
+#define	CHANNEL_QUARTER		0x08000
+#define	CHANNEL_HT20		0x10000
+#define	CHANNEL_HT40PLUS	0x20000
+#define	CHANNEL_HT40MINUS	0x40000
+
+#define	CHANNEL_INTERFERENCE	0x01
+#define	CHANNEL_DFS		0x02
+#define	CHANNEL_4MS_LIMIT	0x04
+#define	CHANNEL_DFS_CLEAR	0x08
+#define	CHANNEL_DISALLOW_ADHOC	0x10
+#define	CHANNEL_PER_11D_ADHOC	0x20
+
+#define	CHANNEL_A		(CHANNEL_5GHZ|CHANNEL_OFDM)
+#define	CHANNEL_B		(CHANNEL_2GHZ|CHANNEL_CCK)
+#define	CHANNEL_G		(CHANNEL_2GHZ|CHANNEL_OFDM)
+#define	CHANNEL_G_HT20		(CHANNEL_2GHZ|CHANNEL_HT20)
+#define	CHANNEL_A_HT20		(CHANNEL_5GHZ|CHANNEL_HT20)
+#define	CHANNEL_G_HT40PLUS	(CHANNEL_2GHZ|CHANNEL_HT40PLUS)
+#define	CHANNEL_G_HT40MINUS	(CHANNEL_2GHZ|CHANNEL_HT40MINUS)
+#define	CHANNEL_A_HT40PLUS	(CHANNEL_5GHZ|CHANNEL_HT40PLUS)
+#define	CHANNEL_A_HT40MINUS	(CHANNEL_5GHZ|CHANNEL_HT40MINUS)
+#define	CHANNEL_ALL		\
+	(CHANNEL_OFDM|		\
+	CHANNEL_CCK|		\
+	CHANNEL_2GHZ |		\
+	CHANNEL_5GHZ |		\
+	CHANNEL_HT20 |		\
+	CHANNEL_HT40PLUS |	\
+	CHANNEL_HT40MINUS)
+
+struct ath9k_channel {
+	uint16_t channel;
+	uint32_t channelFlags;
+	uint8_t privFlags;
+	int8_t maxRegTxPower;
+	int8_t maxTxPower;
+	int8_t minTxPower;
+	uint32_t chanmode;
+	int32_t CalValid;
+	boolean_t oneTimeCalsDone;
+	int8_t iCoff;
+	int8_t qCoff;
+	int16_t rawNoiseFloor;
+	int8_t antennaMax;
+	uint32_t regDmnFlags;
+	uint32_t conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */
+#ifdef ARN_NF_PER_CHAN
+	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+#endif
+};
+
+#define	IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
+	(((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
+	(((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
+	(((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
+#define	IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
+	(((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
+	(((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
+	(((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
+#define	IS_CHAN_OFDM(_c)	(((_c)->channelFlags & CHANNEL_OFDM) != 0)
+#define	IS_CHAN_5GHZ(_c)	(((_c)->channelFlags & CHANNEL_5GHZ) != 0)
+#define	IS_CHAN_2GHZ(_c)	(((_c)->channelFlags & CHANNEL_2GHZ) != 0)
+#define	IS_CHAN_PASSIVE(_c)	(((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
+#define	IS_CHAN_HALF_RATE(_c)	(((_c)->channelFlags & CHANNEL_HALF) != 0)
+#define	IS_CHAN_QUARTER_RATE(_c) \
+	(((_c)->channelFlags & CHANNEL_QUARTER) != 0)
+
+/* These macros check chanmode and not channelFlags */
+#define	IS_CHAN_B(_c)	((_c)->chanmode == CHANNEL_B)
+#define	IS_CHAN_HT20(_c)	(((_c)->chanmode == CHANNEL_A_HT20) ||	\
+	((_c)->chanmode == CHANNEL_G_HT20))
+#define	IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) ||	\
+	((_c)->chanmode == CHANNEL_A_HT40MINUS) ||	\
+	((_c)->chanmode == CHANNEL_G_HT40PLUS) ||	\
+	((_c)->chanmode == CHANNEL_G_HT40MINUS))
+#define	IS_CHAN_HT(_c)	(IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
+
+#define	IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c)	((_c) > 4940 && (_c) < 4990)
+#define	IS_CHAN_A_5MHZ_SPACED(_c)			\
+	((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&	\
+	(((_c)->channel % 20) != 0) &&			\
+	(((_c)->channel % 10) != 0))
+
+struct ath9k_keyval {
+	uint8_t kv_type;
+	uint8_t kv_pad;
+	uint16_t kv_len;
+	uint8_t kv_val[16];
+	uint8_t kv_mic[8];
+	uint8_t kv_txmic[8];
+};
+
+enum ath9k_key_type {
+	ATH9K_KEY_TYPE_CLEAR,
+	ATH9K_KEY_TYPE_WEP,
+	ATH9K_KEY_TYPE_AES,
+	ATH9K_KEY_TYPE_TKIP,
+};
+
+enum ath9k_cipher {
+	ATH9K_CIPHER_WEP = 0,
+	ATH9K_CIPHER_AES_OCB = 1,
+	ATH9K_CIPHER_AES_CCM = 2,
+	ATH9K_CIPHER_CKIP = 3,
+	ATH9K_CIPHER_TKIP = 4,
+	ATH9K_CIPHER_CLR = 5,
+	ATH9K_CIPHER_MIC = 127
+};
+
+#define	AR_EEPROM_EEPCAP_COMPRESS_DIS	0x0001
+#define	AR_EEPROM_EEPCAP_AES_DIS	0x0002
+#define	AR_EEPROM_EEPCAP_FASTFRAME_DIS	0x0004
+#define	AR_EEPROM_EEPCAP_BURST_DIS	0x0008
+#define	AR_EEPROM_EEPCAP_MAXQCU		0x01F0
+#define	AR_EEPROM_EEPCAP_MAXQCU_S	4
+#define	AR_EEPROM_EEPCAP_HEAVY_CLIP_EN	0x0200
+#define	AR_EEPROM_EEPCAP_KC_ENTRIES	0xF000
+#define	AR_EEPROM_EEPCAP_KC_ENTRIES_S	12
+
+#define	AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND	0x0040
+#define	AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN	0x0080
+#define	AR_EEPROM_EEREGCAP_EN_KK_U2		0x0100
+#define	AR_EEPROM_EEREGCAP_EN_KK_MIDBAND	0x0200
+#define	AR_EEPROM_EEREGCAP_EN_KK_U1_ODD		0x0400
+#define	AR_EEPROM_EEREGCAP_EN_KK_NEW_11A	0x0800
+
+#define	AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 	0x4000
+#define	AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0	0x8000
+
+#define	SD_NO_CTL	0xE0
+#define	NO_CTL		0xff
+#define	CTL_MODE_M	7
+#define	CTL_11A		0
+#define	CTL_11B		1
+#define	CTL_11G		2
+#define	CTL_2GHT20	5
+#define	CTL_5GHT20	6
+#define	CTL_2GHT40	7
+#define	CTL_5GHT40	8
+
+#define	AR_EEPROM_MAC(i)	(0x1d+(i))
+
+#define	AR_EEPROM_RFSILENT_GPIO_SEL	0x001c
+#define	AR_EEPROM_RFSILENT_GPIO_SEL_S	2
+#define	AR_EEPROM_RFSILENT_POLARITY	0x0002
+#define	AR_EEPROM_RFSILENT_POLARITY_S	1
+
+#define	CTRY_DEBUG	0x1ff
+#define	CTRY_DEFAULT	0
+
+enum reg_ext_bitmap {
+	REG_EXT_JAPAN_MIDBAND = 1,
+	REG_EXT_FCC_DFS_HT40 = 2,
+	REG_EXT_JAPAN_NONDFS_HT40 = 3,
+	REG_EXT_JAPAN_DFS_HT40 = 4
+};
+
+struct ath9k_country_entry {
+	uint16_t countryCode;
+	uint16_t regDmnEnum;
+	uint16_t regDmn5G;
+	uint16_t regDmn2G;
+	uint8_t isMultidomain;
+	uint8_t iso[3];
+};
+
+/* Register read/write primitives */
+#define	REG_WRITE(_ah, _reg, _val)	arn_iowrite32((_ah), (_reg), (_val))
+#define	REG_READ(_ah, _reg)	arn_ioread32((_ah), (_reg))
+#define	FLASH_READ(_ah, _reg)					\
+	ddi_get16((_ah->ah_sc)->sc_io_handle,			\
+	    (uint16_t *)((uintptr_t)(_ah)->ah_sh + (_reg)))
+
+#define	SM(_v, _f)	(((_v) << _f##_S) & _f)
+#define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
+#define	REG_RMW(_a, _r, _set, _clr)	\
+	REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
+#define	REG_RMW_FIELD(_a, _r, _f, _v) \
+	REG_WRITE(_a, _r, \
+	(REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+#define	REG_SET_BIT(_a, _r, _f) \
+	REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
+#define	REG_CLR_BIT(_a, _r, _f) \
+	REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
+
+#define	ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS	0x00000001
+
+#define	INIT_AIFS	2
+#define	INIT_CWMIN	15
+#define	INIT_CWMIN_11B	31
+#define	INIT_CWMAX	1023
+#define	INIT_SH_RETRY	10
+#define	INIT_LG_RETRY	10
+#define	INIT_SSH_RETRY	32
+#define	INIT_SLG_RETRY	32
+
+#define	WLAN_CTRL_FRAME_SIZE	(2+2+6+4)
+
+#define	ATH_AMPDU_LIMIT_MAX	(64 * 1024 - 1)
+#define	ATH_AMPDU_LIMIT_DEFAULT	ATH_AMPDU_LIMIT_MAX
+
+#define	IEEE80211_WEP_IVLEN	3
+#define	IEEE80211_WEP_KIDLEN	1
+#define	IEEE80211_WEP_CRCLEN	4
+#define	IEEE80211_MAX_MPDU_LEN	(3840 + FCS_LEN +	\
+	(IEEE80211_WEP_IVLEN +	\
+	IEEE80211_WEP_KIDLEN +	\
+	IEEE80211_WEP_CRCLEN))
+#define	MAX_RATE_POWER	63
+
+enum ath9k_power_mode {
+	ATH9K_PM_AWAKE = 0,
+	ATH9K_PM_FULL_SLEEP,
+	ATH9K_PM_NETWORK_SLEEP,
+	ATH9K_PM_UNDEFINED
+};
+
+struct ath9k_mib_stats {
+	uint32_t ackrcv_bad;
+	uint32_t rts_bad;
+	uint32_t rts_good;
+	uint32_t fcs_bad;
+	uint32_t beacons;
+};
+
+enum ath9k_ant_setting {
+	ATH9K_ANT_VARIABLE = 0,
+	ATH9K_ANT_FIXED_A,
+	ATH9K_ANT_FIXED_B
+};
+
+
+enum ath9k_opmode {
+	ATH9K_M_STA = 1,
+	ATH9K_M_IBSS = 0,
+	ATH9K_M_HOSTAP = 6,
+	ATH9K_M_MONITOR = 8
+};
+
+
+#define	ATH9K_SLOT_TIME_6	6
+#define	ATH9K_SLOT_TIME_9	9
+#define	ATH9K_SLOT_TIME_20	20
+
+enum ath9k_ht_macmode {
+	ATH9K_HT_MACMODE_20 = 0,
+	ATH9K_HT_MACMODE_2040 = 1,
+};
+
+enum ath9k_ht_extprotspacing {
+	ATH9K_HT_EXTPROTSPACING_20 = 0,
+	ATH9K_HT_EXTPROTSPACING_25 = 1,
+};
+
+struct ath9k_ht_cwm {
+	enum ath9k_ht_macmode ht_macmode;
+	enum ath9k_ht_extprotspacing ht_extprotspacing;
+};
+
+enum ath9k_ani_cmd {
+	ATH9K_ANI_PRESENT = 0x1,
+	ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
+	ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
+	ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
+	ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
+	ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
+	ATH9K_ANI_MODE = 0x40,
+	ATH9K_ANI_PHYERR_RESET = 0x80,
+	ATH9K_ANI_ALL = 0xff
+};
+
+enum {
+	WLAN_RC_PHY_OFDM,
+	WLAN_RC_PHY_CCK,
+	WLAN_RC_PHY_HT_20_SS,
+	WLAN_RC_PHY_HT_20_DS,
+	WLAN_RC_PHY_HT_40_SS,
+	WLAN_RC_PHY_HT_40_DS,
+	WLAN_RC_PHY_HT_20_SS_HGI,
+	WLAN_RC_PHY_HT_20_DS_HGI,
+	WLAN_RC_PHY_HT_40_SS_HGI,
+	WLAN_RC_PHY_HT_40_DS_HGI,
+	WLAN_RC_PHY_MAX
+};
+
+enum ath9k_tp_scale {
+	ATH9K_TP_SCALE_MAX = 0,
+	ATH9K_TP_SCALE_50,
+	ATH9K_TP_SCALE_25,
+	ATH9K_TP_SCALE_12,
+	ATH9K_TP_SCALE_MIN
+};
+
+enum ser_reg_mode {
+	SER_REG_MODE_OFF = 0,
+	SER_REG_MODE_ON = 1,
+	SER_REG_MODE_AUTO = 2,
+};
+
+#define	AR_PHY_CCA_MAX_GOOD_VALUE		-85
+#define	AR_PHY_CCA_MAX_HIGH_VALUE		-62
+#define	AR_PHY_CCA_MIN_BAD_VALUE		-121
+#define	AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT	3
+#define	AR_PHY_CCA_FILTERWINDOW_LENGTH		5
+
+#define	ATH9K_NF_CAL_HIST_MAX		5
+#define	NUM_NF_READINGS			6
+
+struct ath9k_nfcal_hist {
+	int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
+	uint8_t currIndex;
+	int16_t privNF;
+	uint8_t invalidNFcount;
+};
+
+struct ath9k_beacon_state {
+	uint32_t bs_nexttbtt;
+	uint32_t bs_nextdtim;
+	uint32_t bs_intval;
+#define	ATH9K_BEACON_PERIOD	0x0000ffff
+#define	ATH9K_BEACON_ENA	0x00800000
+#define	ATH9K_BEACON_RESET_TSF	0x01000000
+	uint32_t bs_dtimperiod;
+	uint16_t bs_cfpperiod;
+	uint16_t bs_cfpmaxduration;
+	uint32_t bs_cfpnext;
+	uint16_t bs_timoffset;
+	uint16_t bs_bmissthreshold;
+	uint32_t bs_sleepduration;
+};
+
+struct ath9k_node_stats {
+	uint32_t ns_avgbrssi;
+	uint32_t ns_avgrssi;
+	uint32_t ns_avgtxrssi;
+	uint32_t ns_avgtxrate;
+};
+
+#define	ATH9K_RSSI_EP_MULTIPLIER			(1<<7)
+
+#define	AR_GPIO_OUTPUT_MUX_AS_OUTPUT			0
+#define	AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED	1
+#define	AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED		2
+#define	AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED		5
+#define	AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED		6
+
+enum {
+	ATH9K_RESET_POWER_ON,
+	ATH9K_RESET_WARM,
+	ATH9K_RESET_COLD,
+};
+
+#define	AH_USE_EEPROM	0x1
+
+struct ath_hal {
+	uint32_t ah_magic;
+	uint16_t ah_devid;
+	uint16_t ah_subvendorid;
+	uint32_t ah_macVersion;
+	uint16_t ah_macRev;
+	uint16_t ah_phyRev;
+	uint16_t ah_analog5GhzRev;
+	uint16_t ah_analog2GhzRev;
+
+	caddr_t	 ah_sh;
+	struct arn_softc *ah_sc;
+	enum ath9k_opmode ah_opmode;
+	struct ath9k_ops_config ah_config;
+	struct ath9k_hw_capabilities ah_caps;
+
+	uint16_t ah_countryCode;
+	uint32_t ah_flags;
+	int16_t ah_powerLimit;
+	uint16_t ah_maxPowerLevel;
+	uint32_t ah_tpScale;
+	uint16_t ah_currentRD;
+	uint16_t ah_currentRDExt;
+	uint16_t ah_currentRDInUse;
+	uint16_t ah_currentRD5G;
+	uint16_t ah_currentRD2G;
+	char ah_iso[4];
+
+	struct ath9k_channel ah_channels[150];
+	struct ath9k_channel *ah_curchan;
+	uint32_t ah_nchan;
+
+	boolean_t ah_isPciExpress;
+	uint16_t ah_txTrigLevel;
+	uint16_t ah_rfsilent;
+	uint32_t ah_rfkill_gpio;
+	uint32_t ah_rfkill_polarity;
+
+#ifndef ARN_NF_PER_CHAN
+	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+#endif
+};
+
+struct chan_centers {
+	uint16_t synth_center;
+	uint16_t ctl_center;
+	uint16_t ext_center;
+};
+
+struct ath_rate_table;
+
+/* Helpers */
+
+enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
+    const struct ath9k_channel *chan);
+boolean_t ath9k_hw_wait(struct ath_hal *ah, uint32_t reg, uint32_t mask,
+    uint32_t val);
+uint32_t ath9k_hw_reverse_bits(uint32_t val, uint32_t n);
+boolean_t ath9k_get_channel_edges(struct ath_hal *ah,
+    uint16_t flags, uint16_t *low, uint16_t *high);
+uint16_t ath9k_hw_computetxtime(struct ath_hal *ah,
+    struct ath_rate_table *rates,
+    uint32_t frameLen, uint16_t rateix,
+    boolean_t shortPreamble);
+uint32_t ath9k_hw_mhz2ieee(struct ath_hal *ah, uint32_t freq, uint32_t flags);
+void ath9k_hw_get_channel_centers(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    struct chan_centers *centers);
+
+/* Attach, Detach */
+
+const char *ath9k_hw_probe(uint16_t vendorid, uint16_t devid);
+void ath9k_hw_detach(struct ath_hal *ah);
+struct ath_hal *ath9k_hw_attach(uint16_t devid, struct arn_softc *sc,
+    caddr_t mem, int *error);
+void ath9k_hw_rfdetach(struct ath_hal *ah);
+
+
+/* HW Reset */
+
+boolean_t ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
+    enum ath9k_ht_macmode macmode,
+    uint8_t txchainmask, uint8_t rxchainmask,
+    enum ath9k_ht_extprotspacing extprotspacing,
+    boolean_t bChannelChange, int *status);
+
+/* Key Cache Management */
+
+boolean_t ath9k_hw_keyreset(struct ath_hal *ah, uint16_t entry);
+boolean_t ath9k_hw_keysetmac(struct ath_hal *ah, uint16_t entry,
+    const uint8_t *mac);
+boolean_t ath9k_hw_set_keycache_entry(struct ath_hal *ah, uint16_t entry,
+    const struct ath9k_keyval *k, const uint8_t *mac, int xorKey);
+boolean_t ath9k_hw_keyisvalid(struct ath_hal *ah, uint16_t entry);
+
+/* Power Management */
+
+boolean_t ath9k_hw_setpower(struct ath_hal *ah,
+    enum ath9k_power_mode mode);
+void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
+
+/* Beacon timers */
+
+void ath9k_hw_beaconinit(struct ath_hal *ah, uint32_t next_beacon,
+    uint32_t beacon_period);
+void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
+    const struct ath9k_beacon_state *bs);
+/* HW Capabilities */
+
+boolean_t ath9k_hw_fill_cap_info(struct ath_hal *ah);
+boolean_t ath9k_hw_getcapability(struct ath_hal *ah,
+    enum ath9k_capability_type type,
+    uint32_t capability, uint32_t *result);
+boolean_t ath9k_hw_setcapability(struct ath_hal *ah,
+    enum ath9k_capability_type type,
+    uint32_t capability, uint32_t setting,
+    int *status);
+
+/* GPIO / RFKILL / Antennae */
+
+void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, uint32_t gpio);
+uint32_t ath9k_hw_gpio_get(struct ath_hal *ah, uint32_t gpio);
+void ath9k_hw_cfg_output(struct ath_hal *ah, uint32_t gpio,
+    uint32_t ah_signal_type);
+void ath9k_hw_set_gpio(struct ath_hal *ah, uint32_t gpio, uint32_t val);
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+void ath9k_enable_rfkill(struct ath_hal *ah);
+#endif
+int ath9k_hw_select_antconfig(struct ath_hal *ah, uint32_t cfg);
+uint32_t ath9k_hw_getdefantenna(struct ath_hal *ah);
+void ath9k_hw_setantenna(struct ath_hal *ah, uint32_t antenna);
+boolean_t ath9k_hw_setantennaswitch(struct ath_hal *ah,
+    enum ath9k_ant_setting settings,
+    struct ath9k_channel *chan,
+    uint8_t *tx_chainmask,
+    uint8_t *rx_chainmask,
+    uint8_t *antenna_cfgd);
+
+/* General Operation */
+
+uint32_t ath9k_hw_getrxfilter(struct ath_hal *ah);
+void ath9k_hw_setrxfilter(struct ath_hal *ah, uint32_t bits);
+boolean_t ath9k_hw_phy_disable(struct ath_hal *ah);
+boolean_t ath9k_hw_disable(struct ath_hal *ah);
+boolean_t ath9k_hw_set_txpowerlimit(struct ath_hal *ah, uint32_t limit);
+void ath9k_hw_getmac(struct ath_hal *ah, uint8_t *mac);
+boolean_t ath9k_hw_setmac(struct ath_hal *ah, const uint8_t *mac);
+void ath9k_hw_setopmode(struct ath_hal *ah);
+void ath9k_hw_setmcastfilter(struct ath_hal *ah, uint32_t filter0,
+    uint32_t filter1);
+void ath9k_hw_getbssidmask(struct ath_hal *ah, uint8_t *mask);
+boolean_t ath9k_hw_setbssidmask(struct ath_hal *ah, const uint8_t *mask);
+void ath9k_hw_write_associd(struct ath_hal *ah, const uint8_t *bssid,
+    uint16_t assocId);
+uint64_t ath9k_hw_gettsf64(struct ath_hal *ah);
+void ath9k_hw_reset_tsf(struct ath_hal *ah);
+boolean_t ath9k_hw_set_tsfadjust(struct ath_hal *ah, uint32_t setting);
+boolean_t ath9k_hw_setslottime(struct ath_hal *ah, uint32_t us);
+void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
+
+/* Regulatory */
+
+boolean_t ath9k_regd_is_public_safety_sku(struct ath_hal *ah);
+struct ath9k_channel *ath9k_regd_check_channel(struct ath_hal *ah,
+    const struct ath9k_channel *c);
+uint32_t ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
+uint32_t ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+boolean_t ath9k_regd_init_channels(struct ath_hal *ah,
+    uint32_t maxchans, uint32_t *nchans, uint8_t *regclassids,
+    uint32_t maxregids, uint32_t *nregids, uint16_t cc,
+    boolean_t enableOutdoor, boolean_t enableExtendedChannels);
+
+/* ANI */
+
+void ath9k_ani_reset(struct ath_hal *ah);
+void ath9k_hw_ani_monitor(struct ath_hal *ah,
+    const struct ath9k_node_stats *stats,
+    struct ath9k_channel *chan);
+boolean_t ath9k_hw_phycounters(struct ath_hal *ah);
+void ath9k_enable_mib_counters(struct ath_hal *ah);
+void ath9k_hw_disable_mib_counters(struct ath_hal *ah);
+uint32_t ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
+    uint32_t *rxc_pcnt,
+    uint32_t *rxf_pcnt,
+    uint32_t *txf_pcnt);
+void ath9k_hw_procmibevent(struct ath_hal *ah,
+    const struct ath9k_node_stats *stats);
+void ath9k_hw_ani_setup(struct ath_hal *ah);
+void ath9k_hw_ani_attach(struct ath_hal *ah);
+void ath9k_hw_ani_detach(struct ath_hal *ah);
+
+/* Calibration */
+
+void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
+    boolean_t *isCalDone);
+void ath9k_hw_start_nfcal(struct ath_hal *ah);
+void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan);
+int16_t ath9k_hw_getnf(struct ath_hal *ah, struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah);
+signed short ath9k_hw_getchan_noise(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+boolean_t ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
+    uint8_t rxchainmask, boolean_t longcal, boolean_t *isCalDone);
+boolean_t ath9k_hw_init_cal(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+
+
+/* EEPROM */
+
+int ath9k_hw_set_txpower(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    uint16_t cfgCtl,
+    uint8_t twiceAntennaReduction,
+    uint8_t twiceMaxRegulatoryPower,
+    uint8_t powerLimit);
+void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan);
+boolean_t ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    int16_t *ratesArray,
+    uint16_t cfgCtl,
+    uint8_t AntennaReduction,
+    uint8_t twiceMaxRegulatoryPower,
+    uint8_t powerLimit);
+boolean_t ath9k_hw_set_power_cal_table(struct ath_hal *ah,
+    struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset);
+boolean_t ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
+    struct ath9k_channel *chan, uint8_t index, uint16_t *config);
+
+uint8_t ath9k_hw_get_num_ant_config(struct ath_hal *ah,
+    enum ath9k_band freq_band);
+
+uint16_t ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, uint16_t i,
+    boolean_t is2GHz);
+int ath9k_hw_eeprom_attach(struct ath_hal *ah);
+
+/* Interrupt Handling */
+
+boolean_t ath9k_hw_intrpend(struct ath_hal *ah);
+boolean_t ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
+enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints);
+
+/* MAC (PCU/QCU) */
+
+void ath9k_hw_dmaRegDump(struct ath_hal *ah);
+uint32_t ath9k_hw_gettxbuf(struct ath_hal *ah, uint32_t q);
+boolean_t ath9k_hw_puttxbuf(struct ath_hal *ah, uint32_t q, uint32_t txdp);
+boolean_t ath9k_hw_txstart(struct ath_hal *ah, uint32_t q);
+uint32_t ath9k_hw_numtxpending(struct ath_hal *ah, uint32_t q);
+boolean_t ath9k_hw_updatetxtriglevel(struct ath_hal *ah,
+    boolean_t bIncTrigLevel);
+boolean_t ath9k_hw_stoptxdma(struct ath_hal *ah, uint32_t q);
+boolean_t ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t segLen, boolean_t firstSeg,
+    boolean_t lastSeg, const struct ath_desc *ds0);
+void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
+int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t pktLen, enum ath9k_pkt_type type, uint32_t txPower,
+    uint32_t keyIx, enum ath9k_key_type keyType, uint32_t flags);
+void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
+    struct ath_desc *lastds,
+    uint32_t durUpdateEn, uint32_t rtsctsRate,
+    uint32_t rtsctsDuration,
+    struct ath9k_11n_rate_series series[],
+    uint32_t nseries, uint32_t flags);
+void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t aggrLen);
+void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t numDelims);
+void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
+void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t burstDuration);
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t vmf);
+void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, uint32_t *txqs);
+boolean_t ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
+    const struct ath9k_tx_queue_info *qinfo);
+boolean_t ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
+    struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
+    const struct ath9k_tx_queue_info *qinfo);
+boolean_t ath9k_hw_releasetxqueue(struct ath_hal *ah, uint32_t q);
+boolean_t ath9k_hw_resettxqueue(struct ath_hal *ah, uint32_t q);
+int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t pa, struct ath_desc *nds, uint64_t tsf);
+boolean_t ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t size, uint32_t flags);
+boolean_t ath9k_hw_setrxabort(struct ath_hal *ah, boolean_t set);
+void ath9k_hw_putrxbuf(struct ath_hal *ah, uint32_t rxdp);
+void ath9k_hw_rxena(struct ath_hal *ah);
+void ath9k_hw_startpcureceive(struct ath_hal *ah);
+void ath9k_hw_stoppcurecv(struct ath_hal *ah);
+boolean_t ath9k_hw_stopdmarecv(struct ath_hal *ah);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARN_ATH9K_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_beacon.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,515 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/strsun.h>
+#include <inet/common.h>
+#include <inet/nd.h>
+#include <inet/mi.h>
+#include <inet/wifi_ioctl.h>
+
+#include "arn_core.h"
+
+/*
+ * This function will modify certain transmit queue properties depending on
+ * the operating mode of the station (AP or AdHoc).  Parameters are AIFS
+ * settings and channel width min/max
+ */
+static int
+arn_beaconq_config(struct arn_softc *sc)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	struct ath9k_tx_queue_info qi;
+
+	(void) ath9k_hw_get_txq_props(ah, sc->sc_beaconq, &qi);
+	if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
+		/* Always burst out beacon and CAB traffic. */
+		qi.tqi_aifs = 1;
+		qi.tqi_cwmin = 0;
+		qi.tqi_cwmax = 0;
+	} else {
+		/* Adhoc mode; important thing is to use 2x cwmin. */
+		qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs;
+		qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin;
+		qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax;
+	}
+
+	if (!ath9k_hw_set_txq_props(ah, sc->sc_beaconq, &qi)) {
+		arn_problem("unable to update h/w beacon queue parameters\n");
+		return (0);
+	} else {
+		/* push to h/w */
+		(void) ath9k_hw_resettxqueue(ah, sc->sc_beaconq);
+		return (1);
+	}
+}
+
+/*
+ * Associates the beacon frame buffer with a transmit descriptor.  Will set
+ * up all required antenna switch parameters, rate codes, and channel flags.
+ * Beacons are always sent out at the lowest rate, and are not retried.
+ */
+
+static void
+arn_beacon_setup(struct arn_softc *sc, struct ath_buf *bf)
+{
+#define	USE_SHPREAMBLE(_ic) \
+	(((_ic)->ic_flags & (IEEE80211_F_SHPREAMBLE | IEEE80211_F_USEBARKER))\
+	    == IEEE80211_F_SHPREAMBLE)
+	mblk_t *mp = bf->bf_m;
+	struct ath_hal *ah = sc->sc_ah;
+	struct ath_desc *ds;
+	/* LINTED E_FUNC_SET_NOT_USED */
+	int flags, antenna = 0;
+	struct ath_rate_table *rt;
+	uint8_t rix, rate;
+	struct ath9k_11n_rate_series series[4];
+	int ctsrate = 0;
+	int ctsduration = 0;
+
+	/* set up descriptors */
+	ds = bf->bf_desc;
+
+	flags = ATH9K_TXDESC_NOACK;
+	if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS &&
+	    (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+		ds->ds_link = bf->bf_daddr;	/* self-linked */
+		flags |= ATH9K_TXDESC_VEOL;
+		/*
+		 * Let hardware handle antenna switching.
+		 */
+		antenna = 0;
+	} else {
+		ds->ds_link = 0;
+		/*
+		 * Switch antenna every 4 beacons.
+		 * NB: assumes two antenna
+		 */
+		antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
+	}
+
+	ds->ds_data = bf->bf_dma.cookie.dmac_address;
+	/*
+	 * Calculate rate code.
+	 * XXX everything at min xmit rate
+	 */
+	rix = 0;
+	rt = sc->hw_rate_table[sc->sc_curmode];
+	rate = rt->info[rix].ratecode;
+	if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+		rate |= rt->info[rix].short_preamble;
+
+	ath9k_hw_set11n_txdesc(ah, ds,
+	    MBLKL(mp) + IEEE80211_CRC_LEN, /* frame length */
+	    ATH9K_PKT_TYPE_BEACON,	/* Atheros packet type */
+	    MAX_RATE_POWER,		/* FIXME */
+	    ATH9K_TXKEYIX_INVALID,	/* no encryption */
+	    ATH9K_KEY_TYPE_CLEAR,	/* no encryption */
+	    flags);			/* no ack, veol for beacons */
+
+	/* NB: beacon's BufLen must be a multiple of 4 bytes */
+	(void) ath9k_hw_filltxdesc(ah, ds,
+	    roundup(MBLKL(mp), 4),	/* buffer length */
+	    B_TRUE,			/* first segment */
+	    B_TRUE,			/* last segment */
+	    ds);			/* first descriptor */
+
+	(void) memset(series, 0, sizeof (struct ath9k_11n_rate_series) * 4);
+	series[0].Tries = 1;
+	series[0].Rate = rate;
+	series[0].ChSel = sc->sc_tx_chainmask;
+	series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
+	ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
+	    ctsrate, ctsduration, series, 4, 0);
+#undef	USE_SHPREAMBLE
+}
+
+/*
+ * Startup beacon transmission for adhoc mode when they are sent entirely
+ * by the hardware using the self-linked descriptor + veol trick.
+ */
+static void
+arn_beacon_start_adhoc(struct arn_softc *sc)
+
+{
+	struct ath_buf *bf = list_head(&sc->sc_bcbuf_list);
+	struct ieee80211_node *in = bf->bf_in;
+	struct ieee80211com *ic = in->in_ic;
+	struct ath_hal *ah = sc->sc_ah;
+	mblk_t *mp;
+
+	mp = bf->bf_m;
+	if (ieee80211_beacon_update(ic, bf->bf_in, &sc->asc_boff, mp, 0))
+		bcopy(mp->b_rptr, bf->bf_dma.mem_va, MBLKL(mp));
+
+	/* Construct tx descriptor. */
+	arn_beacon_setup(sc, bf);
+
+	/*
+	 * Stop any current dma and put the new frame on the queue.
+	 * This should never fail since we check above that no frames
+	 * are still pending on the queue.
+	 */
+	if (!ath9k_hw_stoptxdma(ah, sc->sc_beaconq)) {
+		arn_problem("ath: beacon queue %d did not stop?\n",
+		    sc->sc_beaconq);
+	}
+	ARN_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV);
+
+	/* NB: caller is known to have already stopped tx dma */
+	(void) ath9k_hw_puttxbuf(ah, sc->sc_beaconq, bf->bf_daddr);
+	(void) ath9k_hw_txstart(ah, sc->sc_beaconq);
+
+	ARN_DBG((ARN_DBG_BEACON, "arn: arn_bstuck_process(): "
+	    "TXDP%u = %llx (%p)\n", sc->sc_beaconq,
+	    ito64(bf->bf_daddr), bf->bf_desc));
+}
+
+uint32_t
+arn_beaconq_setup(struct ath_hal *ah)
+{
+	struct ath9k_tx_queue_info qi;
+
+	(void) memset(&qi, 0, sizeof (qi));
+	qi.tqi_aifs = 1;
+	qi.tqi_cwmin = 0;
+	qi.tqi_cwmax = 0;
+	/* NB: don't enable any interrupts */
+	return (ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi));
+}
+
+int
+arn_beacon_alloc(struct arn_softc *sc, struct ieee80211_node *in)
+{
+	ieee80211com_t	*ic = in->in_ic;
+	struct ath_buf *bf;
+	mblk_t *mp;
+
+	mutex_enter(&sc->sc_bcbuflock);
+	bf = list_head(&sc->sc_bcbuf_list);
+	if (bf == NULL) {
+		arn_problem("arn: arn_beacon_alloc():"
+		    "no dma buffers");
+		mutex_exit(&sc->sc_bcbuflock);
+		return (ENOMEM);
+	}
+
+	mp = ieee80211_beacon_alloc(ic, in, &sc->asc_boff);
+	if (mp == NULL) {
+		arn_problem("ath: arn_beacon_alloc():"
+		    "cannot get mbuf\n");
+		mutex_exit(&sc->sc_bcbuflock);
+		return (ENOMEM);
+	}
+	ASSERT(mp->b_cont == NULL);
+	bf->bf_m = mp;
+	bcopy(mp->b_rptr, bf->bf_dma.mem_va, MBLKL(mp));
+	bf->bf_in = ieee80211_ref_node(in);
+	mutex_exit(&sc->sc_bcbuflock);
+
+	return (0);
+}
+
+
+void
+arn_beacon_return(struct arn_softc *sc)
+{
+	struct ath_buf *bf;
+
+	mutex_enter(&sc->sc_bcbuflock);
+	bf = list_head(&sc->sc_bcbuf_list);
+	while (bf != NULL) {
+		if (bf->bf_m != NULL) {
+			freemsg(bf->bf_m);
+			bf->bf_m = NULL;
+		}
+		if (bf->bf_in != NULL) {
+			ieee80211_free_node(bf->bf_in);
+			bf->bf_in = NULL;
+		}
+		bf = list_next(&sc->sc_bcbuf_list, bf);
+	}
+	mutex_exit(&sc->sc_bcbuflock);
+}
+
+void
+arn_beacon_config(struct arn_softc *sc)
+
+{
+	struct ath_hal *ah = sc->sc_ah;
+	struct ath_beacon_config conf;
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ieee80211_node *in = ic->ic_bss;
+	uint32_t nexttbtt, intval;
+
+	(void) memset(&conf, 0, sizeof (struct ath_beacon_config));
+
+	/* XXX fix me */
+	conf.beacon_interval = in->in_intval ?
+	    in->in_intval : ATH_DEFAULT_BINTVAL;
+	conf.listen_interval = 1;
+	conf.dtim_period = conf.beacon_interval;
+	conf.dtim_count = 1;
+	conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
+
+	/* extract tstamp from last beacon and convert to TU */
+	// nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp);
+	/* XXX fix me */
+	nexttbtt = (ARN_LE_READ_32(in->in_tstamp.data + 4) << 22) |
+	    (ARN_LE_READ_32(in->in_tstamp.data) >> 10);
+
+	/* XXX conditionalize multi-bss support? */
+	if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
+		/*
+		 * For multi-bss ap support beacons are either staggered
+		 * evenly over N slots or burst together.  For the former
+		 * arrange for the SWBA to be delivered for each slot.
+		 * Slots that are not occupied will generate nothing.
+		 */
+		/* NB: the beacon interval is kept internally in TU's */
+		intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
+		intval /= ATH_BCBUF; /* for staggered beacons */
+	} else {
+		intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
+	}
+
+	if (nexttbtt == 0)	/* e.g. for ap mode */
+		nexttbtt = intval;
+	else if (intval)	/* NB: can be 0 for monitor mode */
+		nexttbtt = roundup(nexttbtt, intval);
+
+	ARN_DBG((ARN_DBG_BEACON, "arn: arn_beacon_config(): "
+	    "nexttbtt %u intval %u (%u)\n",
+	    nexttbtt, intval, conf.beacon_interval));
+
+	/* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
+	if (sc->sc_ah->ah_opmode == ATH9K_M_STA) {
+		struct ath9k_beacon_state bs;
+		uint64_t tsf;
+		uint32_t tsftu;
+		int dtimperiod, dtimcount, sleepduration;
+		int cfpperiod, cfpcount;
+
+		/*
+		 * Setup dtim and cfp parameters according to
+		 * last beacon we received (which may be none).
+		 */
+		dtimperiod = conf.dtim_period;
+		if (dtimperiod <= 0)		/* NB: 0 if not known */
+			dtimperiod = 1;
+		dtimcount = conf.dtim_count;
+		if (dtimcount >= dtimperiod)	/* NB: sanity check */
+			dtimcount = 0;
+		cfpperiod = 1;			/* NB: no PCF support yet */
+		cfpcount = 0;
+
+		sleepduration = conf.listen_interval * intval;
+		if (sleepduration <= 0)
+			sleepduration = intval;
+
+#define	FUDGE	2
+		/*
+		 * Pull nexttbtt forward to reflect the current
+		 * TSF and calculate dtim+cfp state for the result.
+		 */
+		tsf = ath9k_hw_gettsf64(ah);
+		tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
+		do {
+			nexttbtt += intval;
+			if (--dtimcount < 0) {
+				dtimcount = dtimperiod - 1;
+				if (--cfpcount < 0)
+					cfpcount = cfpperiod - 1;
+			}
+		} while (nexttbtt < tsftu);
+#undef FUDGE
+		(void) memset(&bs, 0, sizeof (bs));
+		bs.bs_intval = intval;
+		bs.bs_nexttbtt = nexttbtt;
+		bs.bs_dtimperiod = dtimperiod*intval;
+		bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
+		bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
+		bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
+		bs.bs_cfpmaxduration = 0;
+
+		/*
+		 * Calculate the number of consecutive beacons to miss
+		 * before taking a BMISS interrupt.  The configuration
+		 * is specified in TU so we only need calculate based
+		 * on the beacon interval.  Note that we clamp the
+		 * result to at most 15 beacons.
+		 */
+		if (sleepduration > intval) {
+			bs.bs_bmissthreshold = conf.listen_interval *
+			    ATH_DEFAULT_BMISS_LIMIT / 2;
+		} else {
+			bs.bs_bmissthreshold =
+				DIV_ROUND_UP(conf.bmiss_timeout, intval);
+			if (bs.bs_bmissthreshold > 15)
+				bs.bs_bmissthreshold = 15;
+			/* LINTED E_SUSPICIOUS_COMPARISON */
+			else if (bs.bs_bmissthreshold <= 0)
+				bs.bs_bmissthreshold = 1;
+		}
+
+		/*
+		 * Calculate sleep duration.  The configuration is
+		 * given in ms.  We insure a multiple of the beacon
+		 * period is used.  Also, if the sleep duration is
+		 * greater than the DTIM period then it makes senses
+		 * to make it a multiple of that.
+		 *
+		 * XXX fixed at 100ms
+		 */
+
+		bs.bs_sleepduration =
+		    roundup(IEEE80211_MS_TO_TU(100), sleepduration);
+		if (bs.bs_sleepduration > bs.bs_dtimperiod)
+			bs.bs_sleepduration = bs.bs_dtimperiod;
+
+		ARN_DBG((ARN_DBG_BEACON, "arn: arn_beacon_config(): "
+		    "tsf %llu "
+		    "tsf:tu %u "
+		    "intval %u "
+		    "nexttbtt %u "
+		    "dtim %u "
+		    "nextdtim %u "
+		    "bmiss %u "
+		    "sleep %u "
+		    "cfp:period %u "
+		    "maxdur %u "
+		    "next %u "
+		    "timoffset %u\n",
+		    (unsigned long long)tsf, tsftu,
+		    bs.bs_intval,
+		    bs.bs_nexttbtt,
+		    bs.bs_dtimperiod,
+		    bs.bs_nextdtim,
+		    bs.bs_bmissthreshold,
+		    bs.bs_sleepduration,
+		    bs.bs_cfpperiod,
+		    bs.bs_cfpmaxduration,
+		    bs.bs_cfpnext,
+		    bs.bs_timoffset));
+
+		(void) ath9k_hw_set_interrupts(ah, 0);
+		ath9k_hw_set_sta_beacon_timers(ah, &bs);
+		sc->sc_imask |= ATH9K_INT_BMISS;
+		(void) ath9k_hw_set_interrupts(ah, sc->sc_imask);
+	} else {
+		uint64_t tsf;
+		uint32_t tsftu;
+		(void) ath9k_hw_set_interrupts(ah, 0);
+		if (nexttbtt == intval)
+			intval |= ATH9K_BEACON_RESET_TSF;
+		if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
+			/*
+			 * Pull nexttbtt forward to reflect the current
+			 * TSF
+			 */
+#define	FUDGE	2
+			if (!(intval & ATH9K_BEACON_RESET_TSF)) {
+				tsf = ath9k_hw_gettsf64(ah);
+				tsftu = TSF_TO_TU((uint32_t)(tsf>>32),
+				    (uint32_t)tsf) + FUDGE;
+				do {
+					nexttbtt += intval;
+				} while (nexttbtt < tsftu);
+			}
+#undef FUDGE
+			ARN_DBG((ARN_DBG_BEACON, "arn: arn_beacon_config(): "
+			    "IBSS nexttbtt %u intval %u (%u)\n",
+			    nexttbtt, intval & ~ATH9K_BEACON_RESET_TSF,
+			    conf.beacon_interval));
+
+			/*
+			 * In IBSS mode enable the beacon timers but only
+			 * enable SWBA interrupts if we need to manually
+			 * prepare beacon frames.  Otherwise we use a
+			 * self-linked tx descriptor and let the hardware
+			 * deal with things.
+			 */
+			intval |= ATH9K_BEACON_ENA;
+			if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
+				sc->sc_imask |= ATH9K_INT_SWBA;
+			(void) arn_beaconq_config(sc);
+		} else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
+			/*
+			 * In AP mode we enable the beacon timers and
+			 * SWBA interrupts to prepare beacon frames.
+			 */
+			intval |= ATH9K_BEACON_ENA;
+			sc->sc_imask |= ATH9K_INT_SWBA;   /* beacon prepare */
+			(void) arn_beaconq_config(sc);
+		}
+		ath9k_hw_beaconinit(ah, nexttbtt, intval);
+		sc->sc_bmisscount = 0;
+		(void) ath9k_hw_set_interrupts(ah, sc->sc_imask);
+		/*
+		 * When using a self-linked beacon descriptor in
+		 * ibss mode load it once here.
+		 */
+		if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS &&
+		    (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
+			arn_beacon_start_adhoc(sc);
+	}
+	sc->sc_bsync = 0;
+}
+
+void
+ath_beacon_sync(struct arn_softc *sc)
+{
+	/*
+	 * Resync beacon timers using the tsf of the
+	 * beacon frame we just received.
+	 */
+	arn_beacon_config(sc);
+	sc->sc_flags |= SC_OP_BEACONS;
+}
+
+void
+arn_bmiss_proc(void *arg)
+{
+	struct arn_softc *sc = (struct arn_softc *)arg;
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	uint64_t tsf, lastrx;
+	uint_t  bmisstimeout;
+
+	if (ic->ic_opmode != IEEE80211_M_STA ||
+	    ic->ic_state != IEEE80211_S_RUN) {
+		return;
+	}
+
+	ARN_LOCK(sc);
+	lastrx = sc->sc_lastrx;
+	tsf = ath9k_hw_gettsf64(sc->sc_ah);
+	bmisstimeout = ic->ic_bmissthreshold * ic->ic_bss->in_intval * 1024;
+
+	ARN_DBG((ARN_DBG_BEACON, "arn_bmiss_proc():"
+	    " tsf %llu, lastrx %llu (%lld), bmiss %u\n",
+	    (unsigned long long)tsf, (unsigned long long)sc->sc_lastrx,
+	    (long long)(tsf - lastrx), bmisstimeout));
+	ARN_UNLOCK(sc);
+
+	/* temp workaround */
+	if (tsf - lastrx > bmisstimeout)
+		ieee80211_beacon_miss(ic);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_calib.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,1069 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "arn_core.h"
+#include "arn_hw.h"
+#include "arn_reg.h"
+#include "arn_phy.h"
+
+static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
+
+/* We can tune this as we go by monitoring really low values */
+#define	ATH9K_NF_TOO_LOW	-60
+
+/*
+ * AR5416 may return very high value (like -31 dBm), in those cases the nf
+ * is incorrect and we should use the static NF value. Later we can try to
+ * find out why they are reporting these values
+ */
+
+/* ARGSUSED */
+static boolean_t
+ath9k_hw_nf_in_range(struct ath_hal *ah, signed short nf)
+{
+	if (nf > ATH9K_NF_TOO_LOW) {
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: noise floor value detected (%d) is "
+		    "lower than what we think is a "
+		    "reasonable value (%d)\n",
+		    __func__, nf, ATH9K_NF_TOO_LOW));
+
+		return (B_FALSE);
+	}
+	return (B_TRUE);
+}
+
+static int16_t
+ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
+{
+	int16_t nfval;
+	int16_t sort[ATH9K_NF_CAL_HIST_MAX];
+	int i, j;
+
+	for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
+		sort[i] = nfCalBuffer[i];
+
+	for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
+		for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
+			if (sort[j] > sort[j - 1]) {
+				nfval = sort[j];
+				sort[j] = sort[j - 1];
+				sort[j - 1] = nfval;
+			}
+		}
+	}
+	nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
+
+	return (nfval);
+}
+
+static void
+ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
+    int16_t *nfarray)
+{
+	int i;
+
+	for (i = 0; i < NUM_NF_READINGS; i++) {
+		h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
+
+		if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
+			h[i].currIndex = 0;
+
+		if (h[i].invalidNFcount > 0) {
+			if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
+			    nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
+				h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
+			} else {
+				h[i].invalidNFcount--;
+				h[i].privNF = nfarray[i];
+			}
+		} else {
+			h[i].privNF =
+			    ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
+		}
+	}
+}
+
+static void
+ath9k_hw_do_getnf(struct ath_hal *ah,
+    int16_t nfarray[NUM_NF_READINGS])
+{
+	int16_t nf;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
+	else
+		nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
+
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ARN_DBG((ARN_DBG_CALIBRATE,
+	    "NF calibrated [ctl] [chain 0] is %d\n", nf));
+	nfarray[0] = nf;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+		    AR9280_PHY_CH1_MINCCA_PWR);
+	else
+		nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+		    AR_PHY_CH1_MINCCA_PWR);
+
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ARN_DBG((ARN_DBG_CALIBRATE,
+	    "NF calibrated [ctl] [chain 1] is %d\n", nf));
+	nfarray[1] = nf;
+
+	if (!AR_SREV_9280(ah)) {
+		nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
+		    AR_PHY_CH2_MINCCA_PWR);
+		if (nf & 0x100)
+			nf = 0 - ((nf ^ 0x1ff) + 1);
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "NF calibrated [ctl] [chain 2] is %d\n", nf));
+		nfarray[2] = nf;
+	}
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
+		    AR9280_PHY_EXT_MINCCA_PWR);
+	else
+		nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
+		    AR_PHY_EXT_MINCCA_PWR);
+
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ARN_DBG((ARN_DBG_CALIBRATE,
+	    "NF calibrated [ext] [chain 0] is %d\n", nf));
+	nfarray[3] = nf;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+		    AR9280_PHY_CH1_EXT_MINCCA_PWR);
+	else
+		nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+		    AR_PHY_CH1_EXT_MINCCA_PWR);
+
+	if (nf & 0x100)
+		nf = 0 - ((nf ^ 0x1ff) + 1);
+	ARN_DBG((ARN_DBG_CALIBRATE,
+	    "NF calibrated [ext] [chain 1] is %d\n", nf));
+	nfarray[4] = nf;
+
+	if (!AR_SREV_9280(ah)) {
+		nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
+		    AR_PHY_CH2_EXT_MINCCA_PWR);
+		if (nf & 0x100)
+			nf = 0 - ((nf ^ 0x1ff) + 1);
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "NF calibrated [ext] [chain 2] is %d\n", nf));
+		nfarray[5] = nf;
+	}
+}
+
+static boolean_t
+getNoiseFloorThresh(struct ath_hal *ah,
+    const struct ath9k_channel *chan,
+    int16_t *nft)
+{
+	switch (chan->chanmode) {
+	case CHANNEL_A:
+	case CHANNEL_A_HT20:
+	case CHANNEL_A_HT40PLUS:
+	case CHANNEL_A_HT40MINUS:
+		*nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
+		break;
+	case CHANNEL_B:
+	case CHANNEL_G:
+	case CHANNEL_G_HT20:
+	case CHANNEL_G_HT40PLUS:
+	case CHANNEL_G_HT40MINUS:
+		*nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
+		break;
+	default:
+		ARN_DBG((ARN_DBG_CHANNEL,
+		    "%s: invalid channel flags 0x%x\n", __func__,
+		    chan->channelFlags));
+		return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+static void
+ath9k_hw_setup_calibration(struct ath_hal *ah,
+    struct hal_cal_list *currCal)
+{
+	REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
+	    AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
+	    currCal->calData->calCountMax);
+
+	switch (currCal->calData->calType) {
+	case IQ_MISMATCH_CAL:
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: starting IQ Mismatch Calibration\n",
+		    __func__));
+		break;
+	case ADC_GAIN_CAL:
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: starting ADC Gain Calibration\n", __func__));
+		break;
+	case ADC_DC_CAL:
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: starting ADC DC Calibration\n", __func__));
+		break;
+	case ADC_DC_INIT_CAL:
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: starting Init ADC DC Calibration\n",
+		    __func__));
+		break;
+	}
+
+	REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+	    AR_PHY_TIMING_CTRL4_DO_CAL);
+}
+
+static void
+ath9k_hw_reset_calibration(struct ath_hal *ah,
+    struct hal_cal_list *currCal)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int i;
+
+	ath9k_hw_setup_calibration(ah, currCal);
+
+	currCal->calState = CAL_RUNNING;
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		ahp->ah_Meas0.sign[i] = 0;
+		ahp->ah_Meas1.sign[i] = 0;
+		ahp->ah_Meas2.sign[i] = 0;
+		ahp->ah_Meas3.sign[i] = 0;
+	}
+
+	ahp->ah_CalSamples = 0;
+}
+
+static void
+ath9k_hw_per_calibration(struct ath_hal *ah,
+    struct ath9k_channel *ichan,
+    uint8_t rxchainmask,
+    struct hal_cal_list *currCal,
+    boolean_t *isCalDone)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	*isCalDone = B_FALSE;
+
+	if (currCal->calState == CAL_RUNNING) {
+		if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+		    AR_PHY_TIMING_CTRL4_DO_CAL)) {
+
+			currCal->calData->calCollect(ah);
+			ahp->ah_CalSamples++;
+
+			if (ahp->ah_CalSamples >=
+			    currCal->calData->calNumSamples) {
+				int i, numChains = 0;
+				for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+					if (rxchainmask & (1 << i))
+						numChains++;
+				}
+
+				currCal->calData->calPostProc(ah, numChains);
+				ichan->CalValid |= currCal->calData->calType;
+				currCal->calState = CAL_DONE;
+				*isCalDone = B_TRUE;
+			} else {
+				ath9k_hw_setup_calibration(ah, currCal);
+			}
+		}
+	} else if (!(ichan->CalValid & currCal->calData->calType)) {
+		ath9k_hw_reset_calibration(ah, currCal);
+	}
+}
+
+static boolean_t
+ath9k_hw_iscal_supported(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    enum hal_cal_types calType)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	boolean_t retval = B_FALSE;
+
+	switch (calType & ahp->ah_suppCals) {
+	case IQ_MISMATCH_CAL:
+		if (!IS_CHAN_B(chan))
+			retval = B_TRUE;
+		break;
+	case ADC_GAIN_CAL:
+	case ADC_DC_CAL:
+		if (!IS_CHAN_B(chan) &&
+		    !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
+			retval = B_TRUE;
+		break;
+	}
+
+	return (retval);
+}
+
+static void
+ath9k_hw_iqcal_collect(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int i;
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		ahp->ah_totalPowerMeasI[i] +=
+		    REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+		ahp->ah_totalPowerMeasQ[i] +=
+		    REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+		ahp->ah_totalIqCorrMeas[i] +=
+		    (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+		    ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
+		    ahp->ah_totalPowerMeasQ[i],
+		    ahp->ah_totalIqCorrMeas[i]));
+	}
+}
+
+static void
+ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int i;
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		ahp->ah_totalAdcIOddPhase[i] +=
+		    REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+		ahp->ah_totalAdcIEvenPhase[i] +=
+		    REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+		ahp->ah_totalAdcQOddPhase[i] +=
+		    REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+		ahp->ah_totalAdcQEvenPhase[i] +=
+		    REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+		    "oddq=0x%08x; evenq=0x%08x;\n",
+		    ahp->ah_CalSamples, i,
+		    ahp->ah_totalAdcIOddPhase[i],
+		    ahp->ah_totalAdcIEvenPhase[i],
+		    ahp->ah_totalAdcQOddPhase[i],
+		    ahp->ah_totalAdcQEvenPhase[i]));
+	}
+}
+
+static void
+ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int i;
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
+		    (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+		ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
+		    (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+		ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
+		    (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+		ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
+		    (int32_t)REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+		    "oddq=0x%08x; evenq=0x%08x;\n",
+		    ahp->ah_CalSamples, i,
+		    ahp->ah_totalAdcDcOffsetIOddPhase[i],
+		    ahp->ah_totalAdcDcOffsetIEvenPhase[i],
+		    ahp->ah_totalAdcDcOffsetQOddPhase[i],
+		    ahp->ah_totalAdcDcOffsetQEvenPhase[i]));
+	}
+}
+
+static void
+ath9k_hw_iqcalibrate(struct ath_hal *ah, uint8_t numChains)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t powerMeasQ, powerMeasI, iqCorrMeas;
+	uint32_t qCoffDenom, iCoffDenom;
+	int32_t qCoff, iCoff;
+	int iqCorrNeg, i;
+
+	for (i = 0; i < numChains; i++) {
+		powerMeasI = ahp->ah_totalPowerMeasI[i];
+		powerMeasQ = ahp->ah_totalPowerMeasQ[i];
+		iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Starting IQ Cal and Correction for Chain %d\n",
+		    i));
+
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+		    i, ahp->ah_totalIqCorrMeas[i]));
+
+		iqCorrNeg = 0;
+
+		if (iqCorrMeas > 0x80000000) {
+			iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+			iqCorrNeg = 1;
+		}
+
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ));
+		ARN_DBG((ARN_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+		    iqCorrNeg));
+
+		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
+		qCoffDenom = powerMeasQ / 64;
+
+		if (powerMeasQ != 0) {
+			iCoff = iqCorrMeas / iCoffDenom;
+			qCoff = powerMeasI / qCoffDenom - 64;
+
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "Chn %d iCoff = 0x%08x\n", i, iCoff));
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "Chn %d qCoff = 0x%08x\n", i, qCoff));
+
+			iCoff = iCoff & 0x3f;
+
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "New: Chn %d iCoff = 0x%08x\n", i, iCoff));
+
+			if (iqCorrNeg == 0x0)
+				iCoff = 0x40 - iCoff;
+
+			if (qCoff > 15)
+				qCoff = 15;
+			else if (qCoff <= -16)
+				qCoff = 16;
+
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+			    i, iCoff, qCoff));
+
+			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+			    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
+			    iCoff);
+			REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+			    AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
+			    qCoff);
+
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "IQ Cal and Correction done for Chain %d\n",
+			    i));
+		}
+	}
+
+	REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+	    AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
+}
+
+static void
+ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, uint8_t numChains)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
+	    qEvenMeasOffset;
+	uint32_t qGainMismatch, iGainMismatch, val, i;
+
+	for (i = 0; i < numChains; i++) {
+		iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
+		iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
+		qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
+		qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
+
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Starting ADC Gain Cal for Chain %d\n", i));
+
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+		    iOddMeasOffset));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+		    iEvenMeasOffset));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+		    qOddMeasOffset));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_even_q = 0x%08x\n", i,
+		    qEvenMeasOffset));
+
+		if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
+			iGainMismatch =
+			    ((iEvenMeasOffset * 32) /
+			    iOddMeasOffset) & 0x3f;
+			qGainMismatch =
+			    ((qOddMeasOffset * 32) /
+			    qEvenMeasOffset) & 0x3f;
+
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "Chn %d gain_mismatch_i = 0x%08x\n", i,
+			    iGainMismatch));
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "Chn %d gain_mismatch_q = 0x%08x\n", i,
+			    qGainMismatch));
+
+			val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+			val &= 0xfffff000;
+			val |= (qGainMismatch) | (iGainMismatch << 6);
+			REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "ADC Gain Cal done for Chain %d\n", i));
+		}
+	}
+
+	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+	    REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+	    AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
+}
+
+static void
+ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, uint8_t numChains)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t iOddMeasOffset, iEvenMeasOffset, val, i;
+	int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
+	const struct hal_percal_data *calData =
+	    ahp->ah_cal_list_curr->calData;
+	uint32_t numSamples =
+	    (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
+
+	for (i = 0; i < numChains; i++) {
+		iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
+		iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
+		qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
+		qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
+
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Starting ADC DC Offset Cal for Chain %d\n", i));
+
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_odd_i = %d\n", i,
+		    iOddMeasOffset));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_even_i = %d\n", i,
+		    iEvenMeasOffset));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_odd_q = %d\n", i,
+		    qOddMeasOffset));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d pwr_meas_even_q = %d\n", i,
+		    qEvenMeasOffset));
+
+		iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
+		    numSamples) & 0x1ff;
+		qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
+		    numSamples) & 0x1ff;
+
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+		    iDcMismatch));
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
+		    qDcMismatch));
+
+		val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+		val &= 0xc0000fff;
+		val |= (qDcMismatch << 12) | (iDcMismatch << 21);
+		REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "ADC DC Offset Cal done for Chain %d\n", i));
+	}
+
+	REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+	    REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+	    AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
+}
+
+void
+ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
+    boolean_t *isCalDone)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_channel *ichan =
+	    ath9k_regd_check_channel(ah, chan);
+	struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
+
+	*isCalDone = B_TRUE;
+
+	if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
+		return;
+
+	if (currCal == NULL)
+		return;
+
+	if (ichan == NULL) {
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: invalid channel %u/0x%x; no mapping\n",
+		    __func__, chan->channel, chan->channelFlags));
+		return;
+	}
+
+
+	if (currCal->calState != CAL_DONE) {
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: Calibration state incorrect, %d\n",
+		    __func__, currCal->calState));
+		return;
+	}
+
+
+	if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
+		return;
+	ARN_DBG((ARN_DBG_CALIBRATE,
+	    "%s: Resetting Cal %d state for channel %u/0x%x\n",
+	    __func__, currCal->calData->calType, chan->channel,
+	    chan->channelFlags));
+
+	ichan->CalValid &= ~currCal->calData->calType;
+	currCal->calState = CAL_WAITING;
+
+	*isCalDone = B_FALSE;
+}
+
+void
+ath9k_hw_start_nfcal(struct ath_hal *ah)
+{
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+	    AR_PHY_AGC_CONTROL_ENABLE_NF);
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+	    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	struct ath9k_nfcal_hist *h;
+	int i, j;
+	int32_t val;
+	const uint32_t ar5416_cca_regs[6] = {
+		AR_PHY_CCA,
+		AR_PHY_CH1_CCA,
+		AR_PHY_CH2_CCA,
+		AR_PHY_EXT_CCA,
+		AR_PHY_CH1_EXT_CCA,
+		AR_PHY_CH2_EXT_CCA
+	};
+	uint8_t chainmask;
+
+	if (AR_SREV_9280(ah))
+		chainmask = 0x1B;
+	else
+		chainmask = 0x3F;
+
+#ifdef ARN_NF_PER_CHAN
+	h = chan->nfCalHist;
+#else
+	h = ah->nfCalHist;
+#endif
+
+	for (i = 0; i < NUM_NF_READINGS; i++) {
+		if (chainmask & (1 << i)) {
+			val = REG_READ(ah, ar5416_cca_regs[i]);
+			val &= 0xFFFFFE00;
+			val |= (((uint32_t)(h[i].privNF) << 1) & 0x1ff);
+			REG_WRITE(ah, ar5416_cca_regs[i], val);
+		}
+	}
+
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+	    AR_PHY_AGC_CONTROL_ENABLE_NF);
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+	    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+
+	for (j = 0; j < 1000; j++) {
+		if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
+		    AR_PHY_AGC_CONTROL_NF) == 0)
+			break;
+		drv_usecwait(10);
+	}
+
+	for (i = 0; i < NUM_NF_READINGS; i++) {
+		if (chainmask & (1 << i)) {
+			val = REG_READ(ah, ar5416_cca_regs[i]);
+			val &= 0xFFFFFE00;
+			val |= (((uint32_t)(-50) << 1) & 0x1ff);
+			REG_WRITE(ah, ar5416_cca_regs[i], val);
+		}
+	}
+}
+
+int16_t
+ath9k_hw_getnf(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	int16_t nf, nfThresh;
+	int16_t nfarray[NUM_NF_READINGS] = { 0 };
+	struct ath9k_nfcal_hist *h;
+	/* LINTED E_FUNC_SET_NOT_USED */
+	uint8_t chainmask;
+
+	if (AR_SREV_9280(ah))
+		chainmask = 0x1B;
+	else
+		chainmask = 0x3F;
+
+	chan->channelFlags &= (~CHANNEL_CW_INT);
+	if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
+		ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
+		    "%s: NF did not complete in calibration window\n",
+		    __func__));
+		nf = 0;
+		chan->rawNoiseFloor = nf;
+		return (chan->rawNoiseFloor);
+	} else {
+		ath9k_hw_do_getnf(ah, nfarray);
+		nf = nfarray[0];
+		if (getNoiseFloorThresh(ah, chan, &nfThresh) &&
+		    nf > nfThresh) {
+			ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
+			    "%s: noise floor failed detected; "
+			    "detected %d, threshold %d\n", __func__,
+			    nf, nfThresh));
+			chan->channelFlags |= CHANNEL_CW_INT;
+		}
+	}
+
+#ifdef ARN_NF_PER_CHAN
+	h = chan->nfCalHist;
+#else
+	h = ah->nfCalHist;
+#endif
+
+	ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
+	chan->rawNoiseFloor = h[0].privNF;
+
+	return (chan->rawNoiseFloor);
+}
+
+void
+ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
+{
+	int i, j;
+
+	for (i = 0; i < NUM_NF_READINGS; i++) {
+		ah->nfCalHist[i].currIndex = 0;
+		ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
+		ah->nfCalHist[i].invalidNFcount =
+		    AR_PHY_CCA_FILTERWINDOW_LENGTH;
+		for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
+			ah->nfCalHist[i].nfCalBuffer[j] =
+			    AR_PHY_CCA_MAX_GOOD_VALUE;
+		}
+	}
+}
+
+signed short
+ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	struct ath9k_channel *ichan;
+	signed short nf;
+
+	ichan = ath9k_regd_check_channel(ah, chan);
+	if (ichan == NULL) {
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: invalid channel %u/0x%x; no mapping\n",
+		    __func__, chan->channel, chan->channelFlags));
+		return (ATH_DEFAULT_NOISE_FLOOR);
+	}
+	if (ichan->rawNoiseFloor == 0) {
+		enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
+		nf = NOISE_FLOOR[mode];
+	} else
+		nf = ichan->rawNoiseFloor;
+
+	if (!ath9k_hw_nf_in_range(ah, nf))
+		nf = ATH_DEFAULT_NOISE_FLOOR;
+
+	return (nf);
+}
+
+boolean_t
+ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
+    uint8_t rxchainmask, boolean_t longcal,
+    boolean_t *isCalDone)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
+	struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+
+	*isCalDone = B_TRUE;
+
+	if (ichan == NULL) {
+		ARN_DBG((ARN_DBG_CHANNEL,
+		    "%s: invalid channel %u/0x%x; no mapping\n",
+		    __func__, chan->channel, chan->channelFlags));
+		return (B_FALSE);
+	}
+
+	if (currCal &&
+	    (currCal->calState == CAL_RUNNING ||
+	    currCal->calState == CAL_WAITING)) {
+		ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
+		    isCalDone);
+		if (*isCalDone) {
+			ahp->ah_cal_list_curr = currCal = currCal->calNext;
+
+			if (currCal->calState == CAL_WAITING) {
+				*isCalDone = B_FALSE;
+				ath9k_hw_reset_calibration(ah, currCal);
+			}
+		}
+	}
+
+	if (longcal) {
+		(void) ath9k_hw_getnf(ah, ichan);
+		ath9k_hw_loadnf(ah, ah->ah_curchan);
+		ath9k_hw_start_nfcal(ah);
+
+		if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
+			chan->channelFlags |= CHANNEL_CW_INT;
+			ichan->channelFlags &= ~CHANNEL_CW_INT;
+		}
+	}
+
+	return (B_TRUE);
+}
+
+/* AR9285 */
+static inline void
+ath9k_hw_9285_pa_cal(struct ath_hal *ah)
+{
+
+	uint32_t regVal;
+	int i, offset, offs_6_1, offs_0;
+	uint32_t ccomp_org, reg_field;
+	uint32_t regList[][2] = {
+	    { 0x786c, 0 },
+	    { 0x7854, 0 },
+	    { 0x7820, 0 },
+	    { 0x7824, 0 },
+	    { 0x7868, 0 },
+	    { 0x783c, 0 },
+	    { 0x7838, 0 },
+	};
+
+	if (AR_SREV_9285_11(ah)) {
+		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+		drv_usecwait(10);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(regList); i++)
+		regList[i][1] = REG_READ(ah, regList[i][0]);
+
+	regVal = REG_READ(ah, 0x7834);
+	regVal &= (~(0x1));
+	REG_WRITE(ah, 0x7834, regVal);
+	regVal = REG_READ(ah, 0x9808);
+	regVal |= (0x1 << 27);
+	REG_WRITE(ah, 0x9808, regVal);
+
+	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+	ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7);
+
+	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
+	drv_usecwait(30);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
+
+	for (i = 6; i > 0; i--) {
+		regVal = REG_READ(ah, 0x7834);
+		regVal |= (1 << (19 + i));
+		REG_WRITE(ah, 0x7834, regVal);
+		drv_usecwait(1);
+		regVal = REG_READ(ah, 0x7834);
+		regVal &= (~(0x1 << (19 + i)));
+		reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
+		regVal |= (reg_field << (19 + i));
+		REG_WRITE(ah, 0x7834, regVal);
+	}
+
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
+	drv_usecwait(1);
+	reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
+	offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
+	offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
+
+	offset = (offs_6_1<<1) | offs_0;
+	offset = offset - 0;
+	offs_6_1 = offset>>1;
+	offs_0 = offset & 1;
+
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
+
+	regVal = REG_READ(ah, 0x7834);
+	regVal |= 0x1;
+	REG_WRITE(ah, 0x7834, regVal);
+	regVal = REG_READ(ah, 0x9808);
+	regVal &= (~(0x1 << 27));
+	REG_WRITE(ah, 0x9808, regVal);
+
+	for (i = 0; i < ARRAY_SIZE(regList); i++)
+		REG_WRITE(ah, regList[i][0], regList[i][1]);
+
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
+
+	if (AR_SREV_9285_11(ah))
+		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+}
+
+boolean_t
+ath9k_hw_init_cal(struct ath_hal *ah,
+    struct ath9k_channel *chan)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+
+	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+	    REG_READ(ah, AR_PHY_AGC_CONTROL) |
+	    AR_PHY_AGC_CONTROL_CAL);
+
+	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
+		ARN_DBG((ARN_DBG_CALIBRATE,
+		    "%s: offset calibration failed to complete in 1ms; "
+		    "noisy environment?\n", __func__));
+		return (B_FALSE);
+	}
+
+	if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+			ath9k_hw_9285_pa_cal(ah);
+
+	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+	    REG_READ(ah, AR_PHY_AGC_CONTROL) |
+	    AR_PHY_AGC_CONTROL_NF);
+
+	ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
+
+	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
+		if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
+			/* LINTED: E_CONSTANT_CONDITION */
+			INIT_CAL(&ahp->ah_adcGainCalData);
+			/* LINTED: E_CONSTANT_CONDITION */
+			INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "%s: enabling ADC Gain Calibration.\n",
+			    __func__));
+		}
+		if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
+			/* LINTED: E_CONSTANT_CONDITION */
+			INIT_CAL(&ahp->ah_adcDcCalData);
+			/* LINTED: E_CONSTANT_CONDITION */
+			INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "%s: enabling ADC DC Calibration.\n",
+			    __func__));
+		}
+		if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
+			/* LINTED: E_CONSTANT_CONDITION */
+			INIT_CAL(&ahp->ah_iqCalData);
+			/* LINTED: E_CONSTANT_CONDITION */
+			INSERT_CAL(ahp, &ahp->ah_iqCalData);
+			ARN_DBG((ARN_DBG_CALIBRATE,
+			    "%s: enabling IQ Calibration.\n",
+			    __func__));
+		}
+
+		ahp->ah_cal_list_curr = ahp->ah_cal_list;
+
+		if (ahp->ah_cal_list_curr)
+			ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr);
+	}
+
+	ichan->CalValid = 0;
+
+	return (B_TRUE);
+}
+
+const struct hal_percal_data iq_cal_multi_sample = {
+	IQ_MISMATCH_CAL,
+	MAX_CAL_SAMPLES,
+	PER_MIN_LOG_COUNT,
+	ath9k_hw_iqcal_collect,
+	ath9k_hw_iqcalibrate
+};
+const struct hal_percal_data iq_cal_single_sample = {
+	IQ_MISMATCH_CAL,
+	MIN_CAL_SAMPLES,
+	PER_MAX_LOG_COUNT,
+	ath9k_hw_iqcal_collect,
+	ath9k_hw_iqcalibrate
+};
+const struct hal_percal_data adc_gain_cal_multi_sample = {
+	ADC_GAIN_CAL,
+	MAX_CAL_SAMPLES,
+	PER_MIN_LOG_COUNT,
+	ath9k_hw_adc_gaincal_collect,
+	ath9k_hw_adc_gaincal_calibrate
+};
+const struct hal_percal_data adc_gain_cal_single_sample = {
+	ADC_GAIN_CAL,
+	MIN_CAL_SAMPLES,
+	PER_MAX_LOG_COUNT,
+	ath9k_hw_adc_gaincal_collect,
+	ath9k_hw_adc_gaincal_calibrate
+};
+const struct hal_percal_data adc_dc_cal_multi_sample = {
+	ADC_DC_CAL,
+	MAX_CAL_SAMPLES,
+	PER_MIN_LOG_COUNT,
+	ath9k_hw_adc_dccal_collect,
+	ath9k_hw_adc_dccal_calibrate
+};
+const struct hal_percal_data adc_dc_cal_single_sample = {
+	ADC_DC_CAL,
+	MIN_CAL_SAMPLES,
+	PER_MAX_LOG_COUNT,
+	ath9k_hw_adc_dccal_collect,
+	ath9k_hw_adc_dccal_calibrate
+};
+const struct hal_percal_data adc_init_dc_cal = {
+	ADC_DC_INIT_CAL,
+	MIN_CAL_SAMPLES,
+	INIT_LOG_COUNT,
+	ath9k_hw_adc_dccal_collect,
+	ath9k_hw_adc_dccal_calibrate
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_core.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,877 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _ARN_CORE_H
+#define	_ARN_CORE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/note.h>
+#include <sys/list.h>
+#include <sys/net80211.h>
+
+#include "arn_ath9k.h"
+#include "arn_rc.h"
+
+struct ath_node;
+
+/*
+ * Node type of wifi device
+ */
+#ifndef DDI_NT_NET_WIFI
+#define	DDI_NT_NET_WIFI	"ddi_network:wifi"
+#endif
+#define	ARN_NODENAME	"arn"
+
+#define	ARN_LOCK(_sc)		mutex_enter(&(_sc)->sc_genlock)
+#define	ARN_UNLOCK(_sc)	mutex_exit(&(_sc)->sc_genlock)
+#define	ARN_LOCK_ASSERT(_sc)	ASSERT(mutex_owned(&(_sc)->sc_genlock))
+
+#define	ARRAY_SIZE(x)	(sizeof (x) / sizeof (x[0]))
+
+#define	DIV_ROUND_UP(n, d)	(((n) + (d) - 1) / (d))
+
+#define	ARN_MIN(a, b)	((a) < (b) ? (a) : (b))
+#define	ARN_MAX(a, b)	((a) > (b) ? (a) : (b))
+
+#define	abs(x)		((x) >= 0 ? (x) : -(x))
+
+enum ath9k_key_len {
+	ATH9K_LEN_WEP40 = 5,
+	ATH9K_LEN_WEP104 = 13,
+};
+
+/*
+ * Sync a DMA area described by a dma_area_t
+ */
+#define	ARN_DMA_SYNC(area, flag)    ((void) ddi_dma_sync((area).dma_hdl,    \
+				(area).offset, (area).alength, (flag)))
+
+#define	list_empty(a) ((a)->list_head.list_next == &(a)->list_head)
+
+#define	ARN_LE_READ_16(p)						\
+	((uint16_t)							\
+	((((uint8_t *)(p))[0]) | (((uint8_t *)(p))[1] <<  8)))
+
+#define	ARN_LE_READ_32(p)						\
+	((uint32_t)							\
+	((((uint8_t *)(p))[0]) | (((uint8_t *)(p))[1] <<  8) |		\
+	(((uint8_t *)(p))[2] << 16) | (((uint8_t *)(p))[3] << 24)))
+
+#define	swab16(value)  \
+	((((value) & 0xff) << 8) | ((value) >> 8))
+
+#define	swab32(value)	\
+	(((uint32_t)swab16((uint16_t)((value) & 0xffff)) << 16) | \
+	(uint32_t)swab16((uint16_t)((value) >> 16)))
+
+#define	swab64(value)	\
+	(((uint64_t)swab32((uint32_t)((value) & 0xffffffff)) \
+	    << 32) | \
+	(uint64_t)swab32((uint32_t)((value) >> 32)))
+
+/* Bit map related macros. */
+#define	set_bit(i, a)		((a)[(i)/NBBY] |= (1 << ((i)%NBBY)))
+#define	clr_bit(i, a)		((a)[(i)/NBBY] &= ~(1 << ((i)%NBBY)))
+#define	is_set(i, a)		((a)[(i)/NBBY] & (1 << ((i)%NBBY)))
+#define	is_clr(i, a)		(!((a)[(i)/NBBY] & (1 << ((i)%NBBY))))
+
+/* Macro to expand scalars to 64-bit objects */
+
+#define	ito64(x) (sizeof (x) == 8) ?			\
+	(((unsigned long long int)(x)) & (0xff)) :	\
+	(sizeof (x) == 16) ?				\
+	(((unsigned long long int)(x)) & 0xffff) :	\
+	((sizeof (x) == 32) ?				\
+	(((unsigned long long int)(x)) & 0xffffffff) :	\
+	(unsigned long long int)(x))
+
+/* increment with wrap-around */
+#define	INCR(_l, _sz)	do {			\
+		(_l)++;				\
+		(_l) &= ((_sz) - 1);		\
+	} while (0)
+
+/* decrement with wrap-around */
+#define	DECR(_l, _sz)  do {			\
+		(_l)--;				\
+		(_l) &= ((_sz) - 1);		\
+	} while (0)
+
+#define	A_MAX(a, b)	((a) > (b) ? (a) : (b))
+
+#define	TSF_TO_TU(_h, _l)	\
+	((((uint32_t)(_h)) << 22) | (((uint32_t)(_l)) >> 10))
+
+#define	ARN_TXQ_SETUP(sc, i)	((sc)->sc_txqsetup & (1<<i))
+
+// static const uint8_t ath_bcast_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+/* Debugging */
+enum ARN_DEBUG {
+	ARN_DBG_HW		= 0x00000001,
+	ARN_DBG_REG_IO		= 0x00000002,
+	ARN_DBG_QUEUE		= 0x00000004,
+	ARN_DBG_EEPROM		= 0x00000008,
+	ARN_DBG_XMIT		= 0x00000010,
+	ARN_DBG_RECV		= 0x00000020,
+	ARN_DBG_CALIBRATE	= 0x00000040,
+	ARN_DBG_CHANNEL		= 0x00000080,
+	ARN_DBG_INTERRUPT	= 0x00000100,
+	ARN_DBG_REGULATORY	= 0x00000200,
+	ARN_DBG_ANI		= 0x00000400,
+	ARN_DBG_POWER_MGMT	= 0x00000800,
+	ARN_DBG_KEYCACHE	= 0x00001000,
+	ARN_DBG_BEACON		= 0x00002000,
+	ARN_DBG_RATE		= 0x00004000,
+	ARN_DBG_INIT		= 0x00008000,
+	ARN_DBG_ATTACH		= 0x00010000,
+	ARN_DBG_DEATCH		= 0x00020000,
+	ARN_DBG_AGGR		= 0x00040000,
+	ARN_DBG_RESET		= 0x00080000,
+	ARN_DBG_FATAL		= 0x00100000,
+	ARN_DBG_ANY		= 0x00200000,
+	ARN_DBG_ALL		= 0x00FFFFFF,
+};
+
+/* Debug and log functions */
+void arn_dbg(uint32_t dbg_flags, const int8_t *fmt, ...); /* debug function */
+void arn_log(const int8_t *fmt, ...); /* event log function */
+void arn_problem(const int8_t *fmt, ...); /* run-time problem function */
+
+#ifdef DEBUG
+#define	ARN_DDB(command)	do {				\
+					{ command; }		\
+					_NOTE(CONSTANTCONDITION)\
+				} while (0)
+#else
+#define	ARN_DDB(command)
+#endif /* DEBUG */
+
+#define	ARN_DBG(args)		ARN_DDB(arn_dbg args)
+
+struct ath_stats {
+	uint32_t	ast_hardware;	/* fatal hardware error interrupts */
+	uint32_t	ast_rxorn;	/* rx overrun interrupts */
+	uint32_t	ast_rxeol;	/* rx eol interrupts */
+	uint32_t	ast_txurn;	/* tx underrun interrupts */
+	uint32_t	ast_tx_mgmt;	/* management frames transmitted */
+	uint32_t	ast_tx_discard;	/* frames discarded prior to assoc */
+	uint32_t	ast_tx_invalid; /* frames discarded 'cuz device gone */
+	uint32_t	ast_tx_qstop;	/* tx queue stopped 'cuz full */
+	uint32_t	ast_tx_nobuf;	/* tx failed 'cuz no tx buffer (data) */
+	uint32_t	ast_tx_nobufmgt; /* tx failed 'cuz no tx buffer(mgmt) */
+	uint32_t	ast_tx_xretries; /* tx failed 'cuz too many retries */
+	uint32_t	ast_tx_fifoerr;	/* tx failed 'cuz FIFO underrun */
+	uint32_t	ast_tx_filtered; /* tx failed 'cuz xmit filtered */
+	uint32_t	ast_tx_shortretry; /* tx on-chip retries (short) */
+	uint32_t	ast_tx_longretry; /* tx on-chip retries (long) */
+	uint32_t	ast_tx_noack;	/* tx frames with no ack marked */
+	uint32_t	ast_tx_rts;	/* tx frames with rts enabled */
+	uint32_t	ast_tx_shortpre; /* tx frames with short preamble */
+	uint32_t	ast_tx_altrate;	/* tx frames with alternate rate */
+	uint32_t	ast_tx_protect;	/* tx frames with protection */
+	int16_t		ast_tx_rssi;	/* tx rssi of last ack */
+	int16_t		ast_tx_rssidelta; /* tx rssi delta */
+	uint32_t	ast_rx_crcerr;	/* rx failed 'cuz of bad CRC */
+	uint32_t	ast_rx_fifoerr;	/* rx failed 'cuz of FIFO overrun */
+	uint32_t	ast_rx_badcrypt; /* rx failed 'cuz decryption */
+	uint32_t	ast_rx_phyerr;	/* rx PHY error summary count */
+	uint32_t	ast_rx_phy[32];	/* rx PHY error per-code counts */
+	uint32_t	ast_rx_tooshort; /* rx discarded 'cuz frame too short */
+	uint32_t	ast_per_cal;	/* periodic calibration calls */
+	uint32_t	ast_per_calfail; /* periodic calibration failed */
+	uint32_t	ast_per_rfgain;	/* periodic calibration rfgain reset */
+	uint32_t	ast_rate_calls;	/* rate control checks */
+	uint32_t	ast_rate_raise;	/* rate control raised xmit rate */
+	uint32_t	ast_rate_drop;	/* rate control dropped xmit rate */
+};
+
+struct dma_area {
+	ddi_acc_handle_t	acc_hdl;	/* handle for memory */
+	caddr_t			mem_va;		/* CPU VA of memory */
+	uint32_t		nslots;		/* number of slots */
+	uint32_t		size;		/* size per slot */
+	size_t			alength;	/* allocated size */
+						/* >= product of above */
+
+	ddi_dma_handle_t	dma_hdl;	/* DMA handle */
+	offset_t		offset;		/* relative to handle */
+	ddi_dma_cookie_t	cookie;		/* associated cookie */
+	uint32_t		ncookies;	/* must be 1 */
+	uint32_t		token;		/* arbitrary identifier */
+};
+typedef struct dma_area dma_area_t;
+
+/* Load-time Configuration */
+
+/*
+ * Per-instance load-time (note: NOT run-time)
+ * configurations for Atheros Device
+ */
+struct ath_config {
+	uint32_t ath_aggr_prot;
+	uint16_t txpowlimit;
+	uint16_t txpowlimit_override;
+	uint8_t cabqReadytime; /* Cabq Readytime % */
+	uint8_t swBeaconProcess; /* Process received beacons in SW (vs HW) */
+};
+
+/* Descriptor Management */
+
+#define	ATH_TXBUF_RESET(_bf) do {		\
+		(_bf)->bf_status = 0;		\
+		(_bf)->bf_lastbf = NULL;	\
+		(_bf)->bf_lastfrm = NULL;	\
+		(_bf)->bf_next = NULL;		\
+		memset(&((_bf)->bf_state), 0,	\
+		sizeof (struct ath_buf_state));	\
+	} while (0)
+
+enum buffer_type {
+	BUF_DATA		= BIT(0),
+	BUF_AGGR		= BIT(1),
+	BUF_AMPDU		= BIT(2),
+	BUF_HT			= BIT(3),
+	BUF_RETRY		= BIT(4),
+	BUF_XRETRY		= BIT(5),
+	BUF_SHORT_PREAMBLE	= BIT(6),
+	BUF_BAR			= BIT(7),
+	BUF_PSPOLL		= BIT(8),
+	BUF_AGGR_BURST		= BIT(9),
+	BUF_CALC_AIRTIME	= BIT(10),
+};
+
+struct ath_buf_state {
+	int bfs_nframes;	/* # frames in aggregate */
+	uint16_t bfs_al;	/* length of aggregate */
+	uint16_t bfs_frmlen;	/* length of frame */
+	int bfs_seqno;		/* sequence number */
+	int bfs_tidno;		/* tid of this frame */
+	int bfs_retries;	/* current retries */
+	uint32_t bf_type;	/* BUF_* (enum buffer_type) */
+	/* key type used to encrypt this frame */
+	uint32_t bfs_keyix;
+	enum ath9k_key_type bfs_keytype;
+};
+
+#define	bf_nframes		bf_state.bfs_nframes
+#define	bf_al			bf_state.bfs_al
+#define	bf_frmlen		bf_state.bfs_frmlen
+#define	bf_retries		bf_state.bfs_retries
+#define	bf_seqno		bf_state.bfs_seqno
+#define	bf_tidno		bf_state.bfs_tidno
+#define	bf_rcs			bf_state.bfs_rcs
+#define	bf_keyix		bf_state.bfs_keyix
+#define	bf_keytype		bf_state.bfs_keytype
+#define	bf_isdata(bf)		(bf->bf_state.bf_type & BUF_DATA)
+#define	bf_isaggr(bf)		(bf->bf_state.bf_type & BUF_AGGR)
+#define	bf_isampdu(bf)		(bf->bf_state.bf_type & BUF_AMPDU)
+#define	bf_isht(bf)		(bf->bf_state.bf_type & BUF_HT)
+#define	bf_isretried(bf)	(bf->bf_state.bf_type & BUF_RETRY)
+#define	bf_isxretried(bf)	(bf->bf_state.bf_type & BUF_XRETRY)
+#define	bf_isshpreamble(bf)	(bf->bf_state.bf_type & BUF_SHORT_PREAMBLE)
+#define	bf_isbar(bf)		(bf->bf_state.bf_type & BUF_BAR)
+#define	bf_ispspoll(bf)		(bf->bf_state.bf_type & BUF_PSPOLL)
+#define	bf_isaggrburst(bf)	(bf->bf_state.bf_type & BUF_AGGR_BURST)
+
+/*
+ * Abstraction of a contiguous buffer to transmit/receive.
+ * There is only a single hw descriptor encapsulated here.
+ */
+struct ath_buf {
+	/* last buf of this unit (a frame or an aggregate) */
+	struct ath_buf *bf_lastbf;
+	struct ath_buf *bf_lastfrm;	/* last buf of this frame */
+	struct ath_buf *bf_next;	/* next subframe in the aggregate */
+	mblk_t *bf_m;
+	struct ath_desc	*bf_desc;	/* virtual addr of desc */
+	uint32_t bf_daddr;		/* physical addr of desc */
+	dma_area_t bf_dma;		/* dma area for buf */
+	struct ieee80211_node *bf_in;	/* pointer to the node */
+	uint32_t bf_status;
+	uint16_t bf_flags;		/* tx descriptor flags */
+	struct ath_buf_state bf_state;	/* buffer state */
+
+	/* we're in list of sc->sc_txbuf_list or asc->asc_rxbuf_list */
+	list_node_t bf_node;
+};
+
+/*
+ * reset the rx buffer.
+ * any new fields added to the athbuf and require
+ * reset need to be added to this macro.
+ * currently bf_status is the only one requires that
+ * requires reset.
+ */
+#define	ATH_RXBUF_RESET(_bf)	((_bf)->bf_status = 0)
+
+/* hw processing complete, desc processed by hal */
+#define	ATH_BUFSTATUS_DONE	0x00000001
+/* hw processing complete, desc hold for hw */
+#define	ATH_BUFSTATUS_STALE	0x00000002
+/* Rx-only: OS is done with this packet and it's ok to queued it to hw */
+#define	ATH_BUFSTATUS_FREE	0x00000004
+
+/* RX / TX */
+
+#define	ATH_MAX_ANTENNA	3
+#define	ATH_RXBUF	512
+#define	WME_NUM_TID	16
+
+void arn_rx_buf_link(struct arn_softc *sc, struct ath_buf *bf);
+int arn_startrecv(struct arn_softc *sc);
+boolean_t arn_stoprecv(struct arn_softc *sc);
+void arn_flushrecv(struct arn_softc *sc);
+uint32_t arn_calcrxfilter(struct arn_softc *sc);
+int arn_rx_init(struct arn_softc *sc, int nbufs);
+void arn_rx_cleanup(struct arn_softc *sc);
+uint_t arn_softint_handler(caddr_t data);
+void arn_setdefantenna(struct arn_softc *sc, uint32_t antenna);
+
+#define	ATH_TXBUF	512
+/* max number of transmit attempts (tries) */
+#define	ATH_TXMAXTRY	13
+/* max number of 11n transmit attempts (tries) */
+#define	ATH_11N_TXMAXTRY	10
+/* max number of tries for management and control frames */
+#define	ATH_MGT_TXMAXTRY	4
+#define	WME_BA_BMP_SIZE		64
+#define	WME_MAX_BA		WME_BA_BMP_SIZE
+#define	ATH_TID_MAX_BUFS	(2 * WME_MAX_BA)
+#define	TID_TO_WME_AC(_tid)				\
+	((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE :	\
+	(((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK :	\
+	(((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI :	\
+	WME_AC_VO)
+
+/* Wireless Multimedia Extension Defines */
+#define	WME_AC_BE	0 /* best effort */
+#define	WME_AC_BK	1 /* background */
+#define	WME_AC_VI	2 /* video */
+#define	WME_AC_VO	3 /* voice */
+#define	WME_NUM_AC	4
+
+/*
+ * Data transmit queue state.  One of these exists for each
+ * hardware transmit queue.  Packets sent to us from above
+ * are assigned to queues based on their priority.  Not all
+ * devices support a complete set of hardware transmit queues.
+ * For those devices the array sc_ac2q will map multiple
+ * priorities to fewer hardware queues (typically all to one
+ * hardware queue).
+ */
+
+struct ath_txq {
+	uint_t		axq_qnum; /* hardware q number */
+	uint32_t	*axq_link; /* link ptr in last TX desc */
+	list_t		axq_list; /* transmit queue */
+	kmutex_t	axq_lock; /* lock on q and link */
+	unsigned long	axq_lockflags; /* intr state when must cli */
+	uint_t		axq_depth; /* queue depth (stat only) */
+	uint8_t 	axq_aggr_depth; /* aggregates queued */
+	uint32_t 	axq_totalqueued; /* total ever queued */
+	struct ath_buf	*axq_linkbuf; /* virtual addr of last buffer */
+	/* first desc of the last descriptor that contains CTS */
+	struct ath_desc *axq_lastdsWithCTS;
+	uint_t		axq_intrcnt; /* interrupt count */
+};
+
+
+#define	AGGR_CLEANUP		BIT(1)
+#define	AGGR_ADDBA_COMPLETE	BIT(2)
+#define	AGGR_ADDBA_PROGRESS	BIT(3)
+
+/* per TID aggregate tx state for a destination */
+struct ath_atx_tid {
+	list_node_t list;
+	list_node_t buf_q;
+	struct ath_node *an;
+	struct ath_atx_ac *ac;
+	struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; /* active tx frames */
+	uint16_t seq_start;
+	uint16_t seq_next;
+	uint16_t baw_size;
+	int tidno;
+	int baw_head; /* first un-acked tx buffer */
+	int baw_tail; /* next unused tx buffer slot */
+	int sched;
+	int paused;
+	uint8_t state;
+	int addba_exchangeattempts;
+};
+
+/* per access-category aggregate tx state for a destination */
+struct ath_atx_ac {
+	int sched; /* dest-ac is scheduled */
+	int qnum; /* H/W queue number associated with this AC */
+	list_node_t		list;
+	list_node_t		tid_q;
+};
+
+/* per dest tx state */
+struct ath_atx {
+	struct ath_atx_tid tid[WME_NUM_TID];
+	struct ath_atx_ac ac[WME_NUM_AC];
+};
+
+/* per-frame tx control block */
+struct ath_tx_control {
+	struct ath_txq *txq;
+	int if_id;
+};
+
+/* per frame tx status block */
+struct ath_xmit_status {
+	/* number of retries to successufully transmit this frame */
+	int retries;
+	int flags; /* status of transmit */
+#define	ATH_TX_ERROR	0x01
+#define	ATH_TX_XRETRY	0x02
+#define	ATH_TX_BAR	0x04
+};
+
+struct ath_tx_stat {
+	int rssi; /* RSSI (noise floor ajusted) */
+	int rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
+	int rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
+	int rateieee; /* data rate xmitted (IEEE rate code) */
+	int rateKbps; /* data rate xmitted (Kbps) */
+	int ratecode; /* phy rate code */
+	int flags; /* validity flags */
+/* if any of ctl,extn chain rssis are valid */
+#define	ATH_TX_CHAIN_RSSI_VALID	0x01
+/* if extn chain rssis are valid */
+#define	ATH_TX_RSSI_EXTN_VALID	0x02
+	uint32_t airtime; /* time on air per final tx rate */
+};
+
+struct ath_txq *arn_txq_setup(struct arn_softc *sc, int qtype, int subtype);
+void arn_tx_cleanupq(struct arn_softc *sc, struct ath_txq *txq);
+int arn_tx_setup(struct arn_softc *sc, int haltype);
+void arn_draintxq(struct arn_softc *sc, boolean_t retry_tx);
+void arn_tx_draintxq(struct arn_softc *sc, struct ath_txq *txq);
+int arn_tx(ieee80211com_t *ic, mblk_t *mp, uint8_t type);
+int arn_txq_update(struct arn_softc *sc, int qnum,
+    struct ath9k_tx_queue_info *qinfo);
+void arn_tx_int_proc(void *arg);
+
+/* Node / Aggregation */
+
+#define	ADDBA_EXCHANGE_ATTEMPTS	10
+#define	ATH_AGGR_DELIM_SZ	4 /* delimiter size   */
+#define	ATH_AGGR_MINPLEN	256 /* in bytes, minimum packet length */
+/* number of delimiters for encryption padding */
+#define	ATH_AGGR_ENCRYPTDELIM	10
+/* minimum h/w qdepth to be sustained to maximize aggregation */
+#define	ATH_AGGR_MIN_QDEPTH			2
+#define	ATH_AMPDU_SUBFRAME_DEFAULT		32
+#define	IEEE80211_SEQ_SEQ_SHIFT			4
+#define	IEEE80211_SEQ_MAX			4096
+#define	IEEE80211_MIN_AMPDU_BUF			0x8
+#define	IEEE80211_HTCAP_MAXRXAMPDU_FACTOR	13
+
+/*
+ * return whether a bit at index _n in bitmap _bm is set
+ * _sz is the size of the bitmap
+ */
+#define	ATH_BA_ISSET(_bm, _n)	(((_n) < (WME_BA_BMP_SIZE)) &&	\
+	((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
+
+/* return block-ack bitmap index given sequence and starting sequence */
+#define	ATH_BA_INDEX(_st, _seq)	(((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
+
+/* returns delimiter padding required given the packet length */
+#define	ATH_AGGR_GET_NDELIM(_len)	\
+	(((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ?	\
+	(ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
+
+#define	BAW_WITHIN(_start, _bawsz, _seqno)	\
+	((((_seqno) - (_start)) & 4095) < (_bawsz))
+
+#define	ATH_DS_BA_SEQ(_ds)		((_ds)->ds_us.tx.ts_seqnum)
+#define	ATH_DS_BA_BITMAP(_ds)		(&(_ds)->ds_us.tx.ba_low)
+#define	ATH_DS_TX_BA(_ds)		((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
+#define	ATH_AN_2_TID(_an, _tidno)	(&(_an)->an_aggr.tx.tid[(_tidno)])
+
+enum ATH_AGGR_STATUS {
+	ATH_AGGR_DONE,
+	ATH_AGGR_BAW_CLOSED,
+	ATH_AGGR_LIMITED,
+	ATH_AGGR_SHORTPKT,
+	ATH_AGGR_8K_LIMITED,
+};
+
+struct aggr_rifs_param {
+	int param_max_frames;
+	int param_max_len;
+	int param_rl;
+	int param_al;
+	struct ath_rc_series *param_rcs;
+};
+
+/* driver-specific node state */
+struct ath_node {
+	struct ieee80211_node an_node;	/* base class */
+	uint32_t	an_tx_times;	/* rate ctl times on one rate */
+	uint32_t	an_tx_ok;	/* tx ok pkt */
+	uint32_t	an_tx_err;	/* tx !ok pkt */
+	uint32_t	an_tx_retr;	/* tx retry count */
+	int32_t		an_tx_upper;	/* tx upper rate req cnt */
+	uint32_t	an_tx_antenna;	/* antenna for last good frame */
+	uint8_t		an_tx_rix0;	/* series 0 rate index */
+	uint8_t		an_tx_try0;	/* series 0 try count */
+	uint8_t		an_tx_mgtrate;	/* h/w rate for management/ctl frames */
+	uint8_t		an_tx_mgtratesp; /* short preamble h/w rate for " " */
+	uint8_t		an_tx_rate0;	/* series 0 h/w rate */
+	uint8_t		an_tx_rate1;	/* series 1 h/w rate */
+	uint8_t		an_tx_rate2;	/* series 2 h/w rate */
+	uint8_t		an_tx_rate3;	/* series 3 h/w rate */
+	uint8_t		an_tx_rate0sp;	/* series 0 short preamble h/w rate */
+	uint8_t		an_tx_rate1sp;	/* series 1 short preamble h/w rate */
+	uint8_t		an_tx_rate2sp;	/* series 2 short preamble h/w rate */
+	uint8_t		an_tx_rate3sp;	/* series 3 short preamble h/w rate */
+	struct arn_softc *an_sc;
+#ifdef ARN_11N
+	struct ath_node_aggr an_aggr;
+#endif
+	uint16_t maxampdu;
+	uint8_t mpdudensity;
+};
+#define	ATH_NODE(_n)	((struct ath_node *)(_n))
+
+/*
+ * Define the scheme that we select MAC address for multiple
+ * BSS on the same radio. The very first VAP will just use the MAC
+ * address from the EEPROM. For the next 3 VAPs, we set the
+ * U/L bit (bit 1) in MAC address, and use the next two bits as the
+ * index of the VAP.
+ */
+
+#define	ATH_SET_VAP_BSSID_MASK(bssid_mask) \
+	((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
+
+
+/* driver-specific vap state */
+struct ath_vap {
+	int av_bslot; /* beacon slot index */
+	enum ath9k_opmode av_opmode; /* VAP operational mode */
+	struct ath_buf *av_bcbuf; /* beacon buffer */
+	struct ath_tx_control av_btxctl; /* txctl information for beacon */
+};
+
+/* Beacon Handling */
+
+/*
+ * Regardless of the number of beacons we stagger, (i.e. regardless of the
+ * number of BSSIDs) if a given beacon does not go out even after waiting this
+ * number of beacon intervals, the game's up.
+ */
+#define	BSTUCK_THRESH		(9 * ATH_BCBUF)
+#define	ATH_BCBUF		4 /* number of beacon buffers */
+#define	ATH_DEFAULT_BINTVAL	100 /* default beacon interval in TU */
+#define	ATH_DEFAULT_BMISS_LIMIT	10
+#define	IEEE80211_MS_TO_TU(x)	(((x) * 1000) / 1024)
+
+/* beacon configuration */
+struct ath_beacon_config {
+	uint16_t beacon_interval;
+	uint16_t listen_interval;
+	uint16_t dtim_period;
+	uint16_t bmiss_timeout;
+	uint8_t dtim_count;
+	uint8_t tim_offset;
+	union {
+		uint64_t last_tsf;
+		uint8_t last_tstamp[8];
+	} u; /* last received beacon/probe response timestamp of this BSS. */
+};
+
+uint32_t arn_beaconq_setup(struct ath_hal *ah);
+int arn_beacon_alloc(struct arn_softc *sc, struct ieee80211_node *in);
+void arn_beacon_config(struct arn_softc *sc);
+void arn_beacon_return(struct arn_softc *sc);
+void arn_beacon_sync(struct arn_softc *sc);
+void arn_bmiss_proc(void *arg);
+
+void arn_recv_mgmt(struct ieee80211com *ic, mblk_t *mp,
+	struct ieee80211_node *in, int subtype, int rssi, uint32_t rstamp);
+
+/* ANI */
+
+/*
+ * ANI values for STA only.
+ * FIXME: Add appropriate values for AP later
+ */
+
+#define	ATH_ANI_POLLINTERVAL	100	/* 100 milliseconds between ANI poll */
+#define	ATH_SHORT_CALINTERVAL	1000	/* 1 second between calibrations */
+#define	ATH_LONG_CALINTERVAL	30000	/* 30 seconds between calibrations */
+#define	ATH_RESTART_CALINTERVAL	1200000	/* 20 minutes between calibrations */
+
+struct ath_ani {
+	boolean_t sc_caldone;
+	int16_t sc_noise_floor;
+	unsigned int sc_longcal_timer;
+	unsigned int sc_shortcal_timer;
+	unsigned int sc_resetcal_timer;
+	unsigned int sc_checkani_timer;
+};
+
+/* LED Control */
+#define	ATH_LED_PIN	1
+
+enum ath_led_type {
+	ATH_LED_RADIO,
+	ATH_LED_ASSOC,
+	ATH_LED_TX,
+	ATH_LED_RX
+};
+
+struct ath_led {
+	struct arn_softc *sc;
+	enum ath_led_type led_type;
+	char name[32];
+	boolean_t registered;
+};
+
+/* Rfkill */
+#define	ATH_RFKILL_POLL_INTERVAL	2000 /* msecs */
+
+/* Main driver core */
+/*
+ * Default cache line size, in bytes.
+ * Used when PCI device not fully initialized by bootrom/BIOS
+ */
+#define	DEFAULT_CACHELINE	32
+#define	ATH_DEFAULT_NOISE_FLOOR	-95
+#define	ATH_REGCLASSIDS_MAX	10
+#define	ATH_CABQ_READY_TIME	80 /* % of beacon interval */
+#define	ATH_MAX_SW_RETRIES	10
+#define	ATH_CHAN_MAX		255
+#define	IEEE80211_WEP_NKID	4 /* number of key ids */
+#define	IEEE80211_RATE_VAL	0x7f
+/*
+ * The key cache is used for h/w cipher state and also for
+ * tracking station state such as the current tx antenna.
+ * We also setup a mapping table between key cache slot indices
+ * and station state to short-circuit node lookups on rx.
+ * Different parts have different size key caches.  We handle
+ * up to ATH_KEYMAX entries (could dynamically allocate state).
+ */
+#define	ATH_KEYMAX		128 /* max key cache size we handle */
+
+#define	ATH_IF_ID_ANY		0xff
+#define	ATH_TXPOWER_MAX		100 /* .5 dBm units */
+#define	ATH_RSSI_DUMMY_MARKER	0x127
+#define	ATH_RATE_DUMMY_MARKER	0
+
+enum PROT_MODE {
+	PROT_M_NONE = 0,
+	PROT_M_RTSCTS,
+	PROT_M_CTSONLY
+};
+
+#define	SC_OP_INVALID		BIT(0)
+#define	SC_OP_BEACONS		BIT(1)
+#define	SC_OP_RXAGGR		BIT(2)
+#define	SC_OP_TXAGGR		BIT(3)
+#define	SC_OP_CHAINMASK_UPDATE	BIT(4)
+#define	SC_OP_FULL_RESET	BIT(5)
+#define	SC_OP_NO_RESET		BIT(6)
+#define	SC_OP_PREAMBLE_SHORT	BIT(7)
+#define	SC_OP_PROTECT_ENABLE	BIT(8)
+#define	SC_OP_RXFLUSH		BIT(9)
+#define	SC_OP_LED_ASSOCIATED	BIT(10)
+#define	SC_OP_RFKILL_REGISTERED	BIT(11)
+#define	SC_OP_RFKILL_SW_BLOCKED	BIT(12)
+#define	SC_OP_RFKILL_HW_BLOCKED	BIT(13)
+
+struct arn_softc {
+	ieee80211com_t sc_isc;	/* IEEE 802.11 common */
+	dev_info_t *sc_dev;    /* back pointer to dev_info_t */
+	ddi_taskq_t *sc_tq;    /* private task queue */
+	struct ath_hal *sc_ah;
+	struct ath_config sc_config;
+	caddr_t mem;
+
+	uint8_t sc_isrunning; /* device is operational */
+	uint8_t sc_mrretry;   /* multi-rate retry support */
+	uint8_t sc_have11g;   /* have 11g support */
+	uint8_t sc_bsync;	/* beacon sync */
+
+	ddi_acc_handle_t	sc_cfg_handle;    /* DDI I/O handle */
+	ddi_acc_handle_t	sc_io_handle;	   /* DDI I/O handle */
+	ddi_acc_handle_t	sc_EEPROM_handle; /* DDI I/O handle */
+	ddi_iblock_cookie_t	sc_iblock;
+	ddi_softintr_t		sc_softint_id;
+
+	/* TX/RX descriptors */
+	struct ath_desc *sc_desc;
+	/* descriptor structure */
+	dma_area_t sc_desc_dma;
+	/* pointer to the first "struct ath_buf" */
+	struct ath_buf *sc_vbufptr;
+	/* length of all allocated "struct ath_buf" */
+	uint32_t sc_vbuflen;
+	/* size of one DMA TX/RX buffer based on 802.11 MTU */
+	int32_t sc_dmabuf_size;
+
+	uint8_t sc_curbssid[6];
+	uint8_t sc_myaddr[6];
+	uint8_t sc_bssidmask[6];
+
+	int sc_debug;
+	uint32_t sc_intrstatus;
+	uint32_t sc_flags; /* SC_OP_* */
+	unsigned int rx_filter;
+	uint16_t sc_curtxpow;
+	uint16_t sc_curaid;
+	uint16_t sc_cachelsz;
+	int sc_slotupdate; /* slot to next advance fsm */
+	int sc_slottime;
+	int sc_bslot[ATH_BCBUF];
+	uint8_t sc_tx_chainmask;
+	uint8_t sc_rx_chainmask;
+	enum ath9k_int sc_imask;
+	enum PROT_MODE sc_protmode;
+
+	uint8_t sc_nbcnvaps; /* # of vaps sending beacons */
+	uint16_t sc_nvaps; /* # of active virtual ap's */
+
+	uint8_t sc_mcastantenna;
+	uint8_t sc_defant; /* current default antenna */
+	uint8_t sc_rxotherant; /* rx's on non-default antenna */
+
+	struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */
+	enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
+	enum ath9k_ht_macmode tx_chan_width;
+
+	enum {
+		OK, /* no change needed */
+		UPDATE, /* update pending */
+		COMMIT /* beacon sent, commit change */
+	} sc_updateslot; /* slot time update fsm */
+
+	/* Crypto */
+	uint32_t	sc_keymax; /* size of key cache */
+	uint8_t		sc_keymap[16]; /* bit map of key cache use */
+	uint8_t		sc_splitmic; /* split TKIP MIC keys */
+
+	/* RX */
+	list_t		sc_rxbuf_list;
+	int		sc_rxbufsize; /* rx size based on mtu */
+	uint32_t 	*sc_rxlink; /* link ptr in last RX desc */
+	uint32_t	sc_rx_pend;
+	uint64_t	sc_lastrx; /* tsf at last rx'd frame */
+
+	/* TX */
+	list_t sc_txbuf_list;
+	struct ath_txq 	sc_txq[ATH9K_NUM_TX_QUEUES];
+	uint32_t sc_txqsetup;
+	int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */
+	uint16_t seq_no; /* TX sequence number */
+
+	/* Beacon */
+	struct ath9k_tx_queue_info sc_beacon_qi;
+	struct ath_txq *sc_cabq;
+	list_t sc_bcbuf_list;	/* beacon buffer */
+	uint32_t sc_beaconq;
+	uint32_t sc_bmisscount;
+	uint32_t ast_be_xmit;	/* beacons transmitted */
+	uint64_t bc_tstamp;
+	struct ieee80211_beacon_offsets asc_boff; /* dynamic update state */
+
+	/* Rate */
+	struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
+	struct ath_rate_table *sc_currates; /* current rate table */
+	uint8_t	asc_rixmap[256]; /* IEEE to h/w rate table ix */
+	uint8_t sc_protrix;		/* protection rate index */
+
+	/* mode */
+	enum wireless_mode	sc_curmode; /* current phy mode */
+
+	/* Channel, Band */
+	struct ath9k_channel sc_curchan;
+
+	/* Locks */
+	kmutex_t	sc_genlock;
+	kmutex_t	sc_serial_rw;
+	kmutex_t	sc_rxbuflock;	/* recv lock  */
+	kmutex_t	sc_txbuflock;	/* txbuf lock */
+	kmutex_t	sc_rxflushlock;
+	kmutex_t	sc_resetlock;
+	kmutex_t	sc_bcbuflock;	/* beacon buffer lock */
+	kmutex_t	sc_resched_lock;
+	boolean_t	sc_resched_needed;
+
+	/* LEDs */
+	struct ath_led 	radio_led;
+	struct ath_led 	assoc_led;
+	struct ath_led 	tx_led;
+	struct ath_led 	rx_led;
+
+	uint8_t		sc_mcast_refs[64]; /* refer count */
+	uint32_t	sc_mcast_hash[2]; /* multicast hash table */
+
+	/* Rfkill */
+
+	/* ANI */
+	struct ath_ani sc_ani;
+
+	/* interface statistics */
+	struct ath_stats sc_stats;
+
+	boolean_t sc_promisc; /* Promiscuous mode enabled */
+
+	timeout_id_t sc_scan_timer;
+	timeout_id_t sc_cal_timer;
+
+	int (*sc_newstate)(ieee80211com_t *, enum ieee80211_state, int);
+	void (*sc_recv_mgmt)(ieee80211com_t *, mblk_t *, ieee80211_node_t *,
+	    int, int, uint32_t);
+};
+
+int arn_reset(ieee80211com_t *ic);
+
+int arn_get_hal_qnum(uint16_t queue, struct arn_softc *sc);
+
+int ath_cabq_update(struct arn_softc *);
+
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
+void
+arn_iowrite32(struct ath_hal *ah, uint32_t reg_offset, uint32_t val);
+unsigned int
+arn_ioread32(struct ath_hal *ah, uint32_t reg_offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARN_CORE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_eeprom.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,2912 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <sys/stream.h>
+#include <sys/termio.h>
+#include <sys/errno.h>
+#include <sys/file.h>
+#include <sys/cmn_err.h>
+#include <sys/stropts.h>
+#include <sys/strsubr.h>
+#include <sys/strtty.h>
+#include <sys/kbio.h>
+#include <sys/cred.h>
+#include <sys/stat.h>
+#include <sys/consdev.h>
+#include <sys/kmem.h>
+#include <sys/modctl.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/pci.h>
+#include <sys/errno.h>
+#include <sys/gld.h>
+#include <sys/dlpi.h>
+#include <sys/ethernet.h>
+#include <sys/list.h>
+#include <sys/byteorder.h>
+#include <sys/strsun.h>
+#include <inet/common.h>
+#include <inet/nd.h>
+#include <inet/mi.h>
+#include <inet/wifi_ioctl.h>
+
+#include "arn_core.h"
+#include "arn_hw.h"
+#include "arn_reg.h"
+#include "arn_phy.h"
+
+static void
+ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
+    uint32_t reg, uint32_t mask,
+    uint32_t shift, uint32_t val)
+{
+	uint32_t regVal;
+
+	regVal = REG_READ(ah, reg) & ~mask;
+	regVal |= (val << shift) & mask;
+
+	REG_WRITE(ah, reg, regVal);
+
+	if (ah->ah_config.analog_shiftreg)
+		drv_usecwait(100);
+}
+
+static inline uint16_t
+ath9k_hw_fbin2freq(uint8_t fbin, boolean_t is2GHz)
+{
+
+	if (fbin == AR5416_BCHAN_UNUSED)
+		return (fbin);
+
+	return ((uint16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)));
+}
+
+static inline int16_t
+ath9k_hw_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
+    int16_t targetLeft, int16_t targetRight)
+{
+	int16_t rv;
+
+	if (srcRight == srcLeft) {
+		rv = targetLeft;
+	} else {
+		rv = (int16_t)(((target - srcLeft) * targetRight +
+		    (srcRight - target) * targetLeft) /
+		    (srcRight - srcLeft));
+	}
+	return (rv);
+}
+
+static inline boolean_t
+ath9k_hw_get_lower_upper_index(uint8_t target, uint8_t *pList,
+    uint16_t listSize, uint16_t *indexL, uint16_t *indexR)
+{
+	uint16_t i;
+
+	if (target <= pList[0]) {
+		*indexL = *indexR = 0;
+		return (B_TRUE);
+	}
+	if (target >= pList[listSize - 1]) {
+		*indexL = *indexR = (uint16_t)(listSize - 1);
+		return (B_TRUE);
+	}
+
+	for (i = 0; i < listSize - 1; i++) {
+		if (pList[i] == target) {
+			*indexL = *indexR = i;
+			return (B_TRUE);
+		}
+		if (target < pList[i + 1]) {
+			*indexL = i;
+			*indexR = (uint16_t)(i + 1);
+			return (B_FALSE);
+		}
+	}
+	return (B_FALSE);
+}
+
+static boolean_t
+ath9k_hw_eeprom_read(struct ath_hal *ah, uint32_t off, uint16_t *data)
+{
+	(void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+
+	if (!ath9k_hw_wait(ah, AR_EEPROM_STATUS_DATA,
+	    AR_EEPROM_STATUS_DATA_BUSY |
+	    AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
+		return (B_FALSE);
+	}
+
+	*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+	    AR_EEPROM_STATUS_DATA_VAL);
+
+	return (B_TRUE);
+}
+
+/* ARGSUSED */
+static int
+ath9k_hw_flash_map(struct ath_hal *ah)
+{
+	ARN_DBG((ARN_DBG_EEPROM, "arn: ath9k_hw_flash_map(): "
+	    "using flash but eepom\n"));
+
+	return (0);
+}
+
+static boolean_t
+ath9k_hw_flash_read(struct ath_hal *ah, uint32_t off, uint16_t *data)
+{
+	*data = FLASH_READ(ah, off);
+
+	return (B_TRUE);
+}
+
+static inline boolean_t
+ath9k_hw_nvram_read(struct ath_hal *ah, uint32_t off, uint16_t *data)
+{
+	if (ath9k_hw_use_flash(ah))
+		return (ath9k_hw_flash_read(ah, off, data));
+	else
+		return (ath9k_hw_eeprom_read(ah, off, data));
+}
+
+static boolean_t
+ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
+{
+#define	SIZE_EEPROM_4K	(sizeof (struct ar5416_eeprom_4k) / sizeof (uint16_t))
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+	uint16_t *eep_data;
+	int addr, eep_start_loc = 0;
+
+	eep_start_loc = 64;
+
+	if (!ath9k_hw_use_flash(ah)) {
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "Reading from EEPROM, not flash\n"));
+	}
+
+	eep_data = (uint16_t *)eep;
+
+	for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
+			ARN_DBG((ARN_DBG_EEPROM,
+			    "Unable to read eeprom region \n"));
+			return (B_FALSE);
+		}
+		eep_data++;
+	}
+	return (B_TRUE);
+#undef SIZE_EEPROM_4K
+}
+
+static boolean_t
+ath9k_hw_fill_def_eeprom(struct ath_hal *ah)
+{
+#define	SIZE_EEPROM_DEF	(sizeof (struct ar5416_eeprom_def) / sizeof (uint16_t))
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+	uint16_t *eep_data;
+	int addr, ar5416_eep_start_loc = 0x100;
+
+	eep_data = (uint16_t *)eep;
+
+	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+		    eep_data)) {
+			ARN_DBG((ARN_DBG_EEPROM,
+			    "Unable to read eeprom region\n"));
+			return (B_FALSE);
+		}
+		eep_data++;
+	}
+	return (B_TRUE);
+#undef SIZE_EEPROM_DEF
+}
+
+static boolean_t (*ath9k_fill_eeprom[]) (struct ath_hal *) = {
+	ath9k_hw_fill_def_eeprom,
+	ath9k_hw_fill_4k_eeprom
+};
+
+static inline boolean_t
+ath9k_hw_fill_eeprom(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	return (ath9k_fill_eeprom[ahp->ah_eep_map](ah));
+}
+
+static int
+ath9k_hw_check_def_eeprom(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep =
+	    (struct ar5416_eeprom_def *)&ahp->ah_eeprom.def;
+	uint16_t *eepdata, temp, magic, magic2;
+	uint32_t sum = 0, el;
+	boolean_t need_swap = B_FALSE;
+	int i, addr, size;
+	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+		ARN_DBG((ARN_DBG_EEPROM, "arn: "
+		    "%s: Reading Magic # failed\n", __func__));
+		return (B_FALSE);
+	}
+
+	if (!ath9k_hw_use_flash(ah)) {
+		ARN_DBG((ARN_DBG_EEPROM, "ath9k: "
+		    "%s: Read Magic = 0x%04X\n", __func__, magic));
+
+		if (magic != AR5416_EEPROM_MAGIC) {
+			magic2 = swab16(magic);
+
+			if (magic2 == AR5416_EEPROM_MAGIC) {
+				size = sizeof (struct ar5416_eeprom_def);
+				need_swap = B_TRUE;
+				eepdata = (uint16_t *)(&ahp->ah_eeprom);
+
+				for (addr = 0; addr < size / sizeof (uint16_t);
+				    addr++) {
+					temp = swab16(*eepdata);
+					*eepdata = temp;
+					eepdata++;
+
+					ARN_DBG((ARN_DBG_EEPROM,
+					    "0x%04X  ", *eepdata));
+
+					if (((addr + 1) % 6) == 0)
+						ARN_DBG((ARN_DBG_EEPROM,
+						    "arn: "
+						    "%s\n", __func__));
+				}
+			} else {
+				ARN_DBG((ARN_DBG_EEPROM,
+				    "Invalid EEPROM Magic. "
+				    "endianness mismatch.\n"));
+				return (EINVAL);
+			}
+		}
+	}
+
+	ARN_DBG((ARN_DBG_EEPROM, "need_swap = %s.\n",
+	    need_swap ? "TRUE" : "FALSE"));
+
+	if (need_swap)
+		el = swab16(ahp->ah_eeprom.def.baseEepHeader.length);
+	else
+		el = ahp->ah_eeprom.def.baseEepHeader.length;
+
+	if (el > sizeof (struct ar5416_eeprom_def))
+		el = sizeof (struct ar5416_eeprom_def) / sizeof (uint16_t);
+	else
+		el = el / sizeof (uint16_t);
+
+	eepdata = (uint16_t *)(&ahp->ah_eeprom);
+
+	for (i = 0; i < el; i++)
+		sum ^= *eepdata++;
+
+	if (need_swap) {
+		uint32_t integer, j;
+		uint16_t word;
+
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "EEPROM Endianness is not native.. Changing \n"));
+
+		word = swab16(eep->baseEepHeader.length);
+		eep->baseEepHeader.length = word;
+
+		word = swab16(eep->baseEepHeader.checksum);
+		eep->baseEepHeader.checksum = word;
+
+		word = swab16(eep->baseEepHeader.version);
+		eep->baseEepHeader.version = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[0]);
+		eep->baseEepHeader.regDmn[0] = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[1]);
+		eep->baseEepHeader.regDmn[1] = word;
+
+		word = swab16(eep->baseEepHeader.rfSilent);
+		eep->baseEepHeader.rfSilent = word;
+
+		word = swab16(eep->baseEepHeader.blueToothOptions);
+		eep->baseEepHeader.blueToothOptions = word;
+
+		word = swab16(eep->baseEepHeader.deviceCap);
+		eep->baseEepHeader.deviceCap = word;
+
+		for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
+			struct modal_eep_header *pModal =
+			    &eep->modalHeader[j];
+			integer = swab32(pModal->antCtrlCommon);
+			pModal->antCtrlCommon = integer;
+
+			for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+				integer = swab32(pModal->antCtrlChain[i]);
+				pModal->antCtrlChain[i] = integer;
+			}
+
+			for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+				word = swab16(pModal->spurChans[i].spurChan);
+				pModal->spurChans[i].spurChan = word;
+			}
+		}
+	}
+
+	if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
+	    ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+		    sum, ar5416_get_eep_ver(ahp)));
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+static int
+ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
+{
+#define	EEPROM_4K_SIZE	(sizeof (struct ar5416_eeprom_4k) / sizeof (uint16_t))
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *eep =
+	    (struct ar5416_eeprom_4k *)&ahp->ah_eeprom.map4k;
+	uint16_t *eepdata, temp, magic, magic2;
+	uint32_t sum = 0, el;
+	boolean_t need_swap = B_FALSE;
+	int i, addr;
+
+
+	if (!ath9k_hw_use_flash(ah)) {
+
+		if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+		    &magic)) {
+			ARN_DBG((ARN_DBG_EEPROM,
+			    "Reading Magic # failed\n"));
+			return (B_FALSE);
+		}
+
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "Read Magic = 0x%04X\n", magic));
+
+		if (magic != AR5416_EEPROM_MAGIC) {
+			magic2 = swab16(magic);
+
+			if (magic2 == AR5416_EEPROM_MAGIC) {
+				need_swap = B_TRUE;
+				eepdata = (uint16_t *)(&ahp->ah_eeprom);
+
+				for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
+					temp = swab16(*eepdata);
+					*eepdata = temp;
+					eepdata++;
+
+					ARN_DBG((ARN_DBG_EEPROM,
+					    "0x%04X  ", *eepdata));
+
+					if (((addr + 1) % 6) == 0)
+						ARN_DBG((ARN_DBG_EEPROM, "\n"));
+				}
+			} else {
+				ARN_DBG((ARN_DBG_EEPROM,
+				    "Invalid EEPROM Magic. "
+				    "endianness mismatch.\n"));
+				return (EINVAL);
+			}
+		}
+	}
+
+	ARN_DBG((ARN_DBG_EEPROM, "need_swap = %s.\n",
+	    need_swap ? "True" : "False"));
+
+	if (need_swap)
+		el = swab16(ahp->ah_eeprom.map4k.baseEepHeader.length);
+	else
+		el = ahp->ah_eeprom.map4k.baseEepHeader.length;
+
+	if (el > sizeof (struct ar5416_eeprom_def))
+		el = sizeof (struct ar5416_eeprom_4k) / sizeof (uint16_t);
+	else
+		el = el / sizeof (uint16_t);
+
+	eepdata = (uint16_t *)(&ahp->ah_eeprom);
+
+	for (i = 0; i < el; i++)
+		sum ^= *eepdata++;
+
+	if (need_swap) {
+		uint32_t integer;
+		uint16_t word;
+
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "EEPROM Endianness is not native.. Changing \n"));
+
+		word = swab16(eep->baseEepHeader.length);
+		eep->baseEepHeader.length = word;
+
+		word = swab16(eep->baseEepHeader.checksum);
+		eep->baseEepHeader.checksum = word;
+
+		word = swab16(eep->baseEepHeader.version);
+		eep->baseEepHeader.version = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[0]);
+		eep->baseEepHeader.regDmn[0] = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[1]);
+		eep->baseEepHeader.regDmn[1] = word;
+
+		word = swab16(eep->baseEepHeader.rfSilent);
+		eep->baseEepHeader.rfSilent = word;
+
+		word = swab16(eep->baseEepHeader.blueToothOptions);
+		eep->baseEepHeader.blueToothOptions = word;
+
+		word = swab16(eep->baseEepHeader.deviceCap);
+		eep->baseEepHeader.deviceCap = word;
+
+		integer = swab32(eep->modalHeader.antCtrlCommon);
+		eep->modalHeader.antCtrlCommon = integer;
+
+		for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+			integer = swab32(eep->modalHeader.antCtrlChain[i]);
+			eep->modalHeader.antCtrlChain[i] = integer;
+		}
+
+		for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+			word = swab16(eep->modalHeader.spurChans[i].spurChan);
+			eep->modalHeader.spurChans[i].spurChan = word;
+		}
+	}
+
+	if (sum != 0xffff || ar5416_get_eep4k_ver(ahp) != AR5416_EEP_VER ||
+	    ar5416_get_eep4k_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+		    sum, ar5416_get_eep4k_ver(ahp)));
+		return (EINVAL);
+	}
+
+	return (0);
+#undef EEPROM_4K_SIZE
+}
+
+static int
+(*ath9k_check_eeprom[]) (struct ath_hal *) = {
+    ath9k_hw_check_def_eeprom,
+    ath9k_hw_check_4k_eeprom
+};
+
+static inline int
+ath9k_hw_check_eeprom(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	return (ath9k_check_eeprom[ahp->ah_eep_map](ah));
+}
+
+static inline boolean_t
+ath9k_hw_fill_vpd_table(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
+    uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
+{
+	uint16_t i, k;
+	uint8_t currPwr = pwrMin;
+	uint16_t idxL = 0, idxR = 0;
+
+	for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
+		(void) ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
+		    numIntercepts, &(idxL), &(idxR));
+		if (idxR < 1)
+			idxR = 1;
+		if (idxL == numIntercepts - 1)
+			idxL = (uint16_t)(numIntercepts - 2);
+		if (pPwrList[idxL] == pPwrList[idxR])
+			k = pVpdList[idxL];
+		else
+			k = (uint16_t)
+			    (((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
+			    (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
+			    (pPwrList[idxR] - pPwrList[idxL]));
+		pRetVpdList[i] = (uint8_t)k;
+		currPwr += 2;
+	}
+
+	return (B_TRUE);
+}
+
+static void
+ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    struct cal_data_per_freq_4k *pRawDataSet,
+    uint8_t *bChans, uint16_t availPiers,
+    uint16_t tPdGainOverlap, int16_t *pMinCalPower,
+    uint16_t *pPdGainBoundaries, uint8_t *pPDADCValues,
+    uint16_t numXpdGains)
+{
+#define	TMP_VAL_VPD_TABLE \
+	((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
+	int i, j, k;
+	int16_t ss;
+	uint16_t idxL = 0, idxR = 0, numPiers;
+	static uint8_t vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
+	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static uint8_t vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
+	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static uint8_t vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
+	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+	uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+	uint8_t minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+	uint8_t maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+	int16_t vpdStep;
+	int16_t tmpVal;
+	uint16_t sizeCurrVpdTable, maxIndex, tgtIndex;
+	boolean_t match;
+	int16_t minDelta = 0;
+	struct chan_centers centers;
+#define	PD_GAIN_BOUNDARY_DEFAULT	58;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	for (numPiers = 0; numPiers < availPiers; numPiers++) {
+		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+			break;
+	}
+
+	match = ath9k_hw_get_lower_upper_index(
+	    (uint8_t)FREQ2FBIN(centers.synth_center,
+	    IS_CHAN_2GHZ(chan)), bChans, numPiers,
+	    &idxL, &idxR);
+
+	if (match) {
+		for (i = 0; i < numXpdGains; i++) {
+			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+			    pRawDataSet[idxL].pwrPdg[i],
+			    pRawDataSet[idxL].vpdPdg[i],
+			    AR5416_EEP4K_PD_GAIN_ICEPTS,
+			    vpdTableI[i]);
+		}
+	} else {
+		for (i = 0; i < numXpdGains; i++) {
+			pVpdL = pRawDataSet[idxL].vpdPdg[i];
+			pPwrL = pRawDataSet[idxL].pwrPdg[i];
+			pVpdR = pRawDataSet[idxR].vpdPdg[i];
+			pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+			maxPwrT4[i] =
+			    min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
+			    pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
+
+
+			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+			    pPwrL, pVpdL,
+			    AR5416_EEP4K_PD_GAIN_ICEPTS,
+			    vpdTableL[i]);
+			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+			    pPwrR, pVpdR,
+			    AR5416_EEP4K_PD_GAIN_ICEPTS,
+			    vpdTableR[i]);
+
+			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+				vpdTableI[i][j] =
+				    (uint8_t)(ath9k_hw_interpolate((uint16_t)
+				    FREQ2FBIN(centers.
+				    synth_center,
+				    IS_CHAN_2GHZ
+				    (chan)),
+				    bChans[idxL], bChans[idxR],
+				    vpdTableL[i][j], vpdTableR[i][j]));
+			}
+		}
+	}
+
+	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+	k = 0;
+
+	for (i = 0; i < numXpdGains; i++) {
+		if (i == (numXpdGains - 1))
+			pPdGainBoundaries[i] =
+			    (uint16_t)(maxPwrT4[i] / 2);
+		else
+			pPdGainBoundaries[i] =
+			    (uint16_t)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+		pPdGainBoundaries[i] =
+		    min((uint16_t)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+		if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
+			minDelta = pPdGainBoundaries[0] - 23;
+			pPdGainBoundaries[0] = 23;
+		} else {
+			minDelta = 0;
+		}
+
+		if (i == 0) {
+			if (AR_SREV_9280_10_OR_LATER(ah))
+				ss = (int16_t)(0 - (minPwrT4[i] / 2));
+			else
+				ss = 0;
+		} else {
+			ss = (int16_t)((pPdGainBoundaries[i - 1] -
+			    (minPwrT4[i] / 2)) -
+			    tPdGainOverlap + 1 + minDelta);
+		}
+		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+			pPDADCValues[k++] =
+			    (uint8_t)((tmpVal < 0) ? 0 : tmpVal);
+			ss++;
+		}
+
+		sizeCurrVpdTable =
+		    (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+		tgtIndex = (uint8_t)
+		    (pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2));
+		maxIndex =
+		    (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
+
+		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
+			pPDADCValues[k++] = vpdTableI[i][ss++];
+
+		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+		    vpdTableI[i][sizeCurrVpdTable - 2]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		if (tgtIndex > maxIndex) {
+			while ((ss <= tgtIndex) &&
+			    (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+				tmpVal = (int16_t)TMP_VAL_VPD_TABLE;
+				pPDADCValues[k++] = (uint8_t)
+				    ((tmpVal > 255) ? 255 : tmpVal);
+				ss++;
+			}
+		}
+	}
+
+	while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
+		pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
+		i++;
+	}
+
+	while (k < AR5416_NUM_PDADC_VALUES) {
+		pPDADCValues[k] = pPDADCValues[k - 1];
+		k++;
+	}
+
+	return;
+#undef TMP_VAL_VPD_TABLE
+}
+
+static void
+ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    struct cal_data_per_freq *pRawDataSet,
+    uint8_t *bChans, uint16_t availPiers,
+    uint16_t tPdGainOverlap, int16_t *pMinCalPower,
+    uint16_t *pPdGainBoundaries, uint8_t *pPDADCValues,
+    uint16_t numXpdGains)
+{
+	int i, j, k;
+	int16_t ss;
+	uint16_t idxL = 0, idxR = 0, numPiers;
+	static uint8_t vpdTableL[AR5416_NUM_PD_GAINS]
+	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static uint8_t vpdTableR[AR5416_NUM_PD_GAINS]
+	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static uint8_t vpdTableI[AR5416_NUM_PD_GAINS]
+	    [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+	uint8_t *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+	uint8_t minPwrT4[AR5416_NUM_PD_GAINS];
+	uint8_t maxPwrT4[AR5416_NUM_PD_GAINS];
+	int16_t vpdStep;
+	int16_t tmpVal;
+	uint16_t sizeCurrVpdTable, maxIndex, tgtIndex;
+	boolean_t match;
+	int16_t minDelta = 0;
+	struct chan_centers centers;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	for (numPiers = 0; numPiers < availPiers; numPiers++) {
+		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+			break;
+	}
+
+	match =
+	    ath9k_hw_get_lower_upper_index(
+	    (uint8_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+	    bChans, numPiers, &idxL, &idxR);
+
+	if (match) {
+		for (i = 0; i < numXpdGains; i++) {
+			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+			    pRawDataSet[idxL].pwrPdg[i],
+			    pRawDataSet[idxL].vpdPdg[i],
+			    AR5416_PD_GAIN_ICEPTS,
+			    vpdTableI[i]);
+		}
+	} else {
+		for (i = 0; i < numXpdGains; i++) {
+			pVpdL = pRawDataSet[idxL].vpdPdg[i];
+			pPwrL = pRawDataSet[idxL].pwrPdg[i];
+			pVpdR = pRawDataSet[idxR].vpdPdg[i];
+			pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+			maxPwrT4[i] =
+			    min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
+			    pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
+
+
+			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+			    pPwrL, pVpdL,
+			    AR5416_PD_GAIN_ICEPTS,
+			    vpdTableL[i]);
+			(void) ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+			    pPwrR, pVpdR,
+			    AR5416_PD_GAIN_ICEPTS,
+			    vpdTableR[i]);
+
+			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+				vpdTableI[i][j] =
+				    (uint8_t)(ath9k_hw_interpolate((uint16_t)
+				    FREQ2FBIN(centers.
+				    synth_center,
+				    IS_CHAN_2GHZ
+				    (chan)),
+				    bChans[idxL], bChans[idxR],
+				    vpdTableL[i][j], vpdTableR[i][j]));
+			}
+		}
+	}
+
+	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+	k = 0;
+
+	for (i = 0; i < numXpdGains; i++) {
+		if (i == (numXpdGains - 1))
+			pPdGainBoundaries[i] =
+			    (uint16_t)(maxPwrT4[i] / 2);
+		else
+			pPdGainBoundaries[i] =
+			    (uint16_t)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+		pPdGainBoundaries[i] =
+		    min((uint16_t)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+		if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
+			minDelta = pPdGainBoundaries[0] - 23;
+			pPdGainBoundaries[0] = 23;
+		} else {
+			minDelta = 0;
+		}
+
+		if (i == 0) {
+			if (AR_SREV_9280_10_OR_LATER(ah))
+				ss = (int16_t)(0 - (minPwrT4[i] / 2));
+			else
+				ss = 0;
+		} else {
+			ss = (int16_t)((pPdGainBoundaries[i - 1] -
+			    (minPwrT4[i] / 2)) -
+			    tPdGainOverlap + 1 + minDelta);
+		}
+		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+			pPDADCValues[k++] =
+			    (uint8_t)((tmpVal < 0) ? 0 : tmpVal);
+			ss++;
+		}
+
+		sizeCurrVpdTable =
+		    (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+		tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap -
+		    (minPwrT4[i] / 2));
+		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+		    tgtIndex : sizeCurrVpdTable;
+
+		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+			pPDADCValues[k++] = vpdTableI[i][ss++];
+		}
+
+		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+		    vpdTableI[i][sizeCurrVpdTable - 2]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		if (tgtIndex > maxIndex) {
+			while ((ss <= tgtIndex) &&
+			    (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+				tmpVal =
+				    (int16_t)
+				    ((vpdTableI[i][sizeCurrVpdTable - 1] +
+				    (ss - maxIndex + 1) * vpdStep));
+				pPDADCValues[k++] = (uint8_t)((tmpVal > 255) ?
+				    255 : tmpVal);
+				ss++;
+			}
+		}
+	}
+
+	while (i < AR5416_PD_GAINS_IN_MASK) {
+		pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
+		i++;
+	}
+
+	while (k < AR5416_NUM_PDADC_VALUES) {
+		pPDADCValues[k] = pPDADCValues[k - 1];
+		k++;
+	}
+}
+
+static void
+ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    struct cal_target_power_leg *powInfo,
+    uint16_t numChannels,
+    struct cal_target_power_leg *pNewPower,
+    uint16_t numRates, boolean_t isExtTarget)
+{
+	struct chan_centers centers;
+	uint16_t clo, chi;
+	int i;
+	int matchIndex = -1, lowIndex = -1;
+	uint16_t freq;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
+
+	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
+	    IS_CHAN_2GHZ(chan))) {
+		matchIndex = 0;
+	} else {
+		for (i = 0; (i < numChannels) &&
+		    (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+			    IS_CHAN_2GHZ(chan))) {
+				matchIndex = i;
+				break;
+			} else if ((freq <
+			    ath9k_hw_fbin2freq(powInfo[i].bChannel,
+			    IS_CHAN_2GHZ(chan))) &&
+			    (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+			    IS_CHAN_2GHZ(chan)))) {
+				lowIndex = i - 1;
+				break;
+			}
+		}
+		if ((matchIndex == -1) && (lowIndex == -1))
+			matchIndex = i - 1;
+	}
+
+	if (matchIndex != -1) {
+		*pNewPower = powInfo[matchIndex];
+	} else {
+		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+		    IS_CHAN_2GHZ(chan));
+		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+		    IS_CHAN_2GHZ(chan));
+
+		for (i = 0; i < numRates; i++) {
+			pNewPower->tPow2x[i] =
+			    (uint8_t)ath9k_hw_interpolate(freq, clo, chi,
+			    powInfo[lowIndex].tPow2x[i],
+			    powInfo[lowIndex + 1].tPow2x[i]);
+		}
+	}
+}
+
+static void
+ath9k_hw_get_target_powers(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    struct cal_target_power_ht *powInfo,
+    uint16_t numChannels,
+    struct cal_target_power_ht *pNewPower,
+    uint16_t numRates, boolean_t isHt40Target)
+{
+	struct chan_centers centers;
+	uint16_t clo, chi;
+	int i;
+	int matchIndex = -1, lowIndex = -1;
+	uint16_t freq;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = isHt40Target ? centers.synth_center : centers.ctl_center;
+
+	if (freq <=
+	    ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+		matchIndex = 0;
+	} else {
+		for (i = 0; (i < numChannels) &&
+		    (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+			    IS_CHAN_2GHZ(chan))) {
+				matchIndex = i;
+				break;
+			} else
+				if ((freq <
+				    ath9k_hw_fbin2freq(powInfo[i].bChannel,
+				    IS_CHAN_2GHZ(chan))) &&
+				    (freq > ath9k_hw_fbin2freq
+				    (powInfo[i - 1].bChannel,
+				    IS_CHAN_2GHZ(chan)))) {
+					lowIndex = i - 1;
+					break;
+				}
+		}
+		if ((matchIndex == -1) && (lowIndex == -1))
+			matchIndex = i - 1;
+	}
+
+	if (matchIndex != -1) {
+		*pNewPower = powInfo[matchIndex];
+	} else {
+		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+		    IS_CHAN_2GHZ(chan));
+		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+		    IS_CHAN_2GHZ(chan));
+
+		for (i = 0; i < numRates; i++) {
+			pNewPower->tPow2x[i] =
+			    (uint8_t)ath9k_hw_interpolate(freq,
+			    clo, chi,
+			    powInfo[lowIndex].tPow2x[i],
+			    powInfo[lowIndex + 1].tPow2x[i]);
+		}
+	}
+}
+
+static uint16_t
+ath9k_hw_get_max_edge_power(uint16_t freq,
+    struct cal_ctl_edges *pRdEdgesPower,
+    boolean_t is2GHz, int num_band_edges)
+{
+	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+	int i;
+
+	for (i = 0; (i < num_band_edges) &&
+	    (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+		if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
+		    is2GHz)) {
+			twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+			break;
+		} else if ((i > 0) &&
+		    (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
+		    is2GHz))) {
+			if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
+			    is2GHz) < freq &&
+			    pRdEdgesPower[i - 1].flag) {
+				twiceMaxEdgePower =
+				    pRdEdgesPower[i - 1].tPower;
+			}
+			break;
+		}
+	}
+
+	return (twiceMaxEdgePower);
+}
+
+static boolean_t
+ath9k_hw_set_def_power_cal_table(struct ath_hal *ah,
+    struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
+	struct cal_data_per_freq *pRawDataset;
+	uint8_t *pCalBChans = NULL;
+	uint16_t pdGainOverlap_t2;
+	static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES];
+	uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+	uint16_t numPiers, i, j;
+	int16_t tMinCalPower;
+	uint16_t numXpdGain, xpdMask;
+	uint16_t xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+	uint32_t reg32, regOffset, regChainOffset;
+	int16_t modalIdx;
+
+	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		pdGainOverlap_t2 =
+		    pEepData->modalHeader[modalIdx].pdGainOverlap;
+	} else {
+		pdGainOverlap_t2 =
+		    (uint16_t)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+		    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+	}
+
+	if (IS_CHAN_2GHZ(chan)) {
+		pCalBChans = pEepData->calFreqPier2G;
+		numPiers = AR5416_NUM_2G_CAL_PIERS;
+	} else {
+		pCalBChans = pEepData->calFreqPier5G;
+		numPiers = AR5416_NUM_5G_CAL_PIERS;
+	}
+
+	numXpdGain = 0;
+
+	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+			if (numXpdGain >= AR5416_NUM_PD_GAINS)
+				break;
+			xpdGainValues[numXpdGain] =
+			    (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
+			numXpdGain++;
+		}
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+	    (numXpdGain - 1) & 0x3);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+	    xpdGainValues[0]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+	    xpdGainValues[1]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+	    xpdGainValues[2]);
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		if (AR_SREV_5416_V20_OR_LATER(ah) &&
+		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+		    (i != 0)) {
+			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+		} else
+			regChainOffset = i * 0x1000;
+
+		if (pEepData->baseEepHeader.txMask & (1 << i)) {
+			if (IS_CHAN_2GHZ(chan))
+				pRawDataset = pEepData->calPierData2G[i];
+			else
+				pRawDataset = pEepData->calPierData5G[i];
+
+			ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
+			    pRawDataset, pCalBChans,
+			    numPiers, pdGainOverlap_t2,
+			    &tMinCalPower, gainBoundaries,
+			    pdadcValues, numXpdGain);
+
+			if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+				REG_WRITE(ah,
+				    AR_PHY_TPCRG5 + regChainOffset,
+				    SM(pdGainOverlap_t2,
+				    AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+				    SM(gainBoundaries[0],
+				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) |
+				    SM(gainBoundaries[1],
+				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) |
+				    SM(gainBoundaries[2],
+				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) |
+				    SM(gainBoundaries[3],
+				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+			}
+
+			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+			for (j = 0; j < 32; j++) {
+				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+				    ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+				    ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+				    ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+				REG_WRITE(ah, regOffset, reg32);
+
+				ARN_DBG((ARN_DBG_REG_IO,
+				    "PDADC (%d,%4x): %4.4x %8.8x\n",
+				    i, regChainOffset, regOffset,
+				    reg32));
+				ARN_DBG((ARN_DBG_REG_IO,
+				    "PDADC: Chain %d | PDADC %3d "
+				    "Value %3d | PDADC %3d Value %3d | "
+				    "PDADC %3d Value %3d | PDADC %3d "
+				    "Value %3d |\n",
+				    i, 4 * j, pdadcValues[4 * j],
+				    4 * j + 1, pdadcValues[4 * j + 1],
+				    4 * j + 2, pdadcValues[4 * j + 2],
+				    4 * j + 3,
+				    pdadcValues[4 * j + 3]));
+
+				regOffset += 4;
+			}
+		}
+	}
+
+	*pTxPowerIndexOffset = 0;
+
+	return (B_TRUE);
+}
+
+static boolean_t
+ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
+    struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+	struct cal_data_per_freq_4k *pRawDataset;
+	uint8_t *pCalBChans = NULL;
+	uint16_t pdGainOverlap_t2;
+	static uint8_t pdadcValues[AR5416_NUM_PDADC_VALUES];
+	uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+	uint16_t numPiers, i, j;
+	int16_t tMinCalPower;
+	uint16_t numXpdGain, xpdMask;
+	uint16_t xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+	uint32_t reg32, regOffset, regChainOffset;
+
+	xpdMask = pEepData->modalHeader.xpdGain;
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		pdGainOverlap_t2 =
+		    pEepData->modalHeader.pdGainOverlap;
+	} else {
+		pdGainOverlap_t2 = (uint16_t)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+		    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+	}
+
+	pCalBChans = pEepData->calFreqPier2G;
+	numPiers = AR5416_NUM_2G_CAL_PIERS;
+
+	numXpdGain = 0;
+
+	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+			if (numXpdGain >= AR5416_NUM_PD_GAINS)
+				break;
+			xpdGainValues[numXpdGain] =
+			    (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
+			numXpdGain++;
+		}
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+	    (numXpdGain - 1) & 0x3);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+	    xpdGainValues[0]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+	    xpdGainValues[1]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+	    xpdGainValues[2]);
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		if (AR_SREV_5416_V20_OR_LATER(ah) &&
+		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+		    (i != 0)) {
+			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+		} else
+			regChainOffset = i * 0x1000;
+
+		if (pEepData->baseEepHeader.txMask & (1 << i)) {
+			pRawDataset = pEepData->calPierData2G[i];
+
+			ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
+			    pRawDataset, pCalBChans,
+			    numPiers, pdGainOverlap_t2,
+			    &tMinCalPower, gainBoundaries,
+			    pdadcValues, numXpdGain);
+
+			if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+				REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
+				    SM(pdGainOverlap_t2,
+				    AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+				    SM(gainBoundaries[0],
+				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) |
+				    SM(gainBoundaries[1],
+				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) |
+				    SM(gainBoundaries[2],
+				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) |
+				    SM(gainBoundaries[3],
+				    AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+			}
+
+			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+			for (j = 0; j < 32; j++) {
+				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+				    ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+				    ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+				    ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+				REG_WRITE(ah, regOffset, reg32);
+
+				ARN_DBG((ARN_DBG_REG_IO,
+				    "PDADC (%d,%4x): %4.4x %8.8x\n",
+				    i, regChainOffset, regOffset,
+				    reg32));
+				ARN_DBG((ARN_DBG_REG_IO,
+				    "PDADC: Chain %d | "
+				    "PDADC %3d Value %3d | "
+				    "PDADC %3d Value %3d | "
+				    "PDADC %3d Value %3d | "
+				    "PDADC %3d Value %3d |\n",
+				    i, 4 * j, pdadcValues[4 * j],
+				    4 * j + 1, pdadcValues[4 * j + 1],
+				    4 * j + 2, pdadcValues[4 * j + 2],
+				    4 * j + 3,
+				    pdadcValues[4 * j + 3]));
+
+				regOffset += 4;
+			}
+		}
+	}
+
+	*pTxPowerIndexOffset = 0;
+
+	return (B_TRUE);
+}
+
+static boolean_t
+ath9k_hw_set_def_power_per_rate_table(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    int16_t *ratesArray,
+    uint16_t cfgCtl,
+    uint16_t AntennaReduction,
+    uint16_t twiceMaxRegulatoryPower,
+    uint16_t powerLimit)
+{
+#define	REDUCE_SCALED_POWER_BY_TWO_CHAIN	6  /* 10*log10(2)*2 */
+#define	REDUCE_SCALED_POWER_BY_THREE_CHAIN	10 /* 10*log10(3)*2 */
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
+	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+	static const uint16_t tpScaleReductionTable[5] =
+	    { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+	int i;
+	int8_t twiceLargestAntenna;
+	struct cal_ctl_data *rep;
+	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+		0, { 0, 0, 0, 0}
+	};
+	struct cal_target_power_leg targetPowerOfdmExt = {
+		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+		0, { 0, 0, 0, 0 }
+	};
+	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+		0, {0, 0, 0, 0}
+	};
+	uint16_t scaledPower = 0, minCtlPower, maxRegAllowedPower;
+	uint16_t ctlModesFor11a[] =
+		{ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
+	uint16_t ctlModesFor11g[] =
+		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+		    CTL_2GHT40
+		};
+	uint16_t numCtlModes, *pCtlMode, ctlMode, freq;
+	struct chan_centers centers;
+	int tx_chainmask;
+	uint16_t twiceMinEdgePower;
+
+	tx_chainmask = ahp->ah_txchainmask;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	twiceLargestAntenna = max(
+	    pEepData->modalHeader
+	    [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+	    pEepData->modalHeader
+	    [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+
+	twiceLargestAntenna =
+	    max((uint8_t)twiceLargestAntenna,
+	    pEepData->modalHeader
+	    [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+	twiceLargestAntenna =
+	    (int16_t)min(AntennaReduction - twiceLargestAntenna, 0);
+
+	maxRegAllowedPower =
+	    twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+	if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
+		maxRegAllowedPower -=
+		    (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
+	}
+
+	scaledPower = min(powerLimit, maxRegAllowedPower);
+
+	switch (ar5416_get_ntxchains(tx_chainmask)) {
+	case 1:
+		break;
+	case 2:
+		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+		break;
+	case 3:
+		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+		break;
+	}
+
+	scaledPower = max((uint16_t)0, scaledPower);
+
+	if (IS_CHAN_2GHZ(chan)) {
+		numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
+		    SUB_NUM_CTL_MODES_AT_2G_40;
+		pCtlMode = ctlModesFor11g;
+
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+		    pEepData->calTargetPowerCck,
+		    AR5416_NUM_2G_CCK_TARGET_POWERS,
+		    &targetPowerCck, 4, B_FALSE);
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+		    pEepData->calTargetPower2G,
+		    AR5416_NUM_2G_20_TARGET_POWERS,
+		    &targetPowerOfdm, 4, B_FALSE);
+		ath9k_hw_get_target_powers(ah, chan,
+		    pEepData->calTargetPower2GHT20,
+		    AR5416_NUM_2G_20_TARGET_POWERS,
+		    &targetPowerHt20, 8, B_FALSE);
+
+		if (IS_CHAN_HT40(chan)) {
+			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+			ath9k_hw_get_target_powers(ah, chan,
+			    pEepData->calTargetPower2GHT40,
+			    AR5416_NUM_2G_40_TARGET_POWERS,
+			    &targetPowerHt40, 8, B_TRUE);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+			    pEepData->calTargetPowerCck,
+			    AR5416_NUM_2G_CCK_TARGET_POWERS,
+			    &targetPowerCckExt, 4, B_TRUE);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+			    pEepData->calTargetPower2G,
+			    AR5416_NUM_2G_20_TARGET_POWERS,
+			    &targetPowerOfdmExt, 4, B_TRUE);
+		}
+	} else {
+		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+		    SUB_NUM_CTL_MODES_AT_5G_40;
+		pCtlMode = ctlModesFor11a;
+
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+		    pEepData->calTargetPower5G,
+		    AR5416_NUM_5G_20_TARGET_POWERS,
+		    &targetPowerOfdm, 4, B_FALSE);
+		ath9k_hw_get_target_powers(ah, chan,
+		    pEepData->calTargetPower5GHT20,
+		    AR5416_NUM_5G_20_TARGET_POWERS,
+		    &targetPowerHt20, 8, B_FALSE);
+
+		if (IS_CHAN_HT40(chan)) {
+			numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+			ath9k_hw_get_target_powers(ah, chan,
+			    pEepData->calTargetPower5GHT40,
+			    AR5416_NUM_5G_40_TARGET_POWERS,
+			    &targetPowerHt40, 8, B_TRUE);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+			    pEepData->calTargetPower5G,
+			    AR5416_NUM_5G_20_TARGET_POWERS,
+			    &targetPowerOfdmExt, 4, B_TRUE);
+		}
+	}
+
+	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+		boolean_t isHt40CtlMode =
+		    (pCtlMode[ctlMode] == CTL_5GHT40) ||
+		    (pCtlMode[ctlMode] == CTL_2GHT40);
+		if (isHt40CtlMode)
+			freq = centers.synth_center;
+		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+			freq = centers.ext_center;
+		else
+			freq = centers.ctl_center;
+
+		if (ar5416_get_eep_ver(ahp) == 14 &&
+		    ar5416_get_eep_rev(ahp) <= 2)
+			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+		ARN_DBG((ARN_DBG_EEPROM, "arn: "
+		    "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+		    "EXT_ADDITIVE %d\n",
+		    ctlMode, numCtlModes, isHt40CtlMode,
+		    (pCtlMode[ctlMode] & EXT_ADDITIVE)));
+
+		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
+		    i++) {
+
+			ARN_DBG((ARN_DBG_EEPROM, "arn: "
+			    "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+			    "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+			    "chan %d\n",
+			    i, cfgCtl, pCtlMode[ctlMode],
+			    pEepData->ctlIndex[i], chan->channel));
+
+			if ((((cfgCtl & ~CTL_MODE_M) |
+			    (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			    pEepData->ctlIndex[i]) ||
+			    (((cfgCtl & ~CTL_MODE_M) |
+			    (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			    ((pEepData->ctlIndex[i] & CTL_MODE_M) |
+			    SD_NO_CTL))) {
+				rep = &(pEepData->ctlData[i]);
+
+				twiceMinEdgePower =
+				    ath9k_hw_get_max_edge_power(freq,
+				    rep->ctlEdges[ar5416_get_ntxchains
+				    (tx_chainmask) - 1],
+				    IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
+
+				ARN_DBG((ARN_DBG_EEPROM, "arn: "
+				    "MATCH-EE_IDX %d: ch %d is2 %d "
+				    "2xMinEdge %d chainmask %d chains %d\n",
+				    i, freq, IS_CHAN_2GHZ(chan),
+				    twiceMinEdgePower, tx_chainmask,
+				    ar5416_get_ntxchains(tx_chainmask)));
+
+				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+					twiceMaxEdgePower =
+					    min(twiceMaxEdgePower,
+					    twiceMinEdgePower);
+				} else {
+					twiceMaxEdgePower = twiceMinEdgePower;
+					break;
+				}
+			}
+		}
+
+		minCtlPower = min(twiceMaxEdgePower, scaledPower);
+
+		ARN_DBG((ARN_DBG_EEPROM, "arn: "
+		    "SEL-Min ctlMode %d pCtlMode %d "
+		    "2xMaxEdge %d sP %d minCtlPwr %d\n",
+		    ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+		    scaledPower, minCtlPower));
+
+		switch (pCtlMode[ctlMode]) {
+		case CTL_11B:
+			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
+			    i++) {
+				targetPowerCck.tPow2x[i] =
+				    min((uint16_t)targetPowerCck.tPow2x[i],
+				    minCtlPower);
+			}
+			break;
+		case CTL_11A:
+		case CTL_11G:
+			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
+			    i++) {
+				targetPowerOfdm.tPow2x[i] =
+				    min((uint16_t)targetPowerOfdm.tPow2x[i],
+				    minCtlPower);
+			}
+			break;
+		case CTL_5GHT20:
+		case CTL_2GHT20:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
+			    i++) {
+				targetPowerHt20.tPow2x[i] =
+				    min((uint16_t)targetPowerHt20.tPow2x[i],
+				    minCtlPower);
+			}
+			break;
+		case CTL_11B_EXT:
+			targetPowerCckExt.tPow2x[0] =
+			    min((uint16_t)targetPowerCckExt.tPow2x[0],
+			    minCtlPower);
+			break;
+		case CTL_11A_EXT:
+		case CTL_11G_EXT:
+			targetPowerOfdmExt.tPow2x[0] =
+			    min((uint16_t)targetPowerOfdmExt.tPow2x[0],
+			    minCtlPower);
+			break;
+		case CTL_5GHT40:
+		case CTL_2GHT40:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
+			    i++) {
+				targetPowerHt40.tPow2x[i] =
+				    min((uint16_t)targetPowerHt40.tPow2x[i],
+				    minCtlPower);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+	    ratesArray[rate18mb] = ratesArray[rate24mb] =
+	    targetPowerOfdm.tPow2x[0];
+	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+	if (IS_CHAN_2GHZ(chan)) {
+		ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+		ratesArray[rate2s] = ratesArray[rate2l] =
+		    targetPowerCck.tPow2x[1];
+		ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+		    targetPowerCck.tPow2x[2];
+		;
+		ratesArray[rate11s] = ratesArray[rate11l] =
+		    targetPowerCck.tPow2x[3];
+		;
+	}
+	if (IS_CHAN_HT40(chan)) {
+		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+			ratesArray[rateHt40_0 + i] =
+			    targetPowerHt40.tPow2x[i];
+		}
+		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+		if (IS_CHAN_2GHZ(chan)) {
+			ratesArray[rateExtCck] =
+			    targetPowerCckExt.tPow2x[0];
+		}
+	}
+	return (B_TRUE);
+}
+
+static boolean_t
+ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    int16_t *ratesArray,
+    uint16_t cfgCtl,
+    uint16_t AntennaReduction,
+    uint16_t twiceMaxRegulatoryPower,
+    uint16_t powerLimit)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+	uint16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+	static const uint16_t tpScaleReductionTable[5] =
+		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+	int i;
+	int16_t twiceLargestAntenna;
+	struct cal_ctl_data_4k *rep;
+	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+		0, { 0, 0, 0, 0}
+	};
+	struct cal_target_power_leg targetPowerOfdmExt = {
+		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+		0, { 0, 0, 0, 0 }
+	};
+	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+		0, {0, 0, 0, 0}
+	};
+	uint16_t scaledPower = 0, minCtlPower, maxRegAllowedPower;
+	uint16_t ctlModesFor11g[] =
+	    { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+	    CTL_2GHT40
+	    };
+	uint16_t numCtlModes, *pCtlMode, ctlMode, freq;
+	struct chan_centers centers;
+	int tx_chainmask;
+	uint16_t twiceMinEdgePower;
+
+	tx_chainmask = ahp->ah_txchainmask;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
+
+	twiceLargestAntenna =
+	    (int16_t)min(AntennaReduction - twiceLargestAntenna, 0);
+
+	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+	if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
+		maxRegAllowedPower -=
+		    (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
+	}
+
+	scaledPower = min(powerLimit, maxRegAllowedPower);
+	scaledPower = max((uint16_t)0, scaledPower);
+
+	numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+	pCtlMode = ctlModesFor11g;
+
+	ath9k_hw_get_legacy_target_powers(ah, chan,
+	    pEepData->calTargetPowerCck,
+	    AR5416_NUM_2G_CCK_TARGET_POWERS,
+	    &targetPowerCck, 4, B_FALSE);
+	ath9k_hw_get_legacy_target_powers(ah, chan,
+	    pEepData->calTargetPower2G,
+	    AR5416_NUM_2G_20_TARGET_POWERS,
+	    &targetPowerOfdm, 4, B_FALSE);
+	ath9k_hw_get_target_powers(ah, chan,
+	    pEepData->calTargetPower2GHT20,
+	    AR5416_NUM_2G_20_TARGET_POWERS,
+	    &targetPowerHt20, 8, B_FALSE);
+
+	if (IS_CHAN_HT40(chan)) {
+		numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+		ath9k_hw_get_target_powers(ah, chan,
+		    pEepData->calTargetPower2GHT40,
+		    AR5416_NUM_2G_40_TARGET_POWERS,
+		    &targetPowerHt40, 8, B_TRUE);
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+		    pEepData->calTargetPowerCck,
+		    AR5416_NUM_2G_CCK_TARGET_POWERS,
+		    &targetPowerCckExt, 4, B_TRUE);
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+		    pEepData->calTargetPower2G,
+		    AR5416_NUM_2G_20_TARGET_POWERS,
+		    &targetPowerOfdmExt, 4, B_TRUE);
+	}
+
+	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+		boolean_t isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+		    (pCtlMode[ctlMode] == CTL_2GHT40);
+		if (isHt40CtlMode)
+			freq = centers.synth_center;
+		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+			freq = centers.ext_center;
+		else
+			freq = centers.ctl_center;
+
+		if (ar5416_get_eep_ver(ahp) == 14 &&
+		    ar5416_get_eep_rev(ahp) <= 2)
+			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+		ARN_DBG((ARN_DBG_POWER_MGMT,
+		    "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+		    "EXT_ADDITIVE %d\n",
+		    ctlMode, numCtlModes, isHt40CtlMode,
+		    (pCtlMode[ctlMode] & EXT_ADDITIVE)));
+
+		for (i = 0; (i < AR5416_NUM_CTLS) &&
+		    pEepData->ctlIndex[i]; i++) {
+			ARN_DBG((ARN_DBG_POWER_MGMT,
+			    "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+			    "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+			    "chan %d\n",
+			    i, cfgCtl, pCtlMode[ctlMode],
+			    pEepData->ctlIndex[i], chan->channel));
+
+			if ((((cfgCtl & ~CTL_MODE_M) |
+			    (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			    pEepData->ctlIndex[i]) ||
+			    (((cfgCtl & ~CTL_MODE_M) |
+			    (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			    ((pEepData->ctlIndex[i] & CTL_MODE_M) |
+			    SD_NO_CTL))) {
+				rep = &(pEepData->ctlData[i]);
+
+				twiceMinEdgePower =
+				    ath9k_hw_get_max_edge_power(freq,
+				    rep->ctlEdges[ar5416_get_ntxchains
+				    (tx_chainmask) - 1],
+				    IS_CHAN_2GHZ(chan),
+				    AR5416_EEP4K_NUM_BAND_EDGES);
+
+				ARN_DBG((ARN_DBG_POWER_MGMT,
+				    "   MATCH-EE_IDX %d: ch %d is2 %d "
+				    "2xMinEdge %d chainmask %d chains %d\n",
+				    i, freq, IS_CHAN_2GHZ(chan),
+				    twiceMinEdgePower, tx_chainmask,
+				    ar5416_get_ntxchains
+				    (tx_chainmask)));
+				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+					twiceMaxEdgePower =
+					    min(twiceMaxEdgePower,
+					    twiceMinEdgePower);
+				} else {
+					twiceMaxEdgePower = twiceMinEdgePower;
+					break;
+				}
+			}
+		}
+
+		minCtlPower = (uint8_t)min(twiceMaxEdgePower, scaledPower);
+
+		ARN_DBG((ARN_DBG_POWER_MGMT,
+		    "    SEL-Min ctlMode %d pCtlMode %d "
+		    "2xMaxEdge %d sP %d minCtlPwr %d\n",
+		    ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+		    scaledPower, minCtlPower));
+
+		switch (pCtlMode[ctlMode]) {
+		case CTL_11B:
+			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
+			    i++) {
+				targetPowerCck.tPow2x[i] =
+				    min((uint16_t)targetPowerCck.tPow2x[i],
+				    minCtlPower);
+			}
+			break;
+		case CTL_11G:
+			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
+			    i++) {
+				targetPowerOfdm.tPow2x[i] =
+				    min((uint16_t)targetPowerOfdm.tPow2x[i],
+				    minCtlPower);
+			}
+			break;
+		case CTL_2GHT20:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
+			    i++) {
+				targetPowerHt20.tPow2x[i] =
+				    min((uint16_t)targetPowerHt20.tPow2x[i],
+				    minCtlPower);
+			}
+			break;
+		case CTL_11B_EXT:
+			targetPowerCckExt.tPow2x[0] = min((uint16_t)
+			    targetPowerCckExt.tPow2x[0],
+			    minCtlPower);
+			break;
+		case CTL_11G_EXT:
+			targetPowerOfdmExt.tPow2x[0] = min((uint16_t)
+			    targetPowerOfdmExt.tPow2x[0],
+			    minCtlPower);
+			break;
+		case CTL_2GHT40:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
+			    i++) {
+				targetPowerHt40.tPow2x[i] =
+				    min((uint16_t)targetPowerHt40.tPow2x[i],
+				    minCtlPower);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+	    ratesArray[rate18mb] = ratesArray[rate24mb] =
+	    targetPowerOfdm.tPow2x[0];
+	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+	ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+	ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
+	ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
+	ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
+
+	if (IS_CHAN_HT40(chan)) {
+		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+			ratesArray[rateHt40_0 + i] =
+			    targetPowerHt40.tPow2x[i];
+		}
+		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+		ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
+	}
+	return (B_TRUE);
+}
+
+static int
+ath9k_hw_def_set_txpower(struct ath_hal *ah, struct ath9k_channel *chan,
+    uint16_t cfgCtl, uint8_t twiceAntennaReduction,
+    uint8_t twiceMaxRegulatoryPower, uint8_t powerLimit)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
+	struct modal_eep_header *pModal =
+	    &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+	int16_t ratesArray[Ar5416RateSize];
+	int16_t txPowerIndexOffset = 0;
+	uint8_t ht40PowerIncForPdadc = 2;
+	int i;
+
+	(void) memset(ratesArray, 0, sizeof (ratesArray));
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+	}
+
+	if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+	    &ratesArray[0], cfgCtl,
+	    twiceAntennaReduction,
+	    twiceMaxRegulatoryPower,
+	    powerLimit)) {
+
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "ath9k_hw_set_txpower: unable to set "
+		    "tx power per rate table\n"));
+
+		return (EIO);
+	}
+
+	if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+		ARN_DBG((ARN_DBG_EEPROM, "ath9k: "
+		    "ath9k_hw_set_txpower: unable to set power table\n"));
+		return (EIO);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
+		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+			ratesArray[i] = AR5416_MAX_RATE_POWER;
+	}
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		for (i = 0; i < Ar5416RateSize; i++)
+			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+	    ATH9K_POW_SM(ratesArray[rate18mb], 24) |
+	    ATH9K_POW_SM(ratesArray[rate12mb], 16) |
+	    ATH9K_POW_SM(ratesArray[rate9mb], 8) |
+	    ATH9K_POW_SM(ratesArray[rate6mb], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+	    ATH9K_POW_SM(ratesArray[rate54mb], 24) |
+	    ATH9K_POW_SM(ratesArray[rate48mb], 16) |
+	    ATH9K_POW_SM(ratesArray[rate36mb], 8) |
+	    ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+	if (IS_CHAN_2GHZ(chan)) {
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+		    ATH9K_POW_SM(ratesArray[rate2s], 24) |
+		    ATH9K_POW_SM(ratesArray[rate2l], 16) |
+		    ATH9K_POW_SM(ratesArray[rateXr], 8) |
+		    ATH9K_POW_SM(ratesArray[rate1l], 0));
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+		    ATH9K_POW_SM(ratesArray[rate11s], 24) |
+		    ATH9K_POW_SM(ratesArray[rate11l], 16) |
+		    ATH9K_POW_SM(ratesArray[rate5_5s], 8) |
+		    ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+	    ATH9K_POW_SM(ratesArray[rateHt20_3], 24) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_2], 16) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_1], 8) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+	    ATH9K_POW_SM(ratesArray[rateHt20_7], 24) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_6], 16) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_5], 8) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+	if (IS_CHAN_HT40(chan)) {
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+		    ATH9K_POW_SM(ratesArray[rateHt40_3] +
+		    ht40PowerIncForPdadc, 24) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_2] +
+		    ht40PowerIncForPdadc, 16) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_1] +
+		    ht40PowerIncForPdadc, 8) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_0] +
+		    ht40PowerIncForPdadc, 0));
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+		    ATH9K_POW_SM(ratesArray[rateHt40_7] +
+		    ht40PowerIncForPdadc, 24) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_6] +
+		    ht40PowerIncForPdadc, 16) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_5] +
+		    ht40PowerIncForPdadc, 8) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_4] +
+		    ht40PowerIncForPdadc, 0));
+
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+		    ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) |
+		    ATH9K_POW_SM(ratesArray[rateExtCck], 16) |
+		    ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) |
+		    ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+	    ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) |
+	    ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+	i = rate6mb;
+
+	if (IS_CHAN_HT40(chan))
+		i = rateHt40_0;
+	else if (IS_CHAN_HT20(chan))
+		i = rateHt20_0;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ah->ah_maxPowerLevel =
+		    ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+	else
+		ah->ah_maxPowerLevel = ratesArray[i];
+
+	return (0);
+}
+
+static int
+ath9k_hw_4k_set_txpower(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    uint16_t cfgCtl,
+    uint8_t twiceAntennaReduction,
+    uint8_t twiceMaxRegulatoryPower,
+    uint8_t powerLimit)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
+	int16_t ratesArray[Ar5416RateSize];
+	int16_t txPowerIndexOffset = 0;
+	uint8_t ht40PowerIncForPdadc = 2;
+	int i;
+
+	(void) memset(ratesArray, 0, sizeof (ratesArray));
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+	}
+
+	if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
+	    &ratesArray[0], cfgCtl,
+	    twiceAntennaReduction,
+	    twiceMaxRegulatoryPower,
+	    powerLimit)) {
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "ath9k_hw_set_txpower: unable to set "
+		    "tx power per rate table\n"));
+		return (EIO);
+	}
+
+	if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "ath9k_hw_set_txpower: unable to set power table\n"));
+		return (EIO);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
+		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+			ratesArray[i] = AR5416_MAX_RATE_POWER;
+	}
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		for (i = 0; i < Ar5416RateSize; i++)
+			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+	    ATH9K_POW_SM(ratesArray[rate18mb], 24) |
+	    ATH9K_POW_SM(ratesArray[rate12mb], 16) |
+	    ATH9K_POW_SM(ratesArray[rate9mb], 8) |
+	    ATH9K_POW_SM(ratesArray[rate6mb], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+	    ATH9K_POW_SM(ratesArray[rate54mb], 24) |
+	    ATH9K_POW_SM(ratesArray[rate48mb], 16) |
+	    ATH9K_POW_SM(ratesArray[rate36mb], 8) |
+	    ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+	if (IS_CHAN_2GHZ(chan)) {
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+		    ATH9K_POW_SM(ratesArray[rate2s], 24) |
+		    ATH9K_POW_SM(ratesArray[rate2l], 16) |
+		    ATH9K_POW_SM(ratesArray[rateXr], 8) |
+		    ATH9K_POW_SM(ratesArray[rate1l], 0));
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+		    ATH9K_POW_SM(ratesArray[rate11s], 24) |
+		    ATH9K_POW_SM(ratesArray[rate11l], 16) |
+		    ATH9K_POW_SM(ratesArray[rate5_5s], 8) |
+		    ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+	    ATH9K_POW_SM(ratesArray[rateHt20_3], 24) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_2], 16) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_1], 8) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+	    ATH9K_POW_SM(ratesArray[rateHt20_7], 24) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_6], 16) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_5], 8) |
+	    ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+	if (IS_CHAN_HT40(chan)) {
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+		    ATH9K_POW_SM(ratesArray[rateHt40_3] +
+		    ht40PowerIncForPdadc, 24) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_2] +
+		    ht40PowerIncForPdadc, 16) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_1] +
+		    ht40PowerIncForPdadc, 8) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_0] +
+		    ht40PowerIncForPdadc, 0));
+
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+		    ATH9K_POW_SM(ratesArray[rateHt40_7] +
+		    ht40PowerIncForPdadc, 24) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_6] +
+		    ht40PowerIncForPdadc, 16) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_5] +
+		    ht40PowerIncForPdadc, 8) |
+		    ATH9K_POW_SM(ratesArray[rateHt40_4] +
+		    ht40PowerIncForPdadc, 0));
+
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+		    ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) |
+		    ATH9K_POW_SM(ratesArray[rateExtCck], 16) |
+		    ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) |
+		    ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+	}
+
+	i = rate6mb;
+
+	if (IS_CHAN_HT40(chan))
+		i = rateHt40_0;
+	else if (IS_CHAN_HT20(chan))
+		i = rateHt20_0;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ah->ah_maxPowerLevel =
+		    ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+	else
+		ah->ah_maxPowerLevel = ratesArray[i];
+
+	return (0);
+}
+
+int
+ath9k_hw_set_txpower(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    uint16_t cfgCtl,
+    uint8_t twiceAntennaReduction,
+    uint8_t twiceMaxRegulatoryPower,
+    uint8_t powerLimit)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int val;
+
+	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
+		val = ath9k_hw_def_set_txpower(ah, chan, cfgCtl,
+		    twiceAntennaReduction, twiceMaxRegulatoryPower,
+		    powerLimit);
+	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+		val = ath9k_hw_4k_set_txpower(ah, chan, cfgCtl,
+		    twiceAntennaReduction, twiceMaxRegulatoryPower,
+		    powerLimit);
+	return (val);
+}
+
+static void
+ath9k_hw_set_def_addac(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+#define	XPA_LVL_FREQ(cnt)	(pModal->xpaBiasLvlFreq[cnt])
+	struct modal_eep_header *pModal;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+	uint8_t biaslevel;
+
+	if (ah->ah_macVersion != AR_SREV_VERSION_9160)
+		return;
+
+	if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
+		return;
+
+	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+	if (pModal->xpaBiasLvl != 0xff) {
+		biaslevel = pModal->xpaBiasLvl;
+	} else {
+		uint16_t resetFreqBin, freqBin, freqCount = 0;
+		struct chan_centers centers;
+
+		ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+		resetFreqBin =
+		    FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
+		freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+		biaslevel = (uint8_t)(XPA_LVL_FREQ(0) >> 14);
+
+		freqCount++;
+
+		while (freqCount < 3) {
+			if (XPA_LVL_FREQ(freqCount) == 0x0)
+				break;
+
+			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+			if (resetFreqBin >= freqBin) {
+				biaslevel =
+				    (uint8_t)
+				    (XPA_LVL_FREQ(freqCount) >> 14);
+			} else {
+				break;
+			}
+			freqCount++;
+		}
+	}
+
+	if (IS_CHAN_2GHZ(chan)) {
+		INI_RA(&ahp->ah_iniAddac, 7, 1) =
+		    (INI_RA(&ahp->ah_iniAddac, 7, 1) &
+		    (~0x18)) | biaslevel << 3;
+	} else {
+		INI_RA(&ahp->ah_iniAddac, 6, 1) =
+		    (INI_RA(&ahp->ah_iniAddac, 6, 1) &
+		    (~0xc0)) | biaslevel << 6;
+	}
+#undef XPA_LVL_FREQ
+}
+
+/* ARGSUSED */
+static void
+ath9k_hw_set_4k_addac(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	struct modal_eep_4k_header *pModal;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+	uint8_t biaslevel;
+
+	if (ah->ah_macVersion != AR_SREV_VERSION_9160)
+		return;
+
+	if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
+		return;
+
+	pModal = &eep->modalHeader;
+
+	if (pModal->xpaBiasLvl != 0xff) {
+		biaslevel = pModal->xpaBiasLvl;
+		INI_RA(&ahp->ah_iniAddac, 7, 1) =
+		    (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) |
+		    biaslevel << 3;
+	}
+}
+
+void
+ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
+		ath9k_hw_set_def_addac(ah, chan);
+	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+		ath9k_hw_set_4k_addac(ah, chan);
+}
+
+/* XXX: Clean me up, make me more legible */
+static boolean_t
+ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
+    struct ath9k_channel *chan)
+{
+	struct modal_eep_header *pModal;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+	int i, regChainOffset;
+	uint8_t txRxAttenLocal;
+	uint16_t ant_config;
+
+	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+	txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
+
+	(void) ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
+	REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		if (AR_SREV_9280(ah)) {
+			if (i >= 2)
+				break;
+		}
+
+		if (AR_SREV_5416_V20_OR_LATER(ah) &&
+		    (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+		    (i != 0))
+			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+		else
+			regChainOffset = i * 0x1000;
+
+		REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+		    pModal->antCtrlChain[i]);
+
+		REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+		    (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+		    ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+		    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+		    SM(pModal->iqCalICh[i],
+		    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+		    SM(pModal->iqCalQCh[i],
+		    AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+		if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+			if ((eep->baseEepHeader.version &
+			    AR5416_EEP_VER_MINOR_MASK) >=
+			    AR5416_EEP_MINOR_VER_3) {
+				txRxAttenLocal = pModal->txRxAttenCh[i];
+				if (AR_SREV_9280_10_OR_LATER(ah)) {
+					REG_RMW_FIELD(ah,
+					    AR_PHY_GAIN_2GHZ +
+					    regChainOffset,
+					    AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+					    pModal->
+					    bswMargin[i]);
+					REG_RMW_FIELD(ah,
+					    AR_PHY_GAIN_2GHZ +
+					    regChainOffset,
+					    AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+					    pModal->
+					    bswAtten[i]);
+					REG_RMW_FIELD(ah,
+					    AR_PHY_GAIN_2GHZ +
+					    regChainOffset,
+					    AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+					    pModal->
+					    xatten2Margin[i]);
+					REG_RMW_FIELD(ah,
+					    AR_PHY_GAIN_2GHZ +
+					    regChainOffset,
+					    AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+					    pModal->
+					    xatten2Db[i]);
+				} else {
+					REG_WRITE(ah,
+					    AR_PHY_GAIN_2GHZ +
+					    regChainOffset,
+					    (REG_READ(ah,
+					    AR_PHY_GAIN_2GHZ +
+					    regChainOffset) &
+					    ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
+					    | SM(pModal->
+					    bswMargin[i],
+					    AR_PHY_GAIN_2GHZ_BSW_MARGIN));
+					REG_WRITE(ah,
+					    AR_PHY_GAIN_2GHZ +
+					    regChainOffset,
+					    (REG_READ(ah,
+					    AR_PHY_GAIN_2GHZ +
+					    regChainOffset) &
+					    ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
+					    | SM(pModal->bswAtten[i],
+					    AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+				}
+			}
+			if (AR_SREV_9280_10_OR_LATER(ah)) {
+				REG_RMW_FIELD(ah,
+				    AR_PHY_RXGAIN +
+				    regChainOffset,
+				    AR9280_PHY_RXGAIN_TXRX_ATTEN,
+				    txRxAttenLocal);
+				REG_RMW_FIELD(ah,
+				    AR_PHY_RXGAIN +
+				    regChainOffset,
+				    AR9280_PHY_RXGAIN_TXRX_MARGIN,
+				    pModal->rxTxMarginCh[i]);
+			} else {
+				REG_WRITE(ah,
+				    AR_PHY_RXGAIN + regChainOffset,
+				    (REG_READ(ah,
+				    AR_PHY_RXGAIN +
+				    regChainOffset) &
+				    ~AR_PHY_RXGAIN_TXRX_ATTEN) |
+				    SM(txRxAttenLocal,
+				    AR_PHY_RXGAIN_TXRX_ATTEN));
+				REG_WRITE(ah,
+				    AR_PHY_GAIN_2GHZ +
+				    regChainOffset,
+				    (REG_READ(ah,
+				    AR_PHY_GAIN_2GHZ +
+				    regChainOffset) &
+				    ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
+				    SM(pModal->rxTxMarginCh[i],
+				    AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+			}
+		}
+	}
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		if (IS_CHAN_2GHZ(chan)) {
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+			    AR_AN_RF2G1_CH0_OB,
+			    AR_AN_RF2G1_CH0_OB_S,
+			    pModal->ob);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+			    AR_AN_RF2G1_CH0_DB,
+			    AR_AN_RF2G1_CH0_DB_S,
+			    pModal->db);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+			    AR_AN_RF2G1_CH1_OB,
+			    AR_AN_RF2G1_CH1_OB_S,
+			    pModal->ob_ch1);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+			    AR_AN_RF2G1_CH1_DB,
+			    AR_AN_RF2G1_CH1_DB_S,
+			    pModal->db_ch1);
+		} else {
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+			    AR_AN_RF5G1_CH0_OB5,
+			    AR_AN_RF5G1_CH0_OB5_S,
+			    pModal->ob);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+			    AR_AN_RF5G1_CH0_DB5,
+			    AR_AN_RF5G1_CH0_DB5_S,
+			    pModal->db);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+			    AR_AN_RF5G1_CH1_OB5,
+			    AR_AN_RF5G1_CH1_OB5_S,
+			    pModal->ob_ch1);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+			    AR_AN_RF5G1_CH1_DB5,
+			    AR_AN_RF5G1_CH1_DB5_S,
+			    pModal->db_ch1);
+		}
+		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+		    AR_AN_TOP2_XPABIAS_LVL,
+		    AR_AN_TOP2_XPABIAS_LVL_S,
+		    pModal->xpaBiasLvl);
+		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+		    AR_AN_TOP2_LOCALBIAS,
+		    AR_AN_TOP2_LOCALBIAS_S,
+		    pModal->local_bias);
+
+		ARN_DBG((ARN_DBG_EEPROM, "arn: "
+		    "ForceXPAon: %d\n", pModal->force_xpaon));
+
+		REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
+		    pModal->force_xpaon);
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+	    pModal->switchSettling);
+	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+	    pModal->adcDesiredSize);
+
+	if (!AR_SREV_9280_10_OR_LATER(ah))
+		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+		    AR_PHY_DESIRED_SZ_PGA,
+		    pModal->pgaDesiredSize);
+
+	REG_WRITE(ah, AR_PHY_RF_CTL4,
+	    SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+	    SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+	    SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
+	    SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+	    pModal->txEndToRxOn);
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+		    pModal->thresh62);
+		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+		    AR_PHY_EXT_CCA0_THRESH62,
+		    pModal->thresh62);
+	} else {
+		REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
+		    pModal->thresh62);
+		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+		    AR_PHY_EXT_CCA_THRESH62,
+		    pModal->thresh62);
+	}
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+		    AR_PHY_TX_END_DATA_START,
+		    pModal->txFrameToDataStart);
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+		    pModal->txFrameToPaOn);
+	}
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_3) {
+		if (IS_CHAN_HT40(chan))
+			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+			    AR_PHY_SETTLING_SWITCH,
+			    pModal->swSettleHt40);
+	}
+
+	return (B_TRUE);
+}
+
+static boolean_t
+ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah,
+    struct ath9k_channel *chan)
+{
+	struct modal_eep_4k_header *pModal;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+	int regChainOffset;
+	uint8_t txRxAttenLocal;
+	uint16_t ant_config = 0;
+	uint8_t ob[5], db1[5], db2[5];
+	uint8_t ant_div_control1, ant_div_control2;
+	uint32_t regVal;
+
+
+	pModal = &eep->modalHeader;
+
+	txRxAttenLocal = 23;
+
+	(void) ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
+	REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+
+	regChainOffset = 0;
+	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+	    pModal->antCtrlChain[0]);
+
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+	    (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+	    ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+	    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+	    SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+	    SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_3) {
+		txRxAttenLocal = pModal->txRxAttenCh[0];
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+		    AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+		    AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+		    AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+		    pModal->xatten2Margin[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+		    AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+	    AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+	    AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+
+	if (AR_SREV_9285_11(ah))
+		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+
+	/* Initialize Ant Diversity settings from EEPROM */
+	if (pModal->version == 3) {
+		ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
+		ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
+		regVal = REG_READ(ah, 0x99ac);
+		regVal &= (~(0x7f000000));
+		regVal |= ((ant_div_control1 & 0x1) << 24);
+		regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
+		regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
+		regVal |= ((ant_div_control2 & 0x3) << 25);
+		regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
+		REG_WRITE(ah, 0x99ac, regVal);
+		regVal = REG_READ(ah, 0x99ac);
+		regVal = REG_READ(ah, 0xa208);
+		regVal &= (~(0x1 << 13));
+		regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
+		REG_WRITE(ah, 0xa208, regVal);
+		regVal = REG_READ(ah, 0xa208);
+	}
+
+	if (pModal->version >= 2) {
+		ob[0] = (pModal->ob_01 & 0xf);
+		ob[1] = (pModal->ob_01 >> 4) & 0xf;
+		ob[2] = (pModal->ob_234 & 0xf);
+		ob[3] = ((pModal->ob_234 >> 4) & 0xf);
+		ob[4] = ((pModal->ob_234 >> 8) & 0xf);
+
+		db1[0] = (pModal->db1_01 & 0xf);
+		db1[1] = ((pModal->db1_01 >> 4) & 0xf);
+		db1[2] = (pModal->db1_234 & 0xf);
+		db1[3] = ((pModal->db1_234 >> 4) & 0xf);
+		db1[4] = ((pModal->db1_234 >> 8) & 0xf);
+
+		db2[0] = (pModal->db2_01 & 0xf);
+		db2[1] = ((pModal->db2_01 >> 4) & 0xf);
+		db2[2] = (pModal->db2_234 & 0xf);
+		db2[3] = ((pModal->db2_234 >> 4) & 0xf);
+		db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+
+	} else if (pModal->version == 1) {
+
+		ARN_DBG((ARN_DBG_EEPROM,
+		    "EEPROM Model version is set to 1 \n"));
+		ob[0] = (pModal->ob_01 & 0xf);
+		ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
+		db1[0] = (pModal->db1_01 & 0xf);
+		db1[1] = db1[2] = db1[3] = db1[4] =
+		    ((pModal->db1_01 >> 4) & 0xf);
+		db2[0] = (pModal->db2_01 & 0xf);
+		db2[1] = db2[2] = db2[3] = db2[4] =
+		    ((pModal->db2_01 >> 4) & 0xf);
+	} else {
+		int i;
+		for (i = 0; i < 5; i++) {
+			ob[i] = pModal->ob_01;
+			db1[i] = pModal->db1_01;
+			db2[i] = pModal->db1_01;
+		}
+	}
+
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+	    AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+	    AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+	    AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+	    AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+	    AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
+
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+	    AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+	    AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+	    AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+	    AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+	    AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+	    AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+	    AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+	    AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+	    AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
+	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+	    AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
+
+
+	if (AR_SREV_9285_11(ah))
+		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+	    pModal->switchSettling);
+	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+	    pModal->adcDesiredSize);
+
+	REG_WRITE(ah, AR_PHY_RF_CTL4,
+	    SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+	    SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+	    SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
+	    SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+	    pModal->txEndToRxOn);
+	REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+	    pModal->thresh62);
+	REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
+	    pModal->thresh62);
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
+		    pModal->txFrameToDataStart);
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+		    pModal->txFrameToPaOn);
+	}
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_3) {
+		if (IS_CHAN_HT40(chan))
+			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+			    AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
+	}
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_eeprom_set_board_values(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	boolean_t val;
+
+	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
+		val = ath9k_hw_eeprom_set_def_board_values(ah, chan);
+	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+		val = ath9k_hw_eeprom_set_4k_board_values(ah, chan);
+
+	return (val);
+}
+
+static int
+ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    uint8_t index, uint16_t *config)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+	struct modal_eep_header *pModal =
+	    &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+	struct base_eep_header *pBase = &eep->baseEepHeader;
+
+	switch (index) {
+	case 0:
+		*config = pModal->antCtrlCommon & 0xFFFF;
+		return (0);
+	case 1:
+		if (pBase->version >= 0x0E0D) {
+			if (pModal->useAnt1) {
+				*config =
+				    ((pModal->antCtrlCommon & 0xFFFF0000)
+				    >> 16);
+				return (0);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+
+	return (-EINVAL);
+}
+
+/* ARGSUSED */
+static int
+ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    uint8_t index, uint16_t *config)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &eep->modalHeader;
+
+	switch (index) {
+	case 0:
+		*config = pModal->antCtrlCommon & 0xFFFF;
+		return (0);
+	default:
+		break;
+	}
+
+	return (EINVAL);
+}
+
+int
+ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    uint8_t index, uint16_t *config)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int val;
+
+	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
+		val = ath9k_hw_get_def_eeprom_antenna_cfg(ah, chan,
+		    index, config);
+	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+		val = ath9k_hw_get_4k_eeprom_antenna_cfg(ah, chan,
+		    index, config);
+
+	return (val);
+}
+
+/* ARGSUSED */
+static uint8_t
+ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah,
+    enum ath9k_band freq_band)
+{
+	return (1);
+}
+
+static uint8_t
+ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
+    enum ath9k_band freq_band)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+
+	struct modal_eep_header *pModal =
+	    &(eep->modalHeader[ATH9K_BAND_5GHZ == freq_band]);
+	struct base_eep_header *pBase = &eep->baseEepHeader;
+	uint8_t num_ant_config;
+
+	num_ant_config = 1;
+
+	if (pBase->version >= 0x0E0D)
+		if (pModal->useAnt1)
+			num_ant_config += 1;
+
+	return (num_ant_config);
+}
+
+uint8_t
+ath9k_hw_get_num_ant_config(struct ath_hal *ah,
+    enum ath9k_band freq_band)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint8_t val;
+
+	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
+		val = ath9k_hw_get_def_num_ant_config(ah, freq_band);
+	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+		val = ath9k_hw_get_4k_num_ant_config(ah, freq_band);
+
+	return (val);
+}
+
+uint16_t
+ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, uint16_t i, boolean_t is2GHz)
+{
+#define	EEP_MAP4K_SPURCHAN \
+	(ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
+#define	EEP_DEF_SPURCHAN \
+	(ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint16_t spur_val = AR_NO_SPUR;
+
+	ARN_DBG((ARN_DBG_ANI, "arn: "
+	    "Getting spur idx %d is2Ghz. %d val %x\n",
+	    i, is2GHz, ah->ah_config.spurchans[i][is2GHz]));
+
+	switch (ah->ah_config.spurmode) {
+	case SPUR_DISABLE:
+		break;
+	case SPUR_ENABLE_IOCTL:
+		spur_val = ah->ah_config.spurchans[i][is2GHz];
+		ARN_DBG((ARN_DBG_ANI, "arn: "
+		    "Getting spur val from new loc. %d\n", spur_val));
+		break;
+	case SPUR_ENABLE_EEPROM:
+		if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+			spur_val = EEP_MAP4K_SPURCHAN;
+		else
+			spur_val = EEP_DEF_SPURCHAN;
+		break;
+
+	}
+
+	return (spur_val);
+#undef EEP_DEF_SPURCHAN
+#undef EEP_MAP4K_SPURCHAN
+}
+
+static uint32_t
+ath9k_hw_get_eeprom_4k(struct ath_hal *ah,
+    enum eeprom_param param)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &eep->modalHeader;
+	struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+
+	switch (param) {
+	case EEP_NFTHRESH_2:
+		return (pModal[1].noiseFloorThreshCh[0]);
+	case AR_EEPROM_MAC(0):
+		return (pBase->macAddr[0] << 8 | pBase->macAddr[1]);
+	case AR_EEPROM_MAC(1):
+		return (pBase->macAddr[2] << 8 | pBase->macAddr[3]);
+	case AR_EEPROM_MAC(2):
+		return (pBase->macAddr[4] << 8 | pBase->macAddr[5]);
+	case EEP_REG_0:
+		return (pBase->regDmn[0]);
+	case EEP_REG_1:
+		return (pBase->regDmn[1]);
+	case EEP_OP_CAP:
+		return (pBase->deviceCap);
+	case EEP_OP_MODE:
+		return (pBase->opCapFlags);
+	case EEP_RF_SILENT:
+		return (pBase->rfSilent);
+	case EEP_OB_2:
+		return (pModal->ob_01);
+	case EEP_DB_2:
+		return (pModal->db1_01);
+	case EEP_MINOR_REV:
+		return (pBase->version & AR5416_EEP_VER_MINOR_MASK);
+	case EEP_TX_MASK:
+		return (pBase->txMask);
+	case EEP_RX_MASK:
+		return (pBase->rxMask);
+	default:
+		return (0);
+	}
+}
+
+uint32_t
+ath9k_hw_get_eeprom_def(struct ath_hal *ah, enum eeprom_param param)
+{
+	struct ath_hal_5416 	*ahp = AH5416(ah);
+	struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+	struct modal_eep_header *pModal = eep->modalHeader;
+	struct base_eep_header 	*pBase = &eep->baseEepHeader;
+
+	switch (param) {
+	case EEP_NFTHRESH_5:
+		return (pModal[0].noiseFloorThreshCh[0]);
+	case EEP_NFTHRESH_2:
+		return (pModal[1].noiseFloorThreshCh[0]);
+	case AR_EEPROM_MAC(0):
+		return (pBase->macAddr[0] << 8 | pBase->macAddr[1]);
+	case AR_EEPROM_MAC(1):
+		return (pBase->macAddr[2] << 8 | pBase->macAddr[3]);
+	case AR_EEPROM_MAC(2):
+		return (pBase->macAddr[4] << 8 | pBase->macAddr[5]);
+	case EEP_REG_0:
+		return (pBase->regDmn[0]);
+	case EEP_REG_1:
+		return (pBase->regDmn[1]);
+	case EEP_OP_CAP:
+		return (pBase->deviceCap);
+	case EEP_OP_MODE:
+		return (pBase->opCapFlags);
+	case EEP_RF_SILENT:
+		return (pBase->rfSilent);
+	case EEP_OB_5:
+		return (pModal[0].ob);
+	case EEP_DB_5:
+		return (pModal[0].db);
+	case EEP_OB_2:
+		return (pModal[1].ob);
+	case EEP_DB_2:
+		return (pModal[1].db);
+	case EEP_MINOR_REV:
+		return (pBase->version & AR5416_EEP_VER_MINOR_MASK);
+	case EEP_TX_MASK:
+		return (pBase->txMask);
+	case EEP_RX_MASK:
+		return (pBase->rxMask);
+	case EEP_RXGAIN_TYPE:
+		return (pBase->rxGainType);
+	case EEP_TXGAIN_TYPE:
+		return (pBase->txGainType);
+
+	default:
+		return (0);
+	}
+}
+
+uint32_t
+ath9k_hw_get_eeprom(struct ath_hal *ah, enum eeprom_param param)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t val;
+
+	if (ahp->ah_eep_map == EEP_MAP_DEFAULT)
+		val = ath9k_hw_get_eeprom_def(ah, param);
+	else if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+		val = ath9k_hw_get_eeprom_4k(ah, param);
+
+	return (val);
+}
+
+int
+ath9k_hw_eeprom_attach(struct ath_hal *ah)
+{
+	int status;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (ath9k_hw_use_flash(ah))
+		(void) ath9k_hw_flash_map(ah);
+
+	if (AR_SREV_9285(ah))
+		ahp->ah_eep_map = EEP_MAP_4KBITS;
+	else
+		ahp->ah_eep_map = EEP_MAP_DEFAULT;
+
+	if (!ath9k_hw_fill_eeprom(ah))
+		return (EIO);
+
+	status = ath9k_hw_check_eeprom(ah);
+
+	return (status);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_hw.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,4149 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/cmn_err.h>
+#include <sys/kmem.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/varargs.h>
+
+#include "arn_ath9k.h"
+#include "arn_core.h"
+#include "arn_hw.h"
+#include "arn_reg.h"
+#include "arn_phy.h"
+#include "arn_initvals.h"
+
+static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
+
+extern struct hal_percal_data iq_cal_multi_sample;
+extern struct hal_percal_data iq_cal_single_sample;
+extern struct hal_percal_data adc_gain_cal_multi_sample;
+extern struct hal_percal_data adc_gain_cal_single_sample;
+extern struct hal_percal_data adc_dc_cal_multi_sample;
+extern struct hal_percal_data adc_dc_cal_single_sample;
+extern struct hal_percal_data adc_init_dc_cal;
+
+static boolean_t ath9k_hw_set_reset_reg(struct ath_hal *ah, uint32_t type);
+static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+    enum ath9k_ht_macmode macmode);
+static uint32_t ath9k_hw_ini_fixup(struct ath_hal *ah,
+    struct ar5416_eeprom_def *pEepData,
+    uint32_t reg, uint32_t value);
+static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+
+/* Helper Functions */
+
+static uint32_t
+ath9k_hw_mac_usec(struct ath_hal *ah, uint32_t clks)
+{
+	if (ah->ah_curchan != NULL)
+		return (clks /
+		    CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)]);
+	else
+		return (clks / CLOCK_RATE[ATH9K_MODE_11B]);
+}
+
+static uint32_t
+ath9k_hw_mac_to_usec(struct ath_hal *ah, uint32_t clks)
+{
+	struct ath9k_channel *chan = ah->ah_curchan;
+
+	if (chan && IS_CHAN_HT40(chan))
+		return (ath9k_hw_mac_usec(ah, clks) / 2);
+	else
+		return (ath9k_hw_mac_usec(ah, clks));
+}
+
+static uint32_t
+ath9k_hw_mac_clks(struct ath_hal *ah, uint32_t usecs)
+{
+	if (ah->ah_curchan != NULL)
+		return (usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
+		    ah->ah_curchan)]);
+	else
+		return (usecs * CLOCK_RATE[ATH9K_MODE_11B]);
+}
+
+static uint32_t
+ath9k_hw_mac_to_clks(struct ath_hal *ah, uint32_t usecs)
+{
+	struct ath9k_channel *chan = ah->ah_curchan;
+
+	if (chan && IS_CHAN_HT40(chan))
+		return (ath9k_hw_mac_clks(ah, usecs) * 2);
+	else
+		return (ath9k_hw_mac_clks(ah, usecs));
+}
+
+/* ARGSUSED */
+enum wireless_mode
+ath9k_hw_chan2wmode(struct ath_hal *ah, const struct ath9k_channel *chan)
+{
+	if (IS_CHAN_B(chan))
+		return (ATH9K_MODE_11B);
+	if (IS_CHAN_G(chan))
+		return (ATH9K_MODE_11G);
+
+	return (ATH9K_MODE_11A);
+}
+
+boolean_t
+ath9k_hw_wait(struct ath_hal *ah, uint32_t reg, uint32_t mask, uint32_t val)
+{
+	int i;
+
+	for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
+		if ((REG_READ(ah, reg) & mask) == val)
+			return (B_TRUE);
+
+		drv_usecwait(AH_TIME_QUANTUM);
+	}
+	ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_wait(): "
+	    "timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+	    reg, REG_READ(ah, reg), mask, val));
+
+	return (B_FALSE);
+}
+
+uint32_t
+ath9k_hw_reverse_bits(uint32_t val, uint32_t n)
+{
+	uint32_t retval;
+	int i;
+
+	for (i = 0, retval = 0; i < n; i++) {
+		retval = (retval << 1) | (val & 1);
+		val >>= 1;
+	}
+	return (retval);
+}
+
+boolean_t
+ath9k_get_channel_edges(struct ath_hal *ah,
+    uint16_t flags, uint16_t *low, uint16_t *high)
+{
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+
+	if (flags & CHANNEL_5GHZ) {
+		*low = pCap->low_5ghz_chan;
+		*high = pCap->high_5ghz_chan;
+		return (B_TRUE);
+	}
+	if ((flags & CHANNEL_2GHZ)) {
+		*low = pCap->low_2ghz_chan;
+		*high = pCap->high_2ghz_chan;
+		return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+uint16_t
+ath9k_hw_computetxtime(struct ath_hal *ah,
+    struct ath_rate_table *rates,
+    uint32_t frameLen, uint16_t rateix,
+    boolean_t shortPreamble)
+{
+	uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
+	uint32_t kbps;
+
+	kbps = rates->info[rateix].ratekbps;
+
+	if (kbps == 0)
+		return (0);
+
+	switch (rates->info[rateix].phy) {
+	case WLAN_RC_PHY_CCK:
+		phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
+		if (shortPreamble && rates->info[rateix].short_preamble)
+			phyTime >>= 1;
+		numBits = frameLen << 3;
+		txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
+		break;
+	case WLAN_RC_PHY_OFDM:
+		if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
+			bitsPerSymbol =
+			    (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
+			numBits = OFDM_PLCP_BITS + (frameLen << 3);
+			numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+			txTime = OFDM_SIFS_TIME_QUARTER +
+			    OFDM_PREAMBLE_TIME_QUARTER +
+			    (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
+		} else if (ah->ah_curchan &&
+		    IS_CHAN_HALF_RATE(ah->ah_curchan)) {
+			bitsPerSymbol =	(kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
+			numBits = OFDM_PLCP_BITS + (frameLen << 3);
+			numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+			txTime = OFDM_SIFS_TIME_HALF +
+			    OFDM_PREAMBLE_TIME_HALF +
+			    (numSymbols * OFDM_SYMBOL_TIME_HALF);
+		} else {
+			bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
+			numBits = OFDM_PLCP_BITS + (frameLen << 3);
+			numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+			txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME +
+			    (numSymbols * OFDM_SYMBOL_TIME);
+		}
+		break;
+	default:
+		arn_problem("arn: "
+		    "%s: unknown phy %u (rate ix %u)\n", __func__,
+		    rates->info[rateix].phy, rateix);
+		txTime = 0;
+		break;
+	}
+
+	return ((uint16_t)txTime);
+}
+
+uint32_t
+ath9k_hw_mhz2ieee(struct ath_hal *ah, uint32_t freq, uint32_t flags)
+{
+	if (flags & CHANNEL_2GHZ) {
+		if (freq == 2484)
+			return (14);
+		if (freq < 2484)
+			return ((freq - 2407) / 5);
+		else
+			return (15 + ((freq - 2512) / 20));
+	} else if (flags & CHANNEL_5GHZ) {
+		if (ath9k_regd_is_public_safety_sku(ah) &&
+		    IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
+			return (((freq * 10) +
+			    (((freq % 5) == 2) ? 5 : 0) - 49400) / 5);
+		} else if ((flags & CHANNEL_A) && (freq <= 5000)) {
+			return ((freq - 4000) / 5);
+		} else {
+			return ((freq - 5000) / 5);
+		}
+	} else {
+		if (freq == 2484)
+			return (14);
+		if (freq < 2484)
+			return ((freq - 2407) / 5);
+		if (freq < 5000) {
+			if (ath9k_regd_is_public_safety_sku(ah) &&
+			    IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
+				return (((freq * 10) +
+				    (((freq % 5) ==
+				    2) ? 5 : 0) - 49400) / 5);
+			} else if (freq > 4900) {
+				return ((freq - 4000) / 5);
+			} else {
+				return (15 + ((freq - 2512) / 20));
+			}
+		}
+		return ((freq - 5000) / 5);
+	}
+}
+
+void
+ath9k_hw_get_channel_centers(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    struct chan_centers *centers)
+{
+	int8_t extoff;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (!IS_CHAN_HT40(chan)) {
+		centers->ctl_center = centers->ext_center =
+		    centers->synth_center = chan->channel;
+		return;
+	}
+
+	if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+	    (chan->chanmode == CHANNEL_G_HT40PLUS)) {
+		centers->synth_center =
+		    chan->channel + HT40_CHANNEL_CENTER_SHIFT;
+		extoff = 1;
+	} else {
+		centers->synth_center =
+		    chan->channel - HT40_CHANNEL_CENTER_SHIFT;
+		extoff = -1;
+	}
+
+	centers->ctl_center =
+	    centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
+	centers->ext_center =
+	    centers->synth_center + (extoff *
+	    ((ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
+	    HT40_CHANNEL_CENTER_SHIFT : 15));
+
+}
+
+/* Chip Revisions */
+
+static void
+ath9k_hw_read_revisions(struct ath_hal *ah)
+{
+	uint32_t val;
+
+	val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
+
+	if (val == 0xFF) {
+		val = REG_READ(ah, AR_SREV);
+		ah->ah_macVersion = (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
+		ah->ah_macRev = MS(val, AR_SREV_REVISION2);
+		ah->ah_isPciExpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+	} else {
+		if (!AR_SREV_9100(ah))
+			ah->ah_macVersion = MS(val, AR_SREV_VERSION);
+
+		ah->ah_macRev = val & AR_SREV_REVISION;
+
+		if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
+			ah->ah_isPciExpress = B_TRUE;
+	}
+}
+
+static int
+ath9k_hw_get_radiorev(struct ath_hal *ah)
+{
+	uint32_t val;
+	int i;
+
+	REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
+
+	for (i = 0; i < 8; i++)
+		REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
+	val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
+	val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
+
+	return (ath9k_hw_reverse_bits(val, 8));
+}
+
+/* HW Attach, Detach, Init Routines */
+
+static void
+ath9k_hw_disablepcie(struct ath_hal *ah)
+{
+	if (!AR_SREV_9100(ah))
+		return;
+
+	REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+	REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+	REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
+	REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
+	REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
+	REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
+	REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+	REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+	REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
+
+	REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+}
+
+static boolean_t
+ath9k_hw_chip_test(struct ath_hal *ah)
+{
+	uint32_t regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
+	uint32_t regHold[2];
+	uint32_t patternData[4] = { 0x55555555, 0xaaaaaaaa,
+	    0x66666666, 0x99999999 };
+	int i, j;
+
+	for (i = 0; i < 2; i++) {
+		uint32_t addr = regAddr[i];
+		uint32_t wrData, rdData;
+
+		regHold[i] = REG_READ(ah, addr);
+		for (j = 0; j < 0x100; j++) {
+			wrData = (j << 16) | j;
+			REG_WRITE(ah, addr, wrData);
+			rdData = REG_READ(ah, addr);
+			if (rdData != wrData) {
+				ARN_DBG((ARN_DBG_REG_IO,
+				    "arn: ath9k_hw_chip_test(): "
+				    "address test failed "
+				    "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+				    addr, wrData, rdData));
+
+				return (B_FALSE);
+			}
+		}
+		for (j = 0; j < 4; j++) {
+			wrData = patternData[j];
+			REG_WRITE(ah, addr, wrData);
+			rdData = REG_READ(ah, addr);
+			if (wrData != rdData) {
+				ARN_DBG((ARN_DBG_REG_IO,
+				    "arn: ath9k_hw_chip_test(): "
+				    "address test failed "
+				    "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+				    addr, wrData, rdData));
+
+				return (B_FALSE);
+			}
+		}
+		REG_WRITE(ah, regAddr[i], regHold[i]);
+	}
+	drv_usecwait(100);
+
+	return (B_TRUE);
+}
+
+static const char *
+ath9k_hw_devname(uint16_t devid)
+{
+	switch (devid) {
+	case AR5416_DEVID_PCI:
+		return ("Atheros 5416");
+	case AR5416_DEVID_PCIE:
+		return ("Atheros 5418");
+	case AR9160_DEVID_PCI:
+		return ("Atheros 9160");
+	case AR9280_DEVID_PCI:
+	case AR9280_DEVID_PCIE:
+		return ("Atheros 9280");
+	case AR9285_DEVID_PCIE:
+		return ("Atheros 9285");
+	}
+
+	return (NULL);
+}
+
+static void
+ath9k_hw_set_defaults(struct ath_hal *ah)
+{
+	int i;
+
+	ah->ah_config.dma_beacon_response_time = 2;
+	ah->ah_config.sw_beacon_response_time = 10;
+	ah->ah_config.additional_swba_backoff = 0;
+	ah->ah_config.ack_6mb = 0x0;
+	ah->ah_config.cwm_ignore_extcca = 0;
+	ah->ah_config.pcie_powersave_enable = 0;
+	ah->ah_config.pcie_l1skp_enable = 0;
+	ah->ah_config.pcie_clock_req = 0;
+	ah->ah_config.pcie_power_reset = 0x100;
+	ah->ah_config.pcie_restore = 0;
+	ah->ah_config.pcie_waen = 0;
+	ah->ah_config.analog_shiftreg = 1;
+	ah->ah_config.ht_enable = 1;
+	ah->ah_config.ofdm_trig_low = 200;
+	ah->ah_config.ofdm_trig_high = 500;
+	ah->ah_config.cck_trig_high = 200;
+	ah->ah_config.cck_trig_low = 100;
+	ah->ah_config.enable_ani = 1;
+	ah->ah_config.noise_immunity_level = 4;
+	ah->ah_config.ofdm_weaksignal_det = 1;
+	ah->ah_config.cck_weaksignal_thr = 0;
+	ah->ah_config.spur_immunity_level = 2;
+	ah->ah_config.firstep_level = 0;
+	ah->ah_config.rssi_thr_high = 40;
+	ah->ah_config.rssi_thr_low = 7;
+	ah->ah_config.diversity_control = 0;
+	ah->ah_config.antenna_switch_swap = 0;
+
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+		ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
+		ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
+	}
+
+	ah->ah_config.intr_mitigation = 1;
+
+	/*
+	 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
+	 * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
+	 * This means we use it for all AR5416 devices, and the few
+	 * minor PCI AR9280 devices out there.
+	 *
+	 * Serialization is required because these devices do not handle
+	 * well the case of two concurrent reads/writes due to the latency
+	 * involved. During one read/write another read/write can be issued
+	 * on another CPU while the previous read/write may still be working
+	 * on our hardware, if we hit this case the hardware poops in a loop.
+	 * We prevent this by serializing reads and writes.
+	 *
+	 * This issue is not present on PCI-Express devices or pre-AR5416
+	 * devices (legacy, 802.11abg).
+	 */
+
+	/* num_of_cpus */
+}
+
+static struct ath_hal_5416 *
+ath9k_hw_newstate(uint16_t device_id, struct arn_softc *sc, caddr_t mem,
+    int *status)
+{
+	static const uint8_t defbssidmask[IEEE80211_ADDR_LEN] =
+	    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	struct ath_hal_5416 *ahp;
+	struct ath_hal *ah;
+
+	ahp = (struct ath_hal_5416 *)
+	    kmem_zalloc(sizeof (struct ath_hal_5416), KM_SLEEP);
+	if (ahp == NULL) {
+		ARN_DBG((ARN_DBG_ANY, "arn: ath9k_hw_newstate(): "
+		    "failed to alloc mem for ahp\n"));
+		*status = ENOMEM;
+		return (NULL);
+	}
+
+	ah = &ahp->ah;
+	ah->ah_sc = sc;
+	ah->ah_sh = mem;
+	ah->ah_magic = AR5416_MAGIC;
+	ah->ah_countryCode = CTRY_DEFAULT;
+	ah->ah_devid = device_id;
+	ah->ah_subvendorid = 0;
+
+	ah->ah_flags = 0;
+	if ((device_id == AR5416_AR9100_DEVID))
+		ah->ah_macVersion = AR_SREV_VERSION_9100;
+	if (!AR_SREV_9100(ah))
+		ah->ah_flags = AH_USE_EEPROM;
+
+	ah->ah_powerLimit = MAX_RATE_POWER;
+	ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
+	ahp->ah_atimWindow = 0;
+	ahp->ah_diversityControl = ah->ah_config.diversity_control;
+	ahp->ah_antennaSwitchSwap =
+	    ah->ah_config.antenna_switch_swap;
+	ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
+	ahp->ah_beaconInterval = 100;
+	ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
+	ahp->ah_slottime = (uint32_t)-1;
+	ahp->ah_acktimeout = (uint32_t)-1;
+	ahp->ah_ctstimeout = (uint32_t)-1;
+	ahp->ah_globaltxtimeout = (uint32_t)-1;
+	(void) memcpy(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN);
+
+	ahp->ah_gBeaconRate = 0;
+
+	return (ahp);
+}
+
+static int
+ath9k_hw_rfattach(struct ath_hal *ah)
+{
+	boolean_t  rfStatus = B_FALSE;
+	int ecode = 0;
+
+	rfStatus = ath9k_hw_init_rf(ah, &ecode);
+	if (!rfStatus) {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_rfattach(): "
+		    "RF setup failed, status %u\n", ecode));
+
+		return (ecode);
+	}
+
+	return (0);
+}
+
+static int
+ath9k_hw_rf_claim(struct ath_hal *ah)
+{
+	uint32_t val;
+
+	REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+	val = ath9k_hw_get_radiorev(ah);
+	switch (val & AR_RADIO_SREV_MAJOR) {
+	case 0:
+		val = AR_RAD5133_SREV_MAJOR;
+		break;
+	case AR_RAD5133_SREV_MAJOR:
+	case AR_RAD5122_SREV_MAJOR:
+	case AR_RAD2133_SREV_MAJOR:
+	case AR_RAD2122_SREV_MAJOR:
+		break;
+	default:
+		ARN_DBG((ARN_DBG_CHANNEL,
+		    "arn: ath9k_hw_rf_claim(): "
+		    "5G Radio Chip Rev 0x%02X "
+		    "is not supported by this driver\n",
+		    ah->ah_analog5GhzRev));
+
+		return (ENOTSUP);
+	}
+
+	ah->ah_analog5GhzRev = (uint16_t)val;
+
+	return (0);
+}
+
+static int
+ath9k_hw_init_macaddr(struct ath_hal *ah)
+{
+	uint32_t sum;
+	int i;
+	uint16_t eeval;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	sum = 0;
+	for (i = 0; i < 3; i++) {
+		eeval = ath9k_hw_get_eeprom(ah, AR_EEPROM_MAC(i));
+		sum += eeval;
+		ahp->ah_macaddr[2 * i] = eeval >> 8;
+		ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
+	}
+	if (sum == 0 || sum == 0xffff * 3) {
+		ARN_DBG((ARN_DBG_EEPROM, "arn: ath9k_hw_init_macaddr(): "
+		    "mac address read failed: %pM\n",
+		    ahp->ah_macaddr));
+
+		return (EADDRNOTAVAIL);
+	}
+
+	return (0);
+}
+
+static void
+ath9k_hw_init_rxgain_ini(struct ath_hal *ah)
+{
+	uint32_t rxgain_type;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
+		rxgain_type = ath9k_hw_get_eeprom(ah, EEP_RXGAIN_TYPE);
+		if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) {
+			INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+			    ar9280Modes_backoff_13db_rxgain_9280_2,
+			    ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2),
+			    6);
+		} else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) {
+			INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+			    ar9280Modes_backoff_23db_rxgain_9280_2,
+			    ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2),
+			    6);
+			} else {
+			INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+			    ar9280Modes_original_rxgain_9280_2,
+			    ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+		}
+	} else {
+		INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+		    ar9280Modes_original_rxgain_9280_2,
+		    ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+	}
+}
+
+static void
+ath9k_hw_init_txgain_ini(struct ath_hal *ah)
+{
+	uint32_t txgain_type;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
+		txgain_type = ath9k_hw_get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
+			INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+			    ar9280Modes_high_power_tx_gain_9280_2,
+			    ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2),
+			    6);
+			} else {
+			INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+			    ar9280Modes_original_tx_gain_9280_2,
+			    ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+		}
+	} else {
+		INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+		    ar9280Modes_original_tx_gain_9280_2,
+		    ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+	}
+}
+
+static int
+ath9k_hw_post_attach(struct ath_hal *ah)
+{
+	int ecode;
+
+	if (!ath9k_hw_chip_test(ah)) {
+		ARN_DBG((ARN_DBG_REG_IO, "arn: ath9k_hw_post_attach(): "
+		    "hardware self-test failed\n"));
+
+	}
+
+	ecode = ath9k_hw_rf_claim(ah);
+	if (ecode != 0)
+		return (ecode);
+
+	ecode = ath9k_hw_eeprom_attach(ah);
+	if (ecode != 0)
+		return (ecode);
+	ecode = ath9k_hw_rfattach(ah);
+	if (ecode != 0)
+		return (ecode);
+
+	if (!AR_SREV_9100(ah)) {
+		ath9k_hw_ani_setup(ah);
+		ath9k_hw_ani_attach(ah);
+	}
+
+	return (0);
+}
+
+static struct ath_hal *
+ath9k_hw_do_attach(uint16_t device_id, struct arn_softc *sc,
+    caddr_t mem, int *status)
+{
+	struct ath_hal_5416 *ahp;
+	struct ath_hal *ah;
+	int ecode;
+	uint32_t i;
+	uint32_t j;
+
+	ahp = ath9k_hw_newstate(device_id, sc, mem, status);
+	if (ahp == NULL)
+		return (NULL);
+
+	ah = &ahp->ah;
+
+	ath9k_hw_set_defaults(ah);
+
+	if (ah->ah_config.intr_mitigation != 0)
+		ahp->ah_intrMitigation = B_TRUE;
+
+	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_set_reset_reg(): "
+		    "couldn't reset chip \n"));
+		ecode = EIO;
+		goto bad;
+	}
+
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_setpower(): "
+		    "couldn't wakeup chip \n"));
+		ecode = EIO;
+		goto bad;
+	}
+
+	if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
+		if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI ||
+		    (AR_SREV_9280(ah) && !ah->ah_isPciExpress)) {
+			ah->ah_config.serialize_regmode =
+			    SER_REG_MODE_ON;
+		} else {
+			ah->ah_config.serialize_regmode =
+			    SER_REG_MODE_OFF;
+		}
+	}
+	ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_do_attach(): "
+	    "serialize_regmode is %d\n",
+	    ah->ah_config.serialize_regmode));
+
+	if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
+	    (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
+	    (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
+	    (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) &&
+	    (!AR_SREV_9285(ah))) {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_do_attach(): "
+		    "Mac Chip Rev 0x%02x.%x is not supported by this driver\n",
+		    ah->ah_macVersion, ah->ah_macRev));
+		ecode = ENOTSUP;
+		goto bad;
+	}
+
+	if (AR_SREV_9100(ah)) {
+		ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
+		ahp->ah_suppCals = IQ_MISMATCH_CAL;
+		ah->ah_isPciExpress = B_FALSE;
+	}
+	ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
+
+	if (AR_SREV_9160_10_OR_LATER(ah)) {
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			ahp->ah_iqCalData.calData = &iq_cal_single_sample;
+			ahp->ah_adcGainCalData.calData =
+			    &adc_gain_cal_single_sample;
+			ahp->ah_adcDcCalData.calData =
+			    &adc_dc_cal_single_sample;
+			ahp->ah_adcDcCalInitData.calData =
+			    &adc_init_dc_cal;
+		} else {
+			ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
+			ahp->ah_adcGainCalData.calData =
+			    &adc_gain_cal_multi_sample;
+			ahp->ah_adcDcCalData.calData =
+			    &adc_dc_cal_multi_sample;
+			ahp->ah_adcDcCalInitData.calData =
+			    &adc_init_dc_cal;
+		}
+		ahp->ah_suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+	}
+
+	if (AR_SREV_9160(ah)) {
+		ah->ah_config.enable_ani = 1;
+		ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
+		    ATH9K_ANI_FIRSTEP_LEVEL);
+	} else {
+		ahp->ah_ani_function = ATH9K_ANI_ALL;
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			ahp->ah_ani_function &=
+			    ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
+		}
+	}
+	ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_do_attach(): "
+	    "This Mac Chip Rev 0x%02x.%x is \n",
+	    ah->ah_macVersion, ah->ah_macRev));
+
+	if (AR_SREV_9285_12_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2,
+		    ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
+
+		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2,
+		    ARRAY_SIZE(ar9285Common_9285_1_2), 2);
+
+		if (ah->ah_config.pcie_clock_req) {
+			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			    ar9285PciePhy_clkreq_off_L1_9285_1_2,
+			    ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2),
+			    2);
+		} else {
+			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			    ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
+			    ARRAY_SIZE
+			    (ar9285PciePhy_clkreq_always_on_L1_9285_1_2), 2);
+		}
+	} else if (AR_SREV_9285_10_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285,
+		    ARRAY_SIZE(ar9285Modes_9285), 6);
+
+		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285,
+		    ARRAY_SIZE(ar9285Common_9285), 2);
+
+		if (ah->ah_config.pcie_clock_req) {
+
+			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			    ar9285PciePhy_clkreq_off_L1_9285,
+			    ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
+		} else {
+			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			    ar9285PciePhy_clkreq_always_on_L1_9285,
+			    ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285),
+			    2);
+		}
+	} else if (AR_SREV_9280_20_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
+		    ARRAY_SIZE(ar9280Modes_9280_2), 6);
+
+		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
+		    ARRAY_SIZE(ar9280Common_9280_2), 2);
+
+		if (ah->ah_config.pcie_clock_req) {
+			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			    ar9280PciePhy_clkreq_off_L1_9280,
+			    ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
+		} else {
+			INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+			    ar9280PciePhy_clkreq_always_on_L1_9280,
+			    ARRAY_SIZE
+			    (ar9280PciePhy_clkreq_always_on_L1_9280), 2);
+		}
+
+		INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
+		    ar9280Modes_fast_clock_9280_2,
+		    ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
+	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
+
+		INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
+		    ARRAY_SIZE(ar9280Modes_9280), 6);
+
+		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
+		    ARRAY_SIZE(ar9280Common_9280), 2);
+	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
+		    ARRAY_SIZE(ar5416Modes_9160), 6);
+
+		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
+		    ARRAY_SIZE(ar5416Common_9160), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
+		    ARRAY_SIZE(ar5416Bank0_9160), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
+		    ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
+		    ARRAY_SIZE(ar5416Bank1_9160), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
+		    ARRAY_SIZE(ar5416Bank2_9160), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
+		    ARRAY_SIZE(ar5416Bank3_9160), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
+		    ARRAY_SIZE(ar5416Bank6_9160), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
+		    ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
+		    ARRAY_SIZE(ar5416Bank7_9160), 2);
+		if (AR_SREV_9160_11(ah)) {
+			INIT_INI_ARRAY(&ahp->ah_iniAddac,
+			    ar5416Addac_91601_1,
+			    ARRAY_SIZE(ar5416Addac_91601_1), 2);
+		} else {
+			INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
+			    ARRAY_SIZE(ar5416Addac_9160), 2);
+		}
+	} else if (AR_SREV_9100_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
+		    ARRAY_SIZE(ar5416Modes_9100), 6);
+
+		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
+		    ARRAY_SIZE(ar5416Common_9100), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
+		    ARRAY_SIZE(ar5416Bank0_9100), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
+		    ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
+		    ARRAY_SIZE(ar5416Bank1_9100), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
+		    ARRAY_SIZE(ar5416Bank2_9100), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
+		    ARRAY_SIZE(ar5416Bank3_9100), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
+		    ARRAY_SIZE(ar5416Bank6_9100), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
+		    ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
+		    ARRAY_SIZE(ar5416Bank7_9100), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
+		    ARRAY_SIZE(ar5416Addac_9100), 2);
+	} else {
+		INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
+		    ARRAY_SIZE(ar5416Modes), 6);
+
+		INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
+		    ARRAY_SIZE(ar5416Common), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
+		    ARRAY_SIZE(ar5416Bank0), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
+		    ARRAY_SIZE(ar5416BB_RfGain), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
+		    ARRAY_SIZE(ar5416Bank1), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
+		    ARRAY_SIZE(ar5416Bank2), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
+		    ARRAY_SIZE(ar5416Bank3), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
+		    ARRAY_SIZE(ar5416Bank6), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
+		    ARRAY_SIZE(ar5416Bank6TPC), 3);
+
+		INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
+		    ARRAY_SIZE(ar5416Bank7), 2);
+
+		INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
+		    ARRAY_SIZE(ar5416Addac), 2);
+	}
+
+	if (ah->ah_isPciExpress)
+		ath9k_hw_configpcipowersave(ah, 0);
+	else
+		ath9k_hw_disablepcie(ah);
+
+	ecode = ath9k_hw_post_attach(ah);
+	if (ecode != 0)
+		goto bad;
+
+	/* rxgain table */
+	if (AR_SREV_9280_20(ah))
+		ath9k_hw_init_rxgain_ini(ah);
+
+	/* txgain table */
+	if (AR_SREV_9280_20(ah))
+		ath9k_hw_init_txgain_ini(ah);
+
+	if (ah->ah_devid == AR9280_DEVID_PCI) {
+		for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
+			uint32_t reg =
+			    INI_RA(&ahp->ah_iniModes, i, 0);
+
+			for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
+				uint32_t val
+				    = INI_RA(&ahp->ah_iniModes, i, j);
+
+				INI_RA(&ahp->ah_iniModes, i, j) =
+				    ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom.def,
+				    reg, val);
+			}
+		}
+	}
+
+	if (!ath9k_hw_fill_cap_info(ah)) {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_do_attach(): "
+		    "failed ath9k_hw_fill_cap_info\n"));
+		goto bad;
+	}
+
+	ecode = ath9k_hw_init_macaddr(ah);
+	if (ecode != 0) {
+		ARN_DBG((ARN_DBG_HW, "arn: "
+		    "%s: failed initializing mac address\n",
+		    __func__));
+		goto bad;
+	}
+
+	if (AR_SREV_9285(ah))
+		ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
+	else
+		ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
+
+	ath9k_init_nfcal_hist_buffer(ah);
+
+	return (ah);
+bad:
+	if (ahp)
+		ath9k_hw_detach((struct ath_hal *)ahp);
+	if (status)
+		*status = ecode;
+
+	return (NULL);
+}
+
+static void
+ath9k_hw_init_bb(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	uint32_t synthDelay;
+
+	synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+	if (IS_CHAN_B(chan))
+		synthDelay = (4 * synthDelay) / 22;
+	else
+		synthDelay /= 10;
+
+	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+
+	drv_usecwait(synthDelay + BASE_ACTIVATE_DELAY);
+}
+
+static void
+ath9k_hw_init_qos(struct ath_hal *ah)
+{
+	REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
+	REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
+
+	REG_WRITE(ah, AR_QOS_NO_ACK,
+	    SM(2, AR_QOS_NO_ACK_TWO_BIT) |
+	    SM(5, AR_QOS_NO_ACK_BIT_OFF) |
+	    SM(0, AR_QOS_NO_ACK_BYTE_OFF));
+
+	REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
+	REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
+	REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
+	REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
+	REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
+}
+
+static void
+ath9k_hw_init_pll(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	uint32_t pll;
+
+	if (AR_SREV_9100(ah)) {
+		if (chan && IS_CHAN_5GHZ(chan))
+			pll = 0x1450;
+		else
+			pll = 0x1458;
+	} else {
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+			if (chan && IS_CHAN_HALF_RATE(chan))
+				pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+			else if (chan && IS_CHAN_QUARTER_RATE(chan))
+				pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+			if (chan && IS_CHAN_5GHZ(chan)) {
+				pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
+
+
+				if (AR_SREV_9280_20(ah)) {
+					if (((chan->channel % 20) == 0) ||
+					    ((chan->channel % 10) == 0))
+						pll = 0x2850;
+					else
+						pll = 0x142c;
+				}
+			} else {
+				pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
+			}
+
+		} else if (AR_SREV_9160_10_OR_LATER(ah)) {
+
+			pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+			if (chan && IS_CHAN_HALF_RATE(chan))
+				pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+			else if (chan && IS_CHAN_QUARTER_RATE(chan))
+				pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+			if (chan && IS_CHAN_5GHZ(chan))
+				pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
+			else
+				pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
+		} else {
+			pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
+
+			if (chan && IS_CHAN_HALF_RATE(chan))
+				pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
+			else if (chan && IS_CHAN_QUARTER_RATE(chan))
+				pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
+
+			if (chan && IS_CHAN_5GHZ(chan))
+				pll |= SM(0xa, AR_RTC_PLL_DIV);
+			else
+				pll |= SM(0xb, AR_RTC_PLL_DIV);
+		}
+	}
+	REG_WRITE(ah, (uint16_t)(AR_RTC_PLL_CONTROL), pll);
+
+	drv_usecwait(RTC_PLL_SETTLE_DELAY);
+
+	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
+}
+
+static void
+ath9k_hw_init_chain_masks(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int rx_chainmask, tx_chainmask;
+
+	rx_chainmask = ahp->ah_rxchainmask;
+	tx_chainmask = ahp->ah_txchainmask;
+
+	switch (rx_chainmask) {
+	case 0x5:
+		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+		    AR_PHY_SWAP_ALT_CHAIN);
+		/*FALLTHRU*/
+	case 0x3:
+		if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
+			REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
+			REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
+			break;
+		}
+		/*FALLTHRU*/
+	case 0x1:
+	case 0x2:
+	case 0x7:
+		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+		break;
+	default:
+		break;
+	}
+
+	REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
+	if (tx_chainmask == 0x5) {
+		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+		    AR_PHY_SWAP_ALT_CHAIN);
+	}
+	if (AR_SREV_9100(ah))
+		REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
+		    REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
+}
+
+static void
+ath9k_hw_init_interrupt_masks(struct ath_hal *ah, enum ath9k_opmode opmode)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	ahp->ah_maskReg = AR_IMR_TXERR |
+	    AR_IMR_TXURN |
+	    AR_IMR_RXERR |
+	    AR_IMR_RXORN |
+	    AR_IMR_BCNMISC;
+
+	if (ahp->ah_intrMitigation)
+		ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+	else
+		ahp->ah_maskReg |= AR_IMR_RXOK;
+
+	ahp->ah_maskReg |= AR_IMR_TXOK;
+
+	if (opmode == ATH9K_M_HOSTAP)
+		ahp->ah_maskReg |= AR_IMR_MIB;
+
+	REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
+	REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
+
+	if (!AR_SREV_9100(ah)) {
+		REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
+		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
+		REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
+	}
+}
+
+static boolean_t
+ath9k_hw_set_ack_timeout(struct ath_hal *ah, uint32_t us)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_set_ack_timeout(): "
+		    "bad ack timeout %u\n", us));
+
+		ahp->ah_acktimeout = (uint32_t)-1;
+		return (B_FALSE);
+	} else {
+		REG_RMW_FIELD(ah, AR_TIME_OUT,
+		    AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
+		ahp->ah_acktimeout = us;
+		return (B_TRUE);
+	}
+}
+
+static boolean_t
+ath9k_hw_set_cts_timeout(struct ath_hal *ah, uint32_t us)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_set_cts_timeout(): "
+		    "bad cts timeout %u\n", us));
+
+		ahp->ah_ctstimeout = (uint32_t)-1;
+		return (B_FALSE);
+	} else {
+		REG_RMW_FIELD(ah, AR_TIME_OUT,
+		    AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
+		ahp->ah_ctstimeout = us;
+		return (B_TRUE);
+	}
+}
+
+static boolean_t
+ath9k_hw_set_global_txtimeout(struct ath_hal *ah, uint32_t tu)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (tu > 0xFFFF) {
+		ARN_DBG((ARN_DBG_XMIT,
+		    "arn: ath9k_hw_set_global_txtimeout(): "
+		    "ath9k_hw_set_global_txtimeout\n", tu));
+
+		ahp->ah_globaltxtimeout = (uint32_t)-1;
+		return (B_FALSE);
+	} else {
+		REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
+		ahp->ah_globaltxtimeout = tu;
+		return (B_TRUE);
+	}
+}
+
+static void
+ath9k_hw_init_user_settings(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	ARN_DBG((ARN_DBG_ANY, "arn: ath9k_hw_init_user_settings(): "
+	    "--AP ahp->ah_miscMode 0x%x\n", ahp->ah_miscMode));
+
+	if (ahp->ah_miscMode != 0)
+		REG_WRITE(ah, AR_PCU_MISC,
+		    REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
+	if (ahp->ah_slottime != (uint32_t)-1)
+		(void) ath9k_hw_setslottime(ah, ahp->ah_slottime);
+	if (ahp->ah_acktimeout != (uint32_t)-1)
+		(void) ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
+	if (ahp->ah_ctstimeout != (uint32_t)-1)
+		(void) ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
+	if (ahp->ah_globaltxtimeout != (uint32_t)-1)
+		(void) ath9k_hw_set_global_txtimeout
+		    (ah, ahp->ah_globaltxtimeout);
+}
+
+const char *
+ath9k_hw_probe(uint16_t vendorid, uint16_t devid)
+{
+	return (vendorid == ATHEROS_VENDOR_ID ?
+	    ath9k_hw_devname(devid) : NULL);
+}
+
+void
+ath9k_hw_detach(struct ath_hal *ah)
+{
+	if (!AR_SREV_9100(ah))
+		ath9k_hw_ani_detach(ah);
+
+	ath9k_hw_rfdetach(ah);
+	(void) ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+	kmem_free(ah, sizeof (struct ath_hal_5416)); /* ???? */
+}
+
+struct ath_hal *
+ath9k_hw_attach(uint16_t device_id, struct arn_softc *sc,
+    caddr_t mem, int *error)
+{
+	struct ath_hal *ah = NULL;
+
+	switch (device_id) {
+	case AR5416_DEVID_PCI:
+	case AR5416_DEVID_PCIE:
+	case AR9160_DEVID_PCI:
+	case AR9280_DEVID_PCI:
+	case AR9280_DEVID_PCIE:
+	case AR9285_DEVID_PCIE:
+		ah = ath9k_hw_do_attach(device_id, sc, mem, error);
+		break;
+	default:
+		*error = ENXIO;
+		break;
+	}
+
+	return (ah);
+}
+
+/* INI */
+
+/* ARGSUSED */
+static void
+ath9k_hw_override_ini(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	/*
+	 * Set the RX_ABORT and RX_DIS and clear if off only after
+	 * RXE is set for MAC. This prevents frames with corrupted
+	 * descriptor status.
+	 */
+	REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+	if (!AR_SREV_5416_V20_OR_LATER(ah) ||
+	    AR_SREV_9280_10_OR_LATER(ah))
+		return;
+
+	REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+}
+
+static uint32_t
+ath9k_hw_def_ini_fixup(struct ath_hal *ah,
+    struct ar5416_eeprom_def *pEepData,
+    uint32_t reg, uint32_t value)
+{
+	struct base_eep_header *pBase = &(pEepData->baseEepHeader);
+
+	switch (ah->ah_devid) {
+	case AR9280_DEVID_PCI:
+		if (reg == 0x7894) {
+			ARN_DBG((ARN_DBG_ANY,
+			    "arn: ath9k_hw_ini_fixup(): "
+			    "ini VAL: %x  EEPROM: %x\n",
+			    value, (pBase->version & 0xff)));
+
+			if ((pBase->version & 0xff) > 0x0a) {
+				ARN_DBG((ARN_DBG_ANY,
+				    "arn: ath9k_hw_ini_fixup(): "
+				    "PWDCLKIND: %d\n",
+				    pBase->pwdclkind));
+
+				value &= ~AR_AN_TOP2_PWDCLKIND;
+				value |= AR_AN_TOP2_PWDCLKIND &
+				    (pBase->pwdclkind <<
+				    AR_AN_TOP2_PWDCLKIND_S);
+			} else {
+				ARN_DBG((ARN_DBG_ANY,
+				    "arn: ath9k_hw_ini_fixup(): "
+				    "PWDCLKIND Earlier Rev\n"));
+			}
+
+			ARN_DBG((ARN_DBG_ANY,
+			    "arn: ath9k_hw_ini_fixup(): "
+			    "final ini VAL: %x\n\n", value));
+		}
+		break;
+	}
+
+	return (value);
+}
+
+static uint32_t
+ath9k_hw_ini_fixup(struct ath_hal *ah, struct ar5416_eeprom_def *pEepData,
+    uint32_t reg, uint32_t value)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+		return (value);
+	else
+		return (ath9k_hw_def_ini_fixup(ah, pEepData, reg, value));
+}
+
+static int
+ath9k_hw_process_ini(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    enum ath9k_ht_macmode macmode)
+{
+	int i, regWrites = 0;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t modesIndex, freqIndex;
+	int status;
+
+	switch (chan->chanmode) {
+	case CHANNEL_A:
+	case CHANNEL_A_HT20:
+		modesIndex = 1;
+		freqIndex = 1;
+		break;
+	case CHANNEL_A_HT40PLUS:
+	case CHANNEL_A_HT40MINUS:
+		modesIndex = 2;
+		freqIndex = 1;
+		break;
+	case CHANNEL_G:
+	case CHANNEL_G_HT20:
+	case CHANNEL_B:
+		modesIndex = 4;
+		freqIndex = 2;
+		break;
+	case CHANNEL_G_HT40PLUS:
+	case CHANNEL_G_HT40MINUS:
+		modesIndex = 3;
+		freqIndex = 2;
+		break;
+
+	default:
+		ARN_DBG((ARN_DBG_CHANNEL, "arn: "
+		    "%s: err: unknow chan->chanmode\n", __func__));
+		return (EINVAL);
+	}
+
+	REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+
+	ath9k_hw_set_addac(ah, chan);
+
+	if (AR_SREV_5416_V22_OR_LATER(ah)) {
+		/* LINTED: E_CONSTANT_CONDITION */
+		REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
+	} else {
+		struct ar5416IniArray temp;
+		uint32_t addacSize =
+		    sizeof (uint32_t) * ahp->ah_iniAddac.ia_rows *
+		    ahp->ah_iniAddac.ia_columns;
+
+		(void) memcpy(ahp->ah_addac5416_21,
+		    ahp->ah_iniAddac.ia_array, addacSize);
+
+		(ahp->ah_addac5416_21)
+		    [31 * ahp->ah_iniAddac.ia_columns + 1] = 0;
+
+		temp.ia_array = ahp->ah_addac5416_21;
+		temp.ia_columns = ahp->ah_iniAddac.ia_columns;
+		temp.ia_rows = ahp->ah_iniAddac.ia_rows;
+		/* LINTED: E_CONSTANT_CONDITION */
+		REG_WRITE_ARRAY(&temp, 1, regWrites);
+	}
+
+	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+
+	for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
+		uint32_t reg = INI_RA(&ahp->ah_iniModes, i, 0);
+		uint32_t val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
+
+		REG_WRITE(ah, reg, val);
+
+		if (reg >= 0x7800 && reg < 0x78a0 &&
+		    ah->ah_config.analog_shiftreg) {
+			drv_usecwait(100);
+		}
+
+		/* LINTED: E_CONSTANT_CONDITION */
+		DO_DELAY(regWrites);
+	}
+
+	if (AR_SREV_9280(ah)) {
+		/* LINTED: E_CONSTANT_CONDITION */
+		REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex,
+		    regWrites);
+	}
+
+	if (AR_SREV_9280(ah)) {
+		/* LINTED: E_CONSTANT_CONDITION */
+		REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex,
+		    regWrites);
+	}
+
+	for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
+		uint32_t reg = INI_RA(&ahp->ah_iniCommon, i, 0);
+		uint32_t val = INI_RA(&ahp->ah_iniCommon, i, 1);
+
+		REG_WRITE(ah, reg, val);
+
+		if (reg >= 0x7800 && reg < 0x78a0 &&
+		    ah->ah_config.analog_shiftreg) {
+			drv_usecwait(100);
+		}
+
+		/* LINTED: E_CONSTANT_CONDITION */
+		DO_DELAY(regWrites);
+	}
+
+	ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
+
+	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
+		/* LINTED: E_CONSTANT_CONDITION */
+		REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
+		    regWrites);
+	}
+
+	ath9k_hw_override_ini(ah, chan);
+	ath9k_hw_set_regs(ah, chan, macmode);
+	ath9k_hw_init_chain_masks(ah);
+
+	status = ath9k_hw_set_txpower(ah, chan,
+	    ath9k_regd_get_ctl(ah, chan),
+	    ath9k_regd_get_antenna_allowed(ah, chan),
+	    chan->maxRegTxPower * 2,
+	    min((uint32_t)MAX_RATE_POWER,
+	    (uint32_t)ah->ah_powerLimit));
+	if (status != 0) {
+		ARN_DBG((ARN_DBG_ANY, "arn: ath9k_hw_process_ini(): "
+		    "%s: error init'ing transmit power\n", __func__));
+
+		return (EIO);
+	}
+
+	if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
+		ARN_DBG((ARN_DBG_ANY, "arn: ath9k_hw_process_ini(): "
+		    "%s: ar5416SetRfRegs failed\n", __func__));
+
+		return (EIO);
+	}
+
+	return (0);
+}
+
+/* Reset and Channel Switching Routines */
+
+static void
+ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	uint32_t rfMode = 0;
+
+	if (chan == NULL)
+		return;
+
+	rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
+	    ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+
+	if (!AR_SREV_9280_10_OR_LATER(ah))
+		rfMode |= (IS_CHAN_5GHZ(chan)) ?
+		    AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
+
+	if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
+		rfMode |= (AR_PHY_MODE_DYNAMIC |
+		    AR_PHY_MODE_DYN_CCK_DISABLE);
+
+	REG_WRITE(ah, AR_PHY_MODE, rfMode);
+}
+
+static void
+ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
+{
+	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+}
+
+static inline void
+ath9k_hw_set_dma(struct ath_hal *ah)
+{
+	uint32_t regval;
+
+	regval = REG_READ(ah, AR_AHB_MODE);
+	REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
+
+	regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
+	REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
+
+	REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
+
+	regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
+	REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
+
+	REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
+
+	if (AR_SREV_9285(ah)) {
+		REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
+		    AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
+	} else {
+		REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
+		    AR_PCU_TXBUF_CTRL_USABLE_SIZE);
+	}
+}
+
+static void
+ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
+{
+	uint32_t val;
+
+	val = REG_READ(ah, AR_STA_ID1);
+	val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
+	switch (opmode) {
+	case ATH9K_M_HOSTAP:
+		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP |
+		    AR_STA_ID1_KSRCH_MODE);
+		REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
+		break;
+	case ATH9K_M_IBSS:
+		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC |
+		    AR_STA_ID1_KSRCH_MODE);
+		REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
+		break;
+	case ATH9K_M_STA:
+	case ATH9K_M_MONITOR:
+		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
+		break;
+	}
+}
+
+/* ARGSUSED */
+static inline void
+ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
+    uint32_t coef_scaled,
+    uint32_t *coef_mantissa,
+    uint32_t *coef_exponent)
+{
+	uint32_t coef_exp, coef_man;
+
+	for (coef_exp = 31; coef_exp > 0; coef_exp--)
+		if ((coef_scaled >> coef_exp) & 0x1)
+			break;
+
+	coef_exp = 14 - (coef_exp - COEF_SCALE_S);
+
+	coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
+
+	*coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
+	*coef_exponent = coef_exp - 16;
+}
+
+static void
+ath9k_hw_set_delta_slope(struct ath_hal *ah,
+    struct ath9k_channel *chan)
+{
+	uint32_t coef_scaled, ds_coef_exp, ds_coef_man;
+	uint32_t clockMhzScaled = 0x64000000;
+	struct chan_centers centers;
+
+	if (IS_CHAN_HALF_RATE(chan))
+		clockMhzScaled = clockMhzScaled >> 1;
+	else if (IS_CHAN_QUARTER_RATE(chan))
+		clockMhzScaled = clockMhzScaled >> 2;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	coef_scaled = clockMhzScaled / centers.synth_center;
+
+	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+	    &ds_coef_exp);
+
+	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+	    AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
+	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+	    AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
+
+	coef_scaled = (9 * coef_scaled) / 10;
+
+	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+	    &ds_coef_exp);
+
+	REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+	    AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
+	REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+	    AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
+}
+
+static boolean_t
+ath9k_hw_set_reset(struct ath_hal *ah, int type)
+{
+	uint32_t rst_flags;
+	uint32_t tmpReg;
+
+	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+	    AR_RTC_FORCE_WAKE_ON_INT);
+
+	if (AR_SREV_9100(ah)) {
+		rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
+		    AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
+	} else {
+		tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+		if (tmpReg &
+		    (AR_INTR_SYNC_LOCAL_TIMEOUT |
+		    AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+			REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+			REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
+		} else {
+			REG_WRITE(ah, AR_RC, AR_RC_AHB);
+		}
+
+		rst_flags = AR_RTC_RC_MAC_WARM;
+		if (type == ATH9K_RESET_COLD)
+			rst_flags |= AR_RTC_RC_MAC_COLD;
+	}
+
+	REG_WRITE(ah, (uint16_t)(AR_RTC_RC), rst_flags);
+	drv_usecwait(50);
+
+	REG_WRITE(ah, (uint16_t)(AR_RTC_RC), 0);
+	if (!ath9k_hw_wait(ah, (uint16_t)(AR_RTC_RC), AR_RTC_RC_M, 0)) {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_set_reset(): "
+		    "RTC stuck in MAC reset\n"));
+
+		return (B_FALSE);
+	}
+
+	if (!AR_SREV_9100(ah))
+		REG_WRITE(ah, AR_RC, 0);
+
+	ath9k_hw_init_pll(ah, NULL);
+
+	if (AR_SREV_9100(ah))
+		drv_usecwait(50);
+
+	return (B_TRUE);
+}
+
+static boolean_t
+ath9k_hw_set_reset_power_on(struct ath_hal *ah)
+{
+	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+	    AR_RTC_FORCE_WAKE_ON_INT);
+
+	REG_WRITE(ah, (uint16_t)(AR_RTC_RESET), 0);
+	REG_WRITE(ah, (uint16_t)(AR_RTC_RESET), 1);
+
+	if (!ath9k_hw_wait(ah,
+	    AR_RTC_STATUS,
+	    AR_RTC_STATUS_M,
+	    AR_RTC_STATUS_ON)) {
+		ARN_DBG((ARN_DBG_HW,
+		    "arn: ath9k_hw_set_reset_power_on(): "
+		    "RTC not waking up \n"));
+
+		return (B_FALSE);
+	}
+
+	ath9k_hw_read_revisions(ah);
+
+	return (ath9k_hw_set_reset(ah, ATH9K_RESET_WARM));
+}
+
+static boolean_t
+ath9k_hw_set_reset_reg(struct ath_hal *ah, uint32_t type)
+{
+	REG_WRITE(ah, AR_RTC_FORCE_WAKE,
+	    AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
+
+	switch (type) {
+	case ATH9K_RESET_POWER_ON:
+		return (ath9k_hw_set_reset_power_on(ah));
+	case ATH9K_RESET_WARM:
+	case ATH9K_RESET_COLD:
+		return (ath9k_hw_set_reset(ah, type));
+	default:
+		return (B_FALSE);
+	}
+}
+
+static void
+ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+    enum ath9k_ht_macmode macmode)
+{
+	uint32_t phymode;
+	uint32_t enableDacFifo = 0;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (AR_SREV_9285_10_OR_LATER(ah))
+		enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
+		    AR_PHY_FC_ENABLE_DAC_FIFO);
+
+	phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 |
+	    AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
+
+	if (IS_CHAN_HT40(chan)) {
+		phymode |= AR_PHY_FC_DYN2040_EN;
+
+		if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+		    (chan->chanmode == CHANNEL_G_HT40PLUS))
+			phymode |= AR_PHY_FC_DYN2040_PRI_CH;
+
+		if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
+			phymode |= AR_PHY_FC_DYN2040_EXT_CH;
+	}
+	REG_WRITE(ah, AR_PHY_TURBO, phymode);
+
+	ath9k_hw_set11nmac2040(ah, macmode);
+
+	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
+	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
+}
+
+static boolean_t
+ath9k_hw_chip_reset(struct ath_hal *ah,
+    struct ath9k_channel *chan)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+		return (B_FALSE);
+
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+		return (B_FALSE);
+
+	ahp->ah_chipFullSleep = B_FALSE;
+
+	ath9k_hw_init_pll(ah, chan);
+
+	ath9k_hw_set_rfmode(ah, chan);
+
+	return (B_TRUE);
+}
+
+static struct ath9k_channel *
+ath9k_hw_check_chan(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
+		ARN_DBG((ARN_DBG_CHANNEL, "arn: "
+		    "%s: invalid channel %u/0x%x; not marked as "
+		    "2GHz or 5GHz\n",
+		    __func__, chan->channel, chan->channelFlags));
+		return (NULL);
+	}
+
+	if (!IS_CHAN_OFDM(chan) &&
+	    !IS_CHAN_B(chan) &&
+	    !IS_CHAN_HT20(chan) &&
+	    !IS_CHAN_HT40(chan)) {
+		ARN_DBG((ARN_DBG_CHANNEL, "arn: "
+		    "%s: invalid channel %u/0x%x; not marked as "
+		    "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
+		    __func__, chan->channel, chan->channelFlags));
+
+		return (NULL);
+	}
+
+	return (ath9k_regd_check_channel(ah, chan));
+}
+
+static boolean_t
+ath9k_hw_channel_change(struct ath_hal *ah,
+    struct ath9k_channel *chan,
+    enum ath9k_ht_macmode macmode)
+{
+	uint32_t synthDelay, qnum;
+
+	for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
+		if (ath9k_hw_numtxpending(ah, qnum)) {
+			ARN_DBG((ARN_DBG_QUEUE, "arn: "
+			    "%s: Transmit frames pending on queue %d\n",
+			    __func__, qnum));
+
+			return (B_FALSE);
+		}
+	}
+
+	REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
+	if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
+	    AR_PHY_RFBUS_GRANT_EN)) {
+		ARN_DBG((ARN_DBG_HW, "arn: "
+		    "%s: Could not kill baseband RX\n", __func__));
+
+		return (B_FALSE);
+	}
+
+	ath9k_hw_set_regs(ah, chan, macmode);
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
+			ARN_DBG((ARN_DBG_CHANNEL, "arn: "
+			    "%s: failed to set channel\n", __func__));
+			return (B_FALSE);
+		}
+	} else {
+		if (!(ath9k_hw_set_channel(ah, chan))) {
+			ARN_DBG((ARN_DBG_CHANNEL, "arn: "
+			    "%s: failed to set channel\n", __func__));
+
+			return (B_FALSE);
+		}
+	}
+
+	if (ath9k_hw_set_txpower(ah, chan,
+	    ath9k_regd_get_ctl(ah, chan),
+	    ath9k_regd_get_antenna_allowed(ah, chan),
+	    chan->maxRegTxPower * 2,
+	    min((uint32_t)MAX_RATE_POWER,
+	    (uint32_t)ah->ah_powerLimit)) != 0) {
+		ARN_DBG((ARN_DBG_EEPROM, "arn: "
+		    "%s: error init'ing transmit power\n", __func__));
+
+		return (B_FALSE);
+	}
+
+	synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+	if (IS_CHAN_B(chan))
+		synthDelay = (4 * synthDelay) / 22;
+	else
+		synthDelay /= 10;
+
+	drv_usecwait(synthDelay + BASE_ACTIVATE_DELAY);
+
+	REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+
+	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+		ath9k_hw_set_delta_slope(ah, chan);
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ath9k_hw_9280_spur_mitigate(ah, chan);
+	else
+		ath9k_hw_spur_mitigate(ah, chan);
+
+	if (!chan->oneTimeCalsDone)
+		chan->oneTimeCalsDone = B_TRUE;
+
+	return (B_TRUE);
+}
+
+static void
+ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	int bb_spur = AR_NO_SPUR;
+	int freq;
+	int bin, cur_bin;
+	int bb_spur_off, spur_subchannel_sd;
+	int spur_freq_sd;
+	int spur_delta_phase;
+	int denominator;
+	int upper, lower, cur_vit_mask;
+	int tmp, newVal;
+	int i;
+	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+	    AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+	};
+	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+	    AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+	};
+	int inc[4] = { 0, 100, 0, 0 };
+	struct chan_centers centers;
+
+	int8_t mask_m[123];
+	int8_t mask_p[123];
+	int8_t mask_amt;
+	int tmp_mask;
+	int cur_bb_spur;
+	boolean_t is2GHz = IS_CHAN_2GHZ(chan);
+
+	(void) memset(&mask_m, 0, sizeof (int8_t) * 123);
+	(void) memset(&mask_p, 0, sizeof (int8_t) * 123);
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+		cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+
+		if (is2GHz)
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
+		else
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
+
+		if (AR_NO_SPUR == cur_bb_spur)
+			break;
+		cur_bb_spur = cur_bb_spur - freq;
+
+		if (IS_CHAN_HT40(chan)) {
+			if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
+			    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
+				bb_spur = cur_bb_spur;
+				break;
+			}
+		} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
+		    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
+			bb_spur = cur_bb_spur;
+			break;
+		}
+	}
+
+	if (AR_NO_SPUR == bb_spur) {
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+		    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+		return;
+	} else {
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+		    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+	}
+
+	bin = bb_spur * 320;
+
+	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+
+	newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+	    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+	    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+	    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
+
+	newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+	    AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+	    AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+	    AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+	    SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+	REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
+
+	if (IS_CHAN_HT40(chan)) {
+		if (bb_spur < 0) {
+			spur_subchannel_sd = 1;
+			bb_spur_off = bb_spur + 10;
+		} else {
+			spur_subchannel_sd = 0;
+			bb_spur_off = bb_spur - 10;
+		}
+	} else {
+		spur_subchannel_sd = 0;
+		bb_spur_off = bb_spur;
+	}
+
+	if (IS_CHAN_HT40(chan))
+		spur_delta_phase =
+		    ((bb_spur * 262144) / 10) &
+		    AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+	else
+		spur_delta_phase =
+		    ((bb_spur * 524288) / 10) &
+		    AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+	denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
+	spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
+
+	newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+	    SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+	    SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+	REG_WRITE(ah, AR_PHY_TIMING11, newVal);
+
+	newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
+	REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
+
+	cur_bin = -6000;
+	upper = bin + 100;
+	lower = bin - 100;
+
+	for (i = 0; i < 4; i++) {
+		int pilot_mask = 0;
+		int chan_mask = 0;
+		int bp = 0;
+		for (bp = 0; bp < 30; bp++) {
+			if ((cur_bin > lower) && (cur_bin < upper)) {
+				pilot_mask = pilot_mask | 0x1 << bp;
+				chan_mask = chan_mask | 0x1 << bp;
+			}
+			cur_bin += 100;
+		}
+		cur_bin += inc[i];
+		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+	}
+
+	cur_vit_mask = 6100;
+	upper = bin + 120;
+	lower = bin - 120;
+
+	for (i = 0; i < 123; i++) {
+		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+			/* workaround for gcc bug #37014 */
+			volatile int tmp = abs(cur_vit_mask - bin);
+
+			if (tmp < 75)
+				mask_amt = 1;
+			else
+				mask_amt = 0;
+			if (cur_vit_mask < 0)
+				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+			else
+				mask_p[cur_vit_mask / 100] = mask_amt;
+		}
+		cur_vit_mask -= 100;
+	}
+
+	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) |
+	    (mask_m[48] << 26) | (mask_m[49] << 24) |
+	    (mask_m[50] << 22) | (mask_m[51] << 20) |
+	    (mask_m[52] << 18) | (mask_m[53] << 16) |
+	    (mask_m[54] << 14) | (mask_m[55] << 12) |
+	    (mask_m[56] << 10) | (mask_m[57] << 8) |
+	    (mask_m[58] << 6) | (mask_m[59] << 4) |
+	    (mask_m[60] << 2) | (mask_m[61] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+	tmp_mask = (mask_m[31] << 28) |
+	    (mask_m[32] << 26) | (mask_m[33] << 24) |
+	    (mask_m[34] << 22) | (mask_m[35] << 20) |
+	    (mask_m[36] << 18) | (mask_m[37] << 16) |
+	    (mask_m[48] << 14) | (mask_m[39] << 12) |
+	    (mask_m[40] << 10) | (mask_m[41] << 8) |
+	    (mask_m[42] << 6) | (mask_m[43] << 4) |
+	    (mask_m[44] << 2) | (mask_m[45] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) |
+	    (mask_m[18] << 26) | (mask_m[18] << 24) |
+	    (mask_m[20] << 22) | (mask_m[20] << 20) |
+	    (mask_m[22] << 18) | (mask_m[22] << 16) |
+	    (mask_m[24] << 14) | (mask_m[24] << 12) |
+	    (mask_m[25] << 10) | (mask_m[26] << 8) |
+	    (mask_m[27] << 6) | (mask_m[28] << 4) |
+	    (mask_m[29] << 2) | (mask_m[30] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) |
+	    (mask_m[2] << 26) | (mask_m[3] << 24) |
+	    (mask_m[4] << 22) | (mask_m[5] << 20) |
+	    (mask_m[6] << 18) | (mask_m[7] << 16) |
+	    (mask_m[8] << 14) | (mask_m[9] << 12) |
+	    (mask_m[10] << 10) | (mask_m[11] << 8) |
+	    (mask_m[12] << 6) | (mask_m[13] << 4) |
+	    (mask_m[14] << 2) | (mask_m[15] << 0);
+	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+	tmp_mask = (mask_p[15] << 28) |
+	    (mask_p[14] << 26) | (mask_p[13] << 24) |
+	    (mask_p[12] << 22) | (mask_p[11] << 20) |
+	    (mask_p[10] << 18) | (mask_p[9] << 16) |
+	    (mask_p[8] << 14) | (mask_p[7] << 12) |
+	    (mask_p[6] << 10) | (mask_p[5] << 8) |
+	    (mask_p[4] << 6) | (mask_p[3] << 4) |
+	    (mask_p[2] << 2) | (mask_p[1] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+	tmp_mask = (mask_p[30] << 28) |
+	    (mask_p[29] << 26) | (mask_p[28] << 24) |
+	    (mask_p[27] << 22) | (mask_p[26] << 20) |
+	    (mask_p[25] << 18) | (mask_p[24] << 16) |
+	    (mask_p[23] << 14) | (mask_p[22] << 12) |
+	    (mask_p[21] << 10) | (mask_p[20] << 8) |
+	    (mask_p[19] << 6) | (mask_p[18] << 4) |
+	    (mask_p[17] << 2) | (mask_p[16] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+	tmp_mask = (mask_p[45] << 28) |
+	    (mask_p[44] << 26) | (mask_p[43] << 24) |
+	    (mask_p[42] << 22) | (mask_p[41] << 20) |
+	    (mask_p[40] << 18) | (mask_p[39] << 16) |
+	    (mask_p[38] << 14) | (mask_p[37] << 12) |
+	    (mask_p[36] << 10) | (mask_p[35] << 8) |
+	    (mask_p[34] << 6) | (mask_p[33] << 4) |
+	    (mask_p[32] << 2) | (mask_p[31] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) |
+	    (mask_p[59] << 26) | (mask_p[58] << 24) |
+	    (mask_p[57] << 22) | (mask_p[56] << 20) |
+	    (mask_p[55] << 18) | (mask_p[54] << 16) |
+	    (mask_p[53] << 14) | (mask_p[52] << 12) |
+	    (mask_p[51] << 10) | (mask_p[50] << 8) |
+	    (mask_p[49] << 6) | (mask_p[48] << 4) |
+	    (mask_p[47] << 2) | (mask_p[46] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+static void
+ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	int bb_spur = AR_NO_SPUR;
+	int bin, cur_bin;
+	int spur_freq_sd;
+	int spur_delta_phase;
+	int denominator;
+	int upper, lower, cur_vit_mask;
+	int tmp, new;
+	int i;
+	int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+	    AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+	};
+	int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+	    AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+	};
+	int inc[4] = { 0, 100, 0, 0 };
+
+	int8_t mask_m[123];
+	int8_t mask_p[123];
+	int8_t mask_amt;
+	int tmp_mask;
+	int cur_bb_spur;
+	boolean_t is2GHz = IS_CHAN_2GHZ(chan);
+
+	(void) memset(&mask_m, 0, sizeof (int8_t) * 123);
+	(void) memset(&mask_p, 0, sizeof (int8_t) * 123);
+
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+		cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+		if (AR_NO_SPUR == cur_bb_spur)
+			break;
+		cur_bb_spur = cur_bb_spur - (chan->channel * 10);
+		if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
+			bb_spur = cur_bb_spur;
+			break;
+		}
+	}
+
+	if (AR_NO_SPUR == bb_spur)
+		return;
+
+	bin = bb_spur * 32;
+
+	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+	new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+	    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+	    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+	    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
+
+	new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+	    AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+	    AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+	    AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+	    SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+	REG_WRITE(ah, AR_PHY_SPUR_REG, new);
+
+	spur_delta_phase = ((bb_spur * 524288) / 100) &
+	    AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+	denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
+	spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
+
+	new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+	    SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+	    SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+	REG_WRITE(ah, AR_PHY_TIMING11, new);
+
+	cur_bin = -6000;
+	upper = bin + 100;
+	lower = bin - 100;
+
+	for (i = 0; i < 4; i++) {
+		int pilot_mask = 0;
+		int chan_mask = 0;
+		int bp = 0;
+		for (bp = 0; bp < 30; bp++) {
+			if ((cur_bin > lower) && (cur_bin < upper)) {
+				pilot_mask = pilot_mask | 0x1 << bp;
+				chan_mask = chan_mask | 0x1 << bp;
+			}
+			cur_bin += 100;
+		}
+		cur_bin += inc[i];
+		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+	}
+
+	cur_vit_mask = 6100;
+	upper = bin + 120;
+	lower = bin - 120;
+
+	for (i = 0; i < 123; i++) {
+		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+			/* workaround for gcc bug #37014 */
+			volatile int tmp = abs(cur_vit_mask - bin);
+
+			if (tmp < 75)
+				mask_amt = 1;
+			else
+				mask_amt = 0;
+			if (cur_vit_mask < 0)
+				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+			else
+				mask_p[cur_vit_mask / 100] = mask_amt;
+		}
+		cur_vit_mask -= 100;
+	}
+
+	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) |
+	    (mask_m[48] << 26) | (mask_m[49] << 24) |
+	    (mask_m[50] << 22) | (mask_m[51] << 20) |
+	    (mask_m[52] << 18) | (mask_m[53] << 16) |
+	    (mask_m[54] << 14) | (mask_m[55] << 12) |
+	    (mask_m[56] << 10) | (mask_m[57] << 8) |
+	    (mask_m[58] << 6) | (mask_m[59] << 4) |
+	    (mask_m[60] << 2) | (mask_m[61] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+	tmp_mask = (mask_m[31] << 28) |
+	    (mask_m[32] << 26) | (mask_m[33] << 24) |
+	    (mask_m[34] << 22) | (mask_m[35] << 20) |
+	    (mask_m[36] << 18) | (mask_m[37] << 16) |
+	    (mask_m[48] << 14) | (mask_m[39] << 12) |
+	    (mask_m[40] << 10) | (mask_m[41] << 8) |
+	    (mask_m[42] << 6) | (mask_m[43] << 4) |
+	    (mask_m[44] << 2) | (mask_m[45] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) |
+	    (mask_m[18] << 26) | (mask_m[18] << 24) |
+	    (mask_m[20] << 22) | (mask_m[20] << 20) |
+	    (mask_m[22] << 18) | (mask_m[22] << 16) |
+	    (mask_m[24] << 14) | (mask_m[24] << 12) |
+	    (mask_m[25] << 10) | (mask_m[26] << 8) |
+	    (mask_m[27] << 6) | (mask_m[28] << 4) |
+	    (mask_m[29] << 2) | (mask_m[30] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) |
+	    (mask_m[2] << 26) | (mask_m[3] << 24) |
+	    (mask_m[4] << 22) | (mask_m[5] << 20) |
+	    (mask_m[6] << 18) | (mask_m[7] << 16) |
+	    (mask_m[8] << 14) | (mask_m[9] << 12) |
+	    (mask_m[10] << 10) | (mask_m[11] << 8) |
+	    (mask_m[12] << 6) | (mask_m[13] << 4) |
+	    (mask_m[14] << 2) | (mask_m[15] << 0);
+	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+	tmp_mask = (mask_p[15] << 28) |
+	    (mask_p[14] << 26) | (mask_p[13] << 24) |
+	    (mask_p[12] << 22) | (mask_p[11] << 20) |
+	    (mask_p[10] << 18) | (mask_p[9] << 16) |
+	    (mask_p[8] << 14) | (mask_p[7] << 12) |
+	    (mask_p[6] << 10) | (mask_p[5] << 8) |
+	    (mask_p[4] << 6) | (mask_p[3] << 4) |
+	    (mask_p[2] << 2) | (mask_p[1] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+	tmp_mask = (mask_p[30] << 28) |
+	    (mask_p[29] << 26) | (mask_p[28] << 24) |
+	    (mask_p[27] << 22) | (mask_p[26] << 20) |
+	    (mask_p[25] << 18) | (mask_p[24] << 16) |
+	    (mask_p[23] << 14) | (mask_p[22] << 12) |
+	    (mask_p[21] << 10) | (mask_p[20] << 8) |
+	    (mask_p[19] << 6) | (mask_p[18] << 4) |
+	    (mask_p[17] << 2) | (mask_p[16] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+	tmp_mask = (mask_p[45] << 28) |
+	    (mask_p[44] << 26) | (mask_p[43] << 24) |
+	    (mask_p[42] << 22) | (mask_p[41] << 20) |
+	    (mask_p[40] << 18) | (mask_p[39] << 16) |
+	    (mask_p[38] << 14) | (mask_p[37] << 12) |
+	    (mask_p[36] << 10) | (mask_p[35] << 8) |
+	    (mask_p[34] << 6) | (mask_p[33] << 4) |
+	    (mask_p[32] << 2) | (mask_p[31] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) |
+	    (mask_p[59] << 26) | (mask_p[58] << 24) |
+	    (mask_p[57] << 22) | (mask_p[56] << 20) |
+	    (mask_p[55] << 18) | (mask_p[54] << 16) |
+	    (mask_p[53] << 14) | (mask_p[52] << 12) |
+	    (mask_p[51] << 10) | (mask_p[50] << 8) |
+	    (mask_p[49] << 6) | (mask_p[48] << 4) |
+	    (mask_p[47] << 2) | (mask_p[46] << 0);
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+boolean_t
+ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
+    enum ath9k_ht_macmode macmode,
+    uint8_t txchainmask, uint8_t rxchainmask,
+    enum ath9k_ht_extprotspacing extprotspacing,
+    boolean_t bChannelChange, int *status)
+{
+	uint32_t saveLedState;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_channel *curchan = ah->ah_curchan;
+	uint32_t saveDefAntenna;
+	uint32_t macStaId1;
+	int ecode;
+	int i, rx_chainmask;
+
+	ahp->ah_extprotspacing = extprotspacing;
+	ahp->ah_txchainmask = txchainmask;
+	ahp->ah_rxchainmask = rxchainmask;
+
+	if (AR_SREV_9280(ah)) {
+		ahp->ah_txchainmask &= 0x3;
+		ahp->ah_rxchainmask &= 0x3;
+	}
+
+	if (ath9k_hw_check_chan(ah, chan) == NULL) {
+		ARN_DBG((ARN_DBG_ANY, "arn: "
+		    "%s: invalid channel %u/0x%x; no mapping\n",
+		    __func__, chan->channel, chan->channelFlags));
+		ecode = EINVAL;
+		goto bad;
+	}
+
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
+		ARN_DBG((ARN_DBG_ANY, "arn: "
+		    "%s: ath9k_hw_setpower failed!!!\n", __func__));
+		ecode = EIO;
+		goto bad;
+	}
+
+	if (curchan)
+		(void) ath9k_hw_getnf(ah, curchan);
+
+	if (bChannelChange &&
+	    (ahp->ah_chipFullSleep != B_TRUE) &&
+	    (ah->ah_curchan != NULL) &&
+	    (chan->channel != ah->ah_curchan->channel) &&
+	    ((chan->channelFlags & CHANNEL_ALL) ==
+	    (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
+	    (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
+	    !IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) {
+
+		if (ath9k_hw_channel_change(ah, chan, macmode)) {
+			ath9k_hw_loadnf(ah, ah->ah_curchan);
+			ath9k_hw_start_nfcal(ah);
+			return (B_TRUE);
+		}
+	}
+
+	saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
+	if (saveDefAntenna == 0)
+		saveDefAntenna = 1;
+
+	macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
+
+	saveLedState = REG_READ(ah, AR_CFG_LED) &
+	    (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
+	    AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
+
+	ath9k_hw_mark_phy_inactive(ah);
+
+	if (!ath9k_hw_chip_reset(ah, chan)) {
+		ARN_DBG((ARN_DBG_RESET, "arn: "
+		    "%s: chip reset failed\n", __func__));
+		ecode = EINVAL;
+		goto bad;
+	}
+
+	if (AR_SREV_9280(ah)) {
+		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+		    AR_GPIO_JTAG_DISABLE);
+		if (is_set(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
+			if (IS_CHAN_5GHZ(chan))
+				ath9k_hw_set_gpio(ah, 9, 0);
+			else
+				ath9k_hw_set_gpio(ah, 9, 1);
+		}
+		ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+	}
+
+	ecode = ath9k_hw_process_ini(ah, chan, macmode);
+	if (ecode != 0) {
+		ecode = EINVAL;
+		goto bad;
+	}
+
+	if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+		ath9k_hw_set_delta_slope(ah, chan);
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ath9k_hw_9280_spur_mitigate(ah, chan);
+	else
+		ath9k_hw_spur_mitigate(ah, chan);
+
+	if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
+		ARN_DBG((ARN_DBG_EEPROM, "arn: "
+		    "%s: error setting board options\n", __func__));
+		ecode = EIO;
+		goto bad;
+	}
+
+	ath9k_hw_decrease_chain_power(ah, chan);
+
+	REG_WRITE(ah, AR_STA_ID0, ARN_LE_READ_32(ahp->ah_macaddr));
+	REG_WRITE(ah, AR_STA_ID1, ARN_LE_READ_16(ahp->ah_macaddr + 4) |
+	    macStaId1 |
+	    AR_STA_ID1_RTS_USE_DEF |
+	    (ah->ah_config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) |
+	    ahp->ah_staId1Defaults);
+	ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+
+	REG_WRITE(ah, AR_BSSMSKL, ARN_LE_READ_32(ahp->ah_bssidmask));
+	REG_WRITE(ah, AR_BSSMSKU, ARN_LE_READ_16(ahp->ah_bssidmask + 4));
+
+	REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
+
+	REG_WRITE(ah, AR_BSS_ID0, ARN_LE_READ_32(ahp->ah_bssid));
+	REG_WRITE(ah, AR_BSS_ID1, ARN_LE_READ_16(ahp->ah_bssid + 4) |
+	    ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+
+	REG_WRITE(ah, AR_ISR, ~0);
+
+	REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
+			ARN_DBG((ARN_DBG_FATAL, "arn: "
+			    "%s: ath9k_hw_ar9280_set_channel failed!!!\n",
+			    __func__));
+			ecode = EIO;
+			goto bad;
+		}
+	} else {
+		if (!(ath9k_hw_set_channel(ah, chan))) {
+			ARN_DBG((ARN_DBG_FATAL, "arn: "
+			    "%s: ath9k_hw_set_channel failed!!!\n", __func__));
+			ecode = EIO;
+			goto bad;
+		}
+	}
+
+	for (i = 0; i < AR_NUM_DCU; i++)
+		REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
+
+	ahp->ah_intrTxqs = 0;
+	for (i = 0; i < ah->ah_caps.total_queues; i++)
+		(void) ath9k_hw_resettxqueue(ah, i);
+
+	ath9k_hw_init_interrupt_masks(ah, ah->ah_opmode);
+	ath9k_hw_init_qos(ah);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+		ath9k_enable_rfkill(ah);
+#endif
+	ath9k_hw_init_user_settings(ah);
+
+	REG_WRITE(ah, AR_STA_ID1,
+	    REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
+
+	ath9k_hw_set_dma(ah);
+
+	REG_WRITE(ah, AR_OBS, 8);
+
+	if (ahp->ah_intrMitigation) {
+
+		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
+		REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
+	}
+
+	ath9k_hw_init_bb(ah, chan);
+
+	if (!ath9k_hw_init_cal(ah, chan)) {
+		ecode = EIO;
+		goto bad;
+	}
+
+	rx_chainmask = ahp->ah_rxchainmask;
+	if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
+		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+	}
+
+	REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
+
+	if (AR_SREV_9100(ah)) {
+		uint32_t mask;
+		mask = REG_READ(ah, AR_CFG);
+		if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
+			ARN_DBG((ARN_DBG_RESET, "arn: "
+			    "%s CFG Byte Swap Set 0x%x\n",
+			    __func__, mask));
+		} else {
+			mask = INIT_CONFIG_STATUS |
+			    AR_CFG_SWRB | AR_CFG_SWTB;
+			REG_WRITE(ah, AR_CFG, mask);
+			ARN_DBG((ARN_DBG_RESET, "arn: "
+			    "%s Setting CFG 0x%x\n",
+			    __func__, REG_READ(ah, AR_CFG)));
+		}
+	} else {
+		ARN_DBG((ARN_DBG_HW, "arn: ath9k_hw_keyreset(): "
+		    "#ifdef __BIG_ENDIAN \n"));
+#ifdef __BIG_ENDIAN
+		REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
+#endif
+	}
+
+	return (B_TRUE);
+bad:
+	if (status)
+		*status = ecode;
+	return (B_FALSE);
+}
+
+/* Key Cache Management */
+
+boolean_t
+ath9k_hw_keyreset(struct ath_hal *ah, uint16_t entry)
+{
+	uint32_t keyType;
+
+	if (entry >= ah->ah_caps.keycache_size) {
+		ARN_DBG((ARN_DBG_KEYCACHE, "arn: ath9k_hw_keyreset(): "
+		    "entry %u out of range\n", entry));
+
+		return (B_FALSE);
+	}
+
+	keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
+
+	REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
+	REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
+	REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
+	REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
+	REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
+	REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
+	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
+	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
+
+	if (keyType == AR_KEYTABLE_TYPE_TKIP &&
+	    ATH9K_IS_MIC_ENABLED(ah)) {
+		uint16_t micentry = entry + 64;
+
+		REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
+		REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+		REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
+		REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+	}
+
+	if (ah->ah_curchan == NULL)
+		return (B_TRUE);
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_keysetmac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac)
+{
+	uint32_t macHi, macLo;
+
+	if (entry >= ah->ah_caps.keycache_size) {
+		ARN_DBG((ARN_DBG_KEYCACHE, "arn: "
+		    "%s: entry %u out of range\n", __func__, entry));
+		return (B_FALSE);
+	}
+
+	if (mac != NULL) {
+		macHi = (mac[5] << 8) | mac[4];
+		macLo = (mac[3] << 24) |
+		    (mac[2] << 16) |
+		    (mac[1] << 8) |
+		    mac[0];
+		macLo >>= 1;
+		macLo |= (macHi & 1) << 31;
+		macHi >>= 1;
+	} else {
+		macLo = macHi = 0;
+	}
+	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
+	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_set_keycache_entry(struct ath_hal *ah, uint16_t entry,
+    const struct ath9k_keyval *k, const uint8_t *mac, int xorKey)
+{
+	const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	uint32_t key0, key1, key2, key3, key4;
+	uint32_t keyType;
+	uint32_t xorMask = xorKey ?
+	    (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 |
+	    ATH9K_KEY_XOR << 8 | ATH9K_KEY_XOR) : 0;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (entry >= pCap->keycache_size) {
+		ARN_DBG((ARN_DBG_KEYCACHE, "arn: "
+		    "%s: entry %u out of range\n", __func__, entry));
+		return (B_FALSE);
+	}
+
+	switch (k->kv_type) {
+	case ATH9K_CIPHER_AES_OCB:
+		keyType = AR_KEYTABLE_TYPE_AES;
+		break;
+	case ATH9K_CIPHER_AES_CCM:
+		if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
+			ARN_DBG((ARN_DBG_KEYCACHE, "arn: "
+			    "%s: AES-CCM not supported by "
+			    "mac rev 0x%x\n", __func__,
+			    ah->ah_macRev));
+			return (B_FALSE);
+		}
+		keyType = AR_KEYTABLE_TYPE_CCM;
+		break;
+	case ATH9K_CIPHER_TKIP:
+		keyType = AR_KEYTABLE_TYPE_TKIP;
+		if (ATH9K_IS_MIC_ENABLED(ah) &&
+		    entry + 64 >= pCap->keycache_size) {
+			ARN_DBG((ARN_DBG_KEYCACHE, "arn: "
+			    "%s: entry %u inappropriate for TKIP\n",
+			    __func__, entry));
+			return (B_FALSE);
+		}
+		break;
+	case ATH9K_CIPHER_WEP:
+		if (k->kv_len < ATH9K_LEN_WEP40) {
+			ARN_DBG((ARN_DBG_KEYCACHE, "arn: "
+			    "%s: WEP key length %u too small\n",
+			    __func__, k->kv_len));
+			return (B_FALSE);
+		}
+		if (k->kv_len <= ATH9K_LEN_WEP40)
+			keyType = AR_KEYTABLE_TYPE_40;
+		else if (k->kv_len <= ATH9K_LEN_WEP104)
+			keyType = AR_KEYTABLE_TYPE_104;
+		else
+			keyType = AR_KEYTABLE_TYPE_128;
+		break;
+	case ATH9K_CIPHER_CLR:
+		keyType = AR_KEYTABLE_TYPE_CLR;
+		break;
+	default:
+		ARN_DBG((ARN_DBG_KEYCACHE, "arn: "
+		    "%s: cipher %u not supported\n", __func__,
+		    k->kv_type));
+		return (B_FALSE);
+	}
+
+	key0 = ARN_LE_READ_32(k->kv_val + 0) ^ xorMask;
+	key1 = (ARN_LE_READ_16(k->kv_val + 4) ^ xorMask) & 0xffff;
+	key2 = ARN_LE_READ_32(k->kv_val + 6) ^ xorMask;
+	key3 = (ARN_LE_READ_16(k->kv_val + 10) ^ xorMask) & 0xffff;
+	key4 = ARN_LE_READ_32(k->kv_val + 12) ^ xorMask;
+
+	if (k->kv_len <= ATH9K_LEN_WEP104)
+		key4 &= 0xff;
+
+	if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
+		uint16_t micentry = entry + 64;
+
+		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
+		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
+		REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+		REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+		(void) ath9k_hw_keysetmac(ah, entry, mac);
+
+		if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
+			uint32_t mic0, mic1, mic2, mic3, mic4;
+			mic0 = ARN_LE_READ_32(k->kv_mic + 0);
+			mic2 = ARN_LE_READ_32(k->kv_mic + 4);
+			mic1 = ARN_LE_READ_16(k->kv_txmic + 2) & 0xffff;
+			mic3 = ARN_LE_READ_16(k->kv_txmic + 0) & 0xffff;
+			mic4 = ARN_LE_READ_32(k->kv_txmic + 4);
+			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
+			REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+			REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
+			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
+			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+			    AR_KEYTABLE_TYPE_CLR);
+
+		} else {
+			uint32_t mic0, mic2;
+			mic0 = ARN_LE_READ_32(k->kv_mic + 0);
+			mic2 = ARN_LE_READ_32(k->kv_mic + 4);
+			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+			REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+			REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
+			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+			    AR_KEYTABLE_TYPE_CLR);
+		}
+		REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
+		REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
+		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+	} else {
+		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+		REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+		REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+		(void) ath9k_hw_keysetmac(ah, entry, mac);
+	}
+
+	if (ah->ah_curchan == NULL)
+		return (B_TRUE);
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_keyisvalid(struct ath_hal *ah, uint16_t entry)
+{
+	if (entry < ah->ah_caps.keycache_size) {
+		uint32_t val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
+		if (val & AR_KEYTABLE_VALID)
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+/* Power Management (Chipset) */
+
+static void
+ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
+{
+	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+	if (setChip) {
+		REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
+		    AR_RTC_FORCE_WAKE_EN);
+		if (!AR_SREV_9100(ah))
+			REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
+
+		REG_CLR_BIT(ah, (uint16_t)(AR_RTC_RESET),
+		    AR_RTC_RESET_EN);
+	}
+}
+
+static void
+ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
+{
+	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+	if (setChip) {
+		struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+
+		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+			REG_WRITE(ah, AR_RTC_FORCE_WAKE,
+			    AR_RTC_FORCE_WAKE_ON_INT);
+		} else {
+			REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
+			    AR_RTC_FORCE_WAKE_EN);
+		}
+	}
+}
+
+static boolean_t
+ath9k_hw_set_power_awake(struct ath_hal *ah, int setChip)
+{
+	uint32_t val;
+	int i;
+
+	if (setChip) {
+		if ((REG_READ(ah, AR_RTC_STATUS) &
+		    AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
+			if (ath9k_hw_set_reset_reg(ah,
+			    ATH9K_RESET_POWER_ON) != B_TRUE) {
+				return (B_FALSE);
+			}
+		}
+		if (AR_SREV_9100(ah))
+			REG_SET_BIT(ah, AR_RTC_RESET,
+			    AR_RTC_RESET_EN);
+
+		REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+		    AR_RTC_FORCE_WAKE_EN);
+		drv_usecwait(50);
+
+		for (i = POWER_UP_TIME / 50; i > 0; i--) {
+			val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
+			if (val == AR_RTC_STATUS_ON)
+				break;
+			drv_usecwait(50);
+			REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+			    AR_RTC_FORCE_WAKE_EN);
+		}
+		if (i == 0) {
+			ARN_DBG((ARN_DBG_POWER_MGMT,
+			    "arn: ath9k_hw_set_power_awake(): "
+			    "Failed to wakeup in %uus\n",
+			    POWER_UP_TIME / 20));
+
+			return (B_FALSE);
+		}
+	}
+
+	REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_setpower(struct ath_hal *ah, enum ath9k_power_mode mode)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	static const char *modes[] = {
+		"AWAKE",
+		"FULL-SLEEP",
+		"NETWORK SLEEP",
+		"UNDEFINED"
+	};
+	int status = B_TRUE, setChip = B_TRUE;
+	ARN_DBG((ARN_DBG_ANY, "arn: ath9k_hw_setpower(): "
+	    "%s -> %s (%s)\n",
+	    modes[ahp->ah_powerMode],
+	    modes[mode],
+	    setChip ? "set chip " : ""));
+
+	switch (mode) {
+	case ATH9K_PM_AWAKE:
+		status = ath9k_hw_set_power_awake(ah, setChip);
+		break;
+	case ATH9K_PM_FULL_SLEEP:
+		ath9k_set_power_sleep(ah, setChip);
+		ahp->ah_chipFullSleep = B_TRUE;
+		break;
+	case ATH9K_PM_NETWORK_SLEEP:
+		ath9k_set_power_network_sleep(ah, setChip);
+		break;
+	default:
+		ARN_DBG((ARN_DBG_ANY, "arn: ath9k_hw_setpower(): "
+		    "unknown power mode %u\n", mode));
+		return (B_FALSE);
+	}
+	ahp->ah_powerMode = mode;
+
+	return (status);
+}
+
+void
+ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint8_t i;
+
+	if (ah->ah_isPciExpress != B_TRUE)
+		return;
+
+	if (ah->ah_config.pcie_powersave_enable == 2)
+		return;
+
+	if (restore)
+		return;
+
+	if (AR_SREV_9280_20_OR_LATER(ah)) {
+		for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
+			REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
+			    INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
+		}
+		drv_usecwait(1000);
+	} else if (AR_SREV_9280(ah) &&
+	    (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+		REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
+
+		if (ah->ah_config.pcie_clock_req)
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
+		else
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
+
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
+
+		REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+
+		drv_usecwait(1000);
+	} else {
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+		REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
+		REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+	}
+
+	REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+	if (ah->ah_config.pcie_waen) {
+		REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
+	} else {
+		if (AR_SREV_9285(ah))
+			REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
+		else if (AR_SREV_9280(ah))
+			REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
+		else
+			REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
+	}
+}
+
+/* Interrupt Handling */
+
+boolean_t
+ath9k_hw_intrpend(struct ath_hal *ah)
+{
+	uint32_t host_isr;
+
+	if (AR_SREV_9100(ah))
+		return (B_TRUE);
+
+	host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
+	if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
+		return (B_TRUE);
+
+	host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+
+	if ((host_isr & AR_INTR_SYNC_DEFAULT) &&
+	    (host_isr != AR_INTR_SPURIOUS))
+		return (B_TRUE);
+
+	return (B_FALSE);
+}
+
+boolean_t
+ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
+{
+	uint32_t isr = 0;
+	uint32_t mask2 = 0;
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	uint32_t sync_cause = 0;
+	boolean_t fatal_int = B_FALSE;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (!AR_SREV_9100(ah)) {
+		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
+			if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
+			    == AR_RTC_STATUS_ON) {
+				isr = REG_READ(ah, AR_ISR);
+			}
+		}
+
+		sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
+		    AR_INTR_SYNC_DEFAULT;
+
+		*masked = 0;
+
+		if (!isr && !sync_cause)
+			return (B_FALSE);
+	} else {
+		*masked = 0;
+		isr = REG_READ(ah, AR_ISR);
+	}
+
+	if (isr) {
+		if (isr & AR_ISR_BCNMISC) {
+			uint32_t isr2;
+			isr2 = REG_READ(ah, AR_ISR_S2);
+			if (isr2 & AR_ISR_S2_TIM)
+				mask2 |= ATH9K_INT_TIM;
+			if (isr2 & AR_ISR_S2_DTIM)
+				mask2 |= ATH9K_INT_DTIM;
+			if (isr2 & AR_ISR_S2_DTIMSYNC)
+				mask2 |= ATH9K_INT_DTIMSYNC;
+			if (isr2 & (AR_ISR_S2_CABEND))
+				mask2 |= ATH9K_INT_CABEND;
+			if (isr2 & AR_ISR_S2_GTT)
+				mask2 |= ATH9K_INT_GTT;
+			if (isr2 & AR_ISR_S2_CST)
+				mask2 |= ATH9K_INT_CST;
+		}
+
+		isr = REG_READ(ah, AR_ISR_RAC);
+		if (isr == 0xffffffff) {
+			*masked = 0;
+			return (B_FALSE);
+		}
+
+		*masked = isr & ATH9K_INT_COMMON;
+
+		if (ahp->ah_intrMitigation) {
+			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+				*masked |= ATH9K_INT_RX;
+		}
+
+		if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
+			*masked |= ATH9K_INT_RX;
+		if (isr &
+		    (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
+		    AR_ISR_TXEOL)) {
+			uint32_t s0_s, s1_s;
+
+			*masked |= ATH9K_INT_TX;
+
+			s0_s = REG_READ(ah, AR_ISR_S0_S);
+			ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+			ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+
+			s1_s = REG_READ(ah, AR_ISR_S1_S);
+			ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+			ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+		}
+
+		if (isr & AR_ISR_RXORN) {
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: "
+			    "%s: receive FIFO overrun interrupt\n", __func__));
+		}
+
+		if (!AR_SREV_9100(ah)) {
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+				uint32_t isr5 = REG_READ(ah, AR_ISR_S5_S);
+				if (isr5 & AR_ISR_S5_TIM_TIMER)
+					*masked |= ATH9K_INT_TIM_TIMER;
+			}
+		}
+
+		*masked |= mask2;
+	}
+
+	if (AR_SREV_9100(ah))
+		return (B_TRUE);
+
+	if (sync_cause) {
+		fatal_int = (sync_cause &
+		    (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) ?
+		    B_TRUE : B_FALSE;
+
+		if (fatal_int) {
+			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
+				ARN_DBG((ARN_DBG_INTERRUPT, "arn: "
+				    "%s: received PCI FATAL interrupt\n",
+				    __func__));
+			}
+			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
+				ARN_DBG((ARN_DBG_INTERRUPT, "arn: "
+				    "%s: received PCI PERR interrupt\n",
+				    __func__));
+			}
+		}
+		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: "
+			    "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
+			    __func__));
+
+			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
+			REG_WRITE(ah, AR_RC, 0);
+			*masked |= ATH9K_INT_FATAL;
+		}
+		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
+			ARN_DBG((ARN_DBG_ANY, "arn: "
+			    "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
+			    __func__));
+		}
+
+		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
+	}
+
+	return (B_TRUE);
+}
+
+enum ath9k_int
+ath9k_hw_intrget(struct ath_hal *ah)
+{
+	return (AH5416(ah)->ah_maskReg);
+}
+
+enum ath9k_int
+ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t omask = ahp->ah_maskReg;
+	uint32_t mask, mask2;
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+
+	ARN_DBG((ARN_DBG_INTERRUPT,
+	    "arn: ath9k_hw_set_interrupts(): "
+	    "0x%x => 0x%x\n", omask, ints));
+
+	if (omask & ATH9K_INT_GLOBAL) {
+		ARN_DBG((ARN_DBG_INTERRUPT,
+		    "arn: ath9k_hw_set_interrupts(): "
+		    "disable IER\n"));
+
+		REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
+		(void) REG_READ(ah, AR_IER);
+		if (!AR_SREV_9100(ah)) {
+			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
+			(void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
+
+			REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+			(void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
+		}
+	}
+
+	mask = ints & ATH9K_INT_COMMON;
+	mask2 = 0;
+
+	if (ints & ATH9K_INT_TX) {
+		if (ahp->ah_txOkInterruptMask)
+			mask |= AR_IMR_TXOK;
+		if (ahp->ah_txDescInterruptMask)
+			mask |= AR_IMR_TXDESC;
+		if (ahp->ah_txErrInterruptMask)
+			mask |= AR_IMR_TXERR;
+		if (ahp->ah_txEolInterruptMask)
+			mask |= AR_IMR_TXEOL;
+	}
+	if (ints & ATH9K_INT_RX) {
+		mask |= AR_IMR_RXERR;
+		if (ahp->ah_intrMitigation)
+			mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
+		else
+			mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
+		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+			mask |= AR_IMR_GENTMR;
+	}
+
+	if (ints & (ATH9K_INT_BMISC)) {
+		mask |= AR_IMR_BCNMISC;
+		if (ints & ATH9K_INT_TIM)
+			mask2 |= AR_IMR_S2_TIM;
+		if (ints & ATH9K_INT_DTIM)
+			mask2 |= AR_IMR_S2_DTIM;
+		if (ints & ATH9K_INT_DTIMSYNC)
+			mask2 |= AR_IMR_S2_DTIMSYNC;
+		if (ints & ATH9K_INT_CABEND)
+			mask2 |= (AR_IMR_S2_CABEND);
+	}
+
+	if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
+		mask |= AR_IMR_BCNMISC;
+		if (ints & ATH9K_INT_GTT)
+			mask2 |= AR_IMR_S2_GTT;
+		if (ints & ATH9K_INT_CST)
+			mask2 |= AR_IMR_S2_CST;
+	}
+
+	REG_WRITE(ah, AR_IMR, mask);
+	mask = REG_READ(ah, AR_IMR_S2) &
+	    ~(AR_IMR_S2_TIM |
+	    AR_IMR_S2_DTIM |
+	    AR_IMR_S2_DTIMSYNC |
+	    AR_IMR_S2_CABEND |
+	    AR_IMR_S2_CABTO |
+	    AR_IMR_S2_TSFOOR |
+	    AR_IMR_S2_GTT |
+	    AR_IMR_S2_CST);
+	REG_WRITE(ah, AR_IMR_S2, mask | mask2);
+	ahp->ah_maskReg = ints;
+
+	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+		if (ints & ATH9K_INT_TIM_TIMER)
+			REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+		else
+			REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+	}
+
+	if (ints & ATH9K_INT_GLOBAL) {
+		REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
+		if (!AR_SREV_9100(ah)) {
+			REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
+			    AR_INTR_MAC_IRQ);
+			REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
+
+
+			REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
+			    AR_INTR_SYNC_DEFAULT);
+			REG_WRITE(ah, AR_INTR_SYNC_MASK,
+			    AR_INTR_SYNC_DEFAULT);
+		}
+
+	}
+
+	return (omask);
+}
+
+/* Beacon Handling */
+
+void
+ath9k_hw_beaconinit(struct ath_hal *ah, uint32_t next_beacon,
+    uint32_t beacon_period)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	int flags = 0;
+
+	ahp->ah_beaconInterval = beacon_period;
+
+	switch (ah->ah_opmode) {
+	case ATH9K_M_STA:
+	case ATH9K_M_MONITOR:
+		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
+		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
+		REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
+		flags |= AR_TBTT_TIMER_EN;
+		break;
+	case ATH9K_M_IBSS:
+		REG_SET_BIT(ah, AR_TXCFG,
+		    AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
+		REG_WRITE(ah, AR_NEXT_NDP_TIMER,
+		    TU_TO_USEC(next_beacon +
+		    (ahp->ah_atimWindow ? ahp->
+		    ah_atimWindow : 1)));
+		flags |= AR_NDP_TIMER_EN;
+		/*FALLTHRU*/
+	case ATH9K_M_HOSTAP:
+		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
+		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
+		    TU_TO_USEC(next_beacon -
+		    ah->ah_config.
+		    dma_beacon_response_time));
+		REG_WRITE(ah, AR_NEXT_SWBA,
+		    TU_TO_USEC(next_beacon -
+		    ah->ah_config.
+		    sw_beacon_response_time));
+		flags |=
+		    AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
+		break;
+	default:
+		ARN_DBG((ARN_DBG_BEACON,
+		    "%s: unsupported opmode: %d\n",
+		    __func__, ah->ah_opmode));
+		return;
+	}
+
+	REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
+	REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
+	REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
+	REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
+
+	beacon_period &= ~ATH9K_BEACON_ENA;
+	if (beacon_period & ATH9K_BEACON_RESET_TSF) {
+		beacon_period &= ~ATH9K_BEACON_RESET_TSF;
+		ath9k_hw_reset_tsf(ah);
+	}
+
+	REG_SET_BIT(ah, AR_TIMER_MODE, flags);
+}
+
+void
+ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
+    const struct ath9k_beacon_state *bs)
+{
+	uint32_t nextTbtt, beaconintval, dtimperiod, beacontimeout;
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+
+	REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
+
+	REG_WRITE(ah, AR_BEACON_PERIOD,
+	    TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
+	REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
+	    TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
+
+	REG_RMW_FIELD(ah, AR_RSSI_THR,
+	    AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
+
+	beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
+
+	if (bs->bs_sleepduration > beaconintval)
+		beaconintval = bs->bs_sleepduration;
+
+	dtimperiod = bs->bs_dtimperiod;
+	if (bs->bs_sleepduration > dtimperiod)
+		dtimperiod = bs->bs_sleepduration;
+
+	if (beaconintval == dtimperiod)
+		nextTbtt = bs->bs_nextdtim;
+	else
+		nextTbtt = bs->bs_nexttbtt;
+
+	ARN_DBG((ARN_DBG_BEACON, "arn: "
+	    "%s: next DTIM %d\n", __func__, bs->bs_nextdtim));
+	ARN_DBG((ARN_DBG_BEACON, "arn: "
+	    "%s: next beacon %d\n", __func__, nextTbtt));
+	ARN_DBG((ARN_DBG_BEACON, "arn: "
+	    "%s: beacon period %d\n", __func__, beaconintval));
+	ARN_DBG((ARN_DBG_BEACON, "arn: "
+	    "%s: DTIM period %d\n", __func__, dtimperiod));
+
+	REG_WRITE(ah, AR_NEXT_DTIM,
+	    TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
+	REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
+
+	REG_WRITE(ah, AR_SLEEP1,
+	    SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT) |
+	    AR_SLEEP1_ASSUME_DTIM);
+
+	if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
+		beacontimeout = (BEACON_TIMEOUT_VAL << 3);
+	else
+		beacontimeout = MIN_BEACON_TIMEOUT_VAL;
+
+	REG_WRITE(ah, AR_SLEEP2,
+	    SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
+
+	REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
+	REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
+
+	REG_SET_BIT(ah, AR_TIMER_MODE,
+	    AR_TBTT_TIMER_EN |
+	    AR_TIM_TIMER_EN |
+	    AR_DTIM_TIMER_EN);
+
+}
+
+/* HW Capabilities */
+
+boolean_t
+ath9k_hw_fill_cap_info(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	uint16_t capField = 0, eeval;
+
+	eeval = ath9k_hw_get_eeprom(ah, EEP_REG_0);
+
+	ah->ah_currentRD = eeval;
+
+	eeval = ath9k_hw_get_eeprom(ah, EEP_REG_1);
+	ah->ah_currentRDExt = eeval;
+
+	capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP);
+
+	if (ah->ah_opmode != ATH9K_M_HOSTAP &&
+	    ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+		if (ah->ah_currentRD == 0x64 ||
+		    ah->ah_currentRD == 0x65)
+			ah->ah_currentRD += 5;
+		else if (ah->ah_currentRD == 0x41)
+			ah->ah_currentRD = 0x43;
+
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "%s: regdomain mapped to 0x%x\n", __func__,
+		    ah->ah_currentRD));
+	}
+
+	eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE);
+
+	bzero(pCap->wireless_modes, sizeof (uint8_t)*4);
+
+	if (eeval & AR5416_OPFLAGS_11A) {
+		set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
+		if (ah->ah_config.ht_enable) {
+			if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
+				set_bit(ATH9K_MODE_11NA_HT20,
+				    pCap->wireless_modes);
+			if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
+				set_bit(ATH9K_MODE_11NA_HT40PLUS,
+				    pCap->wireless_modes);
+				set_bit(ATH9K_MODE_11NA_HT40MINUS,
+				    pCap->wireless_modes);
+			}
+		}
+	}
+
+	if (eeval & AR5416_OPFLAGS_11G) {
+		set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
+		set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
+		if (ah->ah_config.ht_enable) {
+			if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
+				set_bit(ATH9K_MODE_11NG_HT20,
+				    pCap->wireless_modes);
+			if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
+				set_bit(ATH9K_MODE_11NG_HT40PLUS,
+				    pCap->wireless_modes);
+				set_bit(ATH9K_MODE_11NG_HT40MINUS,
+				    pCap->wireless_modes);
+			}
+		}
+	}
+
+	pCap->tx_chainmask = ath9k_hw_get_eeprom(ah, EEP_TX_MASK);
+	if ((ah->ah_isPciExpress) ||
+	    (eeval & AR5416_OPFLAGS_11A)) {
+		pCap->rx_chainmask =
+		    ath9k_hw_get_eeprom(ah, EEP_RX_MASK);
+	} else {
+		pCap->rx_chainmask =
+		    (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
+	}
+
+	if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
+		ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
+
+	pCap->low_2ghz_chan = 2312;
+	pCap->high_2ghz_chan = 2732;
+
+	pCap->low_5ghz_chan = 4920;
+	pCap->high_5ghz_chan = 6100;
+
+	pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
+	pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
+	pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
+
+	pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
+	pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
+	pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
+
+	pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
+#ifdef ARN_11N_SUPPORT
+	if (ah->ah_config.ht_enable)
+		pCap->hw_caps |= ATH9K_HW_CAP_HT;
+	else
+		pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
+#else
+	pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
+#endif
+
+	pCap->hw_caps |= ATH9K_HW_CAP_GTT;
+	pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
+	pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
+	pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
+
+	if (capField & AR_EEPROM_EEPCAP_MAXQCU)
+		pCap->total_queues =
+		    MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
+	else
+		pCap->total_queues = ATH9K_NUM_TX_QUEUES;
+
+	if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
+		pCap->keycache_size =
+		    1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
+	else
+		pCap->keycache_size = AR_KEYTABLE_SIZE;
+
+	pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
+	pCap->num_mr_retries = 4;
+	pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		pCap->num_gpio_pins = AR928X_NUM_GPIO;
+	else
+		pCap->num_gpio_pins = AR_NUM_GPIO;
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		pCap->hw_caps |= ATH9K_HW_CAP_WOW;
+		pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
+	} else {
+		pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
+		pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
+	}
+
+	if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
+		pCap->hw_caps |= ATH9K_HW_CAP_CST;
+		pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
+	} else {
+		pCap->rts_aggr_limit = (8 * 1024);
+	}
+
+	pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+	ah->ah_rfsilent = ath9k_hw_get_eeprom(ah, EEP_RF_SILENT);
+	if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
+		ah->ah_rfkill_gpio =
+		    MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
+		ah->ah_rfkill_polarity =
+		    MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
+
+		pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
+	}
+#endif
+
+	if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
+	    (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
+	    (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
+	    (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
+	    (ah->ah_macVersion == AR_SREV_VERSION_9280))
+		pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
+	else
+		pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
+
+	if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
+		pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
+	else
+		pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
+
+	if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
+		pCap->reg_cap =
+		    AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
+		    AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
+		    AR_EEPROM_EEREGCAP_EN_KK_U2 |
+		    AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
+	} else {
+		pCap->reg_cap =
+		    AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
+		    AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
+	}
+
+	pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
+
+	/* ATH9K_HAL_FREQ_BAND_5GHZ == 0 */
+	pCap->num_antcfg_5ghz =
+	    ath9k_hw_get_num_ant_config(ah, 0);
+	/* ATH9K_HAL_FREQ_BAND_2GHZ == 1 */
+	pCap->num_antcfg_2ghz =
+	    ath9k_hw_get_num_ant_config(ah, 1);
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_getcapability(struct ath_hal *ah,
+    enum ath9k_capability_type type,
+    uint32_t capability, uint32_t *result)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+
+	switch (type) {
+	case ATH9K_CAP_CIPHER:
+		switch (capability) {
+		case ATH9K_CIPHER_AES_CCM:
+		case ATH9K_CIPHER_AES_OCB:
+		case ATH9K_CIPHER_TKIP:
+		case ATH9K_CIPHER_WEP:
+		case ATH9K_CIPHER_MIC:
+		case ATH9K_CIPHER_CLR:
+			return (B_TRUE);
+		default:
+			return (B_FALSE);
+		}
+	case ATH9K_CAP_TKIP_MIC:
+		switch (capability) {
+		case 0:
+			return (B_TRUE);
+		case 1:
+			return ((ahp->ah_staId1Defaults &
+			    AR_STA_ID1_CRPT_MIC_ENABLE) ? B_TRUE :
+			    B_FALSE);
+		}
+		/*FALLTHRU*/
+	case ATH9K_CAP_TKIP_SPLIT:
+		return ((ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
+		    B_FALSE : B_TRUE);
+	case ATH9K_CAP_WME_TKIPMIC:
+		return (0);
+	case ATH9K_CAP_PHYCOUNTERS:
+		return (ahp->ah_hasHwPhyCounters ? 0 : -ENXIO);
+	case ATH9K_CAP_DIVERSITY:
+		return ((REG_READ(ah, AR_PHY_CCK_DETECT) &
+		    AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
+		    B_TRUE : B_FALSE);
+	case ATH9K_CAP_PHYDIAG:
+		return (B_TRUE);
+	case ATH9K_CAP_MCAST_KEYSRCH:
+		switch (capability) {
+		case 0:
+			return (B_TRUE);
+		case 1:
+			if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
+				return (B_FALSE);
+			} else {
+				return ((ahp->ah_staId1Defaults &
+				    AR_STA_ID1_MCAST_KSRCH) ? B_TRUE :
+				    B_FALSE);
+			}
+		}
+		return (B_FALSE);
+	case ATH9K_CAP_TSF_ADJUST:
+		return ((ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
+		    B_TRUE : B_FALSE);
+	case ATH9K_CAP_RFSILENT:
+		if (capability == 3)
+			return (B_FALSE);
+		/*FALLTHRU*/
+	case ATH9K_CAP_ANT_CFG_2GHZ:
+		*result = pCap->num_antcfg_2ghz;
+		return (B_TRUE);
+	case ATH9K_CAP_ANT_CFG_5GHZ:
+		*result = pCap->num_antcfg_5ghz;
+		return (B_TRUE);
+	case ATH9K_CAP_TXPOW:
+		switch (capability) {
+		case 0:
+			return (0);
+		case 1:
+			*result = ah->ah_powerLimit;
+			return (0);
+		case 2:
+			*result = ah->ah_maxPowerLevel;
+			return (0);
+		case 3:
+			*result = ah->ah_tpScale;
+			return (0);
+		}
+		return (B_FALSE);
+	default:
+		return (B_FALSE);
+	}
+}
+
+/* ARGSUSED */
+boolean_t
+ath9k_hw_setcapability(struct ath_hal *ah,
+    enum ath9k_capability_type type,
+    uint32_t capability, uint32_t setting,
+    int *status)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t v;
+
+	switch (type) {
+	case ATH9K_CAP_TKIP_MIC:
+		if (setting)
+			ahp->ah_staId1Defaults |=
+			    AR_STA_ID1_CRPT_MIC_ENABLE;
+		else
+			ahp->ah_staId1Defaults &=
+			    ~AR_STA_ID1_CRPT_MIC_ENABLE;
+		return (B_TRUE);
+	case ATH9K_CAP_DIVERSITY:
+		v = REG_READ(ah, AR_PHY_CCK_DETECT);
+		if (setting)
+			v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+		else
+			v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+		REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
+		return (B_TRUE);
+	case ATH9K_CAP_MCAST_KEYSRCH:
+		if (setting)
+			ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
+		else
+			ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
+		return (B_TRUE);
+	case ATH9K_CAP_TSF_ADJUST:
+		if (setting)
+			ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+		else
+			ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+		return (B_TRUE);
+	default:
+		return (B_FALSE);
+	}
+}
+
+/* GPIO / RFKILL / Antennae */
+
+static void
+ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
+    uint32_t gpio, uint32_t type)
+{
+	int addr;
+	uint32_t gpio_shift, tmp;
+
+	if (gpio > 11)
+		addr = AR_GPIO_OUTPUT_MUX3;
+	else if (gpio > 5)
+		addr = AR_GPIO_OUTPUT_MUX2;
+	else
+		addr = AR_GPIO_OUTPUT_MUX1;
+
+	gpio_shift = (gpio % 6) * 5;
+
+	if (AR_SREV_9280_20_OR_LATER(ah) ||
+	    (addr != AR_GPIO_OUTPUT_MUX1)) {
+		REG_RMW(ah, addr, (type << gpio_shift),
+		    (0x1f << gpio_shift));
+	} else {
+		tmp = REG_READ(ah, addr);
+		tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
+		tmp &= ~(0x1f << gpio_shift);
+		tmp |= (type << gpio_shift);
+		REG_WRITE(ah, addr, tmp);
+	}
+}
+
+void
+ath9k_hw_cfg_gpio_input(struct ath_hal *ah, uint32_t gpio)
+{
+	uint32_t gpio_shift;
+
+	ASSERT(gpio < ah->ah_caps.num_gpio_pins);
+
+	gpio_shift = gpio << 1;
+
+	REG_RMW(ah,
+	    AR_GPIO_OE_OUT,
+	    (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
+	    (AR_GPIO_OE_OUT_DRV << gpio_shift));
+}
+
+uint32_t
+ath9k_hw_gpio_get(struct ath_hal *ah, uint32_t gpio)
+{
+	if (gpio >= ah->ah_caps.num_gpio_pins)
+		return (0xffffffff);
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		return ((MS(REG_READ(ah, AR_GPIO_IN_OUT),
+		    AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0);
+	} else {
+		return ((MS(REG_READ(ah,
+		    AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
+		    AR_GPIO_BIT(gpio)) != 0);
+	}
+}
+
+void
+ath9k_hw_cfg_output(struct ath_hal *ah, uint32_t gpio,
+    uint32_t ah_signal_type)
+{
+	uint32_t gpio_shift;
+
+	ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
+
+	gpio_shift = 2 * gpio;
+
+	REG_RMW(ah,
+	    AR_GPIO_OE_OUT,
+	    (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
+	    (AR_GPIO_OE_OUT_DRV << gpio_shift));
+}
+
+void
+ath9k_hw_set_gpio(struct ath_hal *ah, uint32_t gpio, uint32_t val)
+{
+	REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
+	    AR_GPIO_BIT(gpio));
+}
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+void
+ath9k_enable_rfkill(struct ath_hal *ah)
+{
+	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+	    AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
+
+	REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
+	    AR_GPIO_INPUT_MUX2_RFSILENT);
+
+	ath9k_hw_cfg_gpio_input(ah, ah->ah_rfkill_gpio);
+	REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
+}
+#endif
+
+int
+ath9k_hw_select_antconfig(struct ath_hal *ah, uint32_t cfg)
+{
+	struct ath9k_channel *chan = ah->ah_curchan;
+	const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	uint16_t ant_config;
+	uint32_t halNumAntConfig;
+
+	halNumAntConfig = IS_CHAN_2GHZ(chan) ?
+	    pCap->num_antcfg_2ghz : pCap->num_antcfg_5ghz;
+
+	if (cfg < halNumAntConfig) {
+		if (!ath9k_hw_get_eeprom_antenna_cfg(ah, chan,
+		    cfg, &ant_config)) {
+			REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+			return (0);
+		}
+	}
+
+	return (-EINVAL);
+}
+
+uint32_t
+ath9k_hw_getdefantenna(struct ath_hal *ah)
+{
+	return (REG_READ(ah, AR_DEF_ANTENNA) & 0x7);
+}
+
+void
+ath9k_hw_setantenna(struct ath_hal *ah, uint32_t antenna)
+{
+	REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
+}
+
+/* ARGSUSED */
+boolean_t
+ath9k_hw_setantennaswitch(struct ath_hal *ah,
+    enum ath9k_ant_setting settings,
+    struct ath9k_channel *chan,
+    uint8_t *tx_chainmask,
+    uint8_t *rx_chainmask,
+    uint8_t *antenna_cfgd)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	static uint8_t tx_chainmask_cfg, rx_chainmask_cfg;
+
+	if (AR_SREV_9280(ah)) {
+		if (!tx_chainmask_cfg) {
+
+			tx_chainmask_cfg = *tx_chainmask;
+			rx_chainmask_cfg = *rx_chainmask;
+		}
+
+		switch (settings) {
+		case ATH9K_ANT_FIXED_A:
+			*tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
+			*rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
+			*antenna_cfgd = B_TRUE;
+			break;
+		case ATH9K_ANT_FIXED_B:
+			if (ah->ah_caps.tx_chainmask >
+			    ATH9K_ANTENNA1_CHAINMASK) {
+				*tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
+			}
+			*rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
+			*antenna_cfgd = B_TRUE;
+			break;
+		case ATH9K_ANT_VARIABLE:
+			*tx_chainmask = tx_chainmask_cfg;
+			*rx_chainmask = rx_chainmask_cfg;
+			*antenna_cfgd = B_TRUE;
+			break;
+		default:
+			break;
+		}
+	} else {
+		ahp->ah_diversityControl = settings;
+	}
+
+	return (B_TRUE);
+}
+
+/* General Operation */
+
+uint32_t
+ath9k_hw_getrxfilter(struct ath_hal *ah)
+{
+	uint32_t bits = REG_READ(ah, AR_RX_FILTER);
+	uint32_t phybits = REG_READ(ah, AR_PHY_ERR);
+
+	if (phybits & AR_PHY_ERR_RADAR)
+		bits |= ATH9K_RX_FILTER_PHYRADAR;
+	if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
+		bits |= ATH9K_RX_FILTER_PHYERR;
+
+	return (bits);
+}
+
+void
+ath9k_hw_setrxfilter(struct ath_hal *ah, uint32_t bits)
+{
+	uint32_t phybits;
+
+	REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
+	phybits = 0;
+	if (bits & ATH9K_RX_FILTER_PHYRADAR)
+		phybits |= AR_PHY_ERR_RADAR;
+	if (bits & ATH9K_RX_FILTER_PHYERR)
+		phybits |= AR_PHY_ERR_OFDM_TIMING |
+		    AR_PHY_ERR_CCK_TIMING;
+	REG_WRITE(ah, AR_PHY_ERR, phybits);
+
+	if (phybits)
+		REG_WRITE(ah, AR_RXCFG,
+		    REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
+	else
+		REG_WRITE(ah, AR_RXCFG,
+		    REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
+}
+
+boolean_t
+ath9k_hw_phy_disable(struct ath_hal *ah)
+{
+	return (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM));
+}
+
+boolean_t
+ath9k_hw_disable(struct ath_hal *ah)
+{
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+		return (B_FALSE);
+
+	return (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD));
+}
+
+boolean_t
+ath9k_hw_set_txpowerlimit(struct ath_hal *ah, uint32_t limit)
+{
+	struct ath9k_channel *chan = ah->ah_curchan;
+
+	/* LINT */
+	ah->ah_powerLimit = (uint16_t)min(limit, (uint32_t)MAX_RATE_POWER);
+
+	if (ath9k_hw_set_txpower(ah, chan,
+	    ath9k_regd_get_ctl(ah, chan),
+	    ath9k_regd_get_antenna_allowed(ah, chan),
+	    chan->maxRegTxPower * 2,
+	    ARN_MIN((uint32_t)MAX_RATE_POWER,
+	    (uint32_t)ah->ah_powerLimit)) != 0)
+		return (B_FALSE);
+
+	return (B_TRUE);
+}
+
+void
+ath9k_hw_getmac(struct ath_hal *ah, uint8_t *mac)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	(void) memcpy(mac, ahp->ah_macaddr, 6);
+}
+
+boolean_t
+ath9k_hw_setmac(struct ath_hal *ah, const uint8_t *mac)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	(void) memcpy(ahp->ah_macaddr, mac, 6);
+
+	return (B_TRUE);
+}
+
+void
+ath9k_hw_setopmode(struct ath_hal *ah)
+{
+	ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+}
+
+void
+ath9k_hw_setmcastfilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1)
+{
+	REG_WRITE(ah, AR_MCAST_FIL0, filter0);
+	REG_WRITE(ah, AR_MCAST_FIL1, filter1);
+}
+
+void
+ath9k_hw_getbssidmask(struct ath_hal *ah, uint8_t *mask)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	(void) memcpy(mask, ahp->ah_bssidmask, 6);
+}
+
+boolean_t
+ath9k_hw_setbssidmask(struct ath_hal *ah, const uint8_t *mask)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	(void) memcpy(ahp->ah_bssidmask, mask, 6);
+
+	REG_WRITE(ah, AR_BSSMSKL, ARN_LE_READ_32(ahp->ah_bssidmask));
+	REG_WRITE(ah, AR_BSSMSKU, ARN_LE_READ_16(ahp->ah_bssidmask + 4));
+
+	return (B_TRUE);
+}
+
+void
+ath9k_hw_write_associd(struct ath_hal *ah,
+    const uint8_t *bssid, uint16_t assocId)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	(void) memcpy(ahp->ah_bssid, bssid, 6);
+	ahp->ah_assocId = assocId;
+
+	REG_WRITE(ah, AR_BSS_ID0, ARN_LE_READ_32(ahp->ah_bssid));
+	REG_WRITE(ah, AR_BSS_ID1, ARN_LE_READ_16(ahp->ah_bssid + 4) |
+	    ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+}
+
+uint64_t
+ath9k_hw_gettsf64(struct ath_hal *ah)
+{
+	uint64_t tsf;
+
+	tsf = REG_READ(ah, AR_TSF_U32);
+	tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
+
+	return (tsf);
+}
+
+void
+ath9k_hw_reset_tsf(struct ath_hal *ah)
+{
+	int count;
+
+	count = 0;
+	while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
+		count++;
+		if (count > 10) {
+			ARN_DBG((ARN_DBG_HW, "arn: "
+			    "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
+			    __func__));
+
+			break;
+		}
+		drv_usecwait(10);
+	}
+	REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
+}
+
+boolean_t
+ath9k_hw_set_tsfadjust(struct ath_hal *ah, uint32_t setting)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (setting)
+		ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+	else
+		ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_setslottime(struct ath_hal *ah, uint32_t us)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
+		ARN_DBG((ARN_DBG_HW, "arn: "
+		    "%s: bad slot time %u\n",  __func__, us));
+
+		ahp->ah_slottime = (uint32_t)-1;
+		return (B_FALSE);
+	} else {
+		REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
+		ahp->ah_slottime = us;
+		return (B_TRUE);
+	}
+}
+
+void
+ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
+{
+	uint32_t macmode;
+
+	if (mode == ATH9K_HT_MACMODE_2040 &&
+	    !ah->ah_config.cwm_ignore_extcca)
+		macmode = AR_2040_JOINED_RX_CLEAR;
+	else
+		macmode = 0;
+
+	REG_WRITE(ah, AR_2040_MODE, macmode);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_hw.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,1089 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_ARN_HW_H
+#define	_ARN_HW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack(1)
+struct ar5416_desc {
+	uint32_t ds_link;
+	uint32_t ds_data;
+	uint32_t ds_ctl0;
+	uint32_t ds_ctl1;
+	union {
+		struct {
+			uint32_t ctl2;
+			uint32_t ctl3;
+			uint32_t ctl4;
+			uint32_t ctl5;
+			uint32_t ctl6;
+			uint32_t ctl7;
+			uint32_t ctl8;
+			uint32_t ctl9;
+			uint32_t ctl10;
+			uint32_t ctl11;
+			uint32_t status0;
+			uint32_t status1;
+			uint32_t status2;
+			uint32_t status3;
+			uint32_t status4;
+			uint32_t status5;
+			uint32_t status6;
+			uint32_t status7;
+			uint32_t status8;
+			uint32_t status9;
+		} tx;
+		struct {
+			uint32_t status0;
+			uint32_t status1;
+			uint32_t status2;
+			uint32_t status3;
+			uint32_t status4;
+			uint32_t status5;
+			uint32_t status6;
+			uint32_t status7;
+			uint32_t status8;
+		} rx;
+	} u;
+};
+#pragma pack()
+
+#define	AR5416DESC(_ds)		((struct ar5416_desc *)(_ds))
+#define	AR5416DESC_CONST(_ds)	((const struct ar5416_desc *)(_ds))
+
+#define	ds_ctl2		u.tx.ctl2
+#define	ds_ctl3		u.tx.ctl3
+#define	ds_ctl4		u.tx.ctl4
+#define	ds_ctl5		u.tx.ctl5
+#define	ds_ctl6		u.tx.ctl6
+#define	ds_ctl7		u.tx.ctl7
+#define	ds_ctl8		u.tx.ctl8
+#define	ds_ctl9		u.tx.ctl9
+#define	ds_ctl10	u.tx.ctl10
+#define	ds_ctl11	u.tx.ctl11
+
+#define	ds_txstatus0	u.tx.status0
+#define	ds_txstatus1	u.tx.status1
+#define	ds_txstatus2	u.tx.status2
+#define	ds_txstatus3	u.tx.status3
+#define	ds_txstatus4	u.tx.status4
+#define	ds_txstatus5	u.tx.status5
+#define	ds_txstatus6	u.tx.status6
+#define	ds_txstatus7	u.tx.status7
+#define	ds_txstatus8	u.tx.status8
+#define	ds_txstatus9	u.tx.status9
+
+#define	ds_rxstatus0	u.rx.status0
+#define	ds_rxstatus1	u.rx.status1
+#define	ds_rxstatus2	u.rx.status2
+#define	ds_rxstatus3	u.rx.status3
+#define	ds_rxstatus4	u.rx.status4
+#define	ds_rxstatus5	u.rx.status5
+#define	ds_rxstatus6	u.rx.status6
+#define	ds_rxstatus7	u.rx.status7
+#define	ds_rxstatus8	u.rx.status8
+
+#define	AR_FrameLen	0x00000fff
+#define	AR_VirtMoreFrag	0x00001000
+#define	AR_TxCtlRsvd00	0x0000e000
+#define	AR_XmitPower	0x003f0000
+#define	AR_XmitPower_S	16
+#define	AR_RTSEnable	0x00400000
+#define	AR_VEOL		0x00800000
+#define	AR_ClrDestMask	0x01000000
+#define	AR_TxCtlRsvd01	0x1e000000
+#define	AR_TxIntrReq	0x20000000
+#define	AR_DestIdxValid	0x40000000
+#define	AR_CTSEnable	0x80000000
+
+#define	AR_BufLen		0x00000fff
+#define	AR_TxMore		0x00001000
+#define	AR_DestIdx		0x000fe000
+#define	AR_DestIdx_S		13
+#define	AR_FrameType		0x00f00000
+#define	AR_FrameType_S		20
+#define	AR_NoAck		0x01000000
+#define	AR_InsertTS		0x02000000
+#define	AR_CorruptFCS		0x04000000
+#define	AR_ExtOnly		0x08000000
+#define	AR_ExtAndCtl		0x10000000
+#define	AR_MoreAggr		0x20000000
+#define	AR_IsAggr		0x40000000
+
+#define	AR_BurstDur		0x00007fff
+#define	AR_BurstDur_S		0
+#define	AR_DurUpdateEna		0x00008000
+#define	AR_XmitDataTries0	0x000f0000
+#define	AR_XmitDataTries0_S	16
+#define	AR_XmitDataTries1	0x00f00000
+#define	AR_XmitDataTries1_S	20
+#define	AR_XmitDataTries2	0x0f000000
+#define	AR_XmitDataTries2_S	24
+#define	AR_XmitDataTries3	0xf0000000
+#define	AR_XmitDataTries3_S	28
+
+#define	AR_XmitRate0		0x000000ff
+#define	AR_XmitRate0_S		0
+#define	AR_XmitRate1		0x0000ff00
+#define	AR_XmitRate1_S		8
+#define	AR_XmitRate2		0x00ff0000
+#define	AR_XmitRate2_S		16
+#define	AR_XmitRate3		0xff000000
+#define	AR_XmitRate3_S		24
+
+#define	AR_PacketDur0		0x00007fff
+#define	AR_PacketDur0_S		0
+#define	AR_RTSCTSQual0		0x00008000
+#define	AR_PacketDur1		0x7fff0000
+#define	AR_PacketDur1_S		16
+#define	AR_RTSCTSQual1		0x80000000
+
+#define	AR_PacketDur2		0x00007fff
+#define	AR_PacketDur2_S		0
+#define	AR_RTSCTSQual2		0x00008000
+#define	AR_PacketDur3		0x7fff0000
+#define	AR_PacketDur3_S		16
+#define	AR_RTSCTSQual3		0x80000000
+
+#define	AR_AggrLen		0x0000ffff
+#define	AR_AggrLen_S		0
+#define	AR_TxCtlRsvd60		0x00030000
+#define	AR_PadDelim		0x03fc0000
+#define	AR_PadDelim_S		18
+#define	AR_EncrType		0x0c000000
+#define	AR_EncrType_S		26
+#define	AR_TxCtlRsvd61		0xf0000000
+
+#define	AR_2040_0		0x00000001
+#define	AR_GI0			0x00000002
+#define	AR_ChainSel0		0x0000001c
+#define	AR_ChainSel0_S		2
+#define	AR_2040_1		0x00000020
+#define	AR_GI1			0x00000040
+#define	AR_ChainSel1		0x00000380
+#define	AR_ChainSel1_S		7
+#define	AR_2040_2		0x00000400
+#define	AR_GI2			0x00000800
+#define	AR_ChainSel2		0x00007000
+#define	AR_ChainSel2_S		12
+#define	AR_2040_3		0x00008000
+#define	AR_GI3			0x00010000
+#define	AR_ChainSel3		0x000e0000
+#define	AR_ChainSel3_S		17
+#define	AR_RTSCTSRate		0x0ff00000
+#define	AR_RTSCTSRate_S		20
+#define	AR_TxCtlRsvd70		0xf0000000
+
+#define	AR_TxRSSIAnt00		0x000000ff
+#define	AR_TxRSSIAnt00_S	0
+#define	AR_TxRSSIAnt01		0x0000ff00
+#define	AR_TxRSSIAnt01_S	8
+#define	AR_TxRSSIAnt02		0x00ff0000
+#define	AR_TxRSSIAnt02_S	16
+#define	AR_TxStatusRsvd00	0x3f000000
+#define	AR_TxBaStatus		0x40000000
+#define	AR_TxStatusRsvd01	0x80000000
+
+#define	AR_FrmXmitOK		0x00000001
+#define	AR_ExcessiveRetries	0x00000002
+#define	AR_FIFOUnderrun		0x00000004
+#define	AR_Filtered		0x00000008
+#define	AR_RTSFailCnt		0x000000f0
+#define	AR_RTSFailCnt_S		4
+#define	AR_DataFailCnt		0x00000f00
+#define	AR_DataFailCnt_S	8
+#define	AR_VirtRetryCnt		0x0000f000
+#define	AR_VirtRetryCnt_S	12
+#define	AR_TxDelimUnderrun	0x00010000
+#define	AR_TxDataUnderrun	0x00020000
+#define	AR_DescCfgErr		0x00040000
+#define	AR_TxTimerExpired	0x00080000
+#define	AR_TxStatusRsvd10	0xfff00000
+
+#define	AR_SendTimestamp	ds_txstatus2
+#define	AR_BaBitmapLow		ds_txstatus3
+#define	AR_BaBitmapHigh		ds_txstatus4
+
+#define	AR_TxRSSIAnt10		0x000000ff
+#define	AR_TxRSSIAnt10_S	0
+#define	AR_TxRSSIAnt11		0x0000ff00
+#define	AR_TxRSSIAnt11_S	8
+#define	AR_TxRSSIAnt12		0x00ff0000
+#define	AR_TxRSSIAnt12_S	16
+#define	AR_TxRSSICombined	0xff000000
+#define	AR_TxRSSICombined_S	24
+
+#define	AR_TxEVM0		ds_txstatus5
+#define	AR_TxEVM1		ds_txstatus6
+#define	AR_TxEVM2		ds_txstatus7
+
+#define	AR_TxDone		0x00000001
+#define	AR_SeqNum		0x00001ffe
+#define	AR_SeqNum_S		1
+#define	AR_TxStatusRsvd80	0x0001e000
+#define	AR_TxOpExceeded		0x00020000
+#define	AR_TxStatusRsvd81	0x001c0000
+#define	AR_FinalTxIdx		0x00600000
+#define	AR_FinalTxIdx_S		21
+#define	AR_TxStatusRsvd82	0x01800000
+#define	AR_PowerMgmt		0x02000000
+#define	AR_TxStatusRsvd83	0xfc000000
+
+#define	AR_RxCTLRsvd00		0xffffffff
+
+#define	AR_BufLen		0x00000fff
+#define	AR_RxCtlRsvd00		0x00001000
+#define	AR_RxIntrReq		0x00002000
+#define	AR_RxCtlRsvd01		0xffffc000
+
+#define	AR_RxRSSIAnt00		0x000000ff
+#define	AR_RxRSSIAnt00_S	0
+#define	AR_RxRSSIAnt01		0x0000ff00
+#define	AR_RxRSSIAnt01_S	8
+#define	AR_RxRSSIAnt02		0x00ff0000
+#define	AR_RxRSSIAnt02_S	16
+#define	AR_RxRate		0xff000000
+#define	AR_RxRate_S		24
+#define	AR_RxStatusRsvd00	0xff000000
+
+#define	AR_DataLen		0x00000fff
+#define	AR_RxMore		0x00001000
+#define	AR_NumDelim		0x003fc000
+#define	AR_NumDelim_S		14
+#define	AR_RxStatusRsvd10	0xff800000
+
+#define	AR_RcvTimestamp		ds_rxstatus2
+
+#define	AR_GI			0x00000001
+#define	AR_2040			0x00000002
+#define	AR_Parallel40		0x00000004
+#define	AR_Parallel40_S		2
+#define	AR_RxStatusRsvd30	0x000000f8
+#define	AR_RxAntenna		0xffffff00
+#define	AR_RxAntenna_S		8
+
+#define	AR_RxRSSIAnt10		0x000000ff
+#define	AR_RxRSSIAnt10_S	0
+#define	AR_RxRSSIAnt11		0x0000ff00
+#define	AR_RxRSSIAnt11_S	8
+#define	AR_RxRSSIAnt12		0x00ff0000
+#define	AR_RxRSSIAnt12_S	16
+#define	AR_RxRSSICombined	0xff000000
+#define	AR_RxRSSICombined_S	24
+
+#define	AR_RxEVM0		ds_rxstatus4
+#define	AR_RxEVM1		ds_rxstatus5
+#define	AR_RxEVM2		ds_rxstatus6
+
+#define	AR_RxDone		0x00000001
+#define	AR_RxFrameOK		0x00000002
+#define	AR_CRCErr		0x00000004
+#define	AR_DecryptCRCErr	0x00000008
+#define	AR_PHYErr		0x00000010
+#define	AR_MichaelErr		0x00000020
+#define	AR_PreDelimCRCErr	0x00000040
+#define	AR_RxStatusRsvd70	0x00000080
+#define	AR_RxKeyIdxValid	0x00000100
+#define	AR_KeyIdx		0x0000fe00
+#define	AR_KeyIdx_S		9
+#define	AR_PHYErrCode		0x0000ff00
+#define	AR_PHYErrCode_S		8
+#define	AR_RxMoreAggr		0x00010000
+#define	AR_RxAggr		0x00020000
+#define	AR_PostDelimCRCErr	0x00040000
+#define	AR_RxStatusRsvd71	0x3ff80000
+#define	AR_DecryptBusyErr	0x40000000
+#define	AR_KeyMiss		0x80000000
+
+#define	AR5416_MAGIC	0x19641014
+
+#define	RXSTATUS_RATE(ah, ads)	(AR_SREV_5416_V20_OR_LATER(ah) ?	\
+	MS(ads->ds_rxstatus0, AR_RxRate) :				\
+	(ads->ds_rxstatus3 >> 2) & 0xFF)
+
+#define	set11nTries(_series, _index)	\
+	(SM((_series)[_index].Tries, AR_XmitDataTries##_index))
+
+#define	set11nRate(_series, _index)	\
+	(SM((_series)[_index].Rate, AR_XmitRate##_index))
+
+#define	set11nPktDurRTSCTS(_series, _index)				\
+	(SM((_series)[_index].PktDuration, AR_PacketDur##_index) |	\
+	((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS   ?	\
+	    AR_RTSCTSQual##_index : 0))
+
+#define	set11nRateFlags(_series, _index)				\
+	(((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ?		\
+	    AR_2040_##_index : 0)					\
+	|((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ?	\
+	    AR_GI##_index : 0)						\
+	|SM((_series)[_index].ChSel, AR_ChainSel##_index))
+
+#define	AR_SREV_9100(ah)	((ah->ah_macVersion) == AR_SREV_VERSION_9100)
+
+#define	INIT_CONFIG_STATUS	0x00000000
+#define	INIT_RSSI_THR		0x00000700
+#define	INIT_BCON_CNTRL_REG	0x00000000
+
+#define	MIN_TX_FIFO_THRESHOLD	0x1
+#define	MAX_TX_FIFO_THRESHOLD	((4096 / 64) - 1)
+#define	INIT_TX_FIFO_THRESHOLD	MIN_TX_FIFO_THRESHOLD
+
+struct ar5416AniState {
+	struct ath9k_channel c;
+	uint8_t noiseImmunityLevel;
+	uint8_t spurImmunityLevel;
+	uint8_t firstepLevel;
+	uint8_t ofdmWeakSigDetectOff;
+	uint8_t cckWeakSigThreshold;
+	uint32_t listenTime;
+	uint32_t ofdmTrigHigh;
+	uint32_t ofdmTrigLow;
+	int32_t cckTrigHigh;
+	int32_t cckTrigLow;
+	int32_t rssiThrLow;
+	int32_t rssiThrHigh;
+	uint32_t noiseFloor;
+	uint32_t txFrameCount;
+	uint32_t rxFrameCount;
+	uint32_t cycleCount;
+	uint32_t ofdmPhyErrCount;
+	uint32_t cckPhyErrCount;
+	uint32_t ofdmPhyErrBase;
+	uint32_t cckPhyErrBase;
+	int16_t pktRssi[2];
+	int16_t ofdmErrRssi[2];
+	int16_t cckErrRssi[2];
+};
+
+#define	HAL_PROCESS_ANI	0x00000001
+#define	DO_ANI(ah) \
+	((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
+
+struct ar5416Stats {
+	uint32_t ast_ani_niup;
+	uint32_t ast_ani_nidown;
+	uint32_t ast_ani_spurup;
+	uint32_t ast_ani_spurdown;
+	uint32_t ast_ani_ofdmon;
+	uint32_t ast_ani_ofdmoff;
+	uint32_t ast_ani_cckhigh;
+	uint32_t ast_ani_ccklow;
+	uint32_t ast_ani_stepup;
+	uint32_t ast_ani_stepdown;
+	uint32_t ast_ani_ofdmerrs;
+	uint32_t ast_ani_cckerrs;
+	uint32_t ast_ani_reset;
+	uint32_t ast_ani_lzero;
+	uint32_t ast_ani_lneg;
+	struct ath9k_mib_stats ast_mibstats;
+	struct ath9k_node_stats ast_nodestats;
+};
+
+#define	AR5416_OPFLAGS_11A		0x01
+#define	AR5416_OPFLAGS_11G		0x02
+#define	AR5416_OPFLAGS_N_5G_HT40	0x04
+#define	AR5416_OPFLAGS_N_2G_HT40	0x08
+#define	AR5416_OPFLAGS_N_5G_HT20	0x10
+#define	AR5416_OPFLAGS_N_2G_HT20	0x20
+
+#define	EEP_RFSILENT_ENABLED		0x0001
+#define	EEP_RFSILENT_ENABLED_S		0
+#define	EEP_RFSILENT_POLARITY		0x0002
+#define	EEP_RFSILENT_POLARITY_S		1
+#define	EEP_RFSILENT_GPIO_SEL		0x001c
+#define	EEP_RFSILENT_GPIO_SEL_S		2
+
+#define	AR5416_EEP_NO_BACK_VER		0x1
+#define	AR5416_EEP_VER			0xE
+#define	AR5416_EEP_VER_MINOR_MASK	0x0FFF
+#define	AR5416_EEP_MINOR_VER_2		0x2
+#define	AR5416_EEP_MINOR_VER_3		0x3
+#define	AR5416_EEP_MINOR_VER_7		0x7
+#define	AR5416_EEP_MINOR_VER_9		0x9
+#define	AR5416_EEP_MINOR_VER_16		0x10
+#define	AR5416_EEP_MINOR_VER_17		0x11
+#define	AR5416_EEP_MINOR_VER_19		0x13
+
+#define	AR5416_NUM_5G_CAL_PIERS		8
+#define	AR5416_NUM_2G_CAL_PIERS		4
+#define	AR5416_NUM_5G_20_TARGET_POWERS	8
+#define	AR5416_NUM_5G_40_TARGET_POWERS	8
+#define	AR5416_NUM_2G_CCK_TARGET_POWERS	3
+#define	AR5416_NUM_2G_20_TARGET_POWERS	4
+#define	AR5416_NUM_2G_40_TARGET_POWERS	4
+#define	AR5416_NUM_CTLS			24
+#define	AR5416_NUM_BAND_EDGES		8
+#define	AR5416_NUM_PD_GAINS		4
+#define	AR5416_PD_GAINS_IN_MASK		4
+#define	AR5416_PD_GAIN_ICEPTS		5
+#define	AR5416_EEPROM_MODAL_SPURS	5
+#define	AR5416_MAX_RATE_POWER		63
+#define	AR5416_NUM_PDADC_VALUES		128
+#define	AR5416_BCHAN_UNUSED		0xFF
+#define	AR5416_MAX_PWR_RANGE_IN_HALF_DB	64
+#define	AR5416_MAX_CHAINS		3
+#define	AR5416_PWR_TABLE_OFFSET		-5
+
+/* Rx gain type values */
+#define	AR5416_EEP_RXGAIN_23DB_BACKOFF	0
+#define	AR5416_EEP_RXGAIN_13DB_BACKOFF	1
+#define	AR5416_EEP_RXGAIN_ORIG		2
+
+/* Tx gain type values */
+#define	AR5416_EEP_TXGAIN_ORIGINAL	0
+#define	AR5416_EEP_TXGAIN_HIGH_POWER	1
+
+#define	AR5416_EEP4K_START_LOC					64
+#define	AR5416_EEP4K_NUM_2G_CAL_PIERS			3
+#define	AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS	3
+#define	AR5416_EEP4K_NUM_2G_20_TARGET_POWERS	3
+#define	AR5416_EEP4K_NUM_2G_40_TARGET_POWERS	3
+#define	AR5416_EEP4K_NUM_CTLS					12
+#define	AR5416_EEP4K_NUM_BAND_EDGES				4
+#define	AR5416_EEP4K_NUM_PD_GAINS				2
+#define	AR5416_EEP4K_PD_GAINS_IN_MASK			4
+#define	AR5416_EEP4K_PD_GAIN_ICEPTS				5
+#define	AR5416_EEP4K_MAX_CHAINS					1
+
+enum eeprom_param {
+	EEP_NFTHRESH_5,
+	EEP_NFTHRESH_2,
+	EEP_MAC_MSW,
+	EEP_MAC_MID,
+	EEP_MAC_LSW,
+	EEP_REG_0,
+	EEP_REG_1,
+	EEP_OP_CAP,
+	EEP_OP_MODE,
+	EEP_RF_SILENT,
+	EEP_OB_5,
+	EEP_DB_5,
+	EEP_OB_2,
+	EEP_DB_2,
+	EEP_MINOR_REV,
+	EEP_TX_MASK,
+	EEP_RX_MASK,
+	EEP_RXGAIN_TYPE,
+	EEP_TXGAIN_TYPE,
+};
+
+enum ar5416_rates {
+	rate6mb, rate9mb, rate12mb, rate18mb,
+	rate24mb, rate36mb, rate48mb, rate54mb,
+	rate1l, rate2l, rate2s, rate5_5l,
+	rate5_5s, rate11l, rate11s, rateXr,
+	rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
+	rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
+	rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
+	rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
+	rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
+	Ar5416RateSize
+};
+
+enum ath9k_hal_freq_band {
+	ATH9K_HAL_FREQ_BAND_5GHZ = 0,
+	ATH9K_HAL_FREQ_BAND_2GHZ = 1
+};
+
+#pragma pack(1)
+struct base_eep_header {
+	uint16_t length;
+	uint16_t checksum;
+	uint16_t version;
+	uint8_t opCapFlags;
+	uint8_t eepMisc;
+	uint16_t regDmn[2];
+	uint8_t macAddr[6];
+	uint8_t rxMask;
+	uint8_t txMask;
+	uint16_t rfSilent;
+	uint16_t blueToothOptions;
+	uint16_t deviceCap;
+	uint32_t binBuildNumber;
+	uint8_t deviceType;
+	uint8_t pwdclkind;
+	uint8_t futureBase_1[2];
+	uint8_t rxGainType;
+	uint8_t futureBase_2[3];
+	uint8_t txGainType;
+	uint8_t futureBase_3[25];
+};
+
+struct base_eep_header_4k {
+	uint16_t length;
+	uint16_t checksum;
+	uint16_t version;
+	uint8_t opCapFlags;
+	uint8_t eepMisc;
+	uint16_t regDmn[2];
+	uint8_t macAddr[6];
+	uint8_t rxMask;
+	uint8_t txMask;
+	uint16_t rfSilent;
+	uint16_t blueToothOptions;
+	uint16_t deviceCap;
+	uint32_t binBuildNumber;
+	uint8_t deviceType;
+	uint8_t futureBase[1];
+};
+
+struct spur_chan {
+	uint16_t spurChan;
+	uint8_t spurRangeLow;
+	uint8_t spurRangeHigh;
+};
+
+struct modal_eep_header {
+	uint32_t antCtrlChain[AR5416_MAX_CHAINS];
+	uint32_t antCtrlCommon;
+	uint8_t antennaGainCh[AR5416_MAX_CHAINS];
+	uint8_t switchSettling;
+	uint8_t txRxAttenCh[AR5416_MAX_CHAINS];
+	uint8_t rxTxMarginCh[AR5416_MAX_CHAINS];
+	uint8_t adcDesiredSize;
+	uint8_t pgaDesiredSize;
+	uint8_t xlnaGainCh[AR5416_MAX_CHAINS];
+	uint8_t txEndToXpaOff;
+	uint8_t txEndToRxOn;
+	uint8_t txFrameToXpaOn;
+	uint8_t thresh62;
+	uint8_t noiseFloorThreshCh[AR5416_MAX_CHAINS];
+	uint8_t xpdGain;
+	uint8_t xpd;
+	uint8_t iqCalICh[AR5416_MAX_CHAINS];
+	uint8_t iqCalQCh[AR5416_MAX_CHAINS];
+	uint8_t pdGainOverlap;
+	uint8_t ob;
+	uint8_t db;
+	uint8_t xpaBiasLvl;
+	uint8_t pwrDecreaseFor2Chain;
+	uint8_t pwrDecreaseFor3Chain;
+	uint8_t txFrameToDataStart;
+	uint8_t txFrameToPaOn;
+	uint8_t ht40PowerIncForPdadc;
+	uint8_t bswAtten[AR5416_MAX_CHAINS];
+	uint8_t bswMargin[AR5416_MAX_CHAINS];
+	uint8_t swSettleHt40;
+	uint8_t xatten2Db[AR5416_MAX_CHAINS];
+	uint8_t xatten2Margin[AR5416_MAX_CHAINS];
+	uint8_t ob_ch1;
+	uint8_t db_ch1;
+	uint8_t useAnt1:1,
+	    force_xpaon:1,
+	    local_bias:1,
+	    femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+	uint8_t futureModalar9280;
+	uint16_t xpaBiasLvlFreq[3];
+	uint8_t futureModal[6];
+
+	struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+};
+
+struct modal_eep_4k_header {
+    uint32_t  antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+    uint32_t  antCtrlCommon;
+    uint8_t   antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   switchSettling;
+    uint8_t   txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   adcDesiredSize;
+    uint8_t   pgaDesiredSize;
+    uint8_t   xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   txEndToXpaOff;
+    uint8_t   txEndToRxOn;
+    uint8_t   txFrameToXpaOn;
+    uint8_t   thresh62;
+    uint8_t   noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   xpdGain;
+    uint8_t   xpd;
+    uint8_t   iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   pdGainOverlap;
+    uint8_t   ob_01;
+    uint8_t   db1_01;
+    uint8_t   xpaBiasLvl;
+    uint8_t   txFrameToDataStart;
+    uint8_t   txFrameToPaOn;
+    uint8_t   ht40PowerIncForPdadc;
+    uint8_t   bswAtten[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   bswMargin[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   swSettleHt40;
+    uint8_t   xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+    uint8_t   db2_01;
+    uint8_t   version;
+    uint16_t  ob_234;
+    uint16_t  db1_234;
+    uint16_t  db2_234;
+    uint8_t   futureModal[4];
+
+    struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+};
+
+struct cal_data_per_freq {
+	uint8_t pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+	uint8_t vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+};
+
+struct cal_data_per_freq_4k {
+	uint8_t pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+	uint8_t vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+};
+
+struct cal_target_power_leg {
+	uint8_t bChannel;
+	uint8_t tPow2x[4];
+};
+
+struct cal_target_power_ht {
+	uint8_t bChannel;
+	uint8_t tPow2x[8];
+};
+
+#ifdef __BIG_ENDIAN_BITFIELD
+struct cal_ctl_edges {
+	uint8_t bChannel;
+	uint8_t flag:2, tPower:6;
+};
+#else
+struct cal_ctl_edges {
+	uint8_t bChannel;
+	uint8_t tPower:6, flag:2;
+};
+#endif
+
+struct cal_ctl_data {
+	struct cal_ctl_edges
+	    ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+};
+
+struct cal_ctl_data_4k {
+	struct cal_ctl_edges
+	ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
+};
+
+struct ar5416_eeprom_def {
+	struct base_eep_header baseEepHeader;
+	uint8_t custData[64];
+	struct modal_eep_header modalHeader[2];
+	uint8_t calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
+	uint8_t calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
+	struct cal_data_per_freq
+	    calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
+	struct cal_data_per_freq
+	    calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+	struct cal_target_power_leg
+	    calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	    calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	    calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
+	struct cal_target_power_leg
+	    calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
+	struct cal_target_power_leg
+	    calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	    calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	    calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
+	uint8_t ctlIndex[AR5416_NUM_CTLS];
+	struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
+	uint8_t padding;
+};
+
+struct ar5416_eeprom_4k {
+	struct base_eep_header_4k baseEepHeader;
+	uint8_t custData[20];
+	struct modal_eep_4k_header modalHeader;
+	uint8_t calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
+	struct cal_data_per_freq_4k
+	calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
+	struct cal_target_power_leg
+	calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
+	struct cal_target_power_leg
+	calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
+	uint8_t ctlIndex[AR5416_EEP4K_NUM_CTLS];
+	struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
+	uint8_t padding;
+};
+#pragma pack()
+
+struct ar5416IniArray {
+	uint32_t *ia_array;
+	uint32_t ia_rows;
+	uint32_t ia_columns;
+};
+
+#define	INIT_INI_ARRAY(iniarray, array, rows, columns) do {	\
+		(iniarray)->ia_array = (uint32_t *)(array);		\
+		(iniarray)->ia_rows = (rows);			\
+		(iniarray)->ia_columns = (columns);		\
+		_NOTE(CONSTCOND) \
+	} while (0)
+
+#define	INI_RA(iniarray, row, column) \
+	(((iniarray)->ia_array)[(row) *	((iniarray)->ia_columns) + (column)])
+
+#define	INIT_CAL(_perCal) do {				\
+		(_perCal)->calState = CAL_WAITING;	\
+		(_perCal)->calNext = NULL;		\
+	} while (0)
+
+#define	INSERT_CAL(_ahp, _perCal)					\
+	do {								\
+		if ((_ahp)->ah_cal_list_last == NULL) {			\
+			(_ahp)->ah_cal_list =				\
+				(_ahp)->ah_cal_list_last = (_perCal);	\
+			((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
+		} else {						\
+			((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
+			(_ahp)->ah_cal_list_last = (_perCal);		\
+			(_perCal)->calNext = (_ahp)->ah_cal_list;	\
+		}							\
+	} while (0)
+
+enum hal_cal_types {
+	ADC_DC_INIT_CAL = 0x1,
+	ADC_GAIN_CAL = 0x2,
+	ADC_DC_CAL = 0x4,
+	IQ_MISMATCH_CAL = 0x8
+};
+
+enum hal_cal_state {
+	CAL_INACTIVE,
+	CAL_WAITING,
+	CAL_RUNNING,
+	CAL_DONE
+};
+
+#define	MIN_CAL_SAMPLES		1
+#define	MAX_CAL_SAMPLES		64
+#define	INIT_LOG_COUNT		5
+#define	PER_MIN_LOG_COUNT	2
+#define	PER_MAX_LOG_COUNT	10
+
+struct hal_percal_data {
+	enum hal_cal_types calType;
+	uint32_t calNumSamples;
+	uint32_t calCountMax;
+	void (*calCollect) (struct ath_hal *);
+	void (*calPostProc) (struct ath_hal *, uint8_t);
+};
+
+struct hal_cal_list {
+	const struct hal_percal_data *calData;
+	enum hal_cal_state calState;
+	struct hal_cal_list *calNext;
+};
+
+/*
+ * Enum to indentify the eeprom mappings
+ */
+enum hal_eep_map {
+	EEP_MAP_DEFAULT = 0x0,
+	EEP_MAP_4KBITS,
+	EEP_MAP_MAX
+};
+
+struct ath_hal_5416 {
+	struct ath_hal ah;
+	union {
+		struct ar5416_eeprom_def def;
+		struct ar5416_eeprom_4k map4k;
+	} ah_eeprom;
+	struct ar5416Stats ah_stats;
+	struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
+
+	uint8_t ah_macaddr[IEEE80211_ADDR_LEN];
+	uint8_t ah_bssid[IEEE80211_ADDR_LEN];
+	uint8_t ah_bssidmask[IEEE80211_ADDR_LEN];
+	uint16_t ah_assocId;
+
+	int16_t ah_curchanRadIndex;
+	uint32_t ah_maskReg;
+	uint32_t ah_txOkInterruptMask;
+	uint32_t ah_txErrInterruptMask;
+	uint32_t ah_txDescInterruptMask;
+	uint32_t ah_txEolInterruptMask;
+	uint32_t ah_txUrnInterruptMask;
+	boolean_t ah_chipFullSleep;
+	uint32_t ah_atimWindow;
+	uint16_t ah_antennaSwitchSwap;
+	enum ath9k_power_mode ah_powerMode;
+	enum ath9k_ant_setting ah_diversityControl;
+
+	/* Calibration */
+	enum hal_cal_types ah_suppCals;
+	struct hal_cal_list ah_iqCalData;
+	struct hal_cal_list ah_adcGainCalData;
+	struct hal_cal_list ah_adcDcCalInitData;
+	struct hal_cal_list ah_adcDcCalData;
+	struct hal_cal_list *ah_cal_list;
+	struct hal_cal_list *ah_cal_list_last;
+	struct hal_cal_list *ah_cal_list_curr;
+#define	ah_totalPowerMeasI ah_Meas0.unsign
+#define	ah_totalPowerMeasQ ah_Meas1.unsign
+#define	ah_totalIqCorrMeas ah_Meas2.sign
+#define	ah_totalAdcIOddPhase  ah_Meas0.unsign
+#define	ah_totalAdcIEvenPhase ah_Meas1.unsign
+#define	ah_totalAdcQOddPhase  ah_Meas2.unsign
+#define	ah_totalAdcQEvenPhase ah_Meas3.unsign
+#define	ah_totalAdcDcOffsetIOddPhase  ah_Meas0.sign
+#define	ah_totalAdcDcOffsetIEvenPhase ah_Meas1.sign
+#define	ah_totalAdcDcOffsetQOddPhase  ah_Meas2.sign
+#define	ah_totalAdcDcOffsetQEvenPhase ah_Meas3.sign
+	union {
+		uint32_t unsign[AR5416_MAX_CHAINS];
+		int32_t sign[AR5416_MAX_CHAINS];
+	} ah_Meas0;
+	union {
+		uint32_t unsign[AR5416_MAX_CHAINS];
+		int32_t sign[AR5416_MAX_CHAINS];
+	} ah_Meas1;
+	union {
+		uint32_t unsign[AR5416_MAX_CHAINS];
+		int32_t sign[AR5416_MAX_CHAINS];
+	} ah_Meas2;
+	union {
+		uint32_t unsign[AR5416_MAX_CHAINS];
+		int32_t sign[AR5416_MAX_CHAINS];
+	} ah_Meas3;
+	uint16_t ah_CalSamples;
+
+	uint32_t ah_staId1Defaults;
+	uint32_t ah_miscMode;
+	enum {
+		AUTO_32KHZ,
+		USE_32KHZ,
+		DONT_USE_32KHZ,
+	} ah_enable32kHzClock;
+
+	/* RF */
+	uint32_t *ah_analogBank0Data;
+	uint32_t *ah_analogBank1Data;
+	uint32_t *ah_analogBank2Data;
+	uint32_t *ah_analogBank3Data;
+	uint32_t *ah_analogBank6Data;
+	uint32_t *ah_analogBank6TPCData;
+	uint32_t *ah_analogBank7Data;
+	uint32_t *ah_addac5416_21;
+	uint32_t *ah_bank6Temp;
+
+	int16_t ah_txPowerIndexOffset;
+	uint32_t ah_beaconInterval;
+	uint32_t ah_slottime;
+	uint32_t ah_acktimeout;
+	uint32_t ah_ctstimeout;
+	uint32_t ah_globaltxtimeout;
+	uint8_t ah_gBeaconRate;
+	uint32_t ah_gpioSelect;
+	uint32_t ah_polarity;
+	uint32_t ah_gpioBit;
+
+	/* ANI */
+	uint32_t ah_procPhyErr;
+	boolean_t ah_hasHwPhyCounters;
+	uint32_t ah_aniPeriod;
+	struct ar5416AniState *ah_curani;
+	struct ar5416AniState ah_ani[255];
+	int ah_totalSizeDesired[5];
+	int ah_coarseHigh[5];
+	int ah_coarseLow[5];
+	int ah_firpwr[5];
+	enum ath9k_ani_cmd ah_ani_function;
+
+	uint32_t ah_intrTxqs;
+	boolean_t ah_intrMitigation;
+	enum ath9k_ht_extprotspacing ah_extprotspacing;
+	uint8_t ah_txchainmask;
+	uint8_t ah_rxchainmask;
+
+	struct ar5416IniArray ah_iniModes;
+	struct ar5416IniArray ah_iniCommon;
+	struct ar5416IniArray ah_iniBank0;
+	struct ar5416IniArray ah_iniBB_RfGain;
+	struct ar5416IniArray ah_iniBank1;
+	struct ar5416IniArray ah_iniBank2;
+	struct ar5416IniArray ah_iniBank3;
+	struct ar5416IniArray ah_iniBank6;
+	struct ar5416IniArray ah_iniBank6TPC;
+	struct ar5416IniArray ah_iniBank7;
+	struct ar5416IniArray ah_iniAddac;
+	struct ar5416IniArray ah_iniPcieSerdes;
+	struct ar5416IniArray ah_iniModesAdditional;
+	struct ar5416IniArray ah_iniModesRxGain;
+	struct ar5416IniArray ah_iniModesTxGain;
+	/* To indicate EEPROM mapping used */
+	enum hal_eep_map ah_eep_map;
+};
+#define	AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
+
+#define	FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
+
+#define	ar5416RfDetach(ah) do {					\
+		if (AH5416(ah)->ah_rfHal.rfDetach != NULL)	\
+			AH5416(ah)->ah_rfHal.rfDetach(ah);	\
+	} while (0)
+
+#define	ath9k_hw_use_flash(_ah)	\
+	(!(_ah->ah_flags & AH_USE_EEPROM))
+
+
+#define	DO_DELAY(x) do {			\
+		if ((++(x) % 64) == 0)          \
+			drv_usecwait(1);	\
+	} while (0)
+
+#define	REG_WRITE_ARRAY(iniarray, column, regWr) do {                   \
+		int r;							\
+		for (r = 0; r < ((iniarray)->ia_rows); r++) {		\
+			REG_WRITE(ah, INI_RA((iniarray), (r), 0),	\
+			    INI_RA((iniarray), r, (column)));		\
+			DO_DELAY(regWr);				\
+		}							\
+	} while (0)
+
+#define	BASE_ACTIVATE_DELAY		100
+#define	RTC_PLL_SETTLE_DELAY		1000
+#define	COEF_SCALE_S			24
+#define	HT40_CHANNEL_CENTER_SHIFT	10
+
+#define	AR5416_EEPROM_MAGIC_OFFSET	0x0
+
+#define	AR5416_EEPROM_S			2
+#define	AR5416_EEPROM_OFFSET		0x2000
+#define	AR5416_EEPROM_START_ADDR	\
+	(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
+#define	AR5416_EEPROM_MAX	0xae0
+#define	ar5416_get_eep_ver(_ahp)	\
+	(((_ahp)->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF)
+#define	ar5416_get_eep_rev(_ahp)	\
+	(((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF)
+#define	ar5416_get_ntxchains(_txchainmask)	\
+	(((_txchainmask >> 2) & 1) +	\
+	((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+
+/* EEPROM 4K bit map definations */
+#define	ar5416_get_eep4k_ver(_ahp)   \
+	(((_ahp)->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF)
+#define	ar5416_get_eep4k_rev(_ahp)   \
+	(((_ahp)->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF)
+
+#ifdef __BIG_ENDIAN
+#define	AR5416_EEPROM_MAGIC	0x5aa5
+#else
+#define	AR5416_EEPROM_MAGIC	0xa55a
+#endif
+
+#define	ATH9K_POW_SM(_r, _s)		(((_r) & 0x3f) << (_s))
+
+#define	ATH9K_ANTENNA0_CHAINMASK	0x1
+#define	ATH9K_ANTENNA1_CHAINMASK	0x2
+
+#define	ATH9K_NUM_DMA_DEBUG_REGS	8
+#define	ATH9K_NUM_QUEUES		10
+
+#define	HAL_NOISE_IMMUNE_MAX		4
+#define	HAL_SPUR_IMMUNE_MAX		7
+#define	HAL_FIRST_STEP_MAX		2
+
+#define	ATH9K_ANI_OFDM_TRIG_HIGH	500
+#define	ATH9K_ANI_OFDM_TRIG_LOW		200
+#define	ATH9K_ANI_CCK_TRIG_HIGH		200
+#define	ATH9K_ANI_CCK_TRIG_LOW		100
+#define	ATH9K_ANI_NOISE_IMMUNE_LVL	4
+#define	ATH9K_ANI_USE_OFDM_WEAK_SIG	B_TRUE
+#define	ATH9K_ANI_CCK_WEAK_SIG_THR	B_FALSE
+#define	ATH9K_ANI_SPUR_IMMUNE_LVL	7
+#define	ATH9K_ANI_FIRSTEP_LVL		0
+#define	ATH9K_ANI_RSSI_THR_HIGH		40
+#define	ATH9K_ANI_RSSI_THR_LOW		7
+#define	ATH9K_ANI_PERIOD		100
+
+#define	AR_GPIOD_MASK		0x00001FFF
+#define	AR_GPIO_BIT(_gpio)	(1 << (_gpio))
+
+#define	HAL_EP_RND(x, mul)	\
+	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define	BEACON_RSSI(ahp)	\
+	HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi,	\
+	ATH9K_RSSI_EP_MULTIPLIER)
+
+#define	ah_mibStats	ah_stats.ast_mibstats
+
+#define	AH_TIMEOUT	100000
+#define	AH_TIME_QUANTUM	10
+
+#define	AR_KEYTABLE_SIZE	128
+#define	POWER_UP_TIME		200000
+
+#define	EXT_ADDITIVE	(0x8000)
+#define	CTL_11A_EXT	(CTL_11A | EXT_ADDITIVE)
+#define	CTL_11G_EXT	(CTL_11G | EXT_ADDITIVE)
+#define	CTL_11B_EXT	(CTL_11B | EXT_ADDITIVE)
+
+#define	SUB_NUM_CTL_MODES_AT_5G_40	2
+#define	SUB_NUM_CTL_MODES_AT_2G_40	3
+#define	SPUR_RSSI_THRESH		40
+
+#define	TU_TO_USEC(_tu)		((_tu) << 10)
+
+#define	CAB_TIMEOUT_VAL		10
+#define	BEACON_TIMEOUT_VAL	10
+#define	MIN_BEACON_TIMEOUT_VAL	1
+#define	SLEEP_SLOP		3
+
+#define	CCK_SIFS_TIME		10
+#define	CCK_PREAMBLE_BITS	144
+#define	CCK_PLCP_BITS		48
+
+#define	OFDM_SIFS_TIME		16
+#define	OFDM_PREAMBLE_TIME	20
+#define	OFDM_PLCP_BITS		22
+#define	OFDM_SYMBOL_TIME	4
+
+#define	OFDM_SIFS_TIME_HALF	32
+#define	OFDM_PREAMBLE_TIME_HALF	40
+#define	OFDM_PLCP_BITS_HALF	22
+#define	OFDM_SYMBOL_TIME_HALF	8
+
+#define	OFDM_SIFS_TIME_QUARTER		64
+#define	OFDM_PREAMBLE_TIME_QUARTER	80
+#define	OFDM_PLCP_BITS_QUARTER		22
+#define	OFDM_SYMBOL_TIME_QUARTER	16
+
+uint32_t ath9k_hw_get_eeprom(struct ath_hal *ah,
+    enum eeprom_param param);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARN_HW_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_initvals.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,6337 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _ARN_INITVALS_H
+#define	_ARN_INITVALS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AR5416 to Fowl ar5146.ini */
+static const uint32_t ar5416Modes_9100[][6] = {
+	{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160,
+	    0x000001e0 },
+	{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c,
+	    0x000001e0 },
+	{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38,
+	    0x00001180 },
+	{ 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000,
+	    0x00014008 },
+	{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00,
+	    0x06e006e0 },
+	{ 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab,
+	    0x098813cf },
+	{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300,
+	    0x00000303 },
+	{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+	    0x02020200 },
+	{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001,
+	    0x0a020001 },
+	{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
+	    0x00000007 },
+	{ 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0,
+	    0x137216a0 },
+	{ 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x00009850, 0x6c48b4e0, 0x6c48b4e0, 0x6c48b0de, 0x6c48b0de,
+	    0x6c48b0de },
+	{ 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e,
+	    0x7ec82d2e },
+	{ 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e,
+	    0x31395d5e },
+	{ 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18,
+	    0x00049d18 },
+	{ 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00,
+	    0x0001ce00 },
+	{ 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190,
+	    0x409a4190 },
+	{ 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081,
+	    0x050cb081 },
+	{ 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898,
+	    0x000007d0 },
+	{ 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134,
+	    0x00000134 },
+	{ 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b,
+	    0xd0058a0b },
+	{ 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020,
+	    0xffb81020 },
+	{ 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80,
+	    0x00012d80 },
+	{ 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80,
+	    0x00012d80 },
+	{ 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80,
+	    0x00012d80 },
+	{ 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120,
+	    0x00001120 },
+	{ 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00,
+	    0x001a0a00 },
+	{ 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be,
+	    0x038919be },
+	{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77,
+	    0x06336f77 },
+	{ 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c,
+	    0x60f6532c },
+	{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8,
+	    0x08f186c8 },
+	{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384,
+	    0x00046384 },
+	{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880,
+	    0x00000880 },
+	{ 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788,
+	    0xd03e4788 },
+	{ 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a,
+	    0x1883800a },
+	{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108,
+	    0x00000000 },
+	{ 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa,
+	    0x0a1a7caa },
+	{ 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000,
+	    0x18010000 },
+	{ 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402,
+	    0x2e032402 },
+	{ 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06,
+	    0x4a0a3c06 },
+	{ 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b,
+	    0x621a540b },
+	{ 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b,
+	    0x764f6c1b },
+	{ 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a,
+	    0x845b7a5a },
+	{ 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf,
+	    0x950f8ccf },
+	{ 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f,
+	    0xa5cf9b4f },
+	{ 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f,
+	    0xbddfaf1f },
+	{ 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f,
+	    0xd1ffc93f },
+	{ 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 }
+};
+
+static const uint32_t ar5416Common_9100[][2] = {
+	{ 0x0000000c, 0x00000000 },
+	{ 0x00000030, 0x00020015 },
+	{ 0x00000034, 0x00000005 },
+	{ 0x00000040, 0x00000000 },
+	{ 0x00000044, 0x00000008 },
+	{ 0x00000048, 0x00000008 },
+	{ 0x0000004c, 0x00000010 },
+	{ 0x00000050, 0x00000000 },
+	{ 0x00000054, 0x0000001f },
+	{ 0x00000800, 0x00000000 },
+	{ 0x00000804, 0x00000000 },
+	{ 0x00000808, 0x00000000 },
+	{ 0x0000080c, 0x00000000 },
+	{ 0x00000810, 0x00000000 },
+	{ 0x00000814, 0x00000000 },
+	{ 0x00000818, 0x00000000 },
+	{ 0x0000081c, 0x00000000 },
+	{ 0x00000820, 0x00000000 },
+	{ 0x00000824, 0x00000000 },
+	{ 0x00001040, 0x002ffc0f },
+	{ 0x00001044, 0x002ffc0f },
+	{ 0x00001048, 0x002ffc0f },
+	{ 0x0000104c, 0x002ffc0f },
+	{ 0x00001050, 0x002ffc0f },
+	{ 0x00001054, 0x002ffc0f },
+	{ 0x00001058, 0x002ffc0f },
+	{ 0x0000105c, 0x002ffc0f },
+	{ 0x00001060, 0x002ffc0f },
+	{ 0x00001064, 0x002ffc0f },
+	{ 0x00001230, 0x00000000 },
+	{ 0x00001270, 0x00000000 },
+	{ 0x00001038, 0x00000000 },
+	{ 0x00001078, 0x00000000 },
+	{ 0x000010b8, 0x00000000 },
+	{ 0x000010f8, 0x00000000 },
+	{ 0x00001138, 0x00000000 },
+	{ 0x00001178, 0x00000000 },
+	{ 0x000011b8, 0x00000000 },
+	{ 0x000011f8, 0x00000000 },
+	{ 0x00001238, 0x00000000 },
+	{ 0x00001278, 0x00000000 },
+	{ 0x000012b8, 0x00000000 },
+	{ 0x000012f8, 0x00000000 },
+	{ 0x00001338, 0x00000000 },
+	{ 0x00001378, 0x00000000 },
+	{ 0x000013b8, 0x00000000 },
+	{ 0x000013f8, 0x00000000 },
+	{ 0x00001438, 0x00000000 },
+	{ 0x00001478, 0x00000000 },
+	{ 0x000014b8, 0x00000000 },
+	{ 0x000014f8, 0x00000000 },
+	{ 0x00001538, 0x00000000 },
+	{ 0x00001578, 0x00000000 },
+	{ 0x000015b8, 0x00000000 },
+	{ 0x000015f8, 0x00000000 },
+	{ 0x00001638, 0x00000000 },
+	{ 0x00001678, 0x00000000 },
+	{ 0x000016b8, 0x00000000 },
+	{ 0x000016f8, 0x00000000 },
+	{ 0x00001738, 0x00000000 },
+	{ 0x00001778, 0x00000000 },
+	{ 0x000017b8, 0x00000000 },
+	{ 0x000017f8, 0x00000000 },
+	{ 0x0000103c, 0x00000000 },
+	{ 0x0000107c, 0x00000000 },
+	{ 0x000010bc, 0x00000000 },
+	{ 0x000010fc, 0x00000000 },
+	{ 0x0000113c, 0x00000000 },
+	{ 0x0000117c, 0x00000000 },
+	{ 0x000011bc, 0x00000000 },
+	{ 0x000011fc, 0x00000000 },
+	{ 0x0000123c, 0x00000000 },
+	{ 0x0000127c, 0x00000000 },
+	{ 0x000012bc, 0x00000000 },
+	{ 0x000012fc, 0x00000000 },
+	{ 0x0000133c, 0x00000000 },
+	{ 0x0000137c, 0x00000000 },
+	{ 0x000013bc, 0x00000000 },
+	{ 0x000013fc, 0x00000000 },
+	{ 0x0000143c, 0x00000000 },
+	{ 0x0000147c, 0x00000000 },
+	{ 0x00004030, 0x00000002 },
+	{ 0x0000403c, 0x00000002 },
+	{ 0x00007010, 0x00000000 },
+	{ 0x00007038, 0x000004c2 },
+	{ 0x00008004, 0x00000000 },
+	{ 0x00008008, 0x00000000 },
+	{ 0x0000800c, 0x00000000 },
+	{ 0x00008018, 0x00000700 },
+	{ 0x00008020, 0x00000000 },
+	{ 0x00008038, 0x00000000 },
+	{ 0x0000803c, 0x00000000 },
+	{ 0x00008048, 0x40000000 },
+	{ 0x00008054, 0x00000000 },
+	{ 0x00008058, 0x00000000 },
+	{ 0x0000805c, 0x000fc78f },
+	{ 0x00008060, 0x0000000f },
+	{ 0x00008064, 0x00000000 },
+	{ 0x000080c0, 0x2a82301a },
+	{ 0x000080c4, 0x05dc01e0 },
+	{ 0x000080c8, 0x1f402710 },
+	{ 0x000080cc, 0x01f40000 },
+	{ 0x000080d0, 0x00001e00 },
+	{ 0x000080d4, 0x00000000 },
+	{ 0x000080d8, 0x00400000 },
+	{ 0x000080e0, 0xffffffff },
+	{ 0x000080e4, 0x0000ffff },
+	{ 0x000080e8, 0x003f3f3f },
+	{ 0x000080ec, 0x00000000 },
+	{ 0x000080f0, 0x00000000 },
+	{ 0x000080f4, 0x00000000 },
+	{ 0x000080f8, 0x00000000 },
+	{ 0x000080fc, 0x00020000 },
+	{ 0x00008100, 0x00020000 },
+	{ 0x00008104, 0x00000001 },
+	{ 0x00008108, 0x00000052 },
+	{ 0x0000810c, 0x00000000 },
+	{ 0x00008110, 0x00000168 },
+	{ 0x00008118, 0x000100aa },
+	{ 0x0000811c, 0x00003210 },
+	{ 0x00008120, 0x08f04800 },
+	{ 0x00008124, 0x00000000 },
+	{ 0x00008128, 0x00000000 },
+	{ 0x0000812c, 0x00000000 },
+	{ 0x00008130, 0x00000000 },
+	{ 0x00008134, 0x00000000 },
+	{ 0x00008138, 0x00000000 },
+	{ 0x0000813c, 0x00000000 },
+	{ 0x00008144, 0xffffffff },
+	{ 0x00008168, 0x00000000 },
+	{ 0x0000816c, 0x00000000 },
+	{ 0x00008170, 0x32143320 },
+	{ 0x00008174, 0xfaa4fa50 },
+	{ 0x00008178, 0x00000100 },
+	{ 0x0000817c, 0x00000000 },
+	{ 0x000081c4, 0x00000000 },
+	{ 0x000081d0, 0x00003210 },
+	{ 0x000081ec, 0x00000000 },
+	{ 0x000081f0, 0x00000000 },
+	{ 0x000081f4, 0x00000000 },
+	{ 0x000081f8, 0x00000000 },
+	{ 0x000081fc, 0x00000000 },
+	{ 0x00008200, 0x00000000 },
+	{ 0x00008204, 0x00000000 },
+	{ 0x00008208, 0x00000000 },
+	{ 0x0000820c, 0x00000000 },
+	{ 0x00008210, 0x00000000 },
+	{ 0x00008214, 0x00000000 },
+	{ 0x00008218, 0x00000000 },
+	{ 0x0000821c, 0x00000000 },
+	{ 0x00008220, 0x00000000 },
+	{ 0x00008224, 0x00000000 },
+	{ 0x00008228, 0x00000000 },
+	{ 0x0000822c, 0x00000000 },
+	{ 0x00008230, 0x00000000 },
+	{ 0x00008234, 0x00000000 },
+	{ 0x00008238, 0x00000000 },
+	{ 0x0000823c, 0x00000000 },
+	{ 0x00008240, 0x00100000 },
+	{ 0x00008244, 0x0010f400 },
+	{ 0x00008248, 0x00000100 },
+	{ 0x0000824c, 0x0001e800 },
+	{ 0x00008250, 0x00000000 },
+	{ 0x00008254, 0x00000000 },
+	{ 0x00008258, 0x00000000 },
+	{ 0x0000825c, 0x400000ff },
+	{ 0x00008260, 0x00080922 },
+	{ 0x00008270, 0x00000000 },
+	{ 0x00008274, 0x40000000 },
+	{ 0x00008278, 0x003e4180 },
+	{ 0x0000827c, 0x00000000 },
+	{ 0x00008284, 0x0000002c },
+	{ 0x00008288, 0x0000002c },
+	{ 0x0000828c, 0x00000000 },
+	{ 0x00008294, 0x00000000 },
+	{ 0x00008298, 0x00000000 },
+	{ 0x00008300, 0x00000000 },
+	{ 0x00008304, 0x00000000 },
+	{ 0x00008308, 0x00000000 },
+	{ 0x0000830c, 0x00000000 },
+	{ 0x00008310, 0x00000000 },
+	{ 0x00008314, 0x00000000 },
+	{ 0x00008318, 0x00000000 },
+	{ 0x00008328, 0x00000000 },
+	{ 0x0000832c, 0x00000007 },
+	{ 0x00008330, 0x00000302 },
+	{ 0x00008334, 0x00000e00 },
+	{ 0x00008338, 0x00070000 },
+	{ 0x0000833c, 0x00000000 },
+	{ 0x00008340, 0x000107ff },
+	{ 0x00009808, 0x00000000 },
+	{ 0x0000980c, 0xad848e19 },
+	{ 0x00009810, 0x7d14e000 },
+	{ 0x00009814, 0x9c0a9f6b },
+	{ 0x0000981c, 0x00000000 },
+	{ 0x0000982c, 0x0000a000 },
+	{ 0x00009830, 0x00000000 },
+	{ 0x0000983c, 0x00200400 },
+	{ 0x00009840, 0x206a002e },
+	{ 0x0000984c, 0x1284233c },
+	{ 0x00009854, 0x00000859 },
+	{ 0x00009900, 0x00000000 },
+	{ 0x00009904, 0x00000000 },
+	{ 0x00009908, 0x00000000 },
+	{ 0x0000990c, 0x00000000 },
+	{ 0x0000991c, 0x10000fff },
+	{ 0x00009920, 0x05100000 },
+	{ 0x0000a920, 0x05100000 },
+	{ 0x0000b920, 0x05100000 },
+	{ 0x00009928, 0x00000001 },
+	{ 0x0000992c, 0x00000004 },
+	{ 0x00009934, 0x1e1f2022 },
+	{ 0x00009938, 0x0a0b0c0d },
+	{ 0x0000993c, 0x00000000 },
+	{ 0x00009948, 0x9280b212 },
+	{ 0x0000994c, 0x00020028 },
+	{ 0x00009954, 0x5d50e188 },
+	{ 0x00009958, 0x00081fff },
+	{ 0x0000c95c, 0x004b6a8e },
+	{ 0x0000c968, 0x000003ce },
+	{ 0x00009970, 0x190fb515 },
+	{ 0x00009974, 0x00000000 },
+	{ 0x00009978, 0x00000001 },
+	{ 0x0000997c, 0x00000000 },
+	{ 0x00009980, 0x00000000 },
+	{ 0x00009984, 0x00000000 },
+	{ 0x00009988, 0x00000000 },
+	{ 0x0000998c, 0x00000000 },
+	{ 0x00009990, 0x00000000 },
+	{ 0x00009994, 0x00000000 },
+	{ 0x00009998, 0x00000000 },
+	{ 0x0000999c, 0x00000000 },
+	{ 0x000099a0, 0x00000000 },
+	{ 0x000099a4, 0x00000001 },
+	{ 0x000099a8, 0x001fff00 },
+	{ 0x000099ac, 0x00000000 },
+	{ 0x000099b0, 0x03051000 },
+	{ 0x000099dc, 0x00000000 },
+	{ 0x000099e0, 0x00000200 },
+	{ 0x000099e4, 0xaaaaaaaa },
+	{ 0x000099e8, 0x3c466478 },
+	{ 0x000099ec, 0x000000aa },
+	{ 0x000099fc, 0x00001042 },
+	{ 0x00009b00, 0x00000000 },
+	{ 0x00009b04, 0x00000001 },
+	{ 0x00009b08, 0x00000002 },
+	{ 0x00009b0c, 0x00000003 },
+	{ 0x00009b10, 0x00000004 },
+	{ 0x00009b14, 0x00000005 },
+	{ 0x00009b18, 0x00000008 },
+	{ 0x00009b1c, 0x00000009 },
+	{ 0x00009b20, 0x0000000a },
+	{ 0x00009b24, 0x0000000b },
+	{ 0x00009b28, 0x0000000c },
+	{ 0x00009b2c, 0x0000000d },
+	{ 0x00009b30, 0x00000010 },
+	{ 0x00009b34, 0x00000011 },
+	{ 0x00009b38, 0x00000012 },
+	{ 0x00009b3c, 0x00000013 },
+	{ 0x00009b40, 0x00000014 },
+	{ 0x00009b44, 0x00000015 },
+	{ 0x00009b48, 0x00000018 },
+	{ 0x00009b4c, 0x00000019 },
+	{ 0x00009b50, 0x0000001a },
+	{ 0x00009b54, 0x0000001b },
+	{ 0x00009b58, 0x0000001c },
+	{ 0x00009b5c, 0x0000001d },
+	{ 0x00009b60, 0x00000020 },
+	{ 0x00009b64, 0x00000021 },
+	{ 0x00009b68, 0x00000022 },
+	{ 0x00009b6c, 0x00000023 },
+	{ 0x00009b70, 0x00000024 },
+	{ 0x00009b74, 0x00000025 },
+	{ 0x00009b78, 0x00000028 },
+	{ 0x00009b7c, 0x00000029 },
+	{ 0x00009b80, 0x0000002a },
+	{ 0x00009b84, 0x0000002b },
+	{ 0x00009b88, 0x0000002c },
+	{ 0x00009b8c, 0x0000002d },
+	{ 0x00009b90, 0x00000030 },
+	{ 0x00009b94, 0x00000031 },
+	{ 0x00009b98, 0x00000032 },
+	{ 0x00009b9c, 0x00000033 },
+	{ 0x00009ba0, 0x00000034 },
+	{ 0x00009ba4, 0x00000035 },
+	{ 0x00009ba8, 0x00000035 },
+	{ 0x00009bac, 0x00000035 },
+	{ 0x00009bb0, 0x00000035 },
+	{ 0x00009bb4, 0x00000035 },
+	{ 0x00009bb8, 0x00000035 },
+	{ 0x00009bbc, 0x00000035 },
+	{ 0x00009bc0, 0x00000035 },
+	{ 0x00009bc4, 0x00000035 },
+	{ 0x00009bc8, 0x00000035 },
+	{ 0x00009bcc, 0x00000035 },
+	{ 0x00009bd0, 0x00000035 },
+	{ 0x00009bd4, 0x00000035 },
+	{ 0x00009bd8, 0x00000035 },
+	{ 0x00009bdc, 0x00000035 },
+	{ 0x00009be0, 0x00000035 },
+	{ 0x00009be4, 0x00000035 },
+	{ 0x00009be8, 0x00000035 },
+	{ 0x00009bec, 0x00000035 },
+	{ 0x00009bf0, 0x00000035 },
+	{ 0x00009bf4, 0x00000035 },
+	{ 0x00009bf8, 0x00000010 },
+	{ 0x00009bfc, 0x0000001a },
+	{ 0x0000a210, 0x40806333 },
+	{ 0x0000a214, 0x00106c10 },
+	{ 0x0000a218, 0x009c4060 },
+	{ 0x0000a220, 0x018830c6 },
+	{ 0x0000a224, 0x00000400 },
+	{ 0x0000a228, 0x00000bb5 },
+	{ 0x0000a22c, 0x00000011 },
+	{ 0x0000a234, 0x20202020 },
+	{ 0x0000a238, 0x20202020 },
+	{ 0x0000a23c, 0x13c889af },
+	{ 0x0000a240, 0x38490a20 },
+	{ 0x0000a244, 0x00007bb6 },
+	{ 0x0000a248, 0x0fff3ffc },
+	{ 0x0000a24c, 0x00000001 },
+	{ 0x0000a250, 0x0000a000 },
+	{ 0x0000a254, 0x00000000 },
+	{ 0x0000a258, 0x0cc75380 },
+	{ 0x0000a25c, 0x0f0f0f01 },
+	{ 0x0000a260, 0xdfa91f01 },
+	{ 0x0000a268, 0x00000000 },
+	{ 0x0000a26c, 0x0ebae9c6 },
+	{ 0x0000b26c, 0x0ebae9c6 },
+	{ 0x0000c26c, 0x0ebae9c6 },
+	{ 0x0000d270, 0x00820820 },
+	{ 0x0000a278, 0x1ce739ce },
+	{ 0x0000a27c, 0x051701ce },
+	{ 0x0000a338, 0x00000000 },
+	{ 0x0000a33c, 0x00000000 },
+	{ 0x0000a340, 0x00000000 },
+	{ 0x0000a344, 0x00000000 },
+	{ 0x0000a348, 0x3fffffff },
+	{ 0x0000a34c, 0x3fffffff },
+	{ 0x0000a350, 0x3fffffff },
+	{ 0x0000a354, 0x0003ffff },
+	{ 0x0000a358, 0x79a8aa1f },
+	{ 0x0000d35c, 0x07ffffef },
+	{ 0x0000d360, 0x0fffffe7 },
+	{ 0x0000d364, 0x17ffffe5 },
+	{ 0x0000d368, 0x1fffffe4 },
+	{ 0x0000d36c, 0x37ffffe3 },
+	{ 0x0000d370, 0x3fffffe3 },
+	{ 0x0000d374, 0x57ffffe3 },
+	{ 0x0000d378, 0x5fffffe2 },
+	{ 0x0000d37c, 0x7fffffe2 },
+	{ 0x0000d380, 0x7f3c7bba },
+	{ 0x0000d384, 0xf3307ff0 },
+	{ 0x0000a388, 0x08000000 },
+	{ 0x0000a38c, 0x20202020 },
+	{ 0x0000a390, 0x20202020 },
+	{ 0x0000a394, 0x1ce739ce },
+	{ 0x0000a398, 0x000001ce },
+	{ 0x0000a39c, 0x00000001 },
+	{ 0x0000a3a0, 0x00000000 },
+	{ 0x0000a3a4, 0x00000000 },
+	{ 0x0000a3a8, 0x00000000 },
+	{ 0x0000a3ac, 0x00000000 },
+	{ 0x0000a3b0, 0x00000000 },
+	{ 0x0000a3b4, 0x00000000 },
+	{ 0x0000a3b8, 0x00000000 },
+	{ 0x0000a3bc, 0x00000000 },
+	{ 0x0000a3c0, 0x00000000 },
+	{ 0x0000a3c4, 0x00000000 },
+	{ 0x0000a3c8, 0x00000246 },
+	{ 0x0000a3cc, 0x20202020 },
+	{ 0x0000a3d0, 0x20202020 },
+	{ 0x0000a3d4, 0x20202020 },
+	{ 0x0000a3dc, 0x1ce739ce },
+	{ 0x0000a3e0, 0x000001ce },
+};
+
+static const uint32_t ar5416Bank0_9100[][2] = {
+	{ 0x000098b0, 0x1e5795e5 },
+	{ 0x000098e0, 0x02008020 },
+};
+
+static const uint32_t ar5416BB_RfGain_9100[][3] = {
+	{ 0x00009a00, 0x00000000, 0x00000000 },
+	{ 0x00009a04, 0x00000040, 0x00000040 },
+	{ 0x00009a08, 0x00000080, 0x00000080 },
+	{ 0x00009a0c, 0x000001a1, 0x00000141 },
+	{ 0x00009a10, 0x000001e1, 0x00000181 },
+	{ 0x00009a14, 0x00000021, 0x000001c1 },
+	{ 0x00009a18, 0x00000061, 0x00000001 },
+	{ 0x00009a1c, 0x00000168, 0x00000041 },
+	{ 0x00009a20, 0x000001a8, 0x000001a8 },
+	{ 0x00009a24, 0x000001e8, 0x000001e8 },
+	{ 0x00009a28, 0x00000028, 0x00000028 },
+	{ 0x00009a2c, 0x00000068, 0x00000068 },
+	{ 0x00009a30, 0x00000189, 0x000000a8 },
+	{ 0x00009a34, 0x000001c9, 0x00000169 },
+	{ 0x00009a38, 0x00000009, 0x000001a9 },
+	{ 0x00009a3c, 0x00000049, 0x000001e9 },
+	{ 0x00009a40, 0x00000089, 0x00000029 },
+	{ 0x00009a44, 0x00000170, 0x00000069 },
+	{ 0x00009a48, 0x000001b0, 0x00000190 },
+	{ 0x00009a4c, 0x000001f0, 0x000001d0 },
+	{ 0x00009a50, 0x00000030, 0x00000010 },
+	{ 0x00009a54, 0x00000070, 0x00000050 },
+	{ 0x00009a58, 0x00000191, 0x00000090 },
+	{ 0x00009a5c, 0x000001d1, 0x00000151 },
+	{ 0x00009a60, 0x00000011, 0x00000191 },
+	{ 0x00009a64, 0x00000051, 0x000001d1 },
+	{ 0x00009a68, 0x00000091, 0x00000011 },
+	{ 0x00009a6c, 0x000001b8, 0x00000051 },
+	{ 0x00009a70, 0x000001f8, 0x00000198 },
+	{ 0x00009a74, 0x00000038, 0x000001d8 },
+	{ 0x00009a78, 0x00000078, 0x00000018 },
+	{ 0x00009a7c, 0x00000199, 0x00000058 },
+	{ 0x00009a80, 0x000001d9, 0x00000098 },
+	{ 0x00009a84, 0x00000019, 0x00000159 },
+	{ 0x00009a88, 0x00000059, 0x00000199 },
+	{ 0x00009a8c, 0x00000099, 0x000001d9 },
+	{ 0x00009a90, 0x000000d9, 0x00000019 },
+	{ 0x00009a94, 0x000000f9, 0x00000059 },
+	{ 0x00009a98, 0x000000f9, 0x00000099 },
+	{ 0x00009a9c, 0x000000f9, 0x000000d9 },
+	{ 0x00009aa0, 0x000000f9, 0x000000f9 },
+	{ 0x00009aa4, 0x000000f9, 0x000000f9 },
+	{ 0x00009aa8, 0x000000f9, 0x000000f9 },
+	{ 0x00009aac, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab8, 0x000000f9, 0x000000f9 },
+	{ 0x00009abc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac8, 0x000000f9, 0x000000f9 },
+	{ 0x00009acc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad8, 0x000000f9, 0x000000f9 },
+	{ 0x00009adc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae8, 0x000000f9, 0x000000f9 },
+	{ 0x00009aec, 0x000000f9, 0x000000f9 },
+	{ 0x00009af0, 0x000000f9, 0x000000f9 },
+	{ 0x00009af4, 0x000000f9, 0x000000f9 },
+	{ 0x00009af8, 0x000000f9, 0x000000f9 },
+	{ 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const uint32_t ar5416Bank1_9100[][2] = {
+	{ 0x000098b0, 0x02108421 },
+	{ 0x000098ec, 0x00000008 },
+};
+
+static const uint32_t ar5416Bank2_9100[][2] = {
+	{ 0x000098b0, 0x0e73ff17 },
+	{ 0x000098e0, 0x00000420 },
+};
+
+static const uint32_t ar5416Bank3_9100[][3] = {
+	{ 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const uint32_t ar5416Bank6_9100[][3] = {
+
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00e00000, 0x00e00000 },
+	{ 0x0000989c, 0x005e0000, 0x005e0000 },
+	{ 0x0000989c, 0x00120000, 0x00120000 },
+	{ 0x0000989c, 0x00620000, 0x00620000 },
+	{ 0x0000989c, 0x00020000, 0x00020000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x40ff0000, 0x40ff0000 },
+	{ 0x0000989c, 0x005f0000, 0x005f0000 },
+	{ 0x0000989c, 0x00870000, 0x00870000 },
+	{ 0x0000989c, 0x00f90000, 0x00f90000 },
+	{ 0x0000989c, 0x007b0000, 0x007b0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00f50000, 0x00f50000 },
+	{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
+	{ 0x0000989c, 0x00110000, 0x00110000 },
+	{ 0x0000989c, 0x006100a8, 0x006100a8 },
+	{ 0x0000989c, 0x004210a2, 0x004210a2 },
+	{ 0x0000989c, 0x0014008f, 0x0014008f },
+	{ 0x0000989c, 0x00c40003, 0x00c40003 },
+	{ 0x0000989c, 0x003000f2, 0x003000f2 },
+	{ 0x0000989c, 0x00440016, 0x00440016 },
+	{ 0x0000989c, 0x00410040, 0x00410040 },
+	{ 0x0000989c, 0x0001805e, 0x0001805e },
+	{ 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+	{ 0x0000989c, 0x000000f1, 0x000000f1 },
+	{ 0x0000989c, 0x00002081, 0x00002081 },
+	{ 0x0000989c, 0x000000d4, 0x000000d4 },
+	{ 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const uint32_t ar5416Bank6TPC_9100[][3] = {
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00e00000, 0x00e00000 },
+	{ 0x0000989c, 0x005e0000, 0x005e0000 },
+	{ 0x0000989c, 0x00120000, 0x00120000 },
+	{ 0x0000989c, 0x00620000, 0x00620000 },
+	{ 0x0000989c, 0x00020000, 0x00020000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x40ff0000, 0x40ff0000 },
+	{ 0x0000989c, 0x005f0000, 0x005f0000 },
+	{ 0x0000989c, 0x00870000, 0x00870000 },
+	{ 0x0000989c, 0x00f90000, 0x00f90000 },
+	{ 0x0000989c, 0x007b0000, 0x007b0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00f50000, 0x00f50000 },
+	{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
+	{ 0x0000989c, 0x00110000, 0x00110000 },
+	{ 0x0000989c, 0x006100a8, 0x006100a8 },
+	{ 0x0000989c, 0x00423022, 0x00423022 },
+	{ 0x0000989c, 0x201400df, 0x201400df },
+	{ 0x0000989c, 0x00c40002, 0x00c40002 },
+	{ 0x0000989c, 0x003000f2, 0x003000f2 },
+	{ 0x0000989c, 0x00440016, 0x00440016 },
+	{ 0x0000989c, 0x00410040, 0x00410040 },
+	{ 0x0000989c, 0x0001805e, 0x0001805e },
+	{ 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+	{ 0x0000989c, 0x000000e1, 0x000000e1 },
+	{ 0x0000989c, 0x00007081, 0x00007081 },
+	{ 0x0000989c, 0x000000d4, 0x000000d4 },
+	{ 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const uint32_t ar5416Bank7_9100[][2] = {
+	{ 0x0000989c, 0x00000500 },
+	{ 0x0000989c, 0x00000800 },
+	{ 0x000098cc, 0x0000000e },
+};
+
+static const uint32_t ar5416Addac_9100[][2] = {
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000003 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x0000000c },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000030 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000060 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000058 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x000098c4,  0x00000000 },
+};
+
+/* ar5416 - howl ar5416_howl.ini */
+static const uint32_t ar5416Modes[][6] = {
+	{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160,
+	    0x000001e0 },
+	{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c,
+	    0x000001e0 },
+	{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38,
+	    0x00001180 },
+	{ 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000,
+	    0x00014008 },
+	{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00,
+	    0x06e006e0 },
+	{ 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab,
+	    0x098813cf },
+	{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300,
+	    0x00000303 },
+	{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+	    0x02020200 },
+	{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001,
+	    0x0a020001 },
+	{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
+	    0x00000007 },
+	{ 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0,
+	    0x037216a0 },
+	{ 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2,
+	    0x6d48b0e2 },
+	{ 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e,
+	    0x7ec82d2e },
+	{ 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e,
+	    0x3139605e },
+	{ 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20,
+	    0x00048d18 },
+	{ 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00,
+	    0x0001ce00 },
+	{ 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0,
+	    0x409a40d0 },
+	{ 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081,
+	    0x050cb081 },
+	{ 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898,
+	    0x000007d0 },
+	{ 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b,
+	    0x00000016 },
+	{ 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d,
+	    0xd00a8a0d },
+	{ 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204,
+	    0xfff81204 },
+	{ 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020,
+	    0xdfb81020 },
+	{ 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e,
+	    0xe250a51e },
+	{ 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff,
+	    0x3388ffff },
+#ifdef TB243
+	{ 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40,
+	    0x00012d80 },
+	{ 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40,
+	    0x00012d80 },
+	{ 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40,
+	    0x00012d80 },
+	{ 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210,
+	    0x00001120 },
+#else
+	{ 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0,
+	    0x0001bfc0 },
+	{ 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0,
+	    0x0001bfc0 },
+	{ 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0,
+	    0x0001bfc0 },
+	{ 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120,
+	    0x00001120 },
+#endif
+	{ 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00,
+	    0x001a0c00 },
+	{ 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be,
+	    0x038919be },
+	{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77,
+	    0x06336f77 },
+	{ 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329,
+	    0x60f65329 },
+	{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8,
+	    0x08f186c8 },
+	{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384,
+	    0x00046384 },
+	{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880,
+	    0x00000880 },
+	{ 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788,
+	    0xd03e4788 },
+	{ 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a,
+	    0x1883800a },
+	{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108,
+	    0x00000000 },
+	{ 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa,
+	    0x0a1a7caa },
+	{ 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000,
+	    0x18010000 },
+	{ 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402,
+	    0x2e032402 },
+	{ 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06,
+	    0x4a0a3c06 },
+	{ 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b,
+	    0x621a540b },
+	{ 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b,
+	    0x764f6c1b },
+	{ 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a,
+	    0x845b7a5a },
+	{ 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf,
+	    0x950f8ccf },
+	{ 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f,
+	    0xa5cf9b4f },
+	{ 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f,
+	    0xbddfaf1f },
+	{ 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f,
+	    0xd1ffc93f },
+	{ 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+};
+
+static const uint32_t ar5416Common[][2] = {
+	{ 0x0000000c, 0x00000000 },
+	{ 0x00000030, 0x00020015 },
+	{ 0x00000034, 0x00000005 },
+	{ 0x00000040, 0x00000000 },
+	{ 0x00000044, 0x00000008 },
+	{ 0x00000048, 0x00000008 },
+	{ 0x0000004c, 0x00000010 },
+	{ 0x00000050, 0x00000000 },
+	{ 0x00000054, 0x0000001f },
+	{ 0x00000800, 0x00000000 },
+	{ 0x00000804, 0x00000000 },
+	{ 0x00000808, 0x00000000 },
+	{ 0x0000080c, 0x00000000 },
+	{ 0x00000810, 0x00000000 },
+	{ 0x00000814, 0x00000000 },
+	{ 0x00000818, 0x00000000 },
+	{ 0x0000081c, 0x00000000 },
+	{ 0x00000820, 0x00000000 },
+	{ 0x00000824, 0x00000000 },
+	{ 0x00001040, 0x002ffc0f },
+	{ 0x00001044, 0x002ffc0f },
+	{ 0x00001048, 0x002ffc0f },
+	{ 0x0000104c, 0x002ffc0f },
+	{ 0x00001050, 0x002ffc0f },
+	{ 0x00001054, 0x002ffc0f },
+	{ 0x00001058, 0x002ffc0f },
+	{ 0x0000105c, 0x002ffc0f },
+	{ 0x00001060, 0x002ffc0f },
+	{ 0x00001064, 0x002ffc0f },
+	{ 0x00001230, 0x00000000 },
+	{ 0x00001270, 0x00000000 },
+	{ 0x00001038, 0x00000000 },
+	{ 0x00001078, 0x00000000 },
+	{ 0x000010b8, 0x00000000 },
+	{ 0x000010f8, 0x00000000 },
+	{ 0x00001138, 0x00000000 },
+	{ 0x00001178, 0x00000000 },
+	{ 0x000011b8, 0x00000000 },
+	{ 0x000011f8, 0x00000000 },
+	{ 0x00001238, 0x00000000 },
+	{ 0x00001278, 0x00000000 },
+	{ 0x000012b8, 0x00000000 },
+	{ 0x000012f8, 0x00000000 },
+	{ 0x00001338, 0x00000000 },
+	{ 0x00001378, 0x00000000 },
+	{ 0x000013b8, 0x00000000 },
+	{ 0x000013f8, 0x00000000 },
+	{ 0x00001438, 0x00000000 },
+	{ 0x00001478, 0x00000000 },
+	{ 0x000014b8, 0x00000000 },
+	{ 0x000014f8, 0x00000000 },
+	{ 0x00001538, 0x00000000 },
+	{ 0x00001578, 0x00000000 },
+	{ 0x000015b8, 0x00000000 },
+	{ 0x000015f8, 0x00000000 },
+	{ 0x00001638, 0x00000000 },
+	{ 0x00001678, 0x00000000 },
+	{ 0x000016b8, 0x00000000 },
+	{ 0x000016f8, 0x00000000 },
+	{ 0x00001738, 0x00000000 },
+	{ 0x00001778, 0x00000000 },
+	{ 0x000017b8, 0x00000000 },
+	{ 0x000017f8, 0x00000000 },
+	{ 0x0000103c, 0x00000000 },
+	{ 0x0000107c, 0x00000000 },
+	{ 0x000010bc, 0x00000000 },
+	{ 0x000010fc, 0x00000000 },
+	{ 0x0000113c, 0x00000000 },
+	{ 0x0000117c, 0x00000000 },
+	{ 0x000011bc, 0x00000000 },
+	{ 0x000011fc, 0x00000000 },
+	{ 0x0000123c, 0x00000000 },
+	{ 0x0000127c, 0x00000000 },
+	{ 0x000012bc, 0x00000000 },
+	{ 0x000012fc, 0x00000000 },
+	{ 0x0000133c, 0x00000000 },
+	{ 0x0000137c, 0x00000000 },
+	{ 0x000013bc, 0x00000000 },
+	{ 0x000013fc, 0x00000000 },
+	{ 0x0000143c, 0x00000000 },
+	{ 0x0000147c, 0x00000000 },
+	{ 0x00020010, 0x00000003 },
+	{ 0x00020038, 0x000004c2 },
+	{ 0x00008004, 0x00000000 },
+	{ 0x00008008, 0x00000000 },
+	{ 0x0000800c, 0x00000000 },
+	{ 0x00008018, 0x00000700 },
+	{ 0x00008020, 0x00000000 },
+	{ 0x00008038, 0x00000000 },
+	{ 0x0000803c, 0x00000000 },
+	{ 0x00008048, 0x40000000 },
+	{ 0x00008054, 0x00004000 },
+	{ 0x00008058, 0x00000000 },
+	{ 0x0000805c, 0x000fc78f },
+	{ 0x00008060, 0x0000000f },
+	{ 0x00008064, 0x00000000 },
+	{ 0x000080c0, 0x2a82301a },
+	{ 0x000080c4, 0x05dc01e0 },
+	{ 0x000080c8, 0x1f402710 },
+	{ 0x000080cc, 0x01f40000 },
+	{ 0x000080d0, 0x00001e00 },
+	{ 0x000080d4, 0x00000000 },
+	{ 0x000080d8, 0x00400000 },
+	{ 0x000080e0, 0xffffffff },
+	{ 0x000080e4, 0x0000ffff },
+	{ 0x000080e8, 0x003f3f3f },
+	{ 0x000080ec, 0x00000000 },
+	{ 0x000080f0, 0x00000000 },
+	{ 0x000080f4, 0x00000000 },
+	{ 0x000080f8, 0x00000000 },
+	{ 0x000080fc, 0x00020000 },
+	{ 0x00008100, 0x00020000 },
+	{ 0x00008104, 0x00000001 },
+	{ 0x00008108, 0x00000052 },
+	{ 0x0000810c, 0x00000000 },
+	{ 0x00008110, 0x00000168 },
+	{ 0x00008118, 0x000100aa },
+	{ 0x0000811c, 0x00003210 },
+	{ 0x00008120, 0x08f04800 },
+	{ 0x00008124, 0x00000000 },
+	{ 0x00008128, 0x00000000 },
+	{ 0x0000812c, 0x00000000 },
+	{ 0x00008130, 0x00000000 },
+	{ 0x00008134, 0x00000000 },
+	{ 0x00008138, 0x00000000 },
+	{ 0x0000813c, 0x00000000 },
+	{ 0x00008144, 0x00000000 },
+	{ 0x00008168, 0x00000000 },
+	{ 0x0000816c, 0x00000000 },
+	{ 0x00008170, 0x32143320 },
+	{ 0x00008174, 0xfaa4fa50 },
+	{ 0x00008178, 0x00000100 },
+	{ 0x0000817c, 0x00000000 },
+	{ 0x000081c4, 0x00000000 },
+	{ 0x000081d0, 0x00003210 },
+	{ 0x000081ec, 0x00000000 },
+	{ 0x000081f0, 0x00000000 },
+	{ 0x000081f4, 0x00000000 },
+	{ 0x000081f8, 0x00000000 },
+	{ 0x000081fc, 0x00000000 },
+	{ 0x00008200, 0x00000000 },
+	{ 0x00008204, 0x00000000 },
+	{ 0x00008208, 0x00000000 },
+	{ 0x0000820c, 0x00000000 },
+	{ 0x00008210, 0x00000000 },
+	{ 0x00008214, 0x00000000 },
+	{ 0x00008218, 0x00000000 },
+	{ 0x0000821c, 0x00000000 },
+	{ 0x00008220, 0x00000000 },
+	{ 0x00008224, 0x00000000 },
+	{ 0x00008228, 0x00000000 },
+	{ 0x0000822c, 0x00000000 },
+	{ 0x00008230, 0x00000000 },
+	{ 0x00008234, 0x00000000 },
+	{ 0x00008238, 0x00000000 },
+	{ 0x0000823c, 0x00000000 },
+	{ 0x00008240, 0x00100000 },
+	{ 0x00008244, 0x0010f400 },
+	{ 0x00008248, 0x00000100 },
+	{ 0x0000824c, 0x0001e800 },
+	{ 0x00008250, 0x00000000 },
+	{ 0x00008254, 0x00000000 },
+	{ 0x00008258, 0x00000000 },
+	{ 0x0000825c, 0x400000ff },
+	{ 0x00008260, 0x00080922 },
+	{ 0x00008270, 0x00000000 },
+	{ 0x00008274, 0x40000000 },
+	{ 0x00008278, 0x003e4180 },
+	{ 0x0000827c, 0x00000000 },
+	{ 0x00008284, 0x0000002c },
+	{ 0x00008288, 0x0000002c },
+	{ 0x0000828c, 0x00000000 },
+	{ 0x00008294, 0x00000000 },
+	{ 0x00008298, 0x00000000 },
+	{ 0x00008300, 0x00000000 },
+	{ 0x00008304, 0x00000000 },
+	{ 0x00008308, 0x00000000 },
+	{ 0x0000830c, 0x00000000 },
+	{ 0x00008310, 0x00000000 },
+	{ 0x00008314, 0x00000000 },
+	{ 0x00008318, 0x00000000 },
+	{ 0x00008328, 0x00000000 },
+	{ 0x0000832c, 0x00000007 },
+	{ 0x00008330, 0x00000302 },
+	{ 0x00008334, 0x00000e00 },
+	{ 0x00008338, 0x00000000 },
+	{ 0x0000833c, 0x00000000 },
+	{ 0x00008340, 0x000107ff },
+	{ 0x00009808, 0x00000000 },
+	{ 0x0000980c, 0xad848e19 },
+	{ 0x00009810, 0x7d14e000 },
+	{ 0x00009814, 0x9c0a9f6b },
+	{ 0x0000981c, 0x00000000 },
+	{ 0x0000982c, 0x0000a000 },
+	{ 0x00009830, 0x00000000 },
+	{ 0x0000983c, 0x00200400 },
+	{ 0x00009840, 0x206a01ae },
+	{ 0x0000984c, 0x1284233c },
+	{ 0x00009854, 0x00000859 },
+	{ 0x00009900, 0x00000000 },
+	{ 0x00009904, 0x00000000 },
+	{ 0x00009908, 0x00000000 },
+	{ 0x0000990c, 0x00000000 },
+	{ 0x0000991c, 0x10000fff },
+	{ 0x00009920, 0x05100000 },
+	{ 0x0000a920, 0x05100000 },
+	{ 0x0000b920, 0x05100000 },
+	{ 0x00009928, 0x00000001 },
+	{ 0x0000992c, 0x00000004 },
+	{ 0x00009934, 0x1e1f2022 },
+	{ 0x00009938, 0x0a0b0c0d },
+	{ 0x0000993c, 0x00000000 },
+	{ 0x00009948, 0x9280b212 },
+	{ 0x0000994c, 0x00020028 },
+	{ 0x0000c95c, 0x004b6a8e },
+	{ 0x0000c968, 0x000003ce },
+	{ 0x00009970, 0x190fb515 },
+	{ 0x00009974, 0x00000000 },
+	{ 0x00009978, 0x00000001 },
+	{ 0x0000997c, 0x00000000 },
+	{ 0x00009980, 0x00000000 },
+	{ 0x00009984, 0x00000000 },
+	{ 0x00009988, 0x00000000 },
+	{ 0x0000998c, 0x00000000 },
+	{ 0x00009990, 0x00000000 },
+	{ 0x00009994, 0x00000000 },
+	{ 0x00009998, 0x00000000 },
+	{ 0x0000999c, 0x00000000 },
+	{ 0x000099a0, 0x00000000 },
+	{ 0x000099a4, 0x00000001 },
+	{ 0x000099a8, 0x201fff00 },
+	{ 0x000099ac, 0x006f0000 },
+	{ 0x000099b0, 0x03051000 },
+	{ 0x000099dc, 0x00000000 },
+	{ 0x000099e0, 0x00000200 },
+	{ 0x000099e4, 0xaaaaaaaa },
+	{ 0x000099e8, 0x3c466478 },
+	{ 0x000099ec, 0x0cc80caa },
+	{ 0x000099fc, 0x00001042 },
+	{ 0x00009b00, 0x00000000 },
+	{ 0x00009b04, 0x00000001 },
+	{ 0x00009b08, 0x00000002 },
+	{ 0x00009b0c, 0x00000003 },
+	{ 0x00009b10, 0x00000004 },
+	{ 0x00009b14, 0x00000005 },
+	{ 0x00009b18, 0x00000008 },
+	{ 0x00009b1c, 0x00000009 },
+	{ 0x00009b20, 0x0000000a },
+	{ 0x00009b24, 0x0000000b },
+	{ 0x00009b28, 0x0000000c },
+	{ 0x00009b2c, 0x0000000d },
+	{ 0x00009b30, 0x00000010 },
+	{ 0x00009b34, 0x00000011 },
+	{ 0x00009b38, 0x00000012 },
+	{ 0x00009b3c, 0x00000013 },
+	{ 0x00009b40, 0x00000014 },
+	{ 0x00009b44, 0x00000015 },
+	{ 0x00009b48, 0x00000018 },
+	{ 0x00009b4c, 0x00000019 },
+	{ 0x00009b50, 0x0000001a },
+	{ 0x00009b54, 0x0000001b },
+	{ 0x00009b58, 0x0000001c },
+	{ 0x00009b5c, 0x0000001d },
+	{ 0x00009b60, 0x00000020 },
+	{ 0x00009b64, 0x00000021 },
+	{ 0x00009b68, 0x00000022 },
+	{ 0x00009b6c, 0x00000023 },
+	{ 0x00009b70, 0x00000024 },
+	{ 0x00009b74, 0x00000025 },
+	{ 0x00009b78, 0x00000028 },
+	{ 0x00009b7c, 0x00000029 },
+	{ 0x00009b80, 0x0000002a },
+	{ 0x00009b84, 0x0000002b },
+	{ 0x00009b88, 0x0000002c },
+	{ 0x00009b8c, 0x0000002d },
+	{ 0x00009b90, 0x00000030 },
+	{ 0x00009b94, 0x00000031 },
+	{ 0x00009b98, 0x00000032 },
+	{ 0x00009b9c, 0x00000033 },
+	{ 0x00009ba0, 0x00000034 },
+	{ 0x00009ba4, 0x00000035 },
+	{ 0x00009ba8, 0x00000035 },
+	{ 0x00009bac, 0x00000035 },
+	{ 0x00009bb0, 0x00000035 },
+	{ 0x00009bb4, 0x00000035 },
+	{ 0x00009bb8, 0x00000035 },
+	{ 0x00009bbc, 0x00000035 },
+	{ 0x00009bc0, 0x00000035 },
+	{ 0x00009bc4, 0x00000035 },
+	{ 0x00009bc8, 0x00000035 },
+	{ 0x00009bcc, 0x00000035 },
+	{ 0x00009bd0, 0x00000035 },
+	{ 0x00009bd4, 0x00000035 },
+	{ 0x00009bd8, 0x00000035 },
+	{ 0x00009bdc, 0x00000035 },
+	{ 0x00009be0, 0x00000035 },
+	{ 0x00009be4, 0x00000035 },
+	{ 0x00009be8, 0x00000035 },
+	{ 0x00009bec, 0x00000035 },
+	{ 0x00009bf0, 0x00000035 },
+	{ 0x00009bf4, 0x00000035 },
+	{ 0x00009bf8, 0x00000010 },
+	{ 0x00009bfc, 0x0000001a },
+	{ 0x0000a210, 0x40806333 },
+	{ 0x0000a214, 0x00106c10 },
+	{ 0x0000a218, 0x009c4060 },
+	{ 0x0000a220, 0x018830c6 },
+	{ 0x0000a224, 0x00000400 },
+	{ 0x0000a228, 0x001a0bb5 },
+	{ 0x0000a22c, 0x00000000 },
+	{ 0x0000a234, 0x20202020 },
+	{ 0x0000a238, 0x20202020 },
+	{ 0x0000a23c, 0x13c889ae },
+	{ 0x0000a240, 0x38490a20 },
+	{ 0x0000a244, 0x00007bb6 },
+	{ 0x0000a248, 0x0fff3ffc },
+	{ 0x0000a24c, 0x00000001 },
+	{ 0x0000a250, 0x0000a000 },
+	{ 0x0000a254, 0x00000000 },
+	{ 0x0000a258, 0x0cc75380 },
+	{ 0x0000a25c, 0x0f0f0f01 },
+	{ 0x0000a260, 0xdfa91f01 },
+	{ 0x0000a268, 0x00000001 },
+	{ 0x0000a26c, 0x0ebae9c6 },
+	{ 0x0000b26c, 0x0ebae9c6 },
+	{ 0x0000c26c, 0x0ebae9c6 },
+	{ 0x0000d270, 0x00820820 },
+	{ 0x0000a278, 0x1ce739ce },
+	{ 0x0000a27c, 0x050701ce },
+	{ 0x0000a338, 0x00000000 },
+	{ 0x0000a33c, 0x00000000 },
+	{ 0x0000a340, 0x00000000 },
+	{ 0x0000a344, 0x00000000 },
+	{ 0x0000a348, 0x3fffffff },
+	{ 0x0000a34c, 0x3fffffff },
+	{ 0x0000a350, 0x3fffffff },
+	{ 0x0000a354, 0x0003ffff },
+	{ 0x0000a358, 0x79a8aa33 },
+	{ 0x0000d35c, 0x07ffffef },
+	{ 0x0000d360, 0x0fffffe7 },
+	{ 0x0000d364, 0x17ffffe5 },
+	{ 0x0000d368, 0x1fffffe4 },
+	{ 0x0000d36c, 0x37ffffe3 },
+	{ 0x0000d370, 0x3fffffe3 },
+	{ 0x0000d374, 0x57ffffe3 },
+	{ 0x0000d378, 0x5fffffe2 },
+	{ 0x0000d37c, 0x7fffffe2 },
+	{ 0x0000d380, 0x7f3c7bba },
+	{ 0x0000d384, 0xf3307ff0 },
+	{ 0x0000a388, 0x0c000000 },
+	{ 0x0000a38c, 0x20202020 },
+	{ 0x0000a390, 0x20202020 },
+	{ 0x0000a394, 0x1ce739ce },
+	{ 0x0000a398, 0x000001ce },
+	{ 0x0000a39c, 0x00000001 },
+	{ 0x0000a3a0, 0x00000000 },
+	{ 0x0000a3a4, 0x00000000 },
+	{ 0x0000a3a8, 0x00000000 },
+	{ 0x0000a3ac, 0x00000000 },
+	{ 0x0000a3b0, 0x00000000 },
+	{ 0x0000a3b4, 0x00000000 },
+	{ 0x0000a3b8, 0x00000000 },
+	{ 0x0000a3bc, 0x00000000 },
+	{ 0x0000a3c0, 0x00000000 },
+	{ 0x0000a3c4, 0x00000000 },
+	{ 0x0000a3c8, 0x00000246 },
+	{ 0x0000a3cc, 0x20202020 },
+	{ 0x0000a3d0, 0x20202020 },
+	{ 0x0000a3d4, 0x20202020 },
+	{ 0x0000a3dc, 0x1ce739ce },
+	{ 0x0000a3e0, 0x000001ce },
+};
+
+static const uint32_t ar5416Bank0[][2] = {
+	{ 0x000098b0, 0x1e5795e5 },
+	{ 0x000098e0, 0x02008020 },
+};
+
+static const uint32_t ar5416BB_RfGain[][3] = {
+	{ 0x00009a00, 0x00000000, 0x00000000 },
+	{ 0x00009a04, 0x00000040, 0x00000040 },
+	{ 0x00009a08, 0x00000080, 0x00000080 },
+	{ 0x00009a0c, 0x000001a1, 0x00000141 },
+	{ 0x00009a10, 0x000001e1, 0x00000181 },
+	{ 0x00009a14, 0x00000021, 0x000001c1 },
+	{ 0x00009a18, 0x00000061, 0x00000001 },
+	{ 0x00009a1c, 0x00000168, 0x00000041 },
+	{ 0x00009a20, 0x000001a8, 0x000001a8 },
+	{ 0x00009a24, 0x000001e8, 0x000001e8 },
+	{ 0x00009a28, 0x00000028, 0x00000028 },
+	{ 0x00009a2c, 0x00000068, 0x00000068 },
+	{ 0x00009a30, 0x00000189, 0x000000a8 },
+	{ 0x00009a34, 0x000001c9, 0x00000169 },
+	{ 0x00009a38, 0x00000009, 0x000001a9 },
+	{ 0x00009a3c, 0x00000049, 0x000001e9 },
+	{ 0x00009a40, 0x00000089, 0x00000029 },
+	{ 0x00009a44, 0x00000170, 0x00000069 },
+	{ 0x00009a48, 0x000001b0, 0x00000190 },
+	{ 0x00009a4c, 0x000001f0, 0x000001d0 },
+	{ 0x00009a50, 0x00000030, 0x00000010 },
+	{ 0x00009a54, 0x00000070, 0x00000050 },
+	{ 0x00009a58, 0x00000191, 0x00000090 },
+	{ 0x00009a5c, 0x000001d1, 0x00000151 },
+	{ 0x00009a60, 0x00000011, 0x00000191 },
+	{ 0x00009a64, 0x00000051, 0x000001d1 },
+	{ 0x00009a68, 0x00000091, 0x00000011 },
+	{ 0x00009a6c, 0x000001b8, 0x00000051 },
+	{ 0x00009a70, 0x000001f8, 0x00000198 },
+	{ 0x00009a74, 0x00000038, 0x000001d8 },
+	{ 0x00009a78, 0x00000078, 0x00000018 },
+	{ 0x00009a7c, 0x00000199, 0x00000058 },
+	{ 0x00009a80, 0x000001d9, 0x00000098 },
+	{ 0x00009a84, 0x00000019, 0x00000159 },
+	{ 0x00009a88, 0x00000059, 0x00000199 },
+	{ 0x00009a8c, 0x00000099, 0x000001d9 },
+	{ 0x00009a90, 0x000000d9, 0x00000019 },
+	{ 0x00009a94, 0x000000f9, 0x00000059 },
+	{ 0x00009a98, 0x000000f9, 0x00000099 },
+	{ 0x00009a9c, 0x000000f9, 0x000000d9 },
+	{ 0x00009aa0, 0x000000f9, 0x000000f9 },
+	{ 0x00009aa4, 0x000000f9, 0x000000f9 },
+	{ 0x00009aa8, 0x000000f9, 0x000000f9 },
+	{ 0x00009aac, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab8, 0x000000f9, 0x000000f9 },
+	{ 0x00009abc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac8, 0x000000f9, 0x000000f9 },
+	{ 0x00009acc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad8, 0x000000f9, 0x000000f9 },
+	{ 0x00009adc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae8, 0x000000f9, 0x000000f9 },
+	{ 0x00009aec, 0x000000f9, 0x000000f9 },
+	{ 0x00009af0, 0x000000f9, 0x000000f9 },
+	{ 0x00009af4, 0x000000f9, 0x000000f9 },
+	{ 0x00009af8, 0x000000f9, 0x000000f9 },
+	{ 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const uint32_t ar5416Bank1[][2] = {
+	{ 0x000098b0, 0x02108421},
+	{ 0x000098ec, 0x00000008},
+};
+
+static const uint32_t ar5416Bank2[][2] = {
+	{ 0x000098b0, 0x0e73ff17},
+	{ 0x000098e0, 0x00000420},
+};
+
+static const uint32_t ar5416Bank3[][3] = {
+	{ 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const uint32_t ar5416Bank6[][3] = {
+
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00e00000, 0x00e00000 },
+	{ 0x0000989c, 0x005e0000, 0x005e0000 },
+	{ 0x0000989c, 0x00120000, 0x00120000 },
+	{ 0x0000989c, 0x00620000, 0x00620000 },
+	{ 0x0000989c, 0x00020000, 0x00020000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x005f0000, 0x005f0000 },
+	{ 0x0000989c, 0x00870000, 0x00870000 },
+	{ 0x0000989c, 0x00f90000, 0x00f90000 },
+	{ 0x0000989c, 0x007b0000, 0x007b0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00f50000, 0x00f50000 },
+	{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
+	{ 0x0000989c, 0x00110000, 0x00110000 },
+	{ 0x0000989c, 0x006100a8, 0x006100a8 },
+	{ 0x0000989c, 0x004210a2, 0x004210a2 },
+	{ 0x0000989c, 0x0014000f, 0x0014000f },
+	{ 0x0000989c, 0x00c40002, 0x00c40002 },
+	{ 0x0000989c, 0x003000f2, 0x003000f2 },
+	{ 0x0000989c, 0x00440016, 0x00440016 },
+	{ 0x0000989c, 0x00410040, 0x00410040 },
+	{ 0x0000989c, 0x000180d6, 0x000180d6 },
+	{ 0x0000989c, 0x0000c0aa, 0x0000c0aa },
+	{ 0x0000989c, 0x000000b1, 0x000000b1 },
+	{ 0x0000989c, 0x00002000, 0x00002000 },
+	{ 0x0000989c, 0x000000d4, 0x000000d4 },
+	{ 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+
+static const uint32_t ar5416Bank6TPC[][3] = {
+
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00e00000, 0x00e00000 },
+	{ 0x0000989c, 0x005e0000, 0x005e0000 },
+	{ 0x0000989c, 0x00120000, 0x00120000 },
+	{ 0x0000989c, 0x00620000, 0x00620000 },
+	{ 0x0000989c, 0x00020000, 0x00020000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x40ff0000, 0x40ff0000 },
+	{ 0x0000989c, 0x005f0000, 0x005f0000 },
+	{ 0x0000989c, 0x00870000, 0x00870000 },
+	{ 0x0000989c, 0x00f90000, 0x00f90000 },
+	{ 0x0000989c, 0x007b0000, 0x007b0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00f50000, 0x00f50000 },
+	{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
+	{ 0x0000989c, 0x00110000, 0x00110000 },
+	{ 0x0000989c, 0x006100a8, 0x006100a8 },
+	{ 0x0000989c, 0x00423022, 0x00423022 },
+	{ 0x0000989c, 0x2014008f, 0x2014008f },
+	{ 0x0000989c, 0x00c40002, 0x00c40002 },
+	{ 0x0000989c, 0x003000f2, 0x003000f2 },
+	{ 0x0000989c, 0x00440016, 0x00440016 },
+	{ 0x0000989c, 0x00410040, 0x00410040 },
+	{ 0x0000989c, 0x0001805e, 0x0001805e },
+	{ 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+	{ 0x0000989c, 0x000000e1, 0x000000e1 },
+	{ 0x0000989c, 0x00007080, 0x00007080 },
+	{ 0x0000989c, 0x000000d4, 0x000000d4 },
+	{ 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const uint32_t ar5416Bank7[][2] = {
+	{ 0x0000989c, 0x00000500 },
+	{ 0x0000989c, 0x00000800 },
+	{ 0x000098cc, 0x0000000e },
+};
+
+static const uint32_t ar5416Addac[][2] = {
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000010 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x000000c0 },
+	{0x0000989c, 0x00000015 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x0000989c, 0x00000000 },
+	{0x000098cc, 0x00000000 },
+};
+
+/* AR5416 9160 Sowl ar5416_sowl.ini */
+static const uint32_t ar5416Modes_9160[][6] = {
+	{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160,
+	    0x000001e0 },
+	{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c,
+	    0x000001e0 },
+	{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38,
+	    0x00001180 },
+	{ 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000,
+	    0x00014008 },
+	{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00,
+	    0x06e006e0 },
+	{ 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab,
+	    0x098813cf },
+	{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300,
+	    0x00000303 },
+	{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+	    0x02020200 },
+	{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001,
+	    0x0a020001 },
+	{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
+	    0x00000007 },
+	{ 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0,
+	    0x037216a0 },
+	{ 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68,
+	    0x00197a68 },
+	{ 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2,
+	    0x6c48b0e2 },
+	{ 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e,
+	    0x7ec82d2e },
+	{ 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e,
+	    0x31395d5e },
+	{ 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20,
+	    0x00048d18 },
+	{ 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00,
+	    0x0001ce00 },
+	{ 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0,
+	    0x409a40d0 },
+	{ 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081,
+	    0x050cb081 },
+	{ 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898,
+	    0x000007d0 },
+	{ 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b,
+	    0x00000016 },
+	{ 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d,
+	    0xd00a8a0d },
+	{ 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020,
+	    0xffb81020 },
+	{ 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40,
+	    0x00009b40 },
+	{ 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40,
+	    0x00009b40 },
+	{ 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40,
+	    0x00009b40 },
+	{ 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120,
+	    0x00001120 },
+	{ 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce,
+	    0x000003ce },
+	{ 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00,
+	    0x001a0c00 },
+	{ 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be,
+	    0x038919be },
+	{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77,
+	    0x06336f77 },
+	{ 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329,
+	    0x60f65329 },
+	{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8,
+	    0x08f186c8 },
+	{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384,
+	    0x00046384 },
+	{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880,
+	    0x00000880 },
+	{ 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788,
+	    0xd03e4788 },
+	{ 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120,
+	    0x002ac120 },
+	{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a,
+	    0x1883800a },
+	{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108,
+	    0x00000000 },
+	{ 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa,
+	    0x0a1a7caa },
+	{ 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000,
+	    0x18010000 },
+	{ 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402,
+	    0x2e032402 },
+	{ 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06,
+	    0x4a0a3c06 },
+	{ 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b,
+	    0x621a540b },
+	{ 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b,
+	    0x764f6c1b },
+	{ 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a,
+	    0x845b7a5a },
+	{ 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf,
+	    0x950f8ccf },
+	{ 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f,
+	    0xa5cf9b4f },
+	{ 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f,
+	    0xbddfaf1f },
+	{ 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f,
+	    0xd1ffc93f },
+	{ 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+};
+
+static const uint32_t ar5416Common_9160[][2] = {
+	{ 0x0000000c, 0x00000000 },
+	{ 0x00000030, 0x00020015 },
+	{ 0x00000034, 0x00000005 },
+	{ 0x00000040, 0x00000000 },
+	{ 0x00000044, 0x00000008 },
+	{ 0x00000048, 0x00000008 },
+	{ 0x0000004c, 0x00000010 },
+	{ 0x00000050, 0x00000000 },
+	{ 0x00000054, 0x0000001f },
+	{ 0x00000800, 0x00000000 },
+	{ 0x00000804, 0x00000000 },
+	{ 0x00000808, 0x00000000 },
+	{ 0x0000080c, 0x00000000 },
+	{ 0x00000810, 0x00000000 },
+	{ 0x00000814, 0x00000000 },
+	{ 0x00000818, 0x00000000 },
+	{ 0x0000081c, 0x00000000 },
+	{ 0x00000820, 0x00000000 },
+	{ 0x00000824, 0x00000000 },
+	{ 0x00001040, 0x002ffc0f },
+	{ 0x00001044, 0x002ffc0f },
+	{ 0x00001048, 0x002ffc0f },
+	{ 0x0000104c, 0x002ffc0f },
+	{ 0x00001050, 0x002ffc0f },
+	{ 0x00001054, 0x002ffc0f },
+	{ 0x00001058, 0x002ffc0f },
+	{ 0x0000105c, 0x002ffc0f },
+	{ 0x00001060, 0x002ffc0f },
+	{ 0x00001064, 0x002ffc0f },
+	{ 0x00001230, 0x00000000 },
+	{ 0x00001270, 0x00000000 },
+	{ 0x00001038, 0x00000000 },
+	{ 0x00001078, 0x00000000 },
+	{ 0x000010b8, 0x00000000 },
+	{ 0x000010f8, 0x00000000 },
+	{ 0x00001138, 0x00000000 },
+	{ 0x00001178, 0x00000000 },
+	{ 0x000011b8, 0x00000000 },
+	{ 0x000011f8, 0x00000000 },
+	{ 0x00001238, 0x00000000 },
+	{ 0x00001278, 0x00000000 },
+	{ 0x000012b8, 0x00000000 },
+	{ 0x000012f8, 0x00000000 },
+	{ 0x00001338, 0x00000000 },
+	{ 0x00001378, 0x00000000 },
+	{ 0x000013b8, 0x00000000 },
+	{ 0x000013f8, 0x00000000 },
+	{ 0x00001438, 0x00000000 },
+	{ 0x00001478, 0x00000000 },
+	{ 0x000014b8, 0x00000000 },
+	{ 0x000014f8, 0x00000000 },
+	{ 0x00001538, 0x00000000 },
+	{ 0x00001578, 0x00000000 },
+	{ 0x000015b8, 0x00000000 },
+	{ 0x000015f8, 0x00000000 },
+	{ 0x00001638, 0x00000000 },
+	{ 0x00001678, 0x00000000 },
+	{ 0x000016b8, 0x00000000 },
+	{ 0x000016f8, 0x00000000 },
+	{ 0x00001738, 0x00000000 },
+	{ 0x00001778, 0x00000000 },
+	{ 0x000017b8, 0x00000000 },
+	{ 0x000017f8, 0x00000000 },
+	{ 0x0000103c, 0x00000000 },
+	{ 0x0000107c, 0x00000000 },
+	{ 0x000010bc, 0x00000000 },
+	{ 0x000010fc, 0x00000000 },
+	{ 0x0000113c, 0x00000000 },
+	{ 0x0000117c, 0x00000000 },
+	{ 0x000011bc, 0x00000000 },
+	{ 0x000011fc, 0x00000000 },
+	{ 0x0000123c, 0x00000000 },
+	{ 0x0000127c, 0x00000000 },
+	{ 0x000012bc, 0x00000000 },
+	{ 0x000012fc, 0x00000000 },
+	{ 0x0000133c, 0x00000000 },
+	{ 0x0000137c, 0x00000000 },
+	{ 0x000013bc, 0x00000000 },
+	{ 0x000013fc, 0x00000000 },
+	{ 0x0000143c, 0x00000000 },
+	{ 0x0000147c, 0x00000000 },
+	{ 0x00004030, 0x00000002 },
+	{ 0x0000403c, 0x00000002 },
+	{ 0x00007010, 0x00000020 },
+	{ 0x00007038, 0x000004c2 },
+	{ 0x00008004, 0x00000000 },
+	{ 0x00008008, 0x00000000 },
+	{ 0x0000800c, 0x00000000 },
+	{ 0x00008018, 0x00000700 },
+	{ 0x00008020, 0x00000000 },
+	{ 0x00008038, 0x00000000 },
+	{ 0x0000803c, 0x00000000 },
+	{ 0x00008048, 0x40000000 },
+	{ 0x00008054, 0x00000000 },
+	{ 0x00008058, 0x00000000 },
+	{ 0x0000805c, 0x000fc78f },
+	{ 0x00008060, 0x0000000f },
+	{ 0x00008064, 0x00000000 },
+	{ 0x000080c0, 0x2a82301a },
+	{ 0x000080c4, 0x05dc01e0 },
+	{ 0x000080c8, 0x1f402710 },
+	{ 0x000080cc, 0x01f40000 },
+	{ 0x000080d0, 0x00001e00 },
+	{ 0x000080d4, 0x00000000 },
+	{ 0x000080d8, 0x00400000 },
+	{ 0x000080e0, 0xffffffff },
+	{ 0x000080e4, 0x0000ffff },
+	{ 0x000080e8, 0x003f3f3f },
+	{ 0x000080ec, 0x00000000 },
+	{ 0x000080f0, 0x00000000 },
+	{ 0x000080f4, 0x00000000 },
+	{ 0x000080f8, 0x00000000 },
+	{ 0x000080fc, 0x00020000 },
+	{ 0x00008100, 0x00020000 },
+	{ 0x00008104, 0x00000001 },
+	{ 0x00008108, 0x00000052 },
+	{ 0x0000810c, 0x00000000 },
+	{ 0x00008110, 0x00000168 },
+	{ 0x00008118, 0x000100aa },
+	{ 0x0000811c, 0x00003210 },
+	{ 0x00008120, 0x08f04800 },
+	{ 0x00008124, 0x00000000 },
+	{ 0x00008128, 0x00000000 },
+	{ 0x0000812c, 0x00000000 },
+	{ 0x00008130, 0x00000000 },
+	{ 0x00008134, 0x00000000 },
+	{ 0x00008138, 0x00000000 },
+	{ 0x0000813c, 0x00000000 },
+	{ 0x00008144, 0xffffffff },
+	{ 0x00008168, 0x00000000 },
+	{ 0x0000816c, 0x00000000 },
+	{ 0x00008170, 0x32143320 },
+	{ 0x00008174, 0xfaa4fa50 },
+	{ 0x00008178, 0x00000100 },
+	{ 0x0000817c, 0x00000000 },
+	{ 0x000081c4, 0x00000000 },
+	{ 0x000081d0, 0x00003210 },
+	{ 0x000081ec, 0x00000000 },
+	{ 0x000081f0, 0x00000000 },
+	{ 0x000081f4, 0x00000000 },
+	{ 0x000081f8, 0x00000000 },
+	{ 0x000081fc, 0x00000000 },
+	{ 0x00008200, 0x00000000 },
+	{ 0x00008204, 0x00000000 },
+	{ 0x00008208, 0x00000000 },
+	{ 0x0000820c, 0x00000000 },
+	{ 0x00008210, 0x00000000 },
+	{ 0x00008214, 0x00000000 },
+	{ 0x00008218, 0x00000000 },
+	{ 0x0000821c, 0x00000000 },
+	{ 0x00008220, 0x00000000 },
+	{ 0x00008224, 0x00000000 },
+	{ 0x00008228, 0x00000000 },
+	{ 0x0000822c, 0x00000000 },
+	{ 0x00008230, 0x00000000 },
+	{ 0x00008234, 0x00000000 },
+	{ 0x00008238, 0x00000000 },
+	{ 0x0000823c, 0x00000000 },
+	{ 0x00008240, 0x00100000 },
+	{ 0x00008244, 0x0010f400 },
+	{ 0x00008248, 0x00000100 },
+	{ 0x0000824c, 0x0001e800 },
+	{ 0x00008250, 0x00000000 },
+	{ 0x00008254, 0x00000000 },
+	{ 0x00008258, 0x00000000 },
+	{ 0x0000825c, 0x400000ff },
+	{ 0x00008260, 0x00080922 },
+	{ 0x00008270, 0x00000000 },
+	{ 0x00008274, 0x40000000 },
+	{ 0x00008278, 0x003e4180 },
+	{ 0x0000827c, 0x00000000 },
+	{ 0x00008284, 0x0000002c },
+	{ 0x00008288, 0x0000002c },
+	{ 0x0000828c, 0x00000000 },
+	{ 0x00008294, 0x00000000 },
+	{ 0x00008298, 0x00000000 },
+	{ 0x00008300, 0x00000000 },
+	{ 0x00008304, 0x00000000 },
+	{ 0x00008308, 0x00000000 },
+	{ 0x0000830c, 0x00000000 },
+	{ 0x00008310, 0x00000000 },
+	{ 0x00008314, 0x00000000 },
+	{ 0x00008318, 0x00000000 },
+	{ 0x00008328, 0x00000000 },
+	{ 0x0000832c, 0x00000007 },
+	{ 0x00008330, 0x00000302 },
+	{ 0x00008334, 0x00000e00 },
+	{ 0x00008338, 0x00ff0000 },
+	{ 0x0000833c, 0x00000000 },
+	{ 0x00008340, 0x000107ff },
+	{ 0x00009808, 0x00000000 },
+	{ 0x0000980c, 0xad848e19 },
+	{ 0x00009810, 0x7d14e000 },
+	{ 0x00009814, 0x9c0a9f6b },
+	{ 0x0000981c, 0x00000000 },
+	{ 0x0000982c, 0x0000a000 },
+	{ 0x00009830, 0x00000000 },
+	{ 0x0000983c, 0x00200400 },
+	{ 0x00009840, 0x206a01ae },
+	{ 0x0000984c, 0x1284233c },
+	{ 0x00009854, 0x00000859 },
+	{ 0x00009900, 0x00000000 },
+	{ 0x00009904, 0x00000000 },
+	{ 0x00009908, 0x00000000 },
+	{ 0x0000990c, 0x00000000 },
+	{ 0x0000991c, 0x10000fff },
+	{ 0x00009920, 0x05100000 },
+	{ 0x0000a920, 0x05100000 },
+	{ 0x0000b920, 0x05100000 },
+	{ 0x00009928, 0x00000001 },
+	{ 0x0000992c, 0x00000004 },
+	{ 0x00009934, 0x1e1f2022 },
+	{ 0x00009938, 0x0a0b0c0d },
+	{ 0x0000993c, 0x00000000 },
+	{ 0x00009948, 0x9280b212 },
+	{ 0x0000994c, 0x00020028 },
+	{ 0x00009954, 0x5f3ca3de },
+	{ 0x00009958, 0x2108ecff },
+	{ 0x00009940, 0x00750604 },
+	{ 0x0000c95c, 0x004b6a8e },
+	{ 0x00009970, 0x190fb515 },
+	{ 0x00009974, 0x00000000 },
+	{ 0x00009978, 0x00000001 },
+	{ 0x0000997c, 0x00000000 },
+	{ 0x00009980, 0x00000000 },
+	{ 0x00009984, 0x00000000 },
+	{ 0x00009988, 0x00000000 },
+	{ 0x0000998c, 0x00000000 },
+	{ 0x00009990, 0x00000000 },
+	{ 0x00009994, 0x00000000 },
+	{ 0x00009998, 0x00000000 },
+	{ 0x0000999c, 0x00000000 },
+	{ 0x000099a0, 0x00000000 },
+	{ 0x000099a4, 0x00000001 },
+	{ 0x000099a8, 0x201fff00 },
+	{ 0x000099ac, 0x006f0000 },
+	{ 0x000099b0, 0x03051000 },
+	{ 0x000099dc, 0x00000000 },
+	{ 0x000099e0, 0x00000200 },
+	{ 0x000099e4, 0xaaaaaaaa },
+	{ 0x000099e8, 0x3c466478 },
+	{ 0x000099ec, 0x0cc80caa },
+	{ 0x000099fc, 0x00001042 },
+	{ 0x00009b00, 0x00000000 },
+	{ 0x00009b04, 0x00000001 },
+	{ 0x00009b08, 0x00000002 },
+	{ 0x00009b0c, 0x00000003 },
+	{ 0x00009b10, 0x00000004 },
+	{ 0x00009b14, 0x00000005 },
+	{ 0x00009b18, 0x00000008 },
+	{ 0x00009b1c, 0x00000009 },
+	{ 0x00009b20, 0x0000000a },
+	{ 0x00009b24, 0x0000000b },
+	{ 0x00009b28, 0x0000000c },
+	{ 0x00009b2c, 0x0000000d },
+	{ 0x00009b30, 0x00000010 },
+	{ 0x00009b34, 0x00000011 },
+	{ 0x00009b38, 0x00000012 },
+	{ 0x00009b3c, 0x00000013 },
+	{ 0x00009b40, 0x00000014 },
+	{ 0x00009b44, 0x00000015 },
+	{ 0x00009b48, 0x00000018 },
+	{ 0x00009b4c, 0x00000019 },
+	{ 0x00009b50, 0x0000001a },
+	{ 0x00009b54, 0x0000001b },
+	{ 0x00009b58, 0x0000001c },
+	{ 0x00009b5c, 0x0000001d },
+	{ 0x00009b60, 0x00000020 },
+	{ 0x00009b64, 0x00000021 },
+	{ 0x00009b68, 0x00000022 },
+	{ 0x00009b6c, 0x00000023 },
+	{ 0x00009b70, 0x00000024 },
+	{ 0x00009b74, 0x00000025 },
+	{ 0x00009b78, 0x00000028 },
+	{ 0x00009b7c, 0x00000029 },
+	{ 0x00009b80, 0x0000002a },
+	{ 0x00009b84, 0x0000002b },
+	{ 0x00009b88, 0x0000002c },
+	{ 0x00009b8c, 0x0000002d },
+	{ 0x00009b90, 0x00000030 },
+	{ 0x00009b94, 0x00000031 },
+	{ 0x00009b98, 0x00000032 },
+	{ 0x00009b9c, 0x00000033 },
+	{ 0x00009ba0, 0x00000034 },
+	{ 0x00009ba4, 0x00000035 },
+	{ 0x00009ba8, 0x00000035 },
+	{ 0x00009bac, 0x00000035 },
+	{ 0x00009bb0, 0x00000035 },
+	{ 0x00009bb4, 0x00000035 },
+	{ 0x00009bb8, 0x00000035 },
+	{ 0x00009bbc, 0x00000035 },
+	{ 0x00009bc0, 0x00000035 },
+	{ 0x00009bc4, 0x00000035 },
+	{ 0x00009bc8, 0x00000035 },
+	{ 0x00009bcc, 0x00000035 },
+	{ 0x00009bd0, 0x00000035 },
+	{ 0x00009bd4, 0x00000035 },
+	{ 0x00009bd8, 0x00000035 },
+	{ 0x00009bdc, 0x00000035 },
+	{ 0x00009be0, 0x00000035 },
+	{ 0x00009be4, 0x00000035 },
+	{ 0x00009be8, 0x00000035 },
+	{ 0x00009bec, 0x00000035 },
+	{ 0x00009bf0, 0x00000035 },
+	{ 0x00009bf4, 0x00000035 },
+	{ 0x00009bf8, 0x00000010 },
+	{ 0x00009bfc, 0x0000001a },
+	{ 0x0000a210, 0x40806333 },
+	{ 0x0000a214, 0x00106c10 },
+	{ 0x0000a218, 0x009c4060 },
+	{ 0x0000a220, 0x018830c6 },
+	{ 0x0000a224, 0x00000400 },
+	{ 0x0000a228, 0x001a0bb5 },
+	{ 0x0000a22c, 0x00000000 },
+	{ 0x0000a234, 0x20202020 },
+	{ 0x0000a238, 0x20202020 },
+	{ 0x0000a23c, 0x13c889af },
+	{ 0x0000a240, 0x38490a20 },
+	{ 0x0000a244, 0x00007bb6 },
+	{ 0x0000a248, 0x0fff3ffc },
+	{ 0x0000a24c, 0x00000001 },
+	{ 0x0000a250, 0x0000e000 },
+	{ 0x0000a254, 0x00000000 },
+	{ 0x0000a258, 0x0cc75380 },
+	{ 0x0000a25c, 0x0f0f0f01 },
+	{ 0x0000a260, 0xdfa91f01 },
+	{ 0x0000a268, 0x00000001 },
+	{ 0x0000a26c, 0x0ebae9c6 },
+	{ 0x0000b26c, 0x0ebae9c6 },
+	{ 0x0000c26c, 0x0ebae9c6 },
+	{ 0x0000d270, 0x00820820 },
+	{ 0x0000a278, 0x1ce739ce },
+	{ 0x0000a27c, 0x050701ce },
+	{ 0x0000a338, 0x00000000 },
+	{ 0x0000a33c, 0x00000000 },
+	{ 0x0000a340, 0x00000000 },
+	{ 0x0000a344, 0x00000000 },
+	{ 0x0000a348, 0x3fffffff },
+	{ 0x0000a34c, 0x3fffffff },
+	{ 0x0000a350, 0x3fffffff },
+	{ 0x0000a354, 0x0003ffff },
+	{ 0x0000a358, 0x79bfaa03 },
+	{ 0x0000d35c, 0x07ffffef },
+	{ 0x0000d360, 0x0fffffe7 },
+	{ 0x0000d364, 0x17ffffe5 },
+	{ 0x0000d368, 0x1fffffe4 },
+	{ 0x0000d36c, 0x37ffffe3 },
+	{ 0x0000d370, 0x3fffffe3 },
+	{ 0x0000d374, 0x57ffffe3 },
+	{ 0x0000d378, 0x5fffffe2 },
+	{ 0x0000d37c, 0x7fffffe2 },
+	{ 0x0000d380, 0x7f3c7bba },
+	{ 0x0000d384, 0xf3307ff0 },
+	{ 0x0000a388, 0x0c000000 },
+	{ 0x0000a38c, 0x20202020 },
+	{ 0x0000a390, 0x20202020 },
+	{ 0x0000a394, 0x1ce739ce },
+	{ 0x0000a398, 0x000001ce },
+	{ 0x0000a39c, 0x00000001 },
+	{ 0x0000a3a0, 0x00000000 },
+	{ 0x0000a3a4, 0x00000000 },
+	{ 0x0000a3a8, 0x00000000 },
+	{ 0x0000a3ac, 0x00000000 },
+	{ 0x0000a3b0, 0x00000000 },
+	{ 0x0000a3b4, 0x00000000 },
+	{ 0x0000a3b8, 0x00000000 },
+	{ 0x0000a3bc, 0x00000000 },
+	{ 0x0000a3c0, 0x00000000 },
+	{ 0x0000a3c4, 0x00000000 },
+	{ 0x0000a3c8, 0x00000246 },
+	{ 0x0000a3cc, 0x20202020 },
+	{ 0x0000a3d0, 0x20202020 },
+	{ 0x0000a3d4, 0x20202020 },
+	{ 0x0000a3dc, 0x1ce739ce },
+	{ 0x0000a3e0, 0x000001ce },
+};
+
+static const uint32_t ar5416Bank0_9160[][2] = {
+	{ 0x000098b0, 0x1e5795e5 },
+	{ 0x000098e0, 0x02008020 },
+};
+
+static const uint32_t ar5416BB_RfGain_9160[][3] = {
+	{ 0x00009a00, 0x00000000, 0x00000000 },
+	{ 0x00009a04, 0x00000040, 0x00000040 },
+	{ 0x00009a08, 0x00000080, 0x00000080 },
+	{ 0x00009a0c, 0x000001a1, 0x00000141 },
+	{ 0x00009a10, 0x000001e1, 0x00000181 },
+	{ 0x00009a14, 0x00000021, 0x000001c1 },
+	{ 0x00009a18, 0x00000061, 0x00000001 },
+	{ 0x00009a1c, 0x00000168, 0x00000041 },
+	{ 0x00009a20, 0x000001a8, 0x000001a8 },
+	{ 0x00009a24, 0x000001e8, 0x000001e8 },
+	{ 0x00009a28, 0x00000028, 0x00000028 },
+	{ 0x00009a2c, 0x00000068, 0x00000068 },
+	{ 0x00009a30, 0x00000189, 0x000000a8 },
+	{ 0x00009a34, 0x000001c9, 0x00000169 },
+	{ 0x00009a38, 0x00000009, 0x000001a9 },
+	{ 0x00009a3c, 0x00000049, 0x000001e9 },
+	{ 0x00009a40, 0x00000089, 0x00000029 },
+	{ 0x00009a44, 0x00000170, 0x00000069 },
+	{ 0x00009a48, 0x000001b0, 0x00000190 },
+	{ 0x00009a4c, 0x000001f0, 0x000001d0 },
+	{ 0x00009a50, 0x00000030, 0x00000010 },
+	{ 0x00009a54, 0x00000070, 0x00000050 },
+	{ 0x00009a58, 0x00000191, 0x00000090 },
+	{ 0x00009a5c, 0x000001d1, 0x00000151 },
+	{ 0x00009a60, 0x00000011, 0x00000191 },
+	{ 0x00009a64, 0x00000051, 0x000001d1 },
+	{ 0x00009a68, 0x00000091, 0x00000011 },
+	{ 0x00009a6c, 0x000001b8, 0x00000051 },
+	{ 0x00009a70, 0x000001f8, 0x00000198 },
+	{ 0x00009a74, 0x00000038, 0x000001d8 },
+	{ 0x00009a78, 0x00000078, 0x00000018 },
+	{ 0x00009a7c, 0x00000199, 0x00000058 },
+	{ 0x00009a80, 0x000001d9, 0x00000098 },
+	{ 0x00009a84, 0x00000019, 0x00000159 },
+	{ 0x00009a88, 0x00000059, 0x00000199 },
+	{ 0x00009a8c, 0x00000099, 0x000001d9 },
+	{ 0x00009a90, 0x000000d9, 0x00000019 },
+	{ 0x00009a94, 0x000000f9, 0x00000059 },
+	{ 0x00009a98, 0x000000f9, 0x00000099 },
+	{ 0x00009a9c, 0x000000f9, 0x000000d9 },
+	{ 0x00009aa0, 0x000000f9, 0x000000f9 },
+	{ 0x00009aa4, 0x000000f9, 0x000000f9 },
+	{ 0x00009aa8, 0x000000f9, 0x000000f9 },
+	{ 0x00009aac, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ab8, 0x000000f9, 0x000000f9 },
+	{ 0x00009abc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ac8, 0x000000f9, 0x000000f9 },
+	{ 0x00009acc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ad8, 0x000000f9, 0x000000f9 },
+	{ 0x00009adc, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae0, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae4, 0x000000f9, 0x000000f9 },
+	{ 0x00009ae8, 0x000000f9, 0x000000f9 },
+	{ 0x00009aec, 0x000000f9, 0x000000f9 },
+	{ 0x00009af0, 0x000000f9, 0x000000f9 },
+	{ 0x00009af4, 0x000000f9, 0x000000f9 },
+	{ 0x00009af8, 0x000000f9, 0x000000f9 },
+	{ 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const uint32_t ar5416Bank1_9160[][2] = {
+{	0x000098b0, 0x02108421 },
+	{0x000098ec, 0x00000008 },
+};
+
+static const uint32_t ar5416Bank2_9160[][2] = {
+	{ 0x000098b0, 0x0e73ff17 },
+	{ 0x000098e0, 0x00000420 },
+};
+
+static const uint32_t ar5416Bank3_9160[][3] = {
+	{ 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const uint32_t ar5416Bank6_9160[][3] = {
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00e00000, 0x00e00000 },
+	{ 0x0000989c, 0x005e0000, 0x005e0000 },
+	{ 0x0000989c, 0x00120000, 0x00120000 },
+	{ 0x0000989c, 0x00620000, 0x00620000 },
+	{ 0x0000989c, 0x00020000, 0x00020000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x40ff0000, 0x40ff0000 },
+	{ 0x0000989c, 0x005f0000, 0x005f0000 },
+	{ 0x0000989c, 0x00870000, 0x00870000 },
+	{ 0x0000989c, 0x00f90000, 0x00f90000 },
+	{ 0x0000989c, 0x007b0000, 0x007b0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00f50000, 0x00f50000 },
+	{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
+	{ 0x0000989c, 0x00110000, 0x00110000 },
+	{ 0x0000989c, 0x006100a8, 0x006100a8 },
+	{ 0x0000989c, 0x004210a2, 0x004210a2 },
+	{ 0x0000989c, 0x0014008f, 0x0014008f },
+	{ 0x0000989c, 0x00c40003, 0x00c40003 },
+	{ 0x0000989c, 0x003000f2, 0x003000f2 },
+	{ 0x0000989c, 0x00440016, 0x00440016 },
+	{ 0x0000989c, 0x00410040, 0x00410040 },
+	{ 0x0000989c, 0x0001805e, 0x0001805e },
+	{ 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+	{ 0x0000989c, 0x000000f1, 0x000000f1 },
+	{ 0x0000989c, 0x00002081, 0x00002081 },
+	{ 0x0000989c, 0x000000d4, 0x000000d4 },
+	{ 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const uint32_t ar5416Bank6TPC_9160[][3] = {
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00000000, 0x00000000 },
+	{ 0x0000989c, 0x00e00000, 0x00e00000 },
+	{ 0x0000989c, 0x005e0000, 0x005e0000 },
+	{ 0x0000989c, 0x00120000, 0x00120000 },
+	{ 0x0000989c, 0x00620000, 0x00620000 },
+	{ 0x0000989c, 0x00020000, 0x00020000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x40ff0000, 0x40ff0000 },
+	{ 0x0000989c, 0x005f0000, 0x005f0000 },
+	{ 0x0000989c, 0x00870000, 0x00870000 },
+	{ 0x0000989c, 0x00f90000, 0x00f90000 },
+	{ 0x0000989c, 0x007b0000, 0x007b0000 },
+	{ 0x0000989c, 0x00ff0000, 0x00ff0000 },
+	{ 0x0000989c, 0x00f50000, 0x00f50000 },
+	{ 0x0000989c, 0x00dc0000, 0x00dc0000 },
+	{ 0x0000989c, 0x00110000, 0x00110000 },
+	{ 0x0000989c, 0x006100a8, 0x006100a8 },
+	{ 0x0000989c, 0x00423022, 0x00423022 },
+	{ 0x0000989c, 0x2014008f, 0x2014008f },
+	{ 0x0000989c, 0x00c40002, 0x00c40002 },
+	{ 0x0000989c, 0x003000f2, 0x003000f2 },
+	{ 0x0000989c, 0x00440016, 0x00440016 },
+	{ 0x0000989c, 0x00410040, 0x00410040 },
+	{ 0x0000989c, 0x0001805e, 0x0001805e },
+	{ 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+	{ 0x0000989c, 0x000000e1, 0x000000e1 },
+	{ 0x0000989c, 0x00007080, 0x00007080 },
+	{ 0x0000989c, 0x000000d4, 0x000000d4 },
+	{ 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const uint32_t ar5416Bank7_9160[][2] = {
+	{ 0x0000989c, 0x00000500 },
+	{ 0x0000989c, 0x00000800 },
+	{ 0x000098cc, 0x0000000e },
+};
+
+static uint32_t ar5416Addac_9160[][2] = {
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x000000c0 },
+	{0x0000989c,  0x00000018 },
+	{0x0000989c,  0x00000004 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x000000c0 },
+	{0x0000989c,  0x00000019 },
+	{0x0000989c,  0x00000004 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000004 },
+	{0x0000989c,  0x00000003 },
+	{0x0000989c,  0x00000008 },
+	{0x0000989c,  0x00000000 },
+	{0x000098cc,  0x00000000 },
+};
+
+static uint32_t ar5416Addac_91601_1[][2] = {
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x000000c0 },
+	{0x0000989c,  0x00000018 },
+	{0x0000989c,  0x00000004 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x000000c0 },
+	{0x0000989c,  0x00000019 },
+	{0x0000989c,  0x00000004 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x0000989c,  0x00000000 },
+	{0x000098cc,  0x00000000 },
+};
+
+/* XXX 9280 1 */
+static const uint32_t ar9280Modes_9280[][6] = {
+	{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160,
+	    0x000001e0 },
+	{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c,
+	    0x000001e0 },
+	{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38,
+	    0x00001180 },
+	{ 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000,
+	    0x00014008 },
+	{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840,
+	    0x06e006e0 },
+	{ 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b,
+	    0x0988004f },
+	{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300,
+	    0x00000303 },
+	{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+	    0x02020200 },
+	{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001,
+	    0x0a020001 },
+	{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
+	    0x00000007 },
+	{ 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0,
+	    0x137216a0 },
+	{ 0x00009848, 0x00028566, 0x00028566, 0x00028563, 0x00028563,
+	    0x00028563 },
+	{ 0x0000a848, 0x00028566, 0x00028566, 0x00028563, 0x00028563,
+	    0x00028563 },
+	{ 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2,
+	    0x6d4000e2 },
+	{ 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e,
+	    0x7ec82d2e },
+	{ 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e,
+	    0x3139605e },
+	{ 0x00009860, 0x00049d18, 0x00049d18, 0x00049d20, 0x00049d20,
+	    0x00049d18 },
+	{ 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00,
+	    0x0001ce00 },
+	{ 0x00009868, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190,
+	    0x5ac64190 },
+	{ 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881,
+	    0x06903881 },
+	{ 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898,
+	    0x000007d0 },
+	{ 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b,
+	    0x00000016 },
+	{ 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d,
+	    0xd00a8a0d },
+	{ 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010,
+	    0xdfbc1010 },
+	{ 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+	    0x00000010 },
+	{ 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+	    0x00000010 },
+	{ 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210,
+	    0x00000210 },
+	{ 0x0000c9b8, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a,
+	    0x0000001a },
+	{ 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00,
+	    0x00000c00 },
+	{ 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4,
+	    0x05eea6d4 },
+	{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77,
+	    0x06336f77 },
+	{ 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c,
+	    0x60f6532c },
+	{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8,
+	    0x08f186c8 },
+	{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384,
+	    0x00046384 },
+	{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x00009a00, 0x00008184, 0x00008184, 0x00000214, 0x00000214,
+	    0x00000214 },
+	{ 0x00009a04, 0x00008188, 0x00008188, 0x00000218, 0x00000218,
+	    0x00000218 },
+	{ 0x00009a08, 0x0000818c, 0x0000818c, 0x00000224, 0x00000224,
+	    0x00000224 },
+	{ 0x00009a0c, 0x00008190, 0x00008190, 0x00000228, 0x00000228,
+	    0x00000228 },
+	{ 0x00009a10, 0x00008194, 0x00008194, 0x0000022c, 0x0000022c,
+	    0x0000022c },
+	{ 0x00009a14, 0x00008200, 0x00008200, 0x00000230, 0x00000230,
+	    0x00000230 },
+	{ 0x00009a18, 0x00008204, 0x00008204, 0x000002a4, 0x000002a4,
+	    0x000002a4 },
+	{ 0x00009a1c, 0x00008208, 0x00008208, 0x000002a8, 0x000002a8,
+	    0x000002a8 },
+	{ 0x00009a20, 0x0000820c, 0x0000820c, 0x000002ac, 0x000002ac,
+	    0x000002ac },
+	{ 0x00009a24, 0x00008210, 0x00008210, 0x000002b0, 0x000002b0,
+	    0x000002b0 },
+	{ 0x00009a28, 0x00008214, 0x00008214, 0x000002b4, 0x000002b4,
+	    0x000002b4 },
+	{ 0x00009a2c, 0x00008280, 0x00008280, 0x000002b8, 0x000002b8,
+	    0x000002b8 },
+	{ 0x00009a30, 0x00008284, 0x00008284, 0x00000390, 0x00000390,
+	    0x00000390 },
+	{ 0x00009a34, 0x00008288, 0x00008288, 0x00000394, 0x00000394,
+	    0x00000394 },
+	{ 0x00009a38, 0x0000828c, 0x0000828c, 0x00000398, 0x00000398,
+	    0x00000398 },
+	{ 0x00009a3c, 0x00008290, 0x00008290, 0x00000334, 0x00000334,
+	    0x00000334 },
+	{ 0x00009a40, 0x00008300, 0x00008300, 0x00000338, 0x00000338,
+	    0x00000338 },
+	{ 0x00009a44, 0x00008304, 0x00008304, 0x000003ac, 0x000003ac,
+	    0x000003ac },
+	{ 0x00009a48, 0x00008308, 0x00008308, 0x000003b0, 0x000003b0,
+	    0x000003b0 },
+	{ 0x00009a4c, 0x0000830c, 0x0000830c, 0x000003b4, 0x000003b4,
+	    0x000003b4 },
+	{ 0x00009a50, 0x00008310, 0x00008310, 0x000003b8, 0x000003b8,
+	    0x000003b8 },
+	{ 0x00009a54, 0x00008314, 0x00008314, 0x000003a5, 0x000003a5,
+	    0x000003a5 },
+	{ 0x00009a58, 0x00008380, 0x00008380, 0x000003a9, 0x000003a9,
+	    0x000003a9 },
+	{ 0x00009a5c, 0x00008384, 0x00008384, 0x000003ad, 0x000003ad,
+	    0x000003ad },
+	{ 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194,
+	    0x00008194 },
+	{ 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0,
+	    0x000081a0 },
+	{ 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c,
+	    0x0000820c },
+	{ 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8,
+	    0x000081a8 },
+	{ 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284,
+	    0x00008284 },
+	{ 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288,
+	    0x00008288 },
+	{ 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224,
+	    0x00008224 },
+	{ 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290,
+	    0x00008290 },
+	{ 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300,
+	    0x00008300 },
+	{ 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304,
+	    0x00008304 },
+	{ 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308,
+	    0x00008308 },
+	{ 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c,
+	    0x0000830c },
+	{ 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380,
+	    0x00008380 },
+	{ 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384,
+	    0x00008384 },
+	{ 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700,
+	    0x00008700 },
+	{ 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704,
+	    0x00008704 },
+	{ 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708,
+	    0x00008708 },
+	{ 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c,
+	    0x0000870c },
+	{ 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780,
+	    0x00008780 },
+	{ 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784,
+	    0x00008784 },
+	{ 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00,
+	    0x00008b00 },
+	{ 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04,
+	    0x00008b04 },
+	{ 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08,
+	    0x00008b08 },
+	{ 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c,
+	    0x00008b0c },
+	{ 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80,
+	    0x00008b80 },
+	{ 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84,
+	    0x00008b84 },
+	{ 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88,
+	    0x00008b88 },
+	{ 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c,
+	    0x00008b8c },
+	{ 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90,
+	    0x00008b90 },
+	{ 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80,
+	    0x00008f80 },
+	{ 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84,
+	    0x00008f84 },
+	{ 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88,
+	    0x00008f88 },
+	{ 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c,
+	    0x00008f8c },
+	{ 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90,
+	    0x00008f90 },
+	{ 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c,
+	    0x0000930c },
+	{ 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310,
+	    0x00009310 },
+	{ 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384,
+	    0x00009384 },
+	{ 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388,
+	    0x00009388 },
+	{ 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324,
+	    0x00009324 },
+	{ 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704,
+	    0x00009704 },
+	{ 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4,
+	    0x000096a4 },
+	{ 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8,
+	    0x000096a8 },
+	{ 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710,
+	    0x00009710 },
+	{ 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714,
+	    0x00009714 },
+	{ 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720,
+	    0x00009720 },
+	{ 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724,
+	    0x00009724 },
+	{ 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728,
+	    0x00009728 },
+	{ 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c,
+	    0x0000972c },
+	{ 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0,
+	    0x000097a0 },
+	{ 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4,
+	    0x000097a4 },
+	{ 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8,
+	    0x000097a8 },
+	{ 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0,
+	    0x000097b0 },
+	{ 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4,
+	    0x000097b4 },
+	{ 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8,
+	    0x000097b8 },
+	{ 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5,
+	    0x000097a5 },
+	{ 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9,
+	    0x000097a9 },
+	{ 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad,
+	    0x000097ad },
+	{ 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1,
+	    0x000097b1 },
+	{ 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5,
+	    0x000097b5 },
+	{ 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9,
+	    0x000097b9 },
+	{ 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5,
+	    0x000097c5 },
+	{ 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9,
+	    0x000097c9 },
+	{ 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1,
+	    0x000097d1 },
+	{ 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5,
+	    0x000097d5 },
+	{ 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9,
+	    0x000097d9 },
+	{ 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6,
+	    0x000097c6 },
+	{ 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca,
+	    0x000097ca },
+	{ 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce,
+	    0x000097ce },
+	{ 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2,
+	    0x000097d2 },
+	{ 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6,
+	    0x000097d6 },
+	{ 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3,
+	    0x000097c3 },
+	{ 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7,
+	    0x000097c7 },
+	{ 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb,
+	    0x000097cb },
+	{ 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf,
+	    0x000097cf },
+	{ 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7,
+	    0x000097d7 },
+	{ 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444,
+	    0x00000444 },
+	{ 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788,
+	    0x803e4788 },
+	{ 0x0000a20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019,
+	    0x000c6019 },
+	{ 0x0000b20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019,
+	    0x000c6019 },
+	{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a,
+	    0x1883800a },
+	{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108,
+	    0x00000000 },
+	{ 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652,
+	    0x0a1aa652 },
+	{ 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002,
+	    0x00003002 },
+	{ 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009,
+	    0x00008009 },
+	{ 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b,
+	    0x0000b00b },
+	{ 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012,
+	    0x0000e012 },
+	{ 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048,
+	    0x00012048 },
+	{ 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a,
+	    0x0001604a },
+	{ 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211,
+	    0x0001a211 },
+	{ 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213,
+	    0x0001e213 },
+	{ 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b,
+	    0x0002121b },
+	{ 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412,
+	    0x00024412 },
+	{ 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414,
+	    0x00028414 },
+	{ 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a,
+	    0x0002b44a },
+	{ 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649,
+	    0x00030649 },
+	{ 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b,
+	    0x0003364b },
+	{ 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49,
+	    0x00038a49 },
+	{ 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48,
+	    0x0003be48 },
+	{ 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a,
+	    0x0003ee4a },
+	{ 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88,
+	    0x00042e88 },
+	{ 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a,
+	    0x00046e8a },
+	{ 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9,
+	    0x00049ec9 },
+	{ 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42,
+	    0x0004bf42 },
+	{ 0x0000784c, 0x0e4f048c, 0x0e4f048c, 0x0e4d048c, 0x0e4d048c,
+	    0x0e4d048c },
+	{ 0x00007854, 0x12031828, 0x12031828, 0x12035828, 0x12035828,
+	    0x12035828 },
+	{ 0x00007870, 0x807ec400, 0x807ec400, 0x807ec000, 0x807ec000,
+	    0x807ec000 },
+	{ 0x0000788c, 0x00010000, 0x00010000, 0x00110000, 0x00110000,
+	    0x00110000 },
+};
+
+static const uint32_t ar9280Common_9280[][2] = {
+	{ 0x0000000c, 0x00000000 },
+	{ 0x00000030, 0x00020015 },
+	{ 0x00000034, 0x00000005 },
+	{ 0x00000040, 0x00000000 },
+	{ 0x00000044, 0x00000008 },
+	{ 0x00000048, 0x00000008 },
+	{ 0x0000004c, 0x00000010 },
+	{ 0x00000050, 0x00000000 },
+	{ 0x00000054, 0x0000001f },
+	{ 0x00000800, 0x00000000 },
+	{ 0x00000804, 0x00000000 },
+	{ 0x00000808, 0x00000000 },
+	{ 0x0000080c, 0x00000000 },
+	{ 0x00000810, 0x00000000 },
+	{ 0x00000814, 0x00000000 },
+	{ 0x00000818, 0x00000000 },
+	{ 0x0000081c, 0x00000000 },
+	{ 0x00000820, 0x00000000 },
+	{ 0x00000824, 0x00000000 },
+	{ 0x00001040, 0x002ffc0f },
+	{ 0x00001044, 0x002ffc0f },
+	{ 0x00001048, 0x002ffc0f },
+	{ 0x0000104c, 0x002ffc0f },
+	{ 0x00001050, 0x002ffc0f },
+	{ 0x00001054, 0x002ffc0f },
+	{ 0x00001058, 0x002ffc0f },
+	{ 0x0000105c, 0x002ffc0f },
+	{ 0x00001060, 0x002ffc0f },
+	{ 0x00001064, 0x002ffc0f },
+	{ 0x00001230, 0x00000000 },
+	{ 0x00001270, 0x00000000 },
+	{ 0x00001038, 0x00000000 },
+	{ 0x00001078, 0x00000000 },
+	{ 0x000010b8, 0x00000000 },
+	{ 0x000010f8, 0x00000000 },
+	{ 0x00001138, 0x00000000 },
+	{ 0x00001178, 0x00000000 },
+	{ 0x000011b8, 0x00000000 },
+	{ 0x000011f8, 0x00000000 },
+	{ 0x00001238, 0x00000000 },
+	{ 0x00001278, 0x00000000 },
+	{ 0x000012b8, 0x00000000 },
+	{ 0x000012f8, 0x00000000 },
+	{ 0x00001338, 0x00000000 },
+	{ 0x00001378, 0x00000000 },
+	{ 0x000013b8, 0x00000000 },
+	{ 0x000013f8, 0x00000000 },
+	{ 0x00001438, 0x00000000 },
+	{ 0x00001478, 0x00000000 },
+	{ 0x000014b8, 0x00000000 },
+	{ 0x000014f8, 0x00000000 },
+	{ 0x00001538, 0x00000000 },
+	{ 0x00001578, 0x00000000 },
+	{ 0x000015b8, 0x00000000 },
+	{ 0x000015f8, 0x00000000 },
+	{ 0x00001638, 0x00000000 },
+	{ 0x00001678, 0x00000000 },
+	{ 0x000016b8, 0x00000000 },
+	{ 0x000016f8, 0x00000000 },
+	{ 0x00001738, 0x00000000 },
+	{ 0x00001778, 0x00000000 },
+	{ 0x000017b8, 0x00000000 },
+	{ 0x000017f8, 0x00000000 },
+	{ 0x0000103c, 0x00000000 },
+	{ 0x0000107c, 0x00000000 },
+	{ 0x000010bc, 0x00000000 },
+	{ 0x000010fc, 0x00000000 },
+	{ 0x0000113c, 0x00000000 },
+	{ 0x0000117c, 0x00000000 },
+	{ 0x000011bc, 0x00000000 },
+	{ 0x000011fc, 0x00000000 },
+	{ 0x0000123c, 0x00000000 },
+	{ 0x0000127c, 0x00000000 },
+	{ 0x000012bc, 0x00000000 },
+	{ 0x000012fc, 0x00000000 },
+	{ 0x0000133c, 0x00000000 },
+	{ 0x0000137c, 0x00000000 },
+	{ 0x000013bc, 0x00000000 },
+	{ 0x000013fc, 0x00000000 },
+	{ 0x0000143c, 0x00000000 },
+	{ 0x0000147c, 0x00000000 },
+	{ 0x00004030, 0x00000002 },
+	{ 0x0000403c, 0x00000002 },
+	{ 0x00004024, 0x0000001f },
+	{ 0x00007010, 0x00000033 },
+	{ 0x00007038, 0x000004c2 },
+	{ 0x00008004, 0x00000000 },
+	{ 0x00008008, 0x00000000 },
+	{ 0x0000800c, 0x00000000 },
+	{ 0x00008018, 0x00000700 },
+	{ 0x00008020, 0x00000000 },
+	{ 0x00008038, 0x00000000 },
+	{ 0x0000803c, 0x00000000 },
+	{ 0x00008048, 0x40000000 },
+	{ 0x00008054, 0x00000000 },
+	{ 0x00008058, 0x00000000 },
+	{ 0x0000805c, 0x000fc78f },
+	{ 0x00008060, 0x0000000f },
+	{ 0x00008064, 0x00000000 },
+	{ 0x00008070, 0x00000000 },
+	{ 0x000080c0, 0x2a82301a },
+	{ 0x000080c4, 0x05dc01e0 },
+	{ 0x000080c8, 0x1f402710 },
+	{ 0x000080cc, 0x01f40000 },
+	{ 0x000080d0, 0x00001e00 },
+	{ 0x000080d4, 0x00000000 },
+	{ 0x000080d8, 0x00400000 },
+	{ 0x000080e0, 0xffffffff },
+	{ 0x000080e4, 0x0000ffff },
+	{ 0x000080e8, 0x003f3f3f },
+	{ 0x000080ec, 0x00000000 },
+	{ 0x000080f0, 0x00000000 },
+	{ 0x000080f4, 0x00000000 },
+	{ 0x000080f8, 0x00000000 },
+	{ 0x000080fc, 0x00020000 },
+	{ 0x00008100, 0x00020000 },
+	{ 0x00008104, 0x00000001 },
+	{ 0x00008108, 0x00000052 },
+	{ 0x0000810c, 0x00000000 },
+	{ 0x00008110, 0x00000168 },
+	{ 0x00008118, 0x000100aa },
+	{ 0x0000811c, 0x00003210 },
+	{ 0x00008120, 0x08f04800 },
+	{ 0x00008124, 0x00000000 },
+	{ 0x00008128, 0x00000000 },
+	{ 0x0000812c, 0x00000000 },
+	{ 0x00008130, 0x00000000 },
+	{ 0x00008134, 0x00000000 },
+	{ 0x00008138, 0x00000000 },
+	{ 0x0000813c, 0x00000000 },
+	{ 0x00008144, 0x00000000 },
+	{ 0x00008168, 0x00000000 },
+	{ 0x0000816c, 0x00000000 },
+	{ 0x00008170, 0x32143320 },
+	{ 0x00008174, 0xfaa4fa50 },
+	{ 0x00008178, 0x00000100 },
+	{ 0x0000817c, 0x00000000 },
+	{ 0x000081c4, 0x00000000 },
+	{ 0x000081d0, 0x00003210 },
+	{ 0x000081ec, 0x00000000 },
+	{ 0x000081f0, 0x00000000 },
+	{ 0x000081f4, 0x00000000 },
+	{ 0x000081f8, 0x00000000 },
+	{ 0x000081fc, 0x00000000 },
+	{ 0x00008200, 0x00000000 },
+	{ 0x00008204, 0x00000000 },
+	{ 0x00008208, 0x00000000 },
+	{ 0x0000820c, 0x00000000 },
+	{ 0x00008210, 0x00000000 },
+	{ 0x00008214, 0x00000000 },
+	{ 0x00008218, 0x00000000 },
+	{ 0x0000821c, 0x00000000 },
+	{ 0x00008220, 0x00000000 },
+	{ 0x00008224, 0x00000000 },
+	{ 0x00008228, 0x00000000 },
+	{ 0x0000822c, 0x00000000 },
+	{ 0x00008230, 0x00000000 },
+	{ 0x00008234, 0x00000000 },
+	{ 0x00008238, 0x00000000 },
+	{ 0x0000823c, 0x00000000 },
+	{ 0x00008240, 0x00100000 },
+	{ 0x00008244, 0x0010f400 },
+	{ 0x00008248, 0x00000100 },
+	{ 0x0000824c, 0x0001e800 },
+	{ 0x00008250, 0x00000000 },
+	{ 0x00008254, 0x00000000 },
+	{ 0x00008258, 0x00000000 },
+	{ 0x0000825c, 0x400000ff },
+	{ 0x00008260, 0x00080922 },
+	{ 0x00008270, 0x00000000 },
+	{ 0x00008274, 0x40000000 },
+	{ 0x00008278, 0x003e4180 },
+	{ 0x0000827c, 0x00000000 },
+	{ 0x00008284, 0x0000002c },
+	{ 0x00008288, 0x0000002c },
+	{ 0x0000828c, 0x00000000 },
+	{ 0x00008294, 0x00000000 },
+	{ 0x00008298, 0x00000000 },
+	{ 0x00008300, 0x00000000 },
+	{ 0x00008304, 0x00000000 },
+	{ 0x00008308, 0x00000000 },
+	{ 0x0000830c, 0x00000000 },
+	{ 0x00008310, 0x00000000 },
+	{ 0x00008314, 0x00000000 },
+	{ 0x00008318, 0x00000000 },
+	{ 0x00008328, 0x00000000 },
+	{ 0x0000832c, 0x00000007 },
+	{ 0x00008330, 0x00000302 },
+	{ 0x00008334, 0x00000e00 },
+	{ 0x00008338, 0x00000000 },
+	{ 0x0000833c, 0x00000000 },
+	{ 0x00008340, 0x000107ff },
+	{ 0x00008344, 0x00000000 },
+	{ 0x00009808, 0x00000000 },
+	{ 0x0000980c, 0xaf268e30 },
+	{ 0x00009810, 0xfd14e000 },
+	{ 0x00009814, 0x9c0a9f6b },
+	{ 0x0000981c, 0x00000000 },
+	{ 0x0000982c, 0x0000a000 },
+	{ 0x00009830, 0x00000000 },
+	{ 0x0000983c, 0x00200400 },
+	{ 0x00009840, 0x206a01ae },
+	{ 0x0000984c, 0x0040233c },
+	{ 0x0000a84c, 0x0040233c },
+	{ 0x00009854, 0x00000044 },
+	{ 0x00009900, 0x00000000 },
+	{ 0x00009904, 0x00000000 },
+	{ 0x00009908, 0x00000000 },
+	{ 0x0000990c, 0x00000000 },
+	{ 0x0000991c, 0x10000fff },
+	{ 0x00009920, 0x04900000 },
+	{ 0x0000a920, 0x04900000 },
+	{ 0x00009928, 0x00000001 },
+	{ 0x0000992c, 0x00000004 },
+	{ 0x00009934, 0x1e1f2022 },
+	{ 0x00009938, 0x0a0b0c0d },
+	{ 0x0000993c, 0x00000000 },
+	{ 0x00009948, 0x9280c00a },
+	{ 0x0000994c, 0x00020028 },
+	{ 0x00009954, 0xe250a51e },
+	{ 0x00009958, 0x3388ffff },
+	{ 0x00009940, 0x00781204 },
+	{ 0x0000c95c, 0x004b6a8e },
+	{ 0x0000c968, 0x000003ce },
+	{ 0x00009970, 0x190fb514 },
+	{ 0x00009974, 0x00000000 },
+	{ 0x00009978, 0x00000001 },
+	{ 0x0000997c, 0x00000000 },
+	{ 0x00009980, 0x00000000 },
+	{ 0x00009984, 0x00000000 },
+	{ 0x00009988, 0x00000000 },
+	{ 0x0000998c, 0x00000000 },
+	{ 0x00009990, 0x00000000 },
+	{ 0x00009994, 0x00000000 },
+	{ 0x00009998, 0x00000000 },
+	{ 0x0000999c, 0x00000000 },
+	{ 0x000099a0, 0x00000000 },
+	{ 0x000099a4, 0x00000001 },
+	{ 0x000099a8, 0x201fff00 },
+	{ 0x000099ac, 0x006f00c4 },
+	{ 0x000099b0, 0x03051000 },
+	{ 0x000099b4, 0x00000820 },
+	{ 0x000099dc, 0x00000000 },
+	{ 0x000099e0, 0x00000000 },
+	{ 0x000099e4, 0xaaaaaaaa },
+	{ 0x000099e8, 0x3c466478 },
+	{ 0x000099ec, 0x0cc80caa },
+	{ 0x000099fc, 0x00001042 },
+	{ 0x0000a210, 0x4080a333 },
+	{ 0x0000a214, 0x40206c10 },
+	{ 0x0000a218, 0x009c4060 },
+	{ 0x0000a220, 0x01834061 },
+	{ 0x0000a224, 0x00000400 },
+	{ 0x0000a228, 0x000003b5 },
+	{ 0x0000a22c, 0x23277200 },
+	{ 0x0000a234, 0x20202020 },
+	{ 0x0000a238, 0x20202020 },
+	{ 0x0000a23c, 0x13c889af },
+	{ 0x0000a240, 0x38490a20 },
+	{ 0x0000a244, 0x00007bb6 },
+	{ 0x0000a248, 0x0fff3ffc },
+	{ 0x0000a24c, 0x00000001 },
+	{ 0x0000a250, 0x001da000 },
+	{ 0x0000a254, 0x00000000 },
+	{ 0x0000a258, 0x0cdbd380 },
+	{ 0x0000a25c, 0x0f0f0f01 },
+	{ 0x0000a260, 0xdfa91f01 },
+	{ 0x0000a268, 0x00000000 },
+	{ 0x0000a26c, 0x0ebae9c6 },
+	{ 0x0000b26c, 0x0ebae9c6 },
+	{ 0x0000d270, 0x00820820 },
+	{ 0x0000a278, 0x1ce739ce },
+	{ 0x0000a27c, 0x050701ce },
+	{ 0x0000a358, 0x7999aa0f },
+	{ 0x0000d35c, 0x07ffffef },
+	{ 0x0000d360, 0x0fffffe7 },
+	{ 0x0000d364, 0x17ffffe5 },
+	{ 0x0000d368, 0x1fffffe4 },
+	{ 0x0000d36c, 0x37ffffe3 },
+	{ 0x0000d370, 0x3fffffe3 },
+	{ 0x0000d374, 0x57ffffe3 },
+	{ 0x0000d378, 0x5fffffe2 },
+	{ 0x0000d37c, 0x7fffffe2 },
+	{ 0x0000d380, 0x7f3c7bba },
+	{ 0x0000d384, 0xf3307ff0 },
+	{ 0x0000a388, 0x0c000000 },
+	{ 0x0000a38c, 0x20202020 },
+	{ 0x0000a390, 0x20202020 },
+	{ 0x0000a394, 0x1ce739ce },
+	{ 0x0000a398, 0x000001ce },
+	{ 0x0000a39c, 0x00000001 },
+	{ 0x0000a3a0, 0x00000000 },
+	{ 0x0000a3a4, 0x00000000 },
+	{ 0x0000a3a8, 0x00000000 },
+	{ 0x0000a3ac, 0x00000000 },
+	{ 0x0000a3b0, 0x00000000 },
+	{ 0x0000a3b4, 0x00000000 },
+	{ 0x0000a3b8, 0x00000000 },
+	{ 0x0000a3bc, 0x00000000 },
+	{ 0x0000a3c0, 0x00000000 },
+	{ 0x0000a3c4, 0x00000000 },
+	{ 0x0000a3c8, 0x00000246 },
+	{ 0x0000a3cc, 0x20202020 },
+	{ 0x0000a3d0, 0x20202020 },
+	{ 0x0000a3d4, 0x20202020 },
+	{ 0x0000a3dc, 0x1ce739ce },
+	{ 0x0000a3e0, 0x000001ce },
+	{ 0x0000a3e4, 0x00000000 },
+	{ 0x0000a3e8, 0x18c43433 },
+	{ 0x0000a3ec, 0x00f38081 },
+	{ 0x00007800, 0x00040000 },
+	{ 0x00007804, 0xdb005012 },
+	{ 0x00007808, 0x04924914 },
+	{ 0x0000780c, 0x21084210 },
+	{ 0x00007810, 0x6d801300 },
+	{ 0x00007814, 0x0019beff },
+	{ 0x00007818, 0x07e40000 },
+	{ 0x0000781c, 0x00492000 },
+	{ 0x00007820, 0x92492480 },
+	{ 0x00007824, 0x00040000 },
+	{ 0x00007828, 0xdb005012 },
+	{ 0x0000782c, 0x04924914 },
+	{ 0x00007830, 0x21084210 },
+	{ 0x00007834, 0x6d801300 },
+	{ 0x00007838, 0x0019beff },
+	{ 0x0000783c, 0x07e40000 },
+	{ 0x00007840, 0x00492000 },
+	{ 0x00007844, 0x92492480 },
+	{ 0x00007848, 0x00120000 },
+	{ 0x00007850, 0x54214514 },
+	{ 0x00007858, 0x92592692 },
+	{ 0x00007860, 0x52802000 },
+	{ 0x00007864, 0x0a8e370e },
+	{ 0x00007868, 0xc0102850 },
+	{ 0x0000786c, 0x812d4000 },
+	{ 0x00007874, 0x001b6db0 },
+	{ 0x00007878, 0x00376b63 },
+	{ 0x0000787c, 0x06db6db6 },
+	{ 0x00007880, 0x006d8000 },
+	{ 0x00007884, 0xffeffffe },
+	{ 0x00007888, 0xffeffffe },
+	{ 0x00007890, 0x00060aeb },
+	{ 0x00007894, 0x5a108000 },
+	{ 0x00007898, 0x2a850160 },
+};
+
+/* XXX 9280 2 */
+static const uint32_t ar9280Modes_9280_2[][6] = {
+	{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160,
+	    0x000001e0 },
+	{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c,
+	    0x000001e0 },
+	{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38,
+	    0x00001180 },
+	{ 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000008 },
+	{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00,
+	    0x06e006e0 },
+	{ 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b,
+	    0x0988004f },
+	{ 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440,
+	    0x00006880 },
+	{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300,
+	    0x00000303 },
+	{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+	    0x02020200 },
+	{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001,
+	    0x0a020001 },
+	{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
+	    0x00000007 },
+	{ 0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e,
+	    0x206a012e },
+	{ 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0,
+	    0x037216a0 },
+	{ 0x00009850, 0x6c4000e2, 0x6c4000e2, 0x6d4000e2, 0x6c4000e2,
+	    0x6c4000e2 },
+	{ 0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e,
+	    0x7ec84d2e },
+	{ 0x0000985c, 0x31395d5e, 0x31395d5e, 0x3139605e, 0x31395d5e,
+	    0x31395d5e },
+	{ 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20,
+	    0x00048d18 },
+	{ 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00,
+	    0x0001ce00 },
+	{ 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0,
+	    0x5ac640d0 },
+	{ 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881,
+	    0x06903881 },
+	{ 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898,
+	    0x000007d0 },
+	{ 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b,
+	    0x00000016 },
+	{ 0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d,
+	    0xd00a8a0d },
+	{ 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010,
+	    0xffbc1010 },
+	{ 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+	    0x00000010 },
+	{ 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+	    0x00000010 },
+	{ 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210,
+	    0x00000210 },
+	{ 0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c,
+	    0x0000001c },
+	{ 0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00,
+	    0x00000c00 },
+	{ 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4,
+	    0x05eea6d4 },
+	{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77,
+	    0x06336f77 },
+	{ 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329,
+	    0x60f65329 },
+	{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8,
+	    0x08f186c8 },
+	{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384,
+	    0x00046384 },
+	{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444,
+	    0x00000444 },
+	{ 0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019,
+	    0x0001f019 },
+	{ 0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019,
+	    0x0001f019 },
+	{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a,
+	    0x1883800a },
+	{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108,
+	    0x00000000 },
+	{ 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000,
+	    0x0004a000 },
+	{ 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652,
+	    0x0a1aa652 },
+	{ 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e,
+	    0x7999aa0e },
+	{ 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000,
+	    0x5a508000 },
+};
+
+static const uint32_t ar9280Common_9280_2[][2] = {
+	{ 0x0000000c, 0x00000000 },
+	{ 0x00000030, 0x00020015 },
+	{ 0x00000034, 0x00000005 },
+	{ 0x00000040, 0x00000000 },
+	{ 0x00000044, 0x00000008 },
+	{ 0x00000048, 0x00000008 },
+	{ 0x0000004c, 0x00000010 },
+	{ 0x00000050, 0x00000000 },
+	{ 0x00000054, 0x0000001f },
+	{ 0x00000800, 0x00000000 },
+	{ 0x00000804, 0x00000000 },
+	{ 0x00000808, 0x00000000 },
+	{ 0x0000080c, 0x00000000 },
+	{ 0x00000810, 0x00000000 },
+	{ 0x00000814, 0x00000000 },
+	{ 0x00000818, 0x00000000 },
+	{ 0x0000081c, 0x00000000 },
+	{ 0x00000820, 0x00000000 },
+	{ 0x00000824, 0x00000000 },
+	{ 0x00001040, 0x002ffc0f },
+	{ 0x00001044, 0x002ffc0f },
+	{ 0x00001048, 0x002ffc0f },
+	{ 0x0000104c, 0x002ffc0f },
+	{ 0x00001050, 0x002ffc0f },
+	{ 0x00001054, 0x002ffc0f },
+	{ 0x00001058, 0x002ffc0f },
+	{ 0x0000105c, 0x002ffc0f },
+	{ 0x00001060, 0x002ffc0f },
+	{ 0x00001064, 0x002ffc0f },
+	{ 0x00001230, 0x00000000 },
+	{ 0x00001270, 0x00000000 },
+	{ 0x00001038, 0x00000000 },
+	{ 0x00001078, 0x00000000 },
+	{ 0x000010b8, 0x00000000 },
+	{ 0x000010f8, 0x00000000 },
+	{ 0x00001138, 0x00000000 },
+	{ 0x00001178, 0x00000000 },
+	{ 0x000011b8, 0x00000000 },
+	{ 0x000011f8, 0x00000000 },
+	{ 0x00001238, 0x00000000 },
+	{ 0x00001278, 0x00000000 },
+	{ 0x000012b8, 0x00000000 },
+	{ 0x000012f8, 0x00000000 },
+	{ 0x00001338, 0x00000000 },
+	{ 0x00001378, 0x00000000 },
+	{ 0x000013b8, 0x00000000 },
+	{ 0x000013f8, 0x00000000 },
+	{ 0x00001438, 0x00000000 },
+	{ 0x00001478, 0x00000000 },
+	{ 0x000014b8, 0x00000000 },
+	{ 0x000014f8, 0x00000000 },
+	{ 0x00001538, 0x00000000 },
+	{ 0x00001578, 0x00000000 },
+	{ 0x000015b8, 0x00000000 },
+	{ 0x000015f8, 0x00000000 },
+	{ 0x00001638, 0x00000000 },
+	{ 0x00001678, 0x00000000 },
+	{ 0x000016b8, 0x00000000 },
+	{ 0x000016f8, 0x00000000 },
+	{ 0x00001738, 0x00000000 },
+	{ 0x00001778, 0x00000000 },
+	{ 0x000017b8, 0x00000000 },
+	{ 0x000017f8, 0x00000000 },
+	{ 0x0000103c, 0x00000000 },
+	{ 0x0000107c, 0x00000000 },
+	{ 0x000010bc, 0x00000000 },
+	{ 0x000010fc, 0x00000000 },
+	{ 0x0000113c, 0x00000000 },
+	{ 0x0000117c, 0x00000000 },
+	{ 0x000011bc, 0x00000000 },
+	{ 0x000011fc, 0x00000000 },
+	{ 0x0000123c, 0x00000000 },
+	{ 0x0000127c, 0x00000000 },
+	{ 0x000012bc, 0x00000000 },
+	{ 0x000012fc, 0x00000000 },
+	{ 0x0000133c, 0x00000000 },
+	{ 0x0000137c, 0x00000000 },
+	{ 0x000013bc, 0x00000000 },
+	{ 0x000013fc, 0x00000000 },
+	{ 0x0000143c, 0x00000000 },
+	{ 0x0000147c, 0x00000000 },
+	{ 0x00004030, 0x00000002 },
+	{ 0x0000403c, 0x00000002 },
+	{ 0x00004024, 0x0000001f },
+	{ 0x00004060, 0x00000000 },
+	{ 0x00004064, 0x00000000 },
+	{ 0x00007010, 0x00000033 },
+	{ 0x00007034, 0x00000002 },
+	{ 0x00007038, 0x000004c2 },
+	{ 0x00008004, 0x00000000 },
+	{ 0x00008008, 0x00000000 },
+	{ 0x0000800c, 0x00000000 },
+	{ 0x00008018, 0x00000700 },
+	{ 0x00008020, 0x00000000 },
+	{ 0x00008038, 0x00000000 },
+	{ 0x0000803c, 0x00000000 },
+	{ 0x00008048, 0x40000000 },
+	{ 0x00008054, 0x00000000 },
+	{ 0x00008058, 0x00000000 },
+	{ 0x0000805c, 0x000fc78f },
+	{ 0x00008060, 0x0000000f },
+	{ 0x00008064, 0x00000000 },
+	{ 0x00008070, 0x00000000 },
+	{ 0x000080c0, 0x2a80001a },
+	{ 0x000080c4, 0x05dc01e0 },
+	{ 0x000080c8, 0x1f402710 },
+	{ 0x000080cc, 0x01f40000 },
+	{ 0x000080d0, 0x00001e00 },
+	{ 0x000080d4, 0x00000000 },
+	{ 0x000080d8, 0x00400000 },
+	{ 0x000080e0, 0xffffffff },
+	{ 0x000080e4, 0x0000ffff },
+	{ 0x000080e8, 0x003f3f3f },
+	{ 0x000080ec, 0x00000000 },
+	{ 0x000080f0, 0x00000000 },
+	{ 0x000080f4, 0x00000000 },
+	{ 0x000080f8, 0x00000000 },
+	{ 0x000080fc, 0x00020000 },
+	{ 0x00008100, 0x00020000 },
+	{ 0x00008104, 0x00000001 },
+	{ 0x00008108, 0x00000052 },
+	{ 0x0000810c, 0x00000000 },
+	{ 0x00008110, 0x00000168 },
+	{ 0x00008118, 0x000100aa },
+	{ 0x0000811c, 0x00003210 },
+	{ 0x00008120, 0x08f04800 },
+	{ 0x00008124, 0x00000000 },
+	{ 0x00008128, 0x00000000 },
+	{ 0x0000812c, 0x00000000 },
+	{ 0x00008130, 0x00000000 },
+	{ 0x00008134, 0x00000000 },
+	{ 0x00008138, 0x00000000 },
+	{ 0x0000813c, 0x00000000 },
+	{ 0x00008144, 0xffffffff },
+	{ 0x00008168, 0x00000000 },
+	{ 0x0000816c, 0x00000000 },
+	{ 0x00008170, 0x32143320 },
+	{ 0x00008174, 0xfaa4fa50 },
+	{ 0x00008178, 0x00000100 },
+	{ 0x0000817c, 0x00000000 },
+	{ 0x000081c0, 0x00000000 },
+	{ 0x000081d0, 0x00003210 },
+	{ 0x000081ec, 0x00000000 },
+	{ 0x000081f0, 0x00000000 },
+	{ 0x000081f4, 0x00000000 },
+	{ 0x000081f8, 0x00000000 },
+	{ 0x000081fc, 0x00000000 },
+	{ 0x00008200, 0x00000000 },
+	{ 0x00008204, 0x00000000 },
+	{ 0x00008208, 0x00000000 },
+	{ 0x0000820c, 0x00000000 },
+	{ 0x00008210, 0x00000000 },
+	{ 0x00008214, 0x00000000 },
+	{ 0x00008218, 0x00000000 },
+	{ 0x0000821c, 0x00000000 },
+	{ 0x00008220, 0x00000000 },
+	{ 0x00008224, 0x00000000 },
+	{ 0x00008228, 0x00000000 },
+	{ 0x0000822c, 0x00000000 },
+	{ 0x00008230, 0x00000000 },
+	{ 0x00008234, 0x00000000 },
+	{ 0x00008238, 0x00000000 },
+	{ 0x0000823c, 0x00000000 },
+	{ 0x00008240, 0x00100000 },
+	{ 0x00008244, 0x0010f400 },
+	{ 0x00008248, 0x00000100 },
+	{ 0x0000824c, 0x0001e800 },
+	{ 0x00008250, 0x00000000 },
+	{ 0x00008254, 0x00000000 },
+	{ 0x00008258, 0x00000000 },
+	{ 0x0000825c, 0x400000ff },
+	{ 0x00008260, 0x00080922 },
+	{ 0x00008264, 0xa8a00010 },
+	{ 0x00008270, 0x00000000 },
+	{ 0x00008274, 0x40000000 },
+	{ 0x00008278, 0x003e4180 },
+	{ 0x0000827c, 0x00000000 },
+	{ 0x00008284, 0x0000002c },
+	{ 0x00008288, 0x0000002c },
+	{ 0x0000828c, 0x00000000 },
+	{ 0x00008294, 0x00000000 },
+	{ 0x00008298, 0x00000000 },
+	{ 0x0000829c, 0x00000000 },
+	{ 0x00008300, 0x00000040 },
+	{ 0x00008314, 0x00000000 },
+	{ 0x00008328, 0x00000000 },
+	{ 0x0000832c, 0x00000007 },
+	{ 0x00008330, 0x00000302 },
+	{ 0x00008334, 0x00000e00 },
+	{ 0x00008338, 0x00ff0000 },
+	{ 0x0000833c, 0x00000000 },
+	{ 0x00008340, 0x000107ff },
+	{ 0x00008344, 0x00581043 },
+	{ 0x00009808, 0x00000000 },
+	{ 0x0000980c, 0xafa68e30 },
+	{ 0x00009810, 0xfd14e000 },
+	{ 0x00009814, 0x9c0a9f6b },
+	{ 0x0000981c, 0x00000000 },
+	{ 0x0000982c, 0x0000a000 },
+	{ 0x00009830, 0x00000000 },
+	{ 0x0000983c, 0x00200400 },
+	{ 0x0000984c, 0x0040233c },
+	{ 0x0000a84c, 0x0040233c },
+	{ 0x00009854, 0x00000044 },
+	{ 0x00009900, 0x00000000 },
+	{ 0x00009904, 0x00000000 },
+	{ 0x00009908, 0x00000000 },
+	{ 0x0000990c, 0x00000000 },
+	{ 0x00009910, 0x01002310 },
+	{ 0x0000991c, 0x10000fff },
+	{ 0x00009920, 0x04900000 },
+	{ 0x0000a920, 0x04900000 },
+	{ 0x00009928, 0x00000001 },
+	{ 0x0000992c, 0x00000004 },
+	{ 0x00009934, 0x1e1f2022 },
+	{ 0x00009938, 0x0a0b0c0d },
+	{ 0x0000993c, 0x00000000 },
+	{ 0x00009948, 0x9280c00a },
+	{ 0x0000994c, 0x00020028 },
+	{ 0x00009954, 0x5f3ca3de },
+	{ 0x00009958, 0x2108ecff },
+	{ 0x00009940, 0x14750604 },
+	{ 0x0000c95c, 0x004b6a8e },
+	{ 0x00009968, 0x000003ce },
+	{ 0x00009970, 0x190fb515 },
+	{ 0x00009974, 0x00000000 },
+	{ 0x00009978, 0x00000001 },
+	{ 0x0000997c, 0x00000000 },
+	{ 0x00009980, 0x00000000 },
+	{ 0x00009984, 0x00000000 },
+	{ 0x00009988, 0x00000000 },
+	{ 0x0000998c, 0x00000000 },
+	{ 0x00009990, 0x00000000 },
+	{ 0x00009994, 0x00000000 },
+	{ 0x00009998, 0x00000000 },
+	{ 0x0000999c, 0x00000000 },
+	{ 0x000099a0, 0x00000000 },
+	{ 0x000099a4, 0x00000001 },
+	{ 0x000099a8, 0x201fff00 },
+	{ 0x000099ac, 0x006f0000 },
+	{ 0x000099b0, 0x03051000 },
+	{ 0x000099b4, 0x00000820 },
+	{ 0x000099dc, 0x00000000 },
+	{ 0x000099e0, 0x00000000 },
+	{ 0x000099e4, 0xaaaaaaaa },
+	{ 0x000099e8, 0x3c466478 },
+	{ 0x000099ec, 0x0cc80caa },
+	{ 0x000099f0, 0x00000000 },
+	{ 0x000099fc, 0x00001042 },
+	{ 0x0000a208, 0x803e4788 },
+	{ 0x0000a210, 0x4080a333 },
+	{ 0x0000a214, 0x40206c10 },
+	{ 0x0000a218, 0x009c4060 },
+	{ 0x0000a220, 0x01834061 },
+	{ 0x0000a224, 0x00000400 },
+	{ 0x0000a228, 0x000003b5 },
+	{ 0x0000a22c, 0x233f7180 },
+	{ 0x0000a234, 0x20202020 },
+	{ 0x0000a238, 0x20202020 },
+	{ 0x0000a23c, 0x13c88000 },
+	{ 0x0000a240, 0x38490a20 },
+	{ 0x0000a244, 0x00007bb6 },
+	{ 0x0000a248, 0x0fff3ffc },
+	{ 0x0000a24c, 0x00000000 },
+	{ 0x0000a254, 0x00000000 },
+	{ 0x0000a258, 0x0cdbd380 },
+	{ 0x0000a25c, 0x0f0f0f01 },
+	{ 0x0000a260, 0xdfa91f01 },
+	{ 0x0000a268, 0x00000000 },
+	{ 0x0000a26c, 0x0ebae9c6 },
+	{ 0x0000b26c, 0x0ebae9c6 },
+	{ 0x0000d270, 0x00820820 },
+	{ 0x0000a278, 0x1ce739ce },
+	{ 0x0000d35c, 0x07ffffef },
+	{ 0x0000d360, 0x0fffffe7 },
+	{ 0x0000d364, 0x17ffffe5 },
+	{ 0x0000d368, 0x1fffffe4 },
+	{ 0x0000d36c, 0x37ffffe3 },
+	{ 0x0000d370, 0x3fffffe3 },
+	{ 0x0000d374, 0x57ffffe3 },
+	{ 0x0000d378, 0x5fffffe2 },
+	{ 0x0000d37c, 0x7fffffe2 },
+	{ 0x0000d380, 0x7f3c7bba },
+	{ 0x0000d384, 0xf3307ff0 },
+	{ 0x0000a388, 0x0c000000 },
+	{ 0x0000a38c, 0x20202020 },
+	{ 0x0000a390, 0x20202020 },
+	{ 0x0000a394, 0x1ce739ce },
+	{ 0x0000a398, 0x000001ce },
+	{ 0x0000a39c, 0x00000001 },
+	{ 0x0000a3a0, 0x00000000 },
+	{ 0x0000a3a4, 0x00000000 },
+	{ 0x0000a3a8, 0x00000000 },
+	{ 0x0000a3ac, 0x00000000 },
+	{ 0x0000a3b0, 0x00000000 },
+	{ 0x0000a3b4, 0x00000000 },
+	{ 0x0000a3b8, 0x00000000 },
+	{ 0x0000a3bc, 0x00000000 },
+	{ 0x0000a3c0, 0x00000000 },
+	{ 0x0000a3c4, 0x00000000 },
+	{ 0x0000a3c8, 0x00000246 },
+	{ 0x0000a3cc, 0x20202020 },
+	{ 0x0000a3d0, 0x20202020 },
+	{ 0x0000a3d4, 0x20202020 },
+	{ 0x0000a3dc, 0x1ce739ce },
+	{ 0x0000a3e0, 0x000001ce },
+	{ 0x0000a3e4, 0x00000000 },
+	{ 0x0000a3e8, 0x18c43433 },
+	{ 0x0000a3ec, 0x00f70081 },
+	{ 0x00007800, 0x00040000 },
+	{ 0x00007804, 0xdb005012 },
+	{ 0x00007808, 0x04924914 },
+	{ 0x0000780c, 0x21084210 },
+	{ 0x00007810, 0x6d801300 },
+	{ 0x00007818, 0x07e41000 },
+	{ 0x0000781c, 0x00392000 },
+	{ 0x00007820, 0x92592480 },
+	{ 0x00007824, 0x00040000 },
+	{ 0x00007828, 0xdb005012 },
+	{ 0x0000782c, 0x04924914 },
+	{ 0x00007830, 0x21084210 },
+	{ 0x00007834, 0x6d801300 },
+	{ 0x0000783c, 0x07e40000 },
+	{ 0x00007840, 0x00392000 },
+	{ 0x00007844, 0x92592480 },
+	{ 0x00007848, 0x00100000 },
+	{ 0x0000784c, 0x773f0567 },
+	{ 0x00007850, 0x54214514 },
+	{ 0x00007854, 0x12035828 },
+	{ 0x00007858, 0x9259269a },
+	{ 0x00007860, 0x52802000 },
+	{ 0x00007864, 0x0a8e370e },
+	{ 0x00007868, 0xc0102850 },
+	{ 0x0000786c, 0x812d4000 },
+	{ 0x00007870, 0x807ec400 },
+	{ 0x00007874, 0x001b6db0 },
+	{ 0x00007878, 0x00376b63 },
+	{ 0x0000787c, 0x06db6db6 },
+	{ 0x00007880, 0x006d8000 },
+	{ 0x00007884, 0xffeffffe },
+	{ 0x00007888, 0xffeffffe },
+	{ 0x0000788c, 0x00010000 },
+	{ 0x00007890, 0x02060aeb },
+	{ 0x00007898, 0x2a850160 },
+};
+
+static const uint32_t ar9280Modes_fast_clock_9280_2[][3] = {
+	{ 0x00001030, 0x00000268, 0x000004d0 },
+	{ 0x00001070, 0x0000018c, 0x00000318 },
+	{ 0x000010b0, 0x00000fd0, 0x00001fa0 },
+	{ 0x00008014, 0x044c044c, 0x08980898 },
+	{ 0x0000801c, 0x148ec02b, 0x148ec057 },
+	{ 0x00008318, 0x000044c0, 0x00008980 },
+	{ 0x00009820, 0x02020200, 0x02020200 },
+	{ 0x00009824, 0x00000f0f, 0x00000f0f },
+	{ 0x00009828, 0x0b020001, 0x0b020001 },
+	{ 0x00009834, 0x00000f0f, 0x00000f0f },
+	{ 0x00009844, 0x03721821, 0x03721821 },
+	{ 0x00009914, 0x00000898, 0x00001130 },
+	{ 0x00009918, 0x0000000b, 0x00000016 },
+	{ 0x00009944, 0xdfbc1210, 0xdfbc1210 },
+};
+
+static const uint32_t ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
+	{ 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290,
+	    0x00000290 },
+	{ 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300,
+	    0x00000300 },
+	{ 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304,
+	    0x00000304 },
+	{ 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308,
+	    0x00000308 },
+	{ 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c,
+	    0x0000030c },
+	{ 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000,
+	    0x00008000 },
+	{ 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004,
+	    0x00008004 },
+	{ 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008,
+	    0x00008008 },
+	{ 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c,
+	    0x0000800c },
+	{ 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080,
+	    0x00008080 },
+	{ 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084,
+	    0x00008084 },
+	{ 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088,
+	    0x00008088 },
+	{ 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c,
+	    0x0000808c },
+	{ 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100,
+	    0x00008100 },
+	{ 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104,
+	    0x00008104 },
+	{ 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108,
+	    0x00008108 },
+	{ 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c,
+	    0x0000810c },
+	{ 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110,
+	    0x00008110 },
+	{ 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114,
+	    0x00008114 },
+	{ 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180,
+	    0x00008180 },
+	{ 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184,
+	    0x00008184 },
+	{ 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188,
+	    0x00008188 },
+	{ 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c,
+	    0x0000818c },
+	{ 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190,
+	    0x00008190 },
+	{ 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194,
+	    0x00008194 },
+	{ 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0,
+	    0x000081a0 },
+	{ 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c,
+	    0x0000820c },
+	{ 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8,
+	    0x000081a8 },
+	{ 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284,
+	    0x00008284 },
+	{ 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288,
+	    0x00008288 },
+	{ 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224,
+	    0x00008224 },
+	{ 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290,
+	    0x00008290 },
+	{ 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300,
+	    0x00008300 },
+	{ 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304,
+	    0x00008304 },
+	{ 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308,
+	    0x00008308 },
+	{ 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c,
+	    0x0000830c },
+	{ 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380,
+	    0x00008380 },
+	{ 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384,
+	    0x00008384 },
+	{ 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700,
+	    0x00008700 },
+	{ 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704,
+	    0x00008704 },
+	{ 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708,
+	    0x00008708 },
+	{ 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c,
+	    0x0000870c },
+	{ 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780,
+	    0x00008780 },
+	{ 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784,
+	    0x00008784 },
+	{ 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00,
+	    0x00008b00 },
+	{ 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04,
+	    0x00008b04 },
+	{ 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08,
+	    0x00008b08 },
+	{ 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c,
+	    0x00008b0c },
+	{ 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10,
+	    0x00008b10 },
+	{ 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b14, 0x00008b14,
+	    0x00008b14 },
+	{ 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b01, 0x00008b01,
+	    0x00008b01 },
+	{ 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b05, 0x00008b05,
+	    0x00008b05 },
+	{ 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b09, 0x00008b09,
+	    0x00008b09 },
+	{ 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b0d, 0x00008b0d,
+	    0x00008b0d },
+	{ 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b11, 0x00008b11,
+	    0x00008b11 },
+	{ 0x00009adc, 0x0000b390, 0x0000b390, 0x00008b15, 0x00008b15,
+	    0x00008b15 },
+	{ 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008b02, 0x00008b02,
+	    0x00008b02 },
+	{ 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008b06, 0x00008b06,
+	    0x00008b06 },
+	{ 0x00009ae8, 0x0000b780, 0x0000b780, 0x00008b0a, 0x00008b0a,
+	    0x00008b0a },
+	{ 0x00009aec, 0x0000b784, 0x0000b784, 0x00008b0e, 0x00008b0e,
+	    0x00008b0e },
+	{ 0x00009af0, 0x0000b788, 0x0000b788, 0x00008b12, 0x00008b12,
+	    0x00008b12 },
+	{ 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008b16, 0x00008b16,
+	    0x00008b16 },
+	{ 0x00009af8, 0x0000b790, 0x0000b790, 0x00008b03, 0x00008b03,
+	    0x00008b03 },
+	{ 0x00009afc, 0x0000b794, 0x0000b794, 0x00008b07, 0x00008b07,
+	    0x00008b07 },
+	{ 0x00009b00, 0x0000b798, 0x0000b798, 0x00008b0b, 0x00008b0b,
+	    0x00008b0b },
+	{ 0x00009b04, 0x0000d784, 0x0000d784, 0x00008b0f, 0x00008b0f,
+	    0x00008b0f },
+	{ 0x00009b08, 0x0000d788, 0x0000d788, 0x00008b13, 0x00008b13,
+	    0x00008b13 },
+	{ 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008b17, 0x00008b17,
+	    0x00008b17 },
+	{ 0x00009b10, 0x0000d790, 0x0000d790, 0x00008b23, 0x00008b23,
+	    0x00008b23 },
+	{ 0x00009b14, 0x0000f780, 0x0000f780, 0x00008b27, 0x00008b27,
+	    0x00008b27 },
+	{ 0x00009b18, 0x0000f784, 0x0000f784, 0x00008b2b, 0x00008b2b,
+	    0x00008b2b },
+	{ 0x00009b1c, 0x0000f788, 0x0000f788, 0x00008b2f, 0x00008b2f,
+	    0x00008b2f },
+	{ 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008b33, 0x00008b33,
+	    0x00008b33 },
+	{ 0x00009b24, 0x0000f790, 0x0000f790, 0x00008b37, 0x00008b37,
+	    0x00008b37 },
+	{ 0x00009b28, 0x0000f794, 0x0000f794, 0x00008b43, 0x00008b43,
+	    0x00008b43 },
+	{ 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008b47, 0x00008b47,
+	    0x00008b47 },
+	{ 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008b4b, 0x00008b4b,
+	    0x00008b4b },
+	{ 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008b4f, 0x00008b4f,
+	    0x00008b4f },
+	{ 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008b53, 0x00008b53,
+	    0x00008b53 },
+	{ 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008b57, 0x00008b57,
+	    0x00008b57 },
+	{ 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b,
+	    0x00008b5b },
+	{ 0x00009848, 0x00001066, 0x00001066, 0x00001050, 0x00001050,
+	    0x00001050 },
+	{ 0x0000a848, 0x00001066, 0x00001066, 0x00001050, 0x00001050,
+	    0x00001050 },
+};
+
+static const uint32_t ar9280Modes_original_rxgain_9280_2[][6] = {
+	{ 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290,
+	    0x00000290 },
+	{ 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300,
+	    0x00000300 },
+	{ 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304,
+	    0x00000304 },
+	{ 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308,
+	    0x00000308 },
+	{ 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c,
+	    0x0000030c },
+	{ 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000,
+	    0x00008000 },
+	{ 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004,
+	    0x00008004 },
+	{ 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008,
+	    0x00008008 },
+	{ 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c,
+	    0x0000800c },
+	{ 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080,
+	    0x00008080 },
+	{ 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084,
+	    0x00008084 },
+	{ 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088,
+	    0x00008088 },
+	{ 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c,
+	    0x0000808c },
+	{ 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100,
+	    0x00008100 },
+	{ 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104,
+	    0x00008104 },
+	{ 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108,
+	    0x00008108 },
+	{ 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c,
+	    0x0000810c },
+	{ 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110,
+	    0x00008110 },
+	{ 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114,
+	    0x00008114 },
+	{ 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180,
+	    0x00008180 },
+	{ 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184,
+	    0x00008184 },
+	{ 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188,
+	    0x00008188 },
+	{ 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c,
+	    0x0000818c },
+	{ 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190,
+	    0x00008190 },
+	{ 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194,
+	    0x00008194 },
+	{ 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0,
+	    0x000081a0 },
+	{ 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c,
+	    0x0000820c },
+	{ 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8,
+	    0x000081a8 },
+	{ 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284,
+	    0x00008284 },
+	{ 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288,
+	    0x00008288 },
+	{ 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224,
+	    0x00008224 },
+	{ 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290,
+	    0x00008290 },
+	{ 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300,
+	    0x00008300 },
+	{ 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304,
+	    0x00008304 },
+	{ 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308,
+	    0x00008308 },
+	{ 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c,
+	    0x0000830c },
+	{ 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380,
+	    0x00008380 },
+	{ 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384,
+	    0x00008384 },
+	{ 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700,
+	    0x00008700 },
+	{ 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704,
+	    0x00008704 },
+	{ 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708,
+	    0x00008708 },
+	{ 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c,
+	    0x0000870c },
+	{ 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780,
+	    0x00008780 },
+	{ 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784,
+	    0x00008784 },
+	{ 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00,
+	    0x00008b00 },
+	{ 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04,
+	    0x00008b04 },
+	{ 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08,
+	    0x00008b08 },
+	{ 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c,
+	    0x00008b0c },
+	{ 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80,
+	    0x00008b80 },
+	{ 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84,
+	    0x00008b84 },
+	{ 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88,
+	    0x00008b88 },
+	{ 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c,
+	    0x00008b8c },
+	{ 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90,
+	    0x00008b90 },
+	{ 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80,
+	    0x00008f80 },
+	{ 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84,
+	    0x00008f84 },
+	{ 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88,
+	    0x00008f88 },
+	{ 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c,
+	    0x00008f8c },
+	{ 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90,
+	    0x00008f90 },
+	{ 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c,
+	    0x0000930c },
+	{ 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310,
+	    0x00009310 },
+	{ 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384,
+	    0x00009384 },
+	{ 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388,
+	    0x00009388 },
+	{ 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324,
+	    0x00009324 },
+	{ 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704,
+	    0x00009704 },
+	{ 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4,
+	    0x000096a4 },
+	{ 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8,
+	    0x000096a8 },
+	{ 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710,
+	    0x00009710 },
+	{ 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714,
+	    0x00009714 },
+	{ 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720,
+	    0x00009720 },
+	{ 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724,
+	    0x00009724 },
+	{ 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728,
+	    0x00009728 },
+	{ 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c,
+	    0x0000972c },
+	{ 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0,
+	    0x000097a0 },
+	{ 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4,
+	    0x000097a4 },
+	{ 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8,
+	    0x000097a8 },
+	{ 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0,
+	    0x000097b0 },
+	{ 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4,
+	    0x000097b4 },
+	{ 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8,
+	    0x000097b8 },
+	{ 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5,
+	    0x000097a5 },
+	{ 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9,
+	    0x000097a9 },
+	{ 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad,
+	    0x000097ad },
+	{ 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1,
+	    0x000097b1 },
+	{ 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5,
+	    0x000097b5 },
+	{ 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9,
+	    0x000097b9 },
+	{ 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5,
+	    0x000097c5 },
+	{ 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9,
+	    0x000097c9 },
+	{ 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1,
+	    0x000097d1 },
+	{ 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5,
+	    0x000097d5 },
+	{ 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9,
+	    0x000097d9 },
+	{ 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6,
+	    0x000097c6 },
+	{ 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca,
+	    0x000097ca },
+	{ 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce,
+	    0x000097ce },
+	{ 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2,
+	    0x000097d2 },
+	{ 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6,
+	    0x000097d6 },
+	{ 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3,
+	    0x000097c3 },
+	{ 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7,
+	    0x000097c7 },
+	{ 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb,
+	    0x000097cb },
+	{ 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf,
+	    0x000097cf },
+	{ 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7,
+	    0x000097d7 },
+	{ 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db,
+	    0x000097db },
+	{ 0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063,
+	    0x00001063 },
+	{ 0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063,
+	    0x00001063 },
+};
+
+static const uint32_t ar9280Modes_backoff_13db_rxgain_9280_2[][6] = {
+	{ 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290,
+	    0x00000290 },
+	{ 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300,
+	    0x00000300 },
+	{ 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304,
+	    0x00000304 },
+	{ 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308,
+	    0x00000308 },
+	{ 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c,
+	    0x0000030c },
+	{ 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000,
+	    0x00008000 },
+	{ 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004,
+	    0x00008004 },
+	{ 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008,
+	    0x00008008 },
+	{ 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c,
+	    0x0000800c },
+	{ 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080,
+	    0x00008080 },
+	{ 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084,
+	    0x00008084 },
+	{ 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088,
+	    0x00008088 },
+	{ 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c,
+	    0x0000808c },
+	{ 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100,
+	    0x00008100 },
+	{ 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104,
+	    0x00008104 },
+	{ 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108,
+	    0x00008108 },
+	{ 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c,
+	    0x0000810c },
+	{ 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110,
+	    0x00008110 },
+	{ 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114,
+	    0x00008114 },
+	{ 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180,
+	    0x00008180 },
+	{ 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184,
+	    0x00008184 },
+	{ 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188,
+	    0x00008188 },
+	{ 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c,
+	    0x0000818c },
+	{ 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190,
+	    0x00008190 },
+	{ 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194,
+	    0x00008194 },
+	{ 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0,
+	    0x000081a0 },
+	{ 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c,
+	    0x0000820c },
+	{ 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8,
+	    0x000081a8 },
+	{ 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284,
+	    0x00008284 },
+	{ 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288,
+	    0x00008288 },
+	{ 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224,
+	    0x00008224 },
+	{ 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290,
+	    0x00008290 },
+	{ 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300,
+	    0x00008300 },
+	{ 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304,
+	    0x00008304 },
+	{ 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308,
+	    0x00008308 },
+	{ 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c,
+	    0x0000830c },
+	{ 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380,
+	    0x00008380 },
+	{ 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384,
+	    0x00008384 },
+	{ 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700,
+	    0x00008700 },
+	{ 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704,
+	    0x00008704 },
+	{ 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708,
+	    0x00008708 },
+	{ 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c,
+	    0x0000870c },
+	{ 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780,
+	    0x00008780 },
+	{ 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784,
+	    0x00008784 },
+	{ 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00,
+	    0x00008b00 },
+	{ 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04,
+	    0x00008b04 },
+	{ 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08,
+	    0x00008b08 },
+	{ 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c,
+	    0x00008b0c },
+	{ 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80,
+	    0x00008b80 },
+	{ 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84,
+	    0x00008b84 },
+	{ 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88,
+	    0x00008b88 },
+	{ 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c,
+	    0x00008b8c },
+	{ 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90,
+	    0x00008b90 },
+	{ 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80,
+	    0x00008f80 },
+	{ 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84,
+	    0x00008f84 },
+	{ 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88,
+	    0x00008f88 },
+	{ 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c,
+	    0x00008f8c },
+	{ 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90,
+	    0x00008f90 },
+	{ 0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310,
+	    0x00009310 },
+	{ 0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314,
+	    0x00009314 },
+	{ 0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320,
+	    0x00009320 },
+	{ 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324,
+	    0x00009324 },
+	{ 0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328,
+	    0x00009328 },
+	{ 0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c,
+	    0x0000932c },
+	{ 0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330,
+	    0x00009330 },
+	{ 0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334,
+	    0x00009334 },
+	{ 0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321,
+	    0x00009321 },
+	{ 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325,
+	    0x00009325 },
+	{ 0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329,
+	    0x00009329 },
+	{ 0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d,
+	    0x0000932d },
+	{ 0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331,
+	    0x00009331 },
+	{ 0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335,
+	    0x00009335 },
+	{ 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322,
+	    0x00009322 },
+	{ 0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326,
+	    0x00009326 },
+	{ 0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a,
+	    0x0000932a },
+	{ 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e,
+	    0x0000932e },
+	{ 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332,
+	    0x00009332 },
+	{ 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336,
+	    0x00009336 },
+	{ 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323,
+	    0x00009323 },
+	{ 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327,
+	    0x00009327 },
+	{ 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b,
+	    0x0000932b },
+	{ 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f,
+	    0x0000932f },
+	{ 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333,
+	    0x00009333 },
+	{ 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337,
+	    0x00009337 },
+	{ 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343,
+	    0x00009343 },
+	{ 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347,
+	    0x00009347 },
+	{ 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b,
+	    0x0000934b },
+	{ 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f,
+	    0x0000934f },
+	{ 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353,
+	    0x00009353 },
+	{ 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357,
+	    0x00009357 },
+	{ 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b,
+	    0x0000935b },
+	{ 0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a,
+	    0x0000105a },
+	{ 0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a,
+	    0x0000105a },
+};
+
+static const uint32_t ar9280Modes_high_power_tx_gain_9280_2[][6] = {
+	{ 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002,
+	    0x00004002 },
+	{ 0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008,
+	    0x00007008 },
+	{ 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010,
+	    0x0000c010 },
+	{ 0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012,
+	    0x00010012 },
+	{ 0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014,
+	    0x00013014 },
+	{ 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a,
+	    0x0001820a },
+	{ 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211,
+	    0x0001b211 },
+	{ 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213,
+	    0x0001e213 },
+	{ 0x0000a324, 0x00020092, 0x00020092, 0x00022411, 0x00022411,
+	    0x00022411 },
+	{ 0x0000a328, 0x0002410a, 0x0002410a, 0x00025413, 0x00025413,
+	    0x00025413 },
+	{ 0x0000a32c, 0x0002710c, 0x0002710c, 0x00029811, 0x00029811,
+	    0x00029811 },
+	{ 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002c813, 0x0002c813,
+	    0x0002c813 },
+	{ 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030a14, 0x00030a14,
+	    0x00030a14 },
+	{ 0x0000a338, 0x000321ec, 0x000321ec, 0x00035a50, 0x00035a50,
+	    0x00035a50 },
+	{ 0x0000a33c, 0x000321ec, 0x000321ec, 0x00039c4c, 0x00039c4c,
+	    0x00039c4c },
+	{ 0x0000a340, 0x000321ec, 0x000321ec, 0x0003de8a, 0x0003de8a,
+	    0x0003de8a },
+	{ 0x0000a344, 0x000321ec, 0x000321ec, 0x00042e92, 0x00042e92,
+	    0x00042e92 },
+	{ 0x0000a348, 0x000321ec, 0x000321ec, 0x00046ed2, 0x00046ed2,
+	    0x00046ed2 },
+	{ 0x0000a34c, 0x000321ec, 0x000321ec, 0x0004bed5, 0x0004bed5,
+	    0x0004bed5 },
+	{ 0x0000a350, 0x000321ec, 0x000321ec, 0x0004ff54, 0x0004ff54,
+	    0x0004ff54 },
+	{ 0x0000a354, 0x000321ec, 0x000321ec, 0x00053fd5, 0x00053fd5,
+	    0x00053fd5 },
+	{ 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff,
+	    0x00198eff },
+	{ 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff,
+	    0x00198eff },
+	{ 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce,
+	    0x050739ce },
+};
+
+static const uint32_t ar9280Modes_original_tx_gain_9280_2[][6] = {
+	{ 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002,
+	    0x00003002 },
+	{ 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009,
+	    0x00008009 },
+	{ 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b,
+	    0x0000b00b },
+	{ 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012,
+	    0x0000e012 },
+	{ 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048,
+	    0x00012048 },
+	{ 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a,
+	    0x0001604a },
+	{ 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211,
+	    0x0001a211 },
+	{ 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213,
+	    0x0001e213 },
+	{ 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b,
+	    0x0002121b },
+	{ 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412,
+	    0x00024412 },
+	{ 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414,
+	    0x00028414 },
+	{ 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a,
+	    0x0002b44a },
+	{ 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649,
+	    0x00030649 },
+	{ 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b,
+	    0x0003364b },
+	{ 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49,
+	    0x00038a49 },
+	{ 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48,
+	    0x0003be48 },
+	{ 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a,
+	    0x0003ee4a },
+	{ 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88,
+	    0x00042e88 },
+	{ 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a,
+	    0x00046e8a },
+	{ 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9,
+	    0x00049ec9 },
+	{ 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42,
+	    0x0004bf42 },
+	{ 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff,
+	    0x0019beff },
+	{ 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff,
+	    0x0019beff },
+	{ 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce,
+	    0x050701ce },
+};
+
+static const uint32_t ar9280PciePhy_clkreq_off_L1_9280[][2] = {
+	{0x00004040, 0x9248fd00 },
+	{0x00004040, 0x24924924 },
+	{0x00004040, 0xa8000019 },
+	{0x00004040, 0x13160820 },
+	{0x00004040, 0xe5980560 },
+	{0x00004040, 0xc01dcffc },
+	{0x00004040, 0x1aaabe41 },
+	{0x00004040, 0xbe105554 },
+	{0x00004040, 0x00043007 },
+	{0x00004044, 0x00000000 },
+};
+
+static const uint32_t ar9280PciePhy_clkreq_always_on_L1_9280[][2] =
+{
+	{0x00004040, 0x9248fd00 },
+	{0x00004040, 0x24924924 },
+	{0x00004040, 0xa8000019 },
+	{0x00004040, 0x13160820 },
+	{0x00004040, 0xe5980560 },
+	{0x00004040, 0xc01dcffd },
+	{0x00004040, 0x1aaabe41 },
+	{0x00004040, 0xbe105554 },
+	{0x00004040, 0x00043007 },
+	{0x00004044, 0x00000000 }
+};
+
+/* AR9285 */
+static const uint32_t ar9285Modes_9285[][6] = {
+	{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160,
+		0x000001e0 },
+	{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c,
+		0x000001e0 },
+	{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38,
+		0x00001180 },
+	{ 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+		0x00000008 },
+	{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00,
+		0x06e006e0 },
+	{ 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b,
+		0x0988004f },
+	{ 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440,
+		0x00006880 },
+	{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300,
+		0x00000303 },
+	{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+		0x02020200 },
+	{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+		0x00000e0e },
+	{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001,
+		0x0a020001 },
+	{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+		0x00000e0e },
+	{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
+		0x00000007 },
+	{ 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e,
+		0x206a012e },
+	{ 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020,
+		0x037216a0 },
+	{ 0x00009848, 0x00001066, 0x00001066, 0x0000004e, 0x0000004e,
+		0x00001059 },
+	{ 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2,
+		0x6d4000e2 },
+	{ 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e,
+		0x7ec84d2e },
+	{ 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e,
+		0x3139605e },
+	{ 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20,
+		0x00058d18 },
+	{ 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00,
+		0x0001ce00 },
+	{ 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0,
+		0x5ac640d0 },
+	{ 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881,
+		0x06903881 },
+	{ 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898,
+		0x000007d0 },
+	{ 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b,
+		0x00000016 },
+	{ 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d,
+		0xd00a800d },
+	{ 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1020, 0xdfbc1020,
+		0xdfbc1010 },
+	{ 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+		0x00000000 },
+	{ 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+		0x00000000 },
+	{ 0x000099b8, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c,
+		0x00cf4d1c },
+	{ 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00,
+		0x00000c00 },
+	{ 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4,
+		0x05eea6d4 },
+	{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77,
+		0x06336f77 },
+	{ 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329,
+		0x60f65329 },
+	{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8,
+		0x08f186c8 },
+	{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384,
+		0x00046384 },
+	{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+		0x00000000 },
+	{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+		0x00000000 },
+	{ 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084,
+		0x00000000 },
+	{ 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088,
+		0x00000000 },
+	{ 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c,
+		0x00000000 },
+	{ 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100,
+		0x00000000 },
+	{ 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104,
+		0x00000000 },
+	{ 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108,
+		0x00000000 },
+	{ 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c,
+		0x00000000 },
+	{ 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110,
+		0x00000000 },
+	{ 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114,
+		0x00000000 },
+	{ 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180,
+		0x00000000 },
+	{ 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184,
+		0x00000000 },
+	{ 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188,
+		0x00000000 },
+	{ 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c,
+		0x00000000 },
+	{ 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190,
+		0x00000000 },
+	{ 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194,
+		0x00000000 },
+	{ 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0,
+		0x00000000 },
+	{ 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c,
+		0x00000000 },
+	{ 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8,
+		0x00000000 },
+	{ 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284,
+		0x00000000 },
+	{ 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288,
+		0x00000000 },
+	{ 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220,
+		0x00000000 },
+	{ 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290,
+		0x00000000 },
+	{ 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300,
+		0x00000000 },
+	{ 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304,
+		0x00000000 },
+	{ 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308,
+		0x00000000 },
+	{ 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c,
+		0x00000000 },
+	{ 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380,
+		0x00000000 },
+	{ 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384,
+		0x00000000 },
+	{ 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700,
+		0x00000000 },
+	{ 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704,
+		0x00000000 },
+	{ 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708,
+		0x00000000 },
+	{ 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c,
+		0x00000000 },
+	{ 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780,
+		0x00000000 },
+	{ 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784,
+		0x00000000 },
+	{ 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04,
+		0x00000000 },
+	{ 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08,
+		0x00000000 },
+	{ 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08,
+		0x00000000 },
+	{ 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c,
+		0x00000000 },
+	{ 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80,
+		0x00000000 },
+	{ 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84,
+		0x00000000 },
+	{ 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88,
+		0x00000000 },
+	{ 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c,
+		0x00000000 },
+	{ 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90,
+		0x00000000 },
+	{ 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80,
+		0x00000000 },
+	{ 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84,
+		0x00000000 },
+	{ 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88,
+		0x00000000 },
+	{ 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c,
+		0x00000000 },
+	{ 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90,
+		0x00000000 },
+	{ 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c,
+		0x00000000 },
+	{ 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310,
+		0x00000000 },
+	{ 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384,
+		0x00000000 },
+	{ 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388,
+		0x00000000 },
+	{ 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324,
+		0x00000000 },
+	{ 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704,
+		0x00000000 },
+	{ 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4,
+		0x00000000 },
+	{ 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8,
+		0x00000000 },
+	{ 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710,
+		0x00000000 },
+	{ 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714,
+		0x00000000 },
+	{ 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720,
+		0x00000000 },
+	{ 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724,
+		0x00000000 },
+	{ 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728,
+		0x00000000 },
+	{ 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c,
+		0x00000000 },
+	{ 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0,
+		0x00000000 },
+	{ 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4,
+		0x00000000 },
+	{ 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8,
+		0x00000000 },
+	{ 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0,
+		0x00000000 },
+	{ 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4,
+		0x00000000 },
+	{ 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8,
+		0x00000000 },
+	{ 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5,
+		0x00000000 },
+	{ 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9,
+		0x00000000 },
+	{ 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad,
+		0x00000000 },
+	{ 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1,
+		0x00000000 },
+	{ 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5,
+		0x00000000 },
+	{ 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9,
+		0x00000000 },
+	{ 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5,
+		0x00000000 },
+	{ 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9,
+		0x00000000 },
+	{ 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1,
+		0x00000000 },
+	{ 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5,
+		0x00000000 },
+	{ 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9,
+		0x00000000 },
+	{ 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6,
+		0x00000000 },
+	{ 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca,
+		0x00000000 },
+	{ 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce,
+		0x00000000 },
+	{ 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2,
+		0x00000000 },
+	{ 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6,
+		0x00000000 },
+	{ 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3,
+		0x00000000 },
+	{ 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7,
+		0x00000000 },
+	{ 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb,
+		0x00000000 },
+	{ 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf,
+		0x00000000 },
+	{ 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7,
+		0x00000000 },
+	{ 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+		0x00000000 },
+	{ 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c,
+		0x00000000 },
+	{ 0x0000aa04, 0x00000000, 0x00000000, 0x00068080, 0x00068080,
+		0x00000000 },
+	{ 0x0000aa08, 0x00000000, 0x00000000, 0x00068084, 0x00068084,
+		0x00000000 },
+	{ 0x0000aa0c, 0x00000000, 0x00000000, 0x00068088, 0x00068088,
+		0x00000000 },
+	{ 0x0000aa10, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c,
+		0x00000000 },
+	{ 0x0000aa14, 0x00000000, 0x00000000, 0x00068100, 0x00068100,
+		0x00000000 },
+	{ 0x0000aa18, 0x00000000, 0x00000000, 0x00068104, 0x00068104,
+		0x00000000 },
+	{ 0x0000aa1c, 0x00000000, 0x00000000, 0x00068108, 0x00068108,
+		0x00000000 },
+	{ 0x0000aa20, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c,
+		0x00000000 },
+	{ 0x0000aa24, 0x00000000, 0x00000000, 0x00068110, 0x00068110,
+		0x00000000 },
+	{ 0x0000aa28, 0x00000000, 0x00000000, 0x00068110, 0x00068110,
+		0x00000000 },
+	{ 0x0000aa2c, 0x00000000, 0x00000000, 0x00068180, 0x00068180,
+		0x00000000 },
+	{ 0x0000aa30, 0x00000000, 0x00000000, 0x00068184, 0x00068184,
+		0x00000000 },
+	{ 0x0000aa34, 0x00000000, 0x00000000, 0x00068188, 0x00068188,
+		0x00000000 },
+	{ 0x0000aa38, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c,
+		0x00000000 },
+	{ 0x0000aa3c, 0x00000000, 0x00000000, 0x00068190, 0x00068190,
+		0x00000000 },
+	{ 0x0000aa40, 0x00000000, 0x00000000, 0x00068194, 0x00068194,
+		0x00000000 },
+	{ 0x0000aa44, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0,
+		0x00000000 },
+	{ 0x0000aa48, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c,
+		0x00000000 },
+	{ 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8,
+		0x00000000 },
+	{ 0x0000aa50, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac,
+		0x00000000 },
+	{ 0x0000aa54, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c,
+		0x00000000 },
+	{ 0x0000aa58, 0x00000000, 0x00000000, 0x00068224, 0x00068224,
+		0x00000000 },
+	{ 0x0000aa5c, 0x00000000, 0x00000000, 0x00068290, 0x00068290,
+		0x00000000 },
+	{ 0x0000aa60, 0x00000000, 0x00000000, 0x00068300, 0x00068300,
+		0x00000000 },
+	{ 0x0000aa64, 0x00000000, 0x00000000, 0x00068308, 0x00068308,
+		0x00000000 },
+	{ 0x0000aa68, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c,
+		0x00000000 },
+	{ 0x0000aa6c, 0x00000000, 0x00000000, 0x00068310, 0x00068310,
+		0x00000000 },
+	{ 0x0000aa70, 0x00000000, 0x00000000, 0x00068788, 0x00068788,
+		0x00000000 },
+	{ 0x0000aa74, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c,
+		0x00000000 },
+	{ 0x0000aa78, 0x00000000, 0x00000000, 0x00068790, 0x00068790,
+		0x00000000 },
+	{ 0x0000aa7c, 0x00000000, 0x00000000, 0x00068794, 0x00068794,
+		0x00000000 },
+	{ 0x0000aa80, 0x00000000, 0x00000000, 0x00068798, 0x00068798,
+		0x00000000 },
+	{ 0x0000aa84, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c,
+		0x00000000 },
+	{ 0x0000aa88, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89,
+		0x00000000 },
+	{ 0x0000aa8c, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d,
+		0x00000000 },
+	{ 0x0000aa90, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91,
+		0x00000000 },
+	{ 0x0000aa94, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95,
+		0x00000000 },
+	{ 0x0000aa98, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99,
+		0x00000000 },
+	{ 0x0000aa9c, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5,
+		0x00000000 },
+	{ 0x0000aaa0, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9,
+		0x00000000 },
+	{ 0x0000aaa4, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad,
+		0x00000000 },
+	{ 0x0000aaa8, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c,
+		0x00000000 },
+	{ 0x0000aaac, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10,
+		0x00000000 },
+	{ 0x0000aab0, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14,
+		0x00000000 },
+	{ 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84,
+		0x00000000 },
+	{ 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84,
+		0x00000000 },
+	{ 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88,
+		0x00000000 },
+	{ 0x0000aac0, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380,
+		0x00000000 },
+	{ 0x0000aac4, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384,
+		0x00000000 },
+	{ 0x0000aac8, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388,
+		0x00000000 },
+	{ 0x0000aacc, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c,
+		0x00000000 },
+	{ 0x0000aad0, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394,
+		0x00000000 },
+	{ 0x0000aad4, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798,
+		0x00000000 },
+	{ 0x0000aad8, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c,
+		0x00000000 },
+	{ 0x0000aadc, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710,
+		0x00000000 },
+	{ 0x0000aae0, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714,
+		0x00000000 },
+	{ 0x0000aae4, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718,
+		0x00000000 },
+	{ 0x0000aae8, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705,
+		0x00000000 },
+	{ 0x0000aaec, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709,
+		0x00000000 },
+	{ 0x0000aaf0, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d,
+		0x00000000 },
+	{ 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711,
+		0x00000000 },
+	{ 0x0000aaf8, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715,
+		0x00000000 },
+	{ 0x0000aafc, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719,
+		0x00000000 },
+	{ 0x0000ab00, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4,
+		0x00000000 },
+	{ 0x0000ab04, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8,
+		0x00000000 },
+	{ 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac,
+		0x00000000 },
+	{ 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac,
+		0x00000000 },
+	{ 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0,
+		0x00000000 },
+	{ 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8,
+		0x00000000 },
+	{ 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc,
+		0x00000000 },
+	{ 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1,
+		0x00000000 },
+	{ 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5,
+		0x00000000 },
+	{ 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9,
+		0x00000000 },
+	{ 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1,
+		0x00000000 },
+	{ 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5,
+		0x00000000 },
+	{ 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd,
+		0x00000000 },
+	{ 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9,
+		0x00000000 },
+	{ 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd,
+		0x00000000 },
+	{ 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1,
+		0x00000000 },
+	{ 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9,
+		0x00000000 },
+	{ 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2,
+		0x00000000 },
+	{ 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6,
+		0x00000000 },
+	{ 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca,
+		0x00000000 },
+	{ 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce,
+		0x00000000 },
+	{ 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2,
+		0x00000000 },
+	{ 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6,
+		0x00000000 },
+	{ 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3,
+		0x00000000 },
+	{ 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb,
+		0x00000000 },
+	{ 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+		0x00000000 },
+	{ 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004,
+		0x00000004 },
+	{ 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000,
+		0x0001f000 },
+	{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a,
+		0x1883800a },
+	{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108,
+		0x00000000 },
+	{ 0x0000a250, 0x001ff000, 0x001ff000, 0x001ca000, 0x001ca000,
+		0x001da000 },
+	{ 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652,
+		0x0a82a652 },
+	{ 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+		0x00000000 },
+	{ 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201,
+		0x00000000 },
+	{ 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408,
+		0x00000000 },
+	{ 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a,
+		0x00000000 },
+	{ 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818,
+		0x00000000 },
+	{ 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858,
+		0x00000000 },
+	{ 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859,
+		0x00000000 },
+	{ 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b,
+		0x00000000 },
+	{ 0x0000a320, 0x00000000, 0x00000000, 0x0002c89a, 0x0002c89a,
+		0x00000000 },
+	{ 0x0000a324, 0x00000000, 0x00000000, 0x0002e89b, 0x0002e89b,
+		0x00000000 },
+	{ 0x0000a328, 0x00000000, 0x00000000, 0x0003089c, 0x0003089c,
+		0x00000000 },
+	{ 0x0000a32c, 0x00000000, 0x00000000, 0x0003289d, 0x0003289d,
+		0x00000000 },
+	{ 0x0000a330, 0x00000000, 0x00000000, 0x0003489e, 0x0003489e,
+		0x00000000 },
+	{ 0x0000a334, 0x00000000, 0x00000000, 0x000388de, 0x000388de,
+		0x00000000 },
+	{ 0x0000a338, 0x00000000, 0x00000000, 0x0003b91e, 0x0003b91e,
+		0x00000000 },
+	{ 0x0000a33c, 0x00000000, 0x00000000, 0x0003d95e, 0x0003d95e,
+		0x00000000 },
+	{ 0x0000a340, 0x00000000, 0x00000000, 0x000419df, 0x000419df,
+		0x00000000 },
+	{ 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+		0x00000000 },
+	{ 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e,
+		0x7999aa0e },
+};
+
+static const uint32_t ar9285Common_9285[][2] = {
+	{ 0x0000000c, 0x00000000 },
+	{ 0x00000030, 0x00020045 },
+	{ 0x00000034, 0x00000005 },
+	{ 0x00000040, 0x00000000 },
+	{ 0x00000044, 0x00000008 },
+	{ 0x00000048, 0x00000008 },
+	{ 0x0000004c, 0x00000010 },
+	{ 0x00000050, 0x00000000 },
+	{ 0x00000054, 0x0000001f },
+	{ 0x00000800, 0x00000000 },
+	{ 0x00000804, 0x00000000 },
+	{ 0x00000808, 0x00000000 },
+	{ 0x0000080c, 0x00000000 },
+	{ 0x00000810, 0x00000000 },
+	{ 0x00000814, 0x00000000 },
+	{ 0x00000818, 0x00000000 },
+	{ 0x0000081c, 0x00000000 },
+	{ 0x00000820, 0x00000000 },
+	{ 0x00000824, 0x00000000 },
+	{ 0x00001040, 0x002ffc0f },
+	{ 0x00001044, 0x002ffc0f },
+	{ 0x00001048, 0x002ffc0f },
+	{ 0x0000104c, 0x002ffc0f },
+	{ 0x00001050, 0x002ffc0f },
+	{ 0x00001054, 0x002ffc0f },
+	{ 0x00001058, 0x002ffc0f },
+	{ 0x0000105c, 0x002ffc0f },
+	{ 0x00001060, 0x002ffc0f },
+	{ 0x00001064, 0x002ffc0f },
+	{ 0x00001230, 0x00000000 },
+	{ 0x00001270, 0x00000000 },
+	{ 0x00001038, 0x00000000 },
+	{ 0x00001078, 0x00000000 },
+	{ 0x000010b8, 0x00000000 },
+	{ 0x000010f8, 0x00000000 },
+	{ 0x00001138, 0x00000000 },
+	{ 0x00001178, 0x00000000 },
+	{ 0x000011b8, 0x00000000 },
+	{ 0x000011f8, 0x00000000 },
+	{ 0x00001238, 0x00000000 },
+	{ 0x00001278, 0x00000000 },
+	{ 0x000012b8, 0x00000000 },
+	{ 0x000012f8, 0x00000000 },
+	{ 0x00001338, 0x00000000 },
+	{ 0x00001378, 0x00000000 },
+	{ 0x000013b8, 0x00000000 },
+	{ 0x000013f8, 0x00000000 },
+	{ 0x00001438, 0x00000000 },
+	{ 0x00001478, 0x00000000 },
+	{ 0x000014b8, 0x00000000 },
+	{ 0x000014f8, 0x00000000 },
+	{ 0x00001538, 0x00000000 },
+	{ 0x00001578, 0x00000000 },
+	{ 0x000015b8, 0x00000000 },
+	{ 0x000015f8, 0x00000000 },
+	{ 0x00001638, 0x00000000 },
+	{ 0x00001678, 0x00000000 },
+	{ 0x000016b8, 0x00000000 },
+	{ 0x000016f8, 0x00000000 },
+	{ 0x00001738, 0x00000000 },
+	{ 0x00001778, 0x00000000 },
+	{ 0x000017b8, 0x00000000 },
+	{ 0x000017f8, 0x00000000 },
+	{ 0x0000103c, 0x00000000 },
+	{ 0x0000107c, 0x00000000 },
+	{ 0x000010bc, 0x00000000 },
+	{ 0x000010fc, 0x00000000 },
+	{ 0x0000113c, 0x00000000 },
+	{ 0x0000117c, 0x00000000 },
+	{ 0x000011bc, 0x00000000 },
+	{ 0x000011fc, 0x00000000 },
+	{ 0x0000123c, 0x00000000 },
+	{ 0x0000127c, 0x00000000 },
+	{ 0x000012bc, 0x00000000 },
+	{ 0x000012fc, 0x00000000 },
+	{ 0x0000133c, 0x00000000 },
+	{ 0x0000137c, 0x00000000 },
+	{ 0x000013bc, 0x00000000 },
+	{ 0x000013fc, 0x00000000 },
+	{ 0x0000143c, 0x00000000 },
+	{ 0x0000147c, 0x00000000 },
+	{ 0x00004030, 0x00000002 },
+	{ 0x0000403c, 0x00000002 },
+	{ 0x00004024, 0x0000001f },
+	{ 0x00004060, 0x00000000 },
+	{ 0x00004064, 0x00000000 },
+	{ 0x00007010, 0x00000031 },
+	{ 0x00007034, 0x00000002 },
+	{ 0x00007038, 0x000004c2 },
+	{ 0x00008004, 0x00000000 },
+	{ 0x00008008, 0x00000000 },
+	{ 0x0000800c, 0x00000000 },
+	{ 0x00008018, 0x00000700 },
+	{ 0x00008020, 0x00000000 },
+	{ 0x00008038, 0x00000000 },
+	{ 0x0000803c, 0x00000000 },
+	{ 0x00008048, 0x00000000 },
+	{ 0x00008054, 0x00000000 },
+	{ 0x00008058, 0x00000000 },
+	{ 0x0000805c, 0x000fc78f },
+	{ 0x00008060, 0x0000000f },
+	{ 0x00008064, 0x00000000 },
+	{ 0x00008070, 0x00000000 },
+	{ 0x000080c0, 0x2a80001a },
+	{ 0x000080c4, 0x05dc01e0 },
+	{ 0x000080c8, 0x1f402710 },
+	{ 0x000080cc, 0x01f40000 },
+	{ 0x000080d0, 0x00001e00 },
+	{ 0x000080d4, 0x00000000 },
+	{ 0x000080d8, 0x00400000 },
+	{ 0x000080e0, 0xffffffff },
+	{ 0x000080e4, 0x0000ffff },
+	{ 0x000080e8, 0x003f3f3f },
+	{ 0x000080ec, 0x00000000 },
+	{ 0x000080f0, 0x00000000 },
+	{ 0x000080f4, 0x00000000 },
+	{ 0x000080f8, 0x00000000 },
+	{ 0x000080fc, 0x00020000 },
+	{ 0x00008100, 0x00020000 },
+	{ 0x00008104, 0x00000001 },
+	{ 0x00008108, 0x00000052 },
+	{ 0x0000810c, 0x00000000 },
+	{ 0x00008110, 0x00000168 },
+	{ 0x00008118, 0x000100aa },
+	{ 0x0000811c, 0x00003210 },
+	{ 0x00008120, 0x08f04800 },
+	{ 0x00008124, 0x00000000 },
+	{ 0x00008128, 0x00000000 },
+	{ 0x0000812c, 0x00000000 },
+	{ 0x00008130, 0x00000000 },
+	{ 0x00008134, 0x00000000 },
+	{ 0x00008138, 0x00000000 },
+	{ 0x0000813c, 0x00000000 },
+	{ 0x00008144, 0x00000000 },
+	{ 0x00008168, 0x00000000 },
+	{ 0x0000816c, 0x00000000 },
+	{ 0x00008170, 0x32143320 },
+	{ 0x00008174, 0xfaa4fa50 },
+	{ 0x00008178, 0x00000100 },
+	{ 0x0000817c, 0x00000000 },
+	{ 0x000081c0, 0x00000000 },
+	{ 0x000081d0, 0x00003210 },
+	{ 0x000081ec, 0x00000000 },
+	{ 0x000081f0, 0x00000000 },
+	{ 0x000081f4, 0x00000000 },
+	{ 0x000081f8, 0x00000000 },
+	{ 0x000081fc, 0x00000000 },
+	{ 0x00008200, 0x00000000 },
+	{ 0x00008204, 0x00000000 },
+	{ 0x00008208, 0x00000000 },
+	{ 0x0000820c, 0x00000000 },
+	{ 0x00008210, 0x00000000 },
+	{ 0x00008214, 0x00000000 },
+	{ 0x00008218, 0x00000000 },
+	{ 0x0000821c, 0x00000000 },
+	{ 0x00008220, 0x00000000 },
+	{ 0x00008224, 0x00000000 },
+	{ 0x00008228, 0x00000000 },
+	{ 0x0000822c, 0x00000000 },
+	{ 0x00008230, 0x00000000 },
+	{ 0x00008234, 0x00000000 },
+	{ 0x00008238, 0x00000000 },
+	{ 0x0000823c, 0x00000000 },
+	{ 0x00008240, 0x00100000 },
+	{ 0x00008244, 0x0010f400 },
+	{ 0x00008248, 0x00000100 },
+	{ 0x0000824c, 0x0001e800 },
+	{ 0x00008250, 0x00000000 },
+	{ 0x00008254, 0x00000000 },
+	{ 0x00008258, 0x00000000 },
+	{ 0x0000825c, 0x400000ff },
+	{ 0x00008260, 0x00080922 },
+	{ 0x00008264, 0xa8a00010 },
+	{ 0x00008270, 0x00000000 },
+	{ 0x00008274, 0x40000000 },
+	{ 0x00008278, 0x003e4180 },
+	{ 0x0000827c, 0x00000000 },
+	{ 0x00008284, 0x0000002c },
+	{ 0x00008288, 0x0000002c },
+	{ 0x0000828c, 0x00000000 },
+	{ 0x00008294, 0x00000000 },
+	{ 0x00008298, 0x00000000 },
+	{ 0x0000829c, 0x00000000 },
+	{ 0x00008300, 0x00000040 },
+	{ 0x00008314, 0x00000000 },
+	{ 0x00008328, 0x00000000 },
+	{ 0x0000832c, 0x00000001 },
+	{ 0x00008330, 0x00000302 },
+	{ 0x00008334, 0x00000e00 },
+	{ 0x00008338, 0x00000000 },
+	{ 0x0000833c, 0x00000000 },
+	{ 0x00008340, 0x00010380 },
+	{ 0x00008344, 0x00581043 },
+	{ 0x00009808, 0x00000000 },
+	{ 0x0000980c, 0xafe68e30 },
+	{ 0x00009810, 0xfd14e000 },
+	{ 0x00009814, 0x9c0a9f6b },
+	{ 0x0000981c, 0x00000000 },
+	{ 0x0000982c, 0x0000a000 },
+	{ 0x00009830, 0x00000000 },
+	{ 0x0000983c, 0x00200400 },
+	{ 0x0000984c, 0x0040233c },
+	{ 0x00009854, 0x00000044 },
+	{ 0x00009900, 0x00000000 },
+	{ 0x00009904, 0x00000000 },
+	{ 0x00009908, 0x00000000 },
+	{ 0x0000990c, 0x00000000 },
+	{ 0x00009910, 0x01002310 },
+	{ 0x0000991c, 0x10000fff },
+	{ 0x00009920, 0x04900000 },
+	{ 0x00009928, 0x00000001 },
+	{ 0x0000992c, 0x00000004 },
+	{ 0x00009934, 0x1e1f2022 },
+	{ 0x00009938, 0x0a0b0c0d },
+	{ 0x0000993c, 0x00000000 },
+	{ 0x00009940, 0x14750604 },
+	{ 0x00009948, 0x9280c00a },
+	{ 0x0000994c, 0x00020028 },
+	{ 0x00009954, 0x5f3ca3de },
+	{ 0x00009958, 0x2108ecff },
+	{ 0x00009968, 0x000003ce },
+	{ 0x00009970, 0x1927b515 },
+	{ 0x00009974, 0x00000000 },
+	{ 0x00009978, 0x00000001 },
+	{ 0x0000997c, 0x00000000 },
+	{ 0x00009980, 0x00000000 },
+	{ 0x00009984, 0x00000000 },
+	{ 0x00009988, 0x00000000 },
+	{ 0x0000998c, 0x00000000 },
+	{ 0x00009990, 0x00000000 },
+	{ 0x00009994, 0x00000000 },
+	{ 0x00009998, 0x00000000 },
+	{ 0x0000999c, 0x00000000 },
+	{ 0x000099a0, 0x00000000 },
+	{ 0x000099a4, 0x00000001 },
+	{ 0x000099a8, 0x201fff00 },
+	{ 0x000099ac, 0x2def0a00 },
+	{ 0x000099b0, 0x03051000 },
+	{ 0x000099b4, 0x00000820 },
+	{ 0x000099dc, 0x00000000 },
+	{ 0x000099e0, 0x00000000 },
+	{ 0x000099e4, 0xaaaaaaaa },
+	{ 0x000099e8, 0x3c466478 },
+	{ 0x000099ec, 0x0cc80caa },
+	{ 0x000099f0, 0x00000000 },
+	{ 0x0000a208, 0x803e6788 },
+	{ 0x0000a210, 0x4080a333 },
+	{ 0x0000a214, 0x00206c10 },
+	{ 0x0000a218, 0x009c4060 },
+	{ 0x0000a220, 0x01834061 },
+	{ 0x0000a224, 0x00000400 },
+	{ 0x0000a228, 0x000003b5 },
+	{ 0x0000a22c, 0x00000000 },
+	{ 0x0000a234, 0x20202020 },
+	{ 0x0000a238, 0x20202020 },
+	{ 0x0000a244, 0x00000000 },
+	{ 0x0000a248, 0xfffffffc },
+	{ 0x0000a24c, 0x00000000 },
+	{ 0x0000a254, 0x00000000 },
+	{ 0x0000a258, 0x0ccb5380 },
+	{ 0x0000a25c, 0x15151501 },
+	{ 0x0000a260, 0xdfa90f01 },
+	{ 0x0000a268, 0x00000000 },
+	{ 0x0000a26c, 0x0ebae9e6 },
+	{ 0x0000d270, 0x0d820820 },
+	{ 0x0000a278, 0x39ce739c },
+	{ 0x0000a27c, 0x050e039c },
+	{ 0x0000d35c, 0x07ffffef },
+	{ 0x0000d360, 0x0fffffe7 },
+	{ 0x0000d364, 0x17ffffe5 },
+	{ 0x0000d368, 0x1fffffe4 },
+	{ 0x0000d36c, 0x37ffffe3 },
+	{ 0x0000d370, 0x3fffffe3 },
+	{ 0x0000d374, 0x57ffffe3 },
+	{ 0x0000d378, 0x5fffffe2 },
+	{ 0x0000d37c, 0x7fffffe2 },
+	{ 0x0000d380, 0x7f3c7bba },
+	{ 0x0000d384, 0xf3307ff0 },
+	{ 0x0000a388, 0x0c000000 },
+	{ 0x0000a38c, 0x20202020 },
+	{ 0x0000a390, 0x20202020 },
+	{ 0x0000a394, 0x39ce739c },
+	{ 0x0000a398, 0x0000039c },
+	{ 0x0000a39c, 0x00000001 },
+	{ 0x0000a3a0, 0x00000000 },
+	{ 0x0000a3a4, 0x00000000 },
+	{ 0x0000a3a8, 0x00000000 },
+	{ 0x0000a3ac, 0x00000000 },
+	{ 0x0000a3b0, 0x00000000 },
+	{ 0x0000a3b4, 0x00000000 },
+	{ 0x0000a3b8, 0x00000000 },
+	{ 0x0000a3bc, 0x00000000 },
+	{ 0x0000a3c0, 0x00000000 },
+	{ 0x0000a3c4, 0x00000000 },
+	{ 0x0000a3cc, 0x20202020 },
+	{ 0x0000a3d0, 0x20202020 },
+	{ 0x0000a3d4, 0x20202020 },
+	{ 0x0000a3dc, 0x39ce739c },
+	{ 0x0000a3e0, 0x0000039c },
+	{ 0x0000a3e4, 0x00000000 },
+	{ 0x0000a3e8, 0x18c43433 },
+	{ 0x0000a3ec, 0x00f70081 },
+	{ 0x00007800, 0x00140000 },
+	{ 0x00007804, 0x0e4548d8 },
+	{ 0x00007808, 0x54214514 },
+	{ 0x0000780c, 0x02025820 },
+	{ 0x00007810, 0x71c0d388 },
+	{ 0x00007814, 0x924934a8 },
+	{ 0x0000781c, 0x00000000 },
+	{ 0x00007820, 0x00000c04 },
+	{ 0x00007824, 0x00d86fff },
+	{ 0x00007828, 0x26d2491b },
+	{ 0x0000782c, 0x6e36d97b },
+	{ 0x00007830, 0xedb6d96c },
+	{ 0x00007834, 0x71400086 },
+	{ 0x00007838, 0xfac68800 },
+	{ 0x0000783c, 0x0001fffe },
+	{ 0x00007840, 0xffeb1a20 },
+	{ 0x00007844, 0x000c0db6 },
+	{ 0x00007848, 0x6db61b6f },
+	{ 0x0000784c, 0x6d9b66db },
+	{ 0x00007850, 0x6d8c6dba },
+	{ 0x00007854, 0x00040000 },
+	{ 0x00007858, 0xdb003012 },
+	{ 0x0000785c, 0x04924914 },
+	{ 0x00007860, 0x21084210 },
+	{ 0x00007864, 0xf7d7ffde },
+	{ 0x00007868, 0xc2034080 },
+	{ 0x0000786c, 0x48609eb4 },
+	{ 0x00007870, 0x10142c00 },
+};
+
+static const uint32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
+	{0x00004040,  0x9248fd00 },
+	{0x00004040,  0x24924924 },
+	{0x00004040,  0xa8000019 },
+	{0x00004040,  0x13160820 },
+	{0x00004040,  0xe5980560 },
+	{0x00004040,  0xc01dcffd },
+	{0x00004040,  0x1aaabe41 },
+	{0x00004040,  0xbe105554 },
+	{0x00004040,  0x00043007 },
+	{0x00004044,  0x00000000 },
+};
+
+static const uint32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
+	{0x00004040,  0x9248fd00 },
+	{0x00004040,  0x24924924 },
+	{0x00004040,  0xa8000019 },
+	{0x00004040,  0x13160820 },
+	{0x00004040,  0xe5980560 },
+	{0x00004040,  0xc01dcffc },
+	{0x00004040,  0x1aaabe41 },
+	{0x00004040,  0xbe105554 },
+	{0x00004040,  0x00043007 },
+	{0x00004044,  0x00000000 },
+};
+
+static const uint32_t ar9285Modes_9285_1_2[][6] = {
+	{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160,
+		0x000001e0 },
+	{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c,
+	    0x000001e0 },
+	{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38,
+	    0x00001180 },
+	{ 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000008 },
+	{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00,
+	    0x06e006e0 },
+	{ 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b,
+	    0x0988004f },
+	{ 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440,
+	    0x00006880 },
+	{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300,
+	    0x00000303 },
+	{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200,
+	    0x02020200 },
+	{ 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001,
+	    0x0a020001 },
+	{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e,
+	    0x00000e0e },
+	{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
+	    0x00000007 },
+	{ 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e,
+	    0x206a012e },
+	{ 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020,
+	    0x037216a0 },
+	{ 0x00009848, 0x00001066, 0x00001066, 0x00000057, 0x00000057,
+	    0x00001059 },
+	{ 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2,
+	    0x6d4000e2 },
+	{ 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e,
+	    0x7ec84d2e },
+	{ 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e,
+	    0x3139605e },
+	{ 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20,
+	    0x00058d18 },
+	{ 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00,
+	    0x0001ce00 },
+	{ 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0,
+	    0x5ac640d0 },
+	{ 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881,
+	    0x06903881 },
+	{ 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898,
+	    0x000007d0 },
+	{ 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b,
+	    0x00000016 },
+	{ 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d,
+	    0xd00a800d },
+	{ 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020,
+	    0xffbc1010 },
+	{ 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c,
+	    0x0000421c },
+	{ 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00,
+	    0x00000c00 },
+	{ 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4,
+	    0x05eea6d4 },
+	{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77,
+	    0x06336f77 },
+	{ 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329,
+	    0x60f65329 },
+	{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8,
+	    0x08f186c8 },
+	{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384,
+	    0x00046384 },
+	{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084,
+	    0x00000000 },
+	{ 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088,
+	    0x00000000 },
+	{ 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c,
+	    0x00000000 },
+	{ 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100,
+	    0x00000000 },
+	{ 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104,
+	    0x00000000 },
+	{ 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108,
+	    0x00000000 },
+	{ 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c,
+	    0x00000000 },
+	{ 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110,
+	    0x00000000 },
+	{ 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114,
+	    0x00000000 },
+	{ 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180,
+	    0x00000000 },
+	{ 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184,
+	    0x00000000 },
+	{ 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188,
+	    0x00000000 },
+	{ 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c,
+	    0x00000000 },
+	{ 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190,
+	    0x00000000 },
+	{ 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194,
+	    0x00000000 },
+	{ 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0,
+	    0x00000000 },
+	{ 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c,
+	    0x00000000 },
+	{ 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8,
+	    0x00000000 },
+	{ 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284,
+	    0x00000000 },
+	{ 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288,
+	    0x00000000 },
+	{ 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220,
+	    0x00000000 },
+	{ 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290,
+	    0x00000000 },
+	{ 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300,
+	    0x00000000 },
+	{ 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304,
+	    0x00000000 },
+	{ 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308,
+	    0x00000000 },
+	{ 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c,
+	    0x00000000 },
+	{ 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380,
+	    0x00000000 },
+	{ 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384,
+	    0x00000000 },
+	{ 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700,
+	    0x00000000 },
+	{ 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704,
+	    0x00000000 },
+	{ 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708,
+	    0x00000000 },
+	{ 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c,
+	    0x00000000 },
+	{ 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780,
+	    0x00000000 },
+	{ 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784,
+	    0x00000000 },
+	{ 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04,
+	    0x00000000 },
+	{ 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08,
+	    0x00000000 },
+	{ 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08,
+	    0x00000000 },
+	{ 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c,
+	    0x00000000 },
+	{ 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80,
+	    0x00000000 },
+	{ 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84,
+	    0x00000000 },
+	{ 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88,
+	    0x00000000 },
+	{ 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c,
+	    0x00000000 },
+	{ 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90,
+	    0x00000000 },
+	{ 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80,
+	    0x00000000 },
+	{ 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84,
+	    0x00000000 },
+	{ 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88,
+	    0x00000000 },
+	{ 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c,
+	    0x00000000 },
+	{ 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90,
+	    0x00000000 },
+	{ 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c,
+	    0x00000000 },
+	{ 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310,
+	    0x00000000 },
+	{ 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384,
+	    0x00000000 },
+	{ 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388,
+	    0x00000000 },
+	{ 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324,
+	    0x00000000 },
+	{ 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704,
+	    0x00000000 },
+	{ 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4,
+	    0x00000000 },
+	{ 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8,
+	    0x00000000 },
+	{ 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710,
+	    0x00000000 },
+	{ 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714,
+	    0x00000000 },
+	{ 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720,
+	    0x00000000 },
+	{ 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724,
+	    0x00000000 },
+	{ 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728,
+	    0x00000000 },
+	{ 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c,
+	    0x00000000 },
+	{ 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0,
+	    0x00000000 },
+	{ 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4,
+	    0x00000000 },
+	{ 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8,
+	    0x00000000 },
+	{ 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0,
+	    0x00000000 },
+	{ 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4,
+	    0x00000000 },
+	{ 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8,
+	    0x00000000 },
+	{ 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5,
+	    0x00000000 },
+	{ 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9,
+	    0x00000000 },
+	{ 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad,
+	    0x00000000 },
+	{ 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1,
+	    0x00000000 },
+	{ 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5,
+	    0x00000000 },
+	{ 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9,
+	    0x00000000 },
+	{ 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5,
+	    0x00000000 },
+	{ 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9,
+	    0x00000000 },
+	{ 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1,
+	    0x00000000 },
+	{ 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5,
+	    0x00000000 },
+	{ 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9,
+	    0x00000000 },
+	{ 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6,
+	    0x00000000 },
+	{ 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca,
+	    0x00000000 },
+	{ 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce,
+	    0x00000000 },
+	{ 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2,
+	    0x00000000 },
+	{ 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6,
+	    0x00000000 },
+	{ 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3,
+	    0x00000000 },
+	{ 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7,
+	    0x00000000 },
+	{ 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb,
+	    0x00000000 },
+	{ 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf,
+	    0x00000000 },
+	{ 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7,
+	    0x00000000 },
+	{ 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db,
+	    0x00000000 },
+	{ 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c,
+	    0x00000000 },
+	{ 0x0000aa04, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c,
+	    0x00000000 },
+	{ 0x0000aa08, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c,
+	    0x00000000 },
+	{ 0x0000aa0c, 0x00000000, 0x00000000, 0x00068080, 0x00068080,
+	    0x00000000 },
+	{ 0x0000aa10, 0x00000000, 0x00000000, 0x00068084, 0x00068084,
+	    0x00000000 },
+	{ 0x0000aa14, 0x00000000, 0x00000000, 0x00068088, 0x00068088,
+	    0x00000000 },
+	{ 0x0000aa18, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c,
+	    0x00000000 },
+	{ 0x0000aa1c, 0x00000000, 0x00000000, 0x00068100, 0x00068100,
+	    0x00000000 },
+	{ 0x0000aa20, 0x00000000, 0x00000000, 0x00068104, 0x00068104,
+	    0x00000000 },
+	{ 0x0000aa24, 0x00000000, 0x00000000, 0x00068108, 0x00068108,
+	    0x00000000 },
+	{ 0x0000aa28, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c,
+	    0x00000000 },
+	{ 0x0000aa2c, 0x00000000, 0x00000000, 0x00068110, 0x00068110,
+	    0x00000000 },
+	{ 0x0000aa30, 0x00000000, 0x00000000, 0x00068110, 0x00068110,
+	    0x00000000 },
+	{ 0x0000aa34, 0x00000000, 0x00000000, 0x00068180, 0x00068180,
+	    0x00000000 },
+	{ 0x0000aa38, 0x00000000, 0x00000000, 0x00068184, 0x00068184,
+	    0x00000000 },
+	{ 0x0000aa3c, 0x00000000, 0x00000000, 0x00068188, 0x00068188,
+	    0x00000000 },
+	{ 0x0000aa40, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c,
+	    0x00000000 },
+	{ 0x0000aa44, 0x00000000, 0x00000000, 0x00068190, 0x00068190,
+	    0x00000000 },
+	{ 0x0000aa48, 0x00000000, 0x00000000, 0x00068194, 0x00068194,
+	    0x00000000 },
+	{ 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0,
+	    0x00000000 },
+	{ 0x0000aa50, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c,
+	    0x00000000 },
+	{ 0x0000aa54, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8,
+	    0x00000000 },
+	{ 0x0000aa58, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac,
+	    0x00000000 },
+	{ 0x0000aa5c, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c,
+	    0x00000000 },
+	{ 0x0000aa60, 0x00000000, 0x00000000, 0x00068224, 0x00068224,
+	    0x00000000 },
+	{ 0x0000aa64, 0x00000000, 0x00000000, 0x00068290, 0x00068290,
+	    0x00000000 },
+	{ 0x0000aa68, 0x00000000, 0x00000000, 0x00068300, 0x00068300,
+	    0x00000000 },
+	{ 0x0000aa6c, 0x00000000, 0x00000000, 0x00068308, 0x00068308,
+	    0x00000000 },
+	{ 0x0000aa70, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c,
+	    0x00000000 },
+	{ 0x0000aa74, 0x00000000, 0x00000000, 0x00068310, 0x00068310,
+	    0x00000000 },
+	{ 0x0000aa78, 0x00000000, 0x00000000, 0x00068788, 0x00068788,
+	    0x00000000 },
+	{ 0x0000aa7c, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c,
+	    0x00000000 },
+	{ 0x0000aa80, 0x00000000, 0x00000000, 0x00068790, 0x00068790,
+	    0x00000000 },
+	{ 0x0000aa84, 0x00000000, 0x00000000, 0x00068794, 0x00068794,
+	    0x00000000 },
+	{ 0x0000aa88, 0x00000000, 0x00000000, 0x00068798, 0x00068798,
+	    0x00000000 },
+	{ 0x0000aa8c, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c,
+	    0x00000000 },
+	{ 0x0000aa90, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89,
+	    0x00000000 },
+	{ 0x0000aa94, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d,
+	    0x00000000 },
+	{ 0x0000aa98, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91,
+	    0x00000000 },
+	{ 0x0000aa9c, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95,
+	    0x00000000 },
+	{ 0x0000aaa0, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99,
+	    0x00000000 },
+	{ 0x0000aaa4, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5,
+	    0x00000000 },
+	{ 0x0000aaa8, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9,
+	    0x00000000 },
+	{ 0x0000aaac, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad,
+	    0x00000000 },
+	{ 0x0000aab0, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c,
+	    0x00000000 },
+	{ 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10,
+	    0x00000000 },
+	{ 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14,
+	    0x00000000 },
+	{ 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84,
+	    0x00000000 },
+	{ 0x0000aac0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84,
+	    0x00000000 },
+	{ 0x0000aac4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88,
+	    0x00000000 },
+	{ 0x0000aac8, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380,
+	    0x00000000 },
+	{ 0x0000aacc, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384,
+	    0x00000000 },
+	{ 0x0000aad0, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388,
+	    0x00000000 },
+	{ 0x0000aad4, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c,
+	    0x00000000 },
+	{ 0x0000aad8, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394,
+	    0x00000000 },
+	{ 0x0000aadc, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798,
+	    0x00000000 },
+	{ 0x0000aae0, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c,
+	    0x00000000 },
+	{ 0x0000aae4, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710,
+	    0x00000000 },
+	{ 0x0000aae8, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714,
+	    0x00000000 },
+	{ 0x0000aaec, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718,
+	    0x00000000 },
+	{ 0x0000aaf0, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705,
+	    0x00000000 },
+	{ 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709,
+	    0x00000000 },
+	{ 0x0000aaf8, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d,
+	    0x00000000 },
+	{ 0x0000aafc, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711,
+	    0x00000000 },
+	{ 0x0000ab00, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715,
+	    0x00000000 },
+	{ 0x0000ab04, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719,
+	    0x00000000 },
+	{ 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4,
+	    0x00000000 },
+	{ 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8,
+	    0x00000000 },
+	{ 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac,
+	    0x00000000 },
+	{ 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac,
+	    0x00000000 },
+	{ 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0,
+	    0x00000000 },
+	{ 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8,
+	    0x00000000 },
+	{ 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc,
+	    0x00000000 },
+	{ 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1,
+	    0x00000000 },
+	{ 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5,
+	    0x00000000 },
+	{ 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9,
+	    0x00000000 },
+	{ 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1,
+	    0x00000000 },
+	{ 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5,
+	    0x00000000 },
+	{ 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd,
+	    0x00000000 },
+	{ 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9,
+	    0x00000000 },
+	{ 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd,
+	    0x00000000 },
+	{ 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1,
+	    0x00000000 },
+	{ 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9,
+	    0x00000000 },
+	{ 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2,
+	    0x00000000 },
+	{ 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6,
+	    0x00000000 },
+	{ 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca,
+	    0x00000000 },
+	{ 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce,
+	    0x00000000 },
+	{ 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2,
+	    0x00000000 },
+	{ 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6,
+	    0x00000000 },
+	{ 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3,
+	    0x00000000 },
+	{ 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb,
+	    0x00000000 },
+	{ 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3,
+	    0x00000000 },
+	{ 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004,
+	    0x00000004 },
+	{ 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000,
+	    0x0001f000 },
+	{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a,
+	    0x1883800a },
+	{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108,
+	    0x00000000 },
+	{ 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000,
+	    0x0004a000 },
+	{ 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652,
+	    0x0a82a652 },
+	{ 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	    0x00000000 },
+	{ 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201,
+	    0x00000000 },
+	{ 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408,
+	    0x00000000 },
+	{ 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a,
+	    0x00000000 },
+	{ 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818,
+	    0x00000000 },
+	{ 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858,
+	    0x00000000 },
+	{ 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859,
+	    0x00000000 },
+	{ 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b,
+	    0x00000000 },
+	{ 0x0000a320, 0x00000000, 0x00000000, 0x0002b89a, 0x0002b89a,
+	    0x00000000 },
+	{ 0x0000a324, 0x00000000, 0x00000000, 0x0002d89b, 0x0002d89b,
+	    0x00000000 },
+	{ 0x0000a328, 0x00000000, 0x00000000, 0x0002f89c, 0x0002f89c,
+	    0x00000000 },
+	{ 0x0000a32c, 0x00000000, 0x00000000, 0x0003189d, 0x0003189d,
+	    0x00000000 },
+	{ 0x0000a330, 0x00000000, 0x00000000, 0x0003389e, 0x0003389e,
+	    0x00000000 },
+	{ 0x0000a334, 0x00000000, 0x00000000, 0x000368de, 0x000368de,
+	    0x00000000 },
+	{ 0x0000a338, 0x00000000, 0x00000000, 0x0003891e, 0x0003891e,
+	    0x00000000 },
+	{ 0x0000a33c, 0x00000000, 0x00000000, 0x0003a95e, 0x0003a95e,
+	    0x00000000 },
+	{ 0x0000a340, 0x00000000, 0x00000000, 0x0003e9df, 0x0003e9df,
+	    0x00000000 },
+	{ 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df,
+	    0x00000000 },
+	{ 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e,
+	    0x7999aa0e },
+};
+
+static const uint32_t ar9285Common_9285_1_2[][2] = {
+	{ 0x0000000c, 0x00000000 },
+	{ 0x00000030, 0x00020045 },
+	{ 0x00000034, 0x00000005 },
+	{ 0x00000040, 0x00000000 },
+	{ 0x00000044, 0x00000008 },
+	{ 0x00000048, 0x00000008 },
+	{ 0x0000004c, 0x00000010 },
+	{ 0x00000050, 0x00000000 },
+	{ 0x00000054, 0x0000001f },
+	{ 0x00000800, 0x00000000 },
+	{ 0x00000804, 0x00000000 },
+	{ 0x00000808, 0x00000000 },
+	{ 0x0000080c, 0x00000000 },
+	{ 0x00000810, 0x00000000 },
+	{ 0x00000814, 0x00000000 },
+	{ 0x00000818, 0x00000000 },
+	{ 0x0000081c, 0x00000000 },
+	{ 0x00000820, 0x00000000 },
+	{ 0x00000824, 0x00000000 },
+	{ 0x00001040, 0x002ffc0f },
+	{ 0x00001044, 0x002ffc0f },
+	{ 0x00001048, 0x002ffc0f },
+	{ 0x0000104c, 0x002ffc0f },
+	{ 0x00001050, 0x002ffc0f },
+	{ 0x00001054, 0x002ffc0f },
+	{ 0x00001058, 0x002ffc0f },
+	{ 0x0000105c, 0x002ffc0f },
+	{ 0x00001060, 0x002ffc0f },
+	{ 0x00001064, 0x002ffc0f },
+	{ 0x00001230, 0x00000000 },
+	{ 0x00001270, 0x00000000 },
+	{ 0x00001038, 0x00000000 },
+	{ 0x00001078, 0x00000000 },
+	{ 0x000010b8, 0x00000000 },
+	{ 0x000010f8, 0x00000000 },
+	{ 0x00001138, 0x00000000 },
+	{ 0x00001178, 0x00000000 },
+	{ 0x000011b8, 0x00000000 },
+	{ 0x000011f8, 0x00000000 },
+	{ 0x00001238, 0x00000000 },
+	{ 0x00001278, 0x00000000 },
+	{ 0x000012b8, 0x00000000 },
+	{ 0x000012f8, 0x00000000 },
+	{ 0x00001338, 0x00000000 },
+	{ 0x00001378, 0x00000000 },
+	{ 0x000013b8, 0x00000000 },
+	{ 0x000013f8, 0x00000000 },
+	{ 0x00001438, 0x00000000 },
+	{ 0x00001478, 0x00000000 },
+	{ 0x000014b8, 0x00000000 },
+	{ 0x000014f8, 0x00000000 },
+	{ 0x00001538, 0x00000000 },
+	{ 0x00001578, 0x00000000 },
+	{ 0x000015b8, 0x00000000 },
+	{ 0x000015f8, 0x00000000 },
+	{ 0x00001638, 0x00000000 },
+	{ 0x00001678, 0x00000000 },
+	{ 0x000016b8, 0x00000000 },
+	{ 0x000016f8, 0x00000000 },
+	{ 0x00001738, 0x00000000 },
+	{ 0x00001778, 0x00000000 },
+	{ 0x000017b8, 0x00000000 },
+	{ 0x000017f8, 0x00000000 },
+	{ 0x0000103c, 0x00000000 },
+	{ 0x0000107c, 0x00000000 },
+	{ 0x000010bc, 0x00000000 },
+	{ 0x000010fc, 0x00000000 },
+	{ 0x0000113c, 0x00000000 },
+	{ 0x0000117c, 0x00000000 },
+	{ 0x000011bc, 0x00000000 },
+	{ 0x000011fc, 0x00000000 },
+	{ 0x0000123c, 0x00000000 },
+	{ 0x0000127c, 0x00000000 },
+	{ 0x000012bc, 0x00000000 },
+	{ 0x000012fc, 0x00000000 },
+	{ 0x0000133c, 0x00000000 },
+	{ 0x0000137c, 0x00000000 },
+	{ 0x000013bc, 0x00000000 },
+	{ 0x000013fc, 0x00000000 },
+	{ 0x0000143c, 0x00000000 },
+	{ 0x0000147c, 0x00000000 },
+	{ 0x00004030, 0x00000002 },
+	{ 0x0000403c, 0x00000002 },
+	{ 0x00004024, 0x0000001f },
+	{ 0x00004060, 0x00000000 },
+	{ 0x00004064, 0x00000000 },
+	{ 0x00007010, 0x00000031 },
+	{ 0x00007034, 0x00000002 },
+	{ 0x00007038, 0x000004c2 },
+	{ 0x00008004, 0x00000000 },
+	{ 0x00008008, 0x00000000 },
+	{ 0x0000800c, 0x00000000 },
+	{ 0x00008018, 0x00000700 },
+	{ 0x00008020, 0x00000000 },
+	{ 0x00008038, 0x00000000 },
+	{ 0x0000803c, 0x00000000 },
+	{ 0x00008048, 0x00000000 },
+	{ 0x00008054, 0x00000000 },
+	{ 0x00008058, 0x00000000 },
+	{ 0x0000805c, 0x000fc78f },
+	{ 0x00008060, 0x0000000f },
+	{ 0x00008064, 0x00000000 },
+	{ 0x00008070, 0x00000000 },
+	{ 0x000080c0, 0x2a80001a },
+	{ 0x000080c4, 0x05dc01e0 },
+	{ 0x000080c8, 0x1f402710 },
+	{ 0x000080cc, 0x01f40000 },
+	{ 0x000080d0, 0x00001e00 },
+	{ 0x000080d4, 0x00000000 },
+	{ 0x000080d8, 0x00400000 },
+	{ 0x000080e0, 0xffffffff },
+	{ 0x000080e4, 0x0000ffff },
+	{ 0x000080e8, 0x003f3f3f },
+	{ 0x000080ec, 0x00000000 },
+	{ 0x000080f0, 0x00000000 },
+	{ 0x000080f4, 0x00000000 },
+	{ 0x000080f8, 0x00000000 },
+	{ 0x000080fc, 0x00020000 },
+	{ 0x00008100, 0x00020000 },
+	{ 0x00008104, 0x00000001 },
+	{ 0x00008108, 0x00000052 },
+	{ 0x0000810c, 0x00000000 },
+	{ 0x00008110, 0x00000168 },
+	{ 0x00008118, 0x000100aa },
+	{ 0x0000811c, 0x00003210 },
+	{ 0x00008120, 0x08f04800 },
+	{ 0x00008124, 0x00000000 },
+	{ 0x00008128, 0x00000000 },
+	{ 0x0000812c, 0x00000000 },
+	{ 0x00008130, 0x00000000 },
+	{ 0x00008134, 0x00000000 },
+	{ 0x00008138, 0x00000000 },
+	{ 0x0000813c, 0x00000000 },
+	{ 0x00008144, 0xffffffff },
+	{ 0x00008168, 0x00000000 },
+	{ 0x0000816c, 0x00000000 },
+	{ 0x00008170, 0x32143320 },
+	{ 0x00008174, 0xfaa4fa50 },
+	{ 0x00008178, 0x00000100 },
+	{ 0x0000817c, 0x00000000 },
+	{ 0x000081c0, 0x00000000 },
+	{ 0x000081d0, 0x00003210 },
+	{ 0x000081ec, 0x00000000 },
+	{ 0x000081f0, 0x00000000 },
+	{ 0x000081f4, 0x00000000 },
+	{ 0x000081f8, 0x00000000 },
+	{ 0x000081fc, 0x00000000 },
+	{ 0x00008200, 0x00000000 },
+	{ 0x00008204, 0x00000000 },
+	{ 0x00008208, 0x00000000 },
+	{ 0x0000820c, 0x00000000 },
+	{ 0x00008210, 0x00000000 },
+	{ 0x00008214, 0x00000000 },
+	{ 0x00008218, 0x00000000 },
+	{ 0x0000821c, 0x00000000 },
+	{ 0x00008220, 0x00000000 },
+	{ 0x00008224, 0x00000000 },
+	{ 0x00008228, 0x00000000 },
+	{ 0x0000822c, 0x00000000 },
+	{ 0x00008230, 0x00000000 },
+	{ 0x00008234, 0x00000000 },
+	{ 0x00008238, 0x00000000 },
+	{ 0x0000823c, 0x00000000 },
+	{ 0x00008240, 0x00100000 },
+	{ 0x00008244, 0x0010f400 },
+	{ 0x00008248, 0x00000100 },
+	{ 0x0000824c, 0x0001e800 },
+	{ 0x00008250, 0x00000000 },
+	{ 0x00008254, 0x00000000 },
+	{ 0x00008258, 0x00000000 },
+	{ 0x0000825c, 0x400000ff },
+	{ 0x00008260, 0x00080922 },
+	{ 0x00008264, 0xa8a00010 },
+	{ 0x00008270, 0x00000000 },
+	{ 0x00008274, 0x40000000 },
+	{ 0x00008278, 0x003e4180 },
+	{ 0x0000827c, 0x00000000 },
+	{ 0x00008284, 0x0000002c },
+	{ 0x00008288, 0x0000002c },
+	{ 0x0000828c, 0x00000000 },
+	{ 0x00008294, 0x00000000 },
+	{ 0x00008298, 0x00000000 },
+	{ 0x0000829c, 0x00000000 },
+	{ 0x00008300, 0x00000040 },
+	{ 0x00008314, 0x00000000 },
+	{ 0x00008328, 0x00000000 },
+	{ 0x0000832c, 0x00000001 },
+	{ 0x00008330, 0x00000302 },
+	{ 0x00008334, 0x00000e00 },
+	{ 0x00008338, 0x00ff0000 },
+	{ 0x0000833c, 0x00000000 },
+	{ 0x00008340, 0x00010380 },
+	{ 0x00008344, 0x00581043 },
+	{ 0x00009808, 0x00000000 },
+	{ 0x0000980c, 0xafe68e30 },
+	{ 0x00009810, 0xfd14e000 },
+	{ 0x00009814, 0x9c0a9f6b },
+	{ 0x0000981c, 0x00000000 },
+	{ 0x0000982c, 0x0000a000 },
+	{ 0x00009830, 0x00000000 },
+	{ 0x0000983c, 0x00200400 },
+	{ 0x0000984c, 0x0040233c },
+	{ 0x00009854, 0x00000044 },
+	{ 0x00009900, 0x00000000 },
+	{ 0x00009904, 0x00000000 },
+	{ 0x00009908, 0x00000000 },
+	{ 0x0000990c, 0x00000000 },
+	{ 0x00009910, 0x01002310 },
+	{ 0x0000991c, 0x10000fff },
+	{ 0x00009920, 0x04900000 },
+	{ 0x00009928, 0x00000001 },
+	{ 0x0000992c, 0x00000004 },
+	{ 0x00009934, 0x1e1f2022 },
+	{ 0x00009938, 0x0a0b0c0d },
+	{ 0x0000993c, 0x00000000 },
+	{ 0x00009940, 0x14750604 },
+	{ 0x00009948, 0x9280c00a },
+	{ 0x0000994c, 0x00020028 },
+	{ 0x00009954, 0x5f3ca3de },
+	{ 0x00009958, 0x2108ecff },
+	{ 0x00009968, 0x000003ce },
+	{ 0x00009970, 0x192bb515 },
+	{ 0x00009974, 0x00000000 },
+	{ 0x00009978, 0x00000001 },
+	{ 0x0000997c, 0x00000000 },
+	{ 0x00009980, 0x00000000 },
+	{ 0x00009984, 0x00000000 },
+	{ 0x00009988, 0x00000000 },
+	{ 0x0000998c, 0x00000000 },
+	{ 0x00009990, 0x00000000 },
+	{ 0x00009994, 0x00000000 },
+	{ 0x00009998, 0x00000000 },
+	{ 0x0000999c, 0x00000000 },
+	{ 0x000099a0, 0x00000000 },
+	{ 0x000099a4, 0x00000001 },
+	{ 0x000099a8, 0x201fff00 },
+	{ 0x000099ac, 0x2def1000 },
+	{ 0x000099b0, 0x03051000 },
+	{ 0x000099b4, 0x00000820 },
+	{ 0x000099dc, 0x00000000 },
+	{ 0x000099e0, 0x00000000 },
+	{ 0x000099e4, 0xaaaaaaaa },
+	{ 0x000099e8, 0x3c466478 },
+	{ 0x000099ec, 0x0cc80caa },
+	{ 0x000099f0, 0x00000000 },
+	{ 0x0000a208, 0x803e6788 },
+	{ 0x0000a210, 0x4080a333 },
+	{ 0x0000a214, 0x00206c10 },
+	{ 0x0000a218, 0x009c4060 },
+	{ 0x0000a220, 0x01834061 },
+	{ 0x0000a224, 0x00000400 },
+	{ 0x0000a228, 0x000003b5 },
+	{ 0x0000a22c, 0x00000000 },
+	{ 0x0000a234, 0x20202020 },
+	{ 0x0000a238, 0x20202020 },
+	{ 0x0000a244, 0x00000000 },
+	{ 0x0000a248, 0xfffffffc },
+	{ 0x0000a24c, 0x00000000 },
+	{ 0x0000a254, 0x00000000 },
+	{ 0x0000a258, 0x0ccb5380 },
+	{ 0x0000a25c, 0x15151501 },
+	{ 0x0000a260, 0xdfa90f01 },
+	{ 0x0000a268, 0x00000000 },
+	{ 0x0000a26c, 0x0ebae9e6 },
+	{ 0x0000d270, 0x0d820820 },
+	{ 0x0000a278, 0x318c6318 },
+	{ 0x0000a27c, 0x050c0318 },
+	{ 0x0000d35c, 0x07ffffef },
+	{ 0x0000d360, 0x0fffffe7 },
+	{ 0x0000d364, 0x17ffffe5 },
+	{ 0x0000d368, 0x1fffffe4 },
+	{ 0x0000d36c, 0x37ffffe3 },
+	{ 0x0000d370, 0x3fffffe3 },
+	{ 0x0000d374, 0x57ffffe3 },
+	{ 0x0000d378, 0x5fffffe2 },
+	{ 0x0000d37c, 0x7fffffe2 },
+	{ 0x0000d380, 0x7f3c7bba },
+	{ 0x0000d384, 0xf3307ff0 },
+	{ 0x0000a388, 0x0c000000 },
+	{ 0x0000a38c, 0x20202020 },
+	{ 0x0000a390, 0x20202020 },
+	{ 0x0000a394, 0x318c6318 },
+	{ 0x0000a398, 0x00000318 },
+	{ 0x0000a39c, 0x00000001 },
+	{ 0x0000a3a0, 0x00000000 },
+	{ 0x0000a3a4, 0x00000000 },
+	{ 0x0000a3a8, 0x00000000 },
+	{ 0x0000a3ac, 0x00000000 },
+	{ 0x0000a3b0, 0x00000000 },
+	{ 0x0000a3b4, 0x00000000 },
+	{ 0x0000a3b8, 0x00000000 },
+	{ 0x0000a3bc, 0x00000000 },
+	{ 0x0000a3c0, 0x00000000 },
+	{ 0x0000a3c4, 0x00000000 },
+	{ 0x0000a3cc, 0x20202020 },
+	{ 0x0000a3d0, 0x20202020 },
+	{ 0x0000a3d4, 0x20202020 },
+	{ 0x0000a3dc, 0x318c6318 },
+	{ 0x0000a3e0, 0x00000318 },
+	{ 0x0000a3e4, 0x00000000 },
+	{ 0x0000a3e8, 0x18c43433 },
+	{ 0x0000a3ec, 0x00f70081 },
+	{ 0x00007800, 0x00140000 },
+	{ 0x00007804, 0x0e4548d8 },
+	{ 0x00007808, 0x54214514 },
+	{ 0x0000780c, 0x02025820 },
+	{ 0x00007810, 0x71c0d388 },
+	{ 0x00007814, 0x924934a8 },
+	{ 0x0000781c, 0x00000000 },
+	{ 0x00007820, 0x00000c04 },
+	{ 0x00007824, 0x00d86fff },
+	{ 0x00007828, 0x26d2491b },
+	{ 0x0000782c, 0x6e36d97b },
+	{ 0x00007830, 0xedb6d96e },
+	{ 0x00007834, 0x71400087 },
+	{ 0x00007838, 0xfac68801 },
+	{ 0x0000783c, 0x0001fffe },
+	{ 0x00007840, 0xffeb1a20 },
+	{ 0x00007844, 0x000c0db6 },
+	{ 0x00007848, 0x6db61b6f },
+	{ 0x0000784c, 0x6d9b66db },
+	{ 0x00007850, 0x6d8c6dba },
+	{ 0x00007854, 0x00040000 },
+	{ 0x00007858, 0xdb003012 },
+	{ 0x0000785c, 0x04924914 },
+	{ 0x00007860, 0x21084210 },
+	{ 0x00007864, 0xf7d7ffde },
+	{ 0x00007868, 0xc2034080 },
+	{ 0x0000786c, 0x48609eb4 },
+	{ 0x00007870, 0x10142c00 },
+};
+
+static const uint32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
+	{0x00004040,  0x9248fd00 },
+	{0x00004040,  0x24924924 },
+	{0x00004040,  0xa8000019 },
+	{0x00004040,  0x13160820 },
+	{0x00004040,  0xe5980560 },
+	{0x00004040,  0xc01dcffd },
+	{0x00004040,  0x1aaabe41 },
+	{0x00004040,  0xbe105554 },
+	{0x00004040,  0x00043007 },
+	{0x00004044,  0x00000000 },
+};
+
+static const uint32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
+	{0x00004040,  0x9248fd00 },
+	{0x00004040,  0x24924924 },
+	{0x00004040,  0xa8000019 },
+	{0x00004040,  0x13160820 },
+	{0x00004040,  0xe5980560 },
+	{0x00004040,  0xc01dcffc },
+	{0x00004040,  0x1aaabe41 },
+	{0x00004040,  0xbe105554 },
+	{0x00004040,  0x00043007 },
+	{0x00004044,  0x00000000 },
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARN_INITVALS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_mac.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,1107 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/ddi.h>
+
+#include "arn_core.h"
+#include "arn_hw.h"
+#include "arn_reg.h"
+#include "arn_phy.h"
+
+/* ARGSUSED */
+static void
+ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
+    struct ath9k_tx_queue_info *qi)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	ARN_DBG((ARN_DBG_INTERRUPT,
+	    "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
+	    __func__, ahp->ah_txOkInterruptMask,
+	    ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
+	    ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask));
+
+	REG_WRITE(ah, AR_IMR_S0,
+	    SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK) |
+	    SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
+	REG_WRITE(ah, AR_IMR_S1,
+	    SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)|
+	    SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
+	REG_RMW_FIELD(ah, AR_IMR_S2,
+	    AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
+}
+
+void
+ath9k_hw_dmaRegDump(struct ath_hal *ah)
+{
+	uint32_t val[ATH9K_NUM_DMA_DEBUG_REGS];
+	int qcuOffset = 0, dcuOffset = 0;
+	uint32_t *qcuBase = &val[0], *dcuBase = &val[4];
+	int i;
+
+	REG_WRITE(ah, AR_MACMISC,
+	    ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
+	    (AR_MACMISC_MISC_OBS_BUS_1 <<
+	    AR_MACMISC_MISC_OBS_BUS_MSB_S)));
+
+	ARN_DBG((ARN_DBG_REG_IO, "Raw DMA Debug values:\n"));
+
+	for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
+		if (i % 4 == 0)
+			ARN_DBG((ARN_DBG_REG_IO, "\n"));
+
+		val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof (uint32_t)));
+		ARN_DBG((ARN_DBG_REG_IO, "%d: %08x ", i, val[i]));
+	}
+
+	ARN_DBG((ARN_DBG_REG_IO, "\n\n"));
+	ARN_DBG((ARN_DBG_REG_IO,
+	    "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"));
+
+	for (i = 0; i < ATH9K_NUM_QUEUES;
+	    i++, qcuOffset += 4, dcuOffset += 5) {
+		if (i == 8) {
+			qcuOffset = 0;
+			qcuBase++;
+		}
+
+		if (i == 6) {
+			dcuOffset = 0;
+			dcuBase++;
+		}
+
+		ARN_DBG((ARN_DBG_REG_IO,
+		    "%2d          %2x      %1x     %2x           %2x\n",
+		    i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
+		    (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
+		    val[2] & (0x7 << (i * 3)) >> (i * 3),
+		    (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset));
+	}
+
+	ARN_DBG((ARN_DBG_REG_IO, "\n"));
+	ARN_DBG((ARN_DBG_REG_IO,
+	    "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
+	    (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22));
+	ARN_DBG((ARN_DBG_REG_IO,
+	    "qcu_complete state: %2x    dcu_complete state:     %2x\n",
+	    (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)));
+	ARN_DBG((ARN_DBG_REG_IO,
+	    "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
+	    (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27));
+	ARN_DBG((ARN_DBG_REG_IO,
+	    "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
+	    (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10));
+	ARN_DBG((ARN_DBG_REG_IO,
+	    "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
+	    (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12));
+	ARN_DBG((ARN_DBG_REG_IO,
+	    "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
+	    (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17));
+
+	ARN_DBG((ARN_DBG_REG_IO, "pcu observe 0x%x \n",
+	    REG_READ(ah, AR_OBS_BUS_1)));
+	ARN_DBG((ARN_DBG_REG_IO,
+	    "AR_CR 0x%x \n", REG_READ(ah, AR_CR)));
+}
+
+uint32_t
+ath9k_hw_gettxbuf(struct ath_hal *ah, uint32_t q)
+{
+	return (REG_READ(ah, AR_QTXDP(q)));
+}
+
+boolean_t
+ath9k_hw_puttxbuf(struct ath_hal *ah, uint32_t q, uint32_t txdp)
+{
+	REG_WRITE(ah, AR_QTXDP(q), txdp);
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_txstart(struct ath_hal *ah, uint32_t q)
+{
+	ARN_DBG((ARN_DBG_XMIT, "arn: ath9k_hw_txstart(): "
+	    "tramist queue is %u\n", q));
+
+	REG_WRITE(ah, AR_Q_TXE, 1 << q);
+
+	return (B_TRUE);
+}
+
+uint32_t
+ath9k_hw_numtxpending(struct ath_hal *ah, uint32_t q)
+{
+	uint32_t npend;
+
+	npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
+	if (npend == 0) {
+
+		if (REG_READ(ah, AR_Q_TXE) & (1 << q))
+			npend = 1;
+	}
+
+	return (npend);
+}
+
+boolean_t
+ath9k_hw_updatetxtriglevel(struct ath_hal *ah, boolean_t bIncTrigLevel)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t txcfg, curLevel, newLevel;
+	enum ath9k_int omask;
+
+	if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
+		return (B_FALSE);
+
+	omask = ath9k_hw_set_interrupts(ah,
+	    ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
+
+	txcfg = REG_READ(ah, AR_TXCFG);
+	curLevel = MS(txcfg, AR_FTRIG);
+	newLevel = curLevel;
+	if (bIncTrigLevel) {
+		if (curLevel < MAX_TX_FIFO_THRESHOLD)
+			newLevel++;
+	} else if (curLevel > MIN_TX_FIFO_THRESHOLD)
+		newLevel--;
+	if (newLevel != curLevel)
+		REG_WRITE(ah, AR_TXCFG,
+		    (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
+
+	(void) ath9k_hw_set_interrupts(ah, omask);
+
+	ah->ah_txTrigLevel = (uint16_t)newLevel; /* ??? */
+
+	return (newLevel != curLevel);
+}
+
+boolean_t
+ath9k_hw_stoptxdma(struct ath_hal *ah, uint32_t q)
+{
+	uint32_t tsfLow, j, wait;
+
+	REG_WRITE(ah, AR_Q_TXD, 1 << q);
+
+	for (wait = 1000; wait != 0; wait--) {
+		if (ath9k_hw_numtxpending(ah, q) == 0)
+			break;
+		drv_usecwait(100);
+	}
+
+	if (ath9k_hw_numtxpending(ah, q)) {
+		ARN_DBG((ARN_DBG_QUEUE,
+		    "%s: Num of pending TX Frames %d on Q %d\n",
+		    __func__, ath9k_hw_numtxpending(ah, q), q));
+
+		for (j = 0; j < 2; j++) {
+			tsfLow = REG_READ(ah, AR_TSF_L32);
+			REG_WRITE(ah, AR_QUIET2, SM(10, AR_QUIET2_QUIET_DUR));
+			REG_WRITE(ah, AR_QUIET_PERIOD, 100);
+			REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
+			REG_SET_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+
+			if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
+				break;
+			ARN_DBG((ARN_DBG_QUEUE,
+			    "%s: TSF have moved while trying to set "
+			    "quiet time TSF: 0x%08x\n",
+			    __func__, tsfLow));
+		}
+
+		REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+
+		drv_usecwait(200);
+		REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+
+		wait = 1000;
+
+		while (ath9k_hw_numtxpending(ah, q)) {
+			if ((--wait) == 0) {
+				ARN_DBG((ARN_DBG_XMIT,
+				    "%s: Failed to stop Tx DMA in 100 "
+				    "msec after killing last frame\n",
+				    __func__));
+				break;
+			}
+			drv_usecwait(100);
+		}
+
+		REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+	}
+
+	REG_WRITE(ah, AR_Q_TXD, 0);
+
+	return (wait != 0);
+}
+
+/* ARGSUSED */
+boolean_t
+ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t segLen, boolean_t firstSeg,
+    boolean_t lastSeg, const struct ath_desc *ds0)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	if (firstSeg) {
+		ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
+	} else if (lastSeg) {
+		ads->ds_ctl0 = 0;
+		ads->ds_ctl1 = segLen;
+		ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
+		ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
+	} else {
+		ads->ds_ctl0 = 0;
+		ads->ds_ctl1 = segLen | AR_TxMore;
+		ads->ds_ctl2 = 0;
+		ads->ds_ctl3 = 0;
+	}
+	ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+	ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+	ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+
+	return (B_TRUE);
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+	ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+	ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+}
+
+int
+ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	if ((ads->ds_txstatus9 & AR_TxDone) == 0)
+		return (EINPROGRESS);
+
+	ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
+	ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
+	ds->ds_txstat.ts_status = 0;
+	ds->ds_txstat.ts_flags = 0;
+
+	if (ads->ds_txstatus1 & AR_ExcessiveRetries) {
+		ARN_DBG((ARN_DBG_INTERRUPT, "arn: ATH9K_TXERR_XRETRY\n"));
+		ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
+	}
+	if (ads->ds_txstatus1 & AR_Filtered) {
+		ARN_DBG((ARN_DBG_INTERRUPT, "arn: AR_Filtered\n"));
+		ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
+	}
+	if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
+		ARN_DBG((ARN_DBG_INTERRUPT, "arn: ATH9K_TXERR_FIFO\n"));
+		ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
+		(void) ath9k_hw_updatetxtriglevel(ah, B_TRUE);
+	}
+	if (ads->ds_txstatus9 & AR_TxOpExceeded) {
+		ARN_DBG((ARN_DBG_INTERRUPT, "arn: ATH9K_TXERR_XTXOP\n"));
+		ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
+	}
+	if (ads->ds_txstatus1 & AR_TxTimerExpired) {
+		ARN_DBG((ARN_DBG_INTERRUPT,
+		"arn: ATH9K_TXERR_TIMER_EXPIRED\n"));
+		ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+	}
+
+	if (ads->ds_txstatus1 & AR_DescCfgErr) {
+		ARN_DBG((ARN_DBG_INTERRUPT, "arn: ATH9K_TX_DESC_CFG_ERR\n"));
+		ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+	}
+	if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
+		ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+		(void) ath9k_hw_updatetxtriglevel(ah, B_TRUE);
+	}
+	if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
+		ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+		(void) ath9k_hw_updatetxtriglevel(ah, B_TRUE);
+	}
+	if (ads->ds_txstatus0 & AR_TxBaStatus) {
+		ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
+		ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
+		ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
+	}
+
+	ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
+	switch (ds->ds_txstat.ts_rateindex) {
+	case 0:
+		ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
+		break;
+	case 1:
+		ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
+		break;
+	case 2:
+		ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
+		break;
+	case 3:
+		ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
+		break;
+	}
+
+	ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
+	ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
+	ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
+	ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
+	ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
+	ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
+	ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
+	ds->ds_txstat.evm0 = ads->AR_TxEVM0;
+	ds->ds_txstat.evm1 = ads->AR_TxEVM1;
+	ds->ds_txstat.evm2 = ads->AR_TxEVM2;
+	ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
+	ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
+	ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
+	ds->ds_txstat.ts_antenna = 1;
+
+	return (0);
+}
+
+void
+ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t pktLen, enum ath9k_pkt_type type, uint32_t txPower,
+    uint32_t keyIx, enum ath9k_key_type keyType, uint32_t flags)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	txPower += ahp->ah_txPowerIndexOffset;
+	if (txPower > 63)
+		txPower = 63;
+
+	ads->ds_ctl0 = (pktLen & AR_FrameLen) |
+	    (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) |
+	    SM(txPower, AR_XmitPower) |
+	    (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) |
+	    (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) |
+	    (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) |
+	    (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
+
+	ads->ds_ctl1 =
+	    (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) |
+	    SM(type, AR_FrameType) |
+	    (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) |
+	    (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) |
+	    (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
+
+	ads->ds_ctl6 = SM(keyType, AR_EncrType);
+
+	if (AR_SREV_9285(ah)) {
+		ads->ds_ctl8 = 0;
+		ads->ds_ctl9 = 0;
+		ads->ds_ctl10 = 0;
+		ads->ds_ctl11 = 0;
+	}
+
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
+    struct ath_desc *lastds,
+    uint32_t durUpdateEn, uint32_t rtsctsRate,
+    uint32_t rtsctsDuration,
+    struct ath9k_11n_rate_series series[],
+    uint32_t nseries, uint32_t flags)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+	struct ar5416_desc *last_ads = AR5416DESC(lastds);
+	uint32_t ds_ctl0;
+
+	(void) nseries;
+	(void) rtsctsDuration;
+
+	if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
+		ds_ctl0 = ads->ds_ctl0;
+
+		if (flags & ATH9K_TXDESC_RTSENA) {
+			ds_ctl0 &= ~AR_CTSEnable;
+			ds_ctl0 |= AR_RTSEnable;
+		} else {
+			ds_ctl0 &= ~AR_RTSEnable;
+			ds_ctl0 |= AR_CTSEnable;
+		}
+
+		ads->ds_ctl0 = ds_ctl0;
+	} else {
+		ads->ds_ctl0 =
+		    (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
+	}
+
+	ads->ds_ctl2 = set11nTries(series, 0) |
+	    set11nTries(series, 1) |
+	    set11nTries(series, 2) |
+	    set11nTries(series, 3) |
+	    (durUpdateEn ? AR_DurUpdateEna : 0) |
+	    SM(0, AR_BurstDur);
+
+	ads->ds_ctl3 = set11nRate(series, 0) |
+	    set11nRate(series, 1) |
+	    set11nRate(series, 2) |
+	    set11nRate(series, 3);
+
+	ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) |
+	    set11nPktDurRTSCTS(series, 1);
+
+	ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) |
+	    set11nPktDurRTSCTS(series, 3);
+
+	ads->ds_ctl7 = set11nRateFlags(series, 0) |
+	    set11nRateFlags(series, 1) |
+	    set11nRateFlags(series, 2) |
+	    set11nRateFlags(series, 3) |
+	    SM(rtsctsRate, AR_RTSCTSRate);
+	last_ads->ds_ctl2 = ads->ds_ctl2;
+	last_ads->ds_ctl3 = ads->ds_ctl3;
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t aggrLen)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+	ads->ds_ctl6 &= ~AR_AggrLen;
+	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t numDelims)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+	unsigned int ctl6;
+
+	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+
+	ctl6 = ads->ds_ctl6;
+	ctl6 &= ~AR_PadDelim;
+	ctl6 |= SM(numDelims, AR_PadDelim);
+	ads->ds_ctl6 = ctl6;
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_ctl1 |= AR_IsAggr;
+	ads->ds_ctl1 &= ~AR_MoreAggr;
+	ads->ds_ctl6 &= ~AR_PadDelim;
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t burstDuration)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	ads->ds_ctl2 &= ~AR_BurstDur;
+	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t vmf)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	if (vmf)
+		ads->ds_ctl0 |= AR_VirtMoreFrag;
+	else
+		ads->ds_ctl0 &= ~AR_VirtMoreFrag;
+}
+
+void
+ath9k_hw_gettxintrtxqs(struct ath_hal *ah, uint32_t *txqs)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	*txqs &= ahp->ah_intrTxqs;
+	ahp->ah_intrTxqs &= ~(*txqs);
+}
+
+boolean_t
+ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
+    const struct ath9k_tx_queue_info *qinfo)
+{
+	uint32_t cw;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_tx_queue_info *qi;
+
+	if (q >= pCap->total_queues) {
+		ARN_DBG((ARN_DBG_QUEUE, "%s: invalid queue num %u\n",
+		    __func__, q));
+		return (B_FALSE);
+	}
+
+	qi = &ahp->ah_txq[q];
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+		ARN_DBG((ARN_DBG_QUEUE, "%s: inactive queue\n",
+		    __func__));
+		return (B_FALSE);
+	}
+
+	ARN_DBG((ARN_DBG_QUEUE, "%s: queue %p\n", __func__, qi));
+
+	qi->tqi_ver = qinfo->tqi_ver;
+	qi->tqi_subtype = qinfo->tqi_subtype;
+	qi->tqi_qflags = qinfo->tqi_qflags;
+	qi->tqi_priority = qinfo->tqi_priority;
+	if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
+		qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
+	else
+		qi->tqi_aifs = INIT_AIFS;
+	if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
+		cw = min(qinfo->tqi_cwmin, 1024U);
+		qi->tqi_cwmin = 1;
+		while (qi->tqi_cwmin < cw)
+			qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
+	} else
+		qi->tqi_cwmin = qinfo->tqi_cwmin;
+	if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
+		cw = min(qinfo->tqi_cwmax, 1024U);
+		qi->tqi_cwmax = 1;
+		while (qi->tqi_cwmax < cw)
+			qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
+	} else
+		qi->tqi_cwmax = INIT_CWMAX;
+
+	if (qinfo->tqi_shretry != 0)
+		qi->tqi_shretry = min((uint32_t)qinfo->tqi_shretry, 15U);
+	else
+		qi->tqi_shretry = INIT_SH_RETRY;
+	if (qinfo->tqi_lgretry != 0)
+		qi->tqi_lgretry = min((uint32_t)qinfo->tqi_lgretry, 15U);
+	else
+		qi->tqi_lgretry = INIT_LG_RETRY;
+	qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
+	qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
+	qi->tqi_burstTime = qinfo->tqi_burstTime;
+	qi->tqi_readyTime = qinfo->tqi_readyTime;
+
+	switch (qinfo->tqi_subtype) {
+	case ATH9K_WME_UPSD:
+		if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
+			qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
+		break;
+	default:
+		break;
+	}
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
+    struct ath9k_tx_queue_info *qinfo)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_tx_queue_info *qi;
+
+	if (q >= pCap->total_queues) {
+		ARN_DBG((ARN_DBG_QUEUE, "arn: ath9k_hw_get_txq_props(): "
+		    "invalid queue num %u\n", q));
+		return (B_FALSE);
+	}
+
+	qi = &ahp->ah_txq[q];
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+		ARN_DBG((ARN_DBG_QUEUE, "arn: ath9k_hw_get_txq_props(): "
+		    "inactive queue\n"));
+		return (B_FALSE);
+	}
+
+	qinfo->tqi_qflags = qi->tqi_qflags;
+	qinfo->tqi_ver = qi->tqi_ver;
+	qinfo->tqi_subtype = qi->tqi_subtype;
+	qinfo->tqi_qflags = qi->tqi_qflags;
+	qinfo->tqi_priority = qi->tqi_priority;
+	qinfo->tqi_aifs = qi->tqi_aifs;
+	qinfo->tqi_cwmin = qi->tqi_cwmin;
+	qinfo->tqi_cwmax = qi->tqi_cwmax;
+	qinfo->tqi_shretry = qi->tqi_shretry;
+	qinfo->tqi_lgretry = qi->tqi_lgretry;
+	qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
+	qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
+	qinfo->tqi_burstTime = qi->tqi_burstTime;
+	qinfo->tqi_readyTime = qi->tqi_readyTime;
+
+	return (B_TRUE);
+}
+
+int
+ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
+    const struct ath9k_tx_queue_info *qinfo)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_tx_queue_info *qi;
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	int q;
+
+	switch (type) {
+	case ATH9K_TX_QUEUE_BEACON:
+		q = pCap->total_queues - 1;
+		break;
+	case ATH9K_TX_QUEUE_CAB:
+		q = pCap->total_queues - 2;
+		break;
+	case ATH9K_TX_QUEUE_PSPOLL:
+		q = 1;
+		break;
+	case ATH9K_TX_QUEUE_UAPSD:
+		q = pCap->total_queues - 3;
+		break;
+	case ATH9K_TX_QUEUE_DATA:
+		for (q = 0; q < pCap->total_queues; q++)
+			if (ahp->ah_txq[q].tqi_type ==
+			    ATH9K_TX_QUEUE_INACTIVE)
+				break;
+		if (q == pCap->total_queues) {
+			ARN_DBG((ARN_DBG_QUEUE,
+			    "arn: ath9k_hw_setuptxqueue(): "
+			    "no available tx queue\n"));
+			return (-1);
+		}
+		break;
+	default:
+		ARN_DBG((ARN_DBG_QUEUE,
+		    "arn: ath9k_hw_setuptxqueue(): "
+		    "bad tx queue type %u\n", type));
+
+		return (-1);
+	}
+
+	ARN_DBG((ARN_DBG_QUEUE, "arn: ath9k_hw_setuptxqueue(): "
+	    "queue %u\n", q));
+
+	qi = &ahp->ah_txq[q];
+	if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
+		ARN_DBG((ARN_DBG_QUEUE, "arn: ath9k_hw_setuptxqueue(): "
+		    "tx queue %u already active\n", q));
+
+		return (-1);
+	}
+	(void) memset(qi, 0, sizeof (struct ath9k_tx_queue_info));
+	qi->tqi_type = type;
+	if (qinfo == NULL) {
+		qi->tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE |
+		    TXQ_FLAG_TXERRINT_ENABLE |
+		    TXQ_FLAG_TXDESCINT_ENABLE |
+		    TXQ_FLAG_TXURNINT_ENABLE;
+		qi->tqi_aifs = INIT_AIFS;
+		qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
+		qi->tqi_cwmax = INIT_CWMAX;
+		qi->tqi_shretry = INIT_SH_RETRY;
+		qi->tqi_lgretry = INIT_LG_RETRY;
+		qi->tqi_physCompBuf = 0;
+	} else {
+		qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
+		(void) ath9k_hw_set_txq_props(ah, q, qinfo);
+	}
+
+	return (q);
+}
+
+boolean_t
+ath9k_hw_releasetxqueue(struct ath_hal *ah, uint32_t q)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_tx_queue_info *qi;
+
+	if (q >= pCap->total_queues) {
+		ARN_DBG((ARN_DBG_QUEUE, "arn: arn_txq_setup(): "
+		    "invalid queue num %u\n", q));
+		return (B_FALSE);
+	}
+	qi = &ahp->ah_txq[q];
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+		ARN_DBG((ARN_DBG_QUEUE, "arn: arn_txq_setup(): "
+		    "inactive queue %u\n", q));
+		return (B_FALSE);
+	}
+
+	ARN_DBG((ARN_DBG_QUEUE, "arn: arn_txq_setup(): "
+	    "release queue %u\n", q));
+
+
+	qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
+	ahp->ah_txOkInterruptMask &= ~(1 << q);
+	ahp->ah_txErrInterruptMask &= ~(1 << q);
+	ahp->ah_txDescInterruptMask &= ~(1 << q);
+	ahp->ah_txEolInterruptMask &= ~(1 << q);
+	ahp->ah_txUrnInterruptMask &= ~(1 << q);
+	ath9k_hw_set_txq_interrupts(ah, qi);
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_resettxqueue(struct ath_hal *ah, uint32_t q)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+	struct ath9k_channel *chan = ah->ah_curchan;
+	struct ath9k_tx_queue_info *qi;
+	uint32_t cwMin, chanCwMin, value;
+
+	if (q >= pCap->total_queues) {
+		ARN_DBG((ARN_DBG_QUEUE, "%s: invalid queue num %u\n",
+		    __func__, q));
+
+		return (B_FALSE);
+	}
+
+	qi = &ahp->ah_txq[q];
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+		ARN_DBG((ARN_DBG_QUEUE, "%s: inactive queue %u\n",
+		    __func__, q));
+
+		return (B_TRUE);
+	}
+
+	ARN_DBG((ARN_DBG_QUEUE,
+	    "%s: reset queue %u\n", __func__, q));
+
+	if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
+		if (chan && IS_CHAN_B(chan))
+			chanCwMin = INIT_CWMIN_11B;
+		else
+			chanCwMin = INIT_CWMIN;
+
+		for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1) {
+			/* Nothing to do */
+		}
+	} else
+		cwMin = qi->tqi_cwmin;
+
+	REG_WRITE(ah, AR_DLCL_IFS(q),
+	    SM(cwMin, AR_D_LCL_IFS_CWMIN) |
+	    SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
+	    SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
+
+	REG_WRITE(ah, AR_DRETRY_LIMIT(q),
+	    SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
+	    SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
+	    SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
+
+	REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
+	REG_WRITE(ah, AR_DMISC(q),
+	    AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
+
+	if (qi->tqi_cbrPeriod) {
+		REG_WRITE(ah, AR_QCBRCFG(q),
+		    SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
+		    SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
+		REG_WRITE(ah, AR_QMISC(q),
+		    REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
+		    (qi->tqi_cbrOverflowLimit ?
+		    AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
+	}
+	if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
+		REG_WRITE(ah, AR_QRDYTIMECFG(q),
+		    SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
+		    AR_Q_RDYTIMECFG_EN);
+	}
+
+	REG_WRITE(ah, AR_DCHNTIME(q),
+	    SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
+	    (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
+
+	if (qi->tqi_burstTime &&
+	    (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
+		REG_WRITE(ah, AR_QMISC(q),
+		    REG_READ(ah, AR_QMISC(q)) |
+		    AR_Q_MISC_RDYTIME_EXP_POLICY);
+
+	}
+
+	if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
+		REG_WRITE(ah, AR_DMISC(q),
+		    REG_READ(ah, AR_DMISC(q)) |
+		    AR_D_MISC_POST_FR_BKOFF_DIS);
+	}
+	if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
+		REG_WRITE(ah, AR_DMISC(q),
+		    REG_READ(ah, AR_DMISC(q)) |
+		    AR_D_MISC_FRAG_BKOFF_EN);
+	}
+	switch (qi->tqi_type) {
+	case ATH9K_TX_QUEUE_BEACON:
+		REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) |
+		    AR_Q_MISC_FSP_DBA_GATED |
+		    AR_Q_MISC_BEACON_USE |
+		    AR_Q_MISC_CBR_INCR_DIS1);
+
+		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
+		    (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+		    AR_D_MISC_ARB_LOCKOUT_CNTRL_S) |
+		    AR_D_MISC_BEACON_USE |
+		    AR_D_MISC_POST_FR_BKOFF_DIS);
+		break;
+	case ATH9K_TX_QUEUE_CAB:
+		REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) |
+		    AR_Q_MISC_FSP_DBA_GATED |
+		    AR_Q_MISC_CBR_INCR_DIS1 |
+		    AR_Q_MISC_CBR_INCR_DIS0);
+		value = (qi->tqi_readyTime -
+		    (ah->ah_config.sw_beacon_response_time -
+		    ah->ah_config.dma_beacon_response_time) -
+		    ah->ah_config.additional_swba_backoff) * 1024;
+		REG_WRITE(ah, AR_QRDYTIMECFG(q),
+		    value | AR_Q_RDYTIMECFG_EN);
+		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
+		    (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+		    AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
+		break;
+	case ATH9K_TX_QUEUE_PSPOLL:
+		REG_WRITE(ah, AR_QMISC(q),
+		    REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
+		break;
+	case ATH9K_TX_QUEUE_UAPSD:
+		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
+		    AR_D_MISC_POST_FR_BKOFF_DIS);
+		break;
+	default:
+		break;
+	}
+
+	if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
+		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
+		    SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
+		    AR_D_MISC_ARB_LOCKOUT_CNTRL) |
+		    AR_D_MISC_POST_FR_BKOFF_DIS);
+	}
+
+	if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
+		ahp->ah_txOkInterruptMask |= 1 << q;
+	else
+		ahp->ah_txOkInterruptMask &= ~(1 << q);
+	if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
+		ahp->ah_txErrInterruptMask |= 1 << q;
+	else
+		ahp->ah_txErrInterruptMask &= ~(1 << q);
+	if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
+		ahp->ah_txDescInterruptMask |= 1 << q;
+	else
+		ahp->ah_txDescInterruptMask &= ~(1 << q);
+	if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
+		ahp->ah_txEolInterruptMask |= 1 << q;
+	else
+		ahp->ah_txEolInterruptMask &= ~(1 << q);
+	if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
+		ahp->ah_txUrnInterruptMask |= 1 << q;
+	else
+		ahp->ah_txUrnInterruptMask &= ~(1 << q);
+	ath9k_hw_set_txq_interrupts(ah, qi);
+
+	return (B_TRUE);
+}
+
+/* ARGSUSED */
+int
+ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t pa,
+    struct ath_desc *nds,
+    uint64_t tsf)
+{
+	struct ar5416_desc ads;
+	struct ar5416_desc *adsp = AR5416DESC(ds);
+	uint32_t phyerr;
+
+	if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
+		return (EINPROGRESS);
+
+	ads.u.rx = adsp->u.rx;
+
+	ds->ds_rxstat.rs_status = 0;
+	ds->ds_rxstat.rs_flags = 0;
+
+	ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
+	ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
+
+	ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
+	ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
+	ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
+	ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
+	ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
+	ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
+	ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
+	if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
+		ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
+	else
+		ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
+
+	ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
+	ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
+
+	ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
+	ds->ds_rxstat.rs_moreaggr =
+	    (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
+	ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
+	ds->ds_rxstat.rs_flags =
+	    (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
+	ds->ds_rxstat.rs_flags |=
+	    (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+	if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
+		ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
+	if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
+		ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
+	if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
+		ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
+
+	if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
+		if (ads.ds_rxstatus8 & AR_CRCErr)
+			ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
+		else if (ads.ds_rxstatus8 & AR_PHYErr) {
+			ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
+			phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
+			ds->ds_rxstat.rs_phyerr = (uint8_t)phyerr; /* LINT */
+		} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
+			ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
+		else if (ads.ds_rxstatus8 & AR_MichaelErr)
+			ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
+	}
+
+	return (0);
+}
+
+boolean_t
+ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
+    uint32_t size, uint32_t flags)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+	struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+
+	ads->ds_ctl1 = size & AR_BufLen;
+	if (flags & ATH9K_RXDESC_INTREQ)
+		ads->ds_ctl1 |= AR_RxIntrReq;
+
+	ads->ds_rxstatus8 &= ~AR_RxDone;
+	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+		(void) memset(&(ads->u), 0, sizeof (ads->u));
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_setrxabort(struct ath_hal *ah, boolean_t set)
+{
+	uint32_t reg;
+
+	if (set) {
+		REG_SET_BIT(ah, AR_DIAG_SW,
+		    (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+		if (!ath9k_hw_wait(ah, AR_OBS_BUS_1,
+		    AR_OBS_BUS_1_RX_STATE, 0)) {
+			REG_CLR_BIT(ah, AR_DIAG_SW,
+			    (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+			reg = REG_READ(ah, AR_OBS_BUS_1);
+
+			ARN_DBG((ARN_DBG_FATAL,
+			    "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
+			    __func__, reg));
+
+			return (B_FALSE);
+		}
+	} else {
+		REG_CLR_BIT(ah, AR_DIAG_SW,
+		    (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+	}
+
+	return (B_TRUE);
+}
+
+void
+ath9k_hw_putrxbuf(struct ath_hal *ah, uint32_t rxdp)
+{
+	REG_WRITE(ah, AR_RXDP, rxdp);
+}
+
+void
+ath9k_hw_rxena(struct ath_hal *ah)
+{
+	REG_WRITE(ah, AR_CR, AR_CR_RXE);
+}
+
+void
+ath9k_hw_startpcureceive(struct ath_hal *ah)
+{
+	ath9k_enable_mib_counters(ah);
+
+	ath9k_ani_reset(ah);
+
+	REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+}
+
+void
+ath9k_hw_stoppcurecv(struct ath_hal *ah)
+{
+	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
+
+	ath9k_hw_disable_mib_counters(ah);
+}
+
+boolean_t
+ath9k_hw_stopdmarecv(struct ath_hal *ah)
+{
+	REG_WRITE(ah, AR_CR, AR_CR_RXD);
+
+	if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
+		ARN_DBG((ARN_DBG_QUEUE, "arn: ath9k_hw_stopdmarecv(): "
+		    "dma failed to stop in 10ms\n"
+		    "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
+		    REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)));
+		return (B_FALSE);
+	} else {
+		return (B_TRUE);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_main.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,3190 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <sys/stream.h>
+#include <sys/termio.h>
+#include <sys/errno.h>
+#include <sys/file.h>
+#include <sys/cmn_err.h>
+#include <sys/stropts.h>
+#include <sys/strsubr.h>
+#include <sys/strtty.h>
+#include <sys/kbio.h>
+#include <sys/cred.h>
+#include <sys/stat.h>
+#include <sys/consdev.h>
+#include <sys/kmem.h>
+#include <sys/modctl.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/pci.h>
+#include <sys/errno.h>
+#include <sys/mac_provider.h>
+#include <sys/dlpi.h>
+#include <sys/ethernet.h>
+#include <sys/list.h>
+#include <sys/byteorder.h>
+#include <sys/strsun.h>
+#include <sys/policy.h>
+#include <inet/common.h>
+#include <inet/nd.h>
+#include <inet/mi.h>
+#include <inet/wifi_ioctl.h>
+#include <sys/mac_wifi.h>
+
+#include "arn_ath9k.h"
+#include "arn_core.h"
+#include "arn_reg.h"
+#include "arn_hw.h"
+
+#define	ARN_MAX_RSSI	63	/* max rssi */
+
+/*
+ * PIO access attributes for registers
+ */
+static ddi_device_acc_attr_t arn_reg_accattr = {
+	DDI_DEVICE_ATTR_V0,
+	DDI_STRUCTURE_LE_ACC,
+	DDI_STRICTORDER_ACC
+};
+
+/*
+ * DMA access attributes for descriptors: NOT to be byte swapped.
+ */
+static ddi_device_acc_attr_t arn_desc_accattr = {
+	DDI_DEVICE_ATTR_V0,
+	DDI_STRUCTURE_LE_ACC,
+	DDI_STRICTORDER_ACC
+};
+
+/*
+ * Describes the chip's DMA engine
+ */
+static ddi_dma_attr_t arn_dma_attr = {
+	DMA_ATTR_V0,	/* version number */
+	0,				/* low address */
+	0xffffffffU,	/* high address */
+	0x3ffffU,		/* counter register max */
+	1,				/* alignment */
+	0xFFF,			/* burst sizes */
+	1,				/* minimum transfer size */
+	0x3ffffU,		/* max transfer size */
+	0xffffffffU,	/* address register max */
+	1,				/* no scatter-gather */
+	1,				/* granularity of device */
+	0,				/* DMA flags */
+};
+
+static ddi_dma_attr_t arn_desc_dma_attr = {
+	DMA_ATTR_V0,	/* version number */
+	0,				/* low address */
+	0xffffffffU,	/* high address */
+	0xffffffffU,	/* counter register max */
+	0x1000,			/* alignment */
+	0xFFF,			/* burst sizes */
+	1,				/* minimum transfer size */
+	0xffffffffU,	/* max transfer size */
+	0xffffffffU,	/* address register max */
+	1,				/* no scatter-gather */
+	1,				/* granularity of device */
+	0,				/* DMA flags */
+};
+
+#define	ATH_DEF_CACHE_BYTES	32 /* default cache line size */
+
+static kmutex_t arn_loglock;
+static void *arn_soft_state_p = NULL;
+/* scan interval, ms? */
+static int arn_dwelltime = 200; /* 150 */
+
+static int	arn_m_stat(void *,  uint_t, uint64_t *);
+static int	arn_m_start(void *);
+static void	arn_m_stop(void *);
+static int	arn_m_promisc(void *, boolean_t);
+static int	arn_m_multicst(void *, boolean_t, const uint8_t *);
+static int	arn_m_unicst(void *, const uint8_t *);
+static mblk_t	*arn_m_tx(void *, mblk_t *);
+static void	arn_m_ioctl(void *, queue_t *, mblk_t *);
+static int	arn_m_setprop(void *, const char *, mac_prop_id_t,
+    uint_t, const void *);
+static int	arn_m_getprop(void *, const char *, mac_prop_id_t,
+    uint_t, uint_t, void *, uint_t *);
+
+/* MAC Callcack Functions */
+static mac_callbacks_t arn_m_callbacks = {
+	MC_IOCTL | MC_SETPROP | MC_GETPROP,
+	arn_m_stat,
+	arn_m_start,
+	arn_m_stop,
+	arn_m_promisc,
+	arn_m_multicst,
+	arn_m_unicst,
+	arn_m_tx,
+	arn_m_ioctl,
+	NULL,
+	NULL,
+	NULL,
+	arn_m_setprop,
+	arn_m_getprop
+};
+
+/*
+ * ARN_DBG_HW
+ * ARN_DBG_REG_IO
+ * ARN_DBG_QUEUE
+ * ARN_DBG_EEPROM
+ * ARN_DBG_XMIT
+ * ARN_DBG_RECV
+ * ARN_DBG_CALIBRATE
+ * ARN_DBG_CHANNEL
+ * ARN_DBG_INTERRUPT
+ * ARN_DBG_REGULATORY
+ * ARN_DBG_ANI
+ * ARN_DBG_POWER_MGMT
+ * ARN_DBG_KEYCACHE
+ * ARN_DBG_BEACON
+ * ARN_DBG_RATE
+ * ARN_DBG_INIT
+ * ARN_DBG_ATTACH
+ * ARN_DBG_DEATCH
+ * ARN_DBG_AGGR
+ * ARN_DBG_RESET
+ * ARN_DBG_FATAL
+ * ARN_DBG_ANY
+ * ARN_DBG_ALL
+ */
+uint32_t arn_dbg_mask = 0;
+
+/*
+ * Exception/warning cases not leading to panic.
+ */
+void
+arn_problem(const int8_t *fmt, ...)
+{
+	va_list args;
+
+	mutex_enter(&arn_loglock);
+
+	va_start(args, fmt);
+	vcmn_err(CE_WARN, fmt, args);
+	va_end(args);
+
+	mutex_exit(&arn_loglock);
+}
+
+/*
+ * Normal log information independent of debug.
+ */
+void
+arn_log(const int8_t *fmt, ...)
+{
+	va_list args;
+
+	mutex_enter(&arn_loglock);
+
+	va_start(args, fmt);
+	vcmn_err(CE_CONT, fmt, args);
+	va_end(args);
+
+	mutex_exit(&arn_loglock);
+}
+
+void
+arn_dbg(uint32_t dbg_flags, const int8_t *fmt, ...)
+{
+	va_list args;
+
+	if (dbg_flags & arn_dbg_mask) {
+		mutex_enter(&arn_loglock);
+		va_start(args, fmt);
+		vcmn_err(CE_CONT, fmt, args);
+		va_end(args);
+		mutex_exit(&arn_loglock);
+	}
+}
+
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
+void
+arn_iowrite32(struct ath_hal *ah, uint32_t reg_offset, uint32_t val)
+{
+	struct arn_softc *sc = ah->ah_sc;
+	if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) {
+		mutex_enter(&sc->sc_serial_rw);
+		ddi_put32(sc->sc_io_handle,
+		    (uint32_t *)((uintptr_t)(sc->mem) + (reg_offset)), val);
+		mutex_exit(&sc->sc_serial_rw);
+	} else {
+		ddi_put32(sc->sc_io_handle,
+		    (uint32_t *)((uintptr_t)(sc->mem) + (reg_offset)), val);
+	}
+}
+
+unsigned int
+arn_ioread32(struct ath_hal *ah, uint32_t reg_offset)
+{
+	uint32_t val;
+	struct arn_softc *sc = ah->ah_sc;
+	if (ah->ah_config.serialize_regmode == SER_REG_MODE_ON) {
+		mutex_enter(&sc->sc_serial_rw);
+		val = ddi_get32(sc->sc_io_handle,
+		    (uint32_t *)((uintptr_t)(sc->mem) + (reg_offset)));
+		mutex_exit(&sc->sc_serial_rw);
+	} else {
+		val = ddi_get32(sc->sc_io_handle,
+		    (uint32_t *)((uintptr_t)(sc->mem) + (reg_offset)));
+	}
+
+	return (val);
+}
+
+void
+arn_rx_buf_link(struct arn_softc *sc, struct ath_buf *bf)
+{
+	struct ath_desc *ds;
+
+	ds = bf->bf_desc;
+	ds->ds_link = bf->bf_daddr;
+	ds->ds_data = bf->bf_dma.cookie.dmac_address;
+	/* virtual addr of the beginning of the buffer. */
+	ds->ds_vdata = bf->bf_dma.mem_va;
+
+	/*
+	 * setup rx descriptors. The bf_dma.alength here tells the H/W
+	 * how much data it can DMA to us and that we are prepared
+	 * to process
+	 */
+	(void) ath9k_hw_setuprxdesc(sc->sc_ah, ds,
+	    bf->bf_dma.alength, /* buffer size */
+	    0);
+
+	if (sc->sc_rxlink != NULL)
+		*sc->sc_rxlink = bf->bf_daddr;
+	sc->sc_rxlink = &ds->ds_link;
+}
+
+/*
+ * Allocate an area of memory and a DMA handle for accessing it
+ */
+static int
+arn_alloc_dma_mem(dev_info_t *devinfo, ddi_dma_attr_t *dma_attr, size_t memsize,
+    ddi_device_acc_attr_t *attr_p, uint_t alloc_flags,
+    uint_t bind_flags, dma_area_t *dma_p)
+{
+	int err;
+
+	/*
+	 * Allocate handle
+	 */
+	err = ddi_dma_alloc_handle(devinfo, dma_attr,
+	    DDI_DMA_SLEEP, NULL, &dma_p->dma_hdl);
+	if (err != DDI_SUCCESS)
+		return (DDI_FAILURE);
+
+	/*
+	 * Allocate memory
+	 */
+	err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
+	    alloc_flags, DDI_DMA_SLEEP, NULL, &dma_p->mem_va,
+	    &dma_p->alength, &dma_p->acc_hdl);
+	if (err != DDI_SUCCESS)
+		return (DDI_FAILURE);
+
+	/*
+	 * Bind the two together
+	 */
+	err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
+	    dma_p->mem_va, dma_p->alength, bind_flags,
+	    DDI_DMA_SLEEP, NULL, &dma_p->cookie, &dma_p->ncookies);
+	if (err != DDI_DMA_MAPPED)
+		return (DDI_FAILURE);
+
+	dma_p->nslots = ~0U;
+	dma_p->size = ~0U;
+	dma_p->token = ~0U;
+	dma_p->offset = 0;
+	return (DDI_SUCCESS);
+}
+
+/*
+ * Free one allocated area of DMAable memory
+ */
+static void
+arn_free_dma_mem(dma_area_t *dma_p)
+{
+	if (dma_p->dma_hdl != NULL) {
+		(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
+		if (dma_p->acc_hdl != NULL) {
+			ddi_dma_mem_free(&dma_p->acc_hdl);
+			dma_p->acc_hdl = NULL;
+		}
+		ddi_dma_free_handle(&dma_p->dma_hdl);
+		dma_p->ncookies = 0;
+		dma_p->dma_hdl = NULL;
+	}
+}
+
+/*
+ * Initialize tx, rx. or beacon buffer list. Allocate DMA memory for
+ * each buffer.
+ */
+static int
+arn_buflist_setup(dev_info_t *devinfo, struct arn_softc *sc, list_t *bflist,
+    struct ath_buf **pbf, struct ath_desc **pds, int nbuf, uint_t dmabflags)
+{
+	int i, err;
+	struct ath_buf *bf = *pbf;
+	struct ath_desc *ds = *pds;
+
+	list_create(bflist, sizeof (struct ath_buf),
+	    offsetof(struct ath_buf, bf_node));
+	for (i = 0; i < nbuf; i++, bf++, ds++) {
+		bf->bf_desc = ds;
+		bf->bf_daddr = sc->sc_desc_dma.cookie.dmac_address +
+		    ((uintptr_t)ds - (uintptr_t)sc->sc_desc);
+		list_insert_tail(bflist, bf);
+
+		/* alloc DMA memory */
+		err = arn_alloc_dma_mem(devinfo, &arn_dma_attr,
+		    sc->sc_dmabuf_size, &arn_desc_accattr, DDI_DMA_STREAMING,
+		    dmabflags, &bf->bf_dma);
+		if (err != DDI_SUCCESS)
+			return (err);
+	}
+	*pbf = bf;
+	*pds = ds;
+
+	return (DDI_SUCCESS);
+}
+
+/*
+ * Destroy tx, rx or beacon buffer list. Free DMA memory.
+ */
+static void
+arn_buflist_cleanup(list_t *buflist)
+{
+	struct ath_buf *bf;
+
+	if (!buflist)
+		return;
+
+	bf = list_head(buflist);
+	while (bf != NULL) {
+		if (bf->bf_m != NULL) {
+			freemsg(bf->bf_m);
+			bf->bf_m = NULL;
+		}
+		/* Free DMA buffer */
+		arn_free_dma_mem(&bf->bf_dma);
+		if (bf->bf_in != NULL) {
+			ieee80211_free_node(bf->bf_in);
+			bf->bf_in = NULL;
+		}
+		list_remove(buflist, bf);
+		bf = list_head(buflist);
+	}
+	list_destroy(buflist);
+}
+
+static void
+arn_desc_free(struct arn_softc *sc)
+{
+	arn_buflist_cleanup(&sc->sc_txbuf_list);
+	arn_buflist_cleanup(&sc->sc_rxbuf_list);
+#ifdef ARN_IBSS
+	arn_buflist_cleanup(&sc->sc_bcbuf_list);
+#endif
+
+	/* Free descriptor DMA buffer */
+	arn_free_dma_mem(&sc->sc_desc_dma);
+
+	kmem_free((void *)sc->sc_vbufptr, sc->sc_vbuflen);
+	sc->sc_vbufptr = NULL;
+}
+
+static int
+arn_desc_alloc(dev_info_t *devinfo, struct arn_softc *sc)
+{
+	int err;
+	size_t size;
+	struct ath_desc *ds;
+	struct ath_buf *bf;
+
+#ifdef ARN_IBSS
+	size = sizeof (struct ath_desc) * (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF);
+#else
+	size = sizeof (struct ath_desc) * (ATH_TXBUF + ATH_RXBUF);
+#endif
+
+	err = arn_alloc_dma_mem(devinfo, &arn_desc_dma_attr, size,
+	    &arn_desc_accattr, DDI_DMA_CONSISTENT,
+	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT, &sc->sc_desc_dma);
+
+	/* virtual address of the first descriptor */
+	sc->sc_desc = (struct ath_desc *)sc->sc_desc_dma.mem_va;
+
+	ds = sc->sc_desc;
+	ARN_DBG((ARN_DBG_INIT, "arn: arn_desc_alloc(): DMA map: "
+	    "%p (%d) -> %p\n",
+	    sc->sc_desc, sc->sc_desc_dma.alength,
+	    sc->sc_desc_dma.cookie.dmac_address));
+
+	/* allocate data structures to describe TX/RX DMA buffers */
+#ifdef ARN_IBSS
+	sc->sc_vbuflen = sizeof (struct ath_buf) * (ATH_TXBUF + ATH_RXBUF +
+	    ATH_BCBUF);
+#else
+	sc->sc_vbuflen = sizeof (struct ath_buf) * (ATH_TXBUF + ATH_RXBUF);
+#endif
+	bf = (struct ath_buf *)kmem_zalloc(sc->sc_vbuflen, KM_SLEEP);
+	sc->sc_vbufptr = bf;
+
+	/* DMA buffer size for each TX/RX packet */
+	sc->sc_dmabuf_size = roundup(1000 + sizeof (struct ieee80211_frame) +
+	    IEEE80211_MTU + IEEE80211_CRC_LEN +
+	    (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN +
+	    IEEE80211_WEP_CRCLEN), sc->sc_cachelsz);
+
+	/* create RX buffer list */
+	err = arn_buflist_setup(devinfo, sc, &sc->sc_rxbuf_list, &bf, &ds,
+	    ATH_RXBUF, DDI_DMA_READ | DDI_DMA_STREAMING);
+	if (err != DDI_SUCCESS) {
+		arn_desc_free(sc);
+		return (err);
+	}
+
+	/* create TX buffer list */
+	err = arn_buflist_setup(devinfo, sc, &sc->sc_txbuf_list, &bf, &ds,
+	    ATH_TXBUF, DDI_DMA_STREAMING);
+	if (err != DDI_SUCCESS) {
+		arn_desc_free(sc);
+		return (err);
+	}
+
+	/* create beacon buffer list */
+#ifdef ARN_IBSS
+	err = arn_buflist_setup(devinfo, sc, &sc->sc_bcbuf_list, &bf, &ds,
+	    ATH_BCBUF, DDI_DMA_STREAMING);
+	if (err != DDI_SUCCESS) {
+		arn_desc_free(sc);
+		return (err);
+	}
+#endif
+
+	return (DDI_SUCCESS);
+}
+
+static struct ath_rate_table *
+/* LINTED E_STATIC_UNUSED */
+arn_get_ratetable(struct arn_softc *sc, uint32_t mode)
+{
+	struct ath_rate_table *rate_table = NULL;
+
+	switch (mode) {
+	case IEEE80211_MODE_11A:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
+		break;
+	case IEEE80211_MODE_11B:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11B];
+		break;
+	case IEEE80211_MODE_11G:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
+		break;
+#ifdef ARB_11N
+	case IEEE80211_MODE_11NA_HT20:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
+		break;
+	case IEEE80211_MODE_11NG_HT20:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
+		break;
+	case IEEE80211_MODE_11NA_HT40PLUS:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+		break;
+	case IEEE80211_MODE_11NA_HT40MINUS:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+		break;
+	case IEEE80211_MODE_11NG_HT40PLUS:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+		break;
+	case IEEE80211_MODE_11NG_HT40MINUS:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+		break;
+#endif
+	default:
+		ARN_DBG((ARN_DBG_FATAL, "arn: arn_get_ratetable(): "
+		    "invalid mode %u\n", mode));
+		return (NULL);
+	}
+
+	return (rate_table);
+
+}
+
+static void
+arn_setcurmode(struct arn_softc *sc, enum wireless_mode mode)
+{
+	struct ath_rate_table *rt;
+	int i;
+
+	for (i = 0; i < sizeof (sc->asc_rixmap); i++)
+		sc->asc_rixmap[i] = 0xff;
+
+	rt = sc->hw_rate_table[mode];
+	ASSERT(rt != NULL);
+
+	for (i = 0; i < rt->rate_cnt; i++)
+		sc->asc_rixmap[rt->info[i].dot11rate &
+		    IEEE80211_RATE_VAL] = (uint8_t)i; /* LINT */
+
+	sc->sc_currates = rt;
+	sc->sc_curmode = mode;
+
+	/*
+	 * All protection frames are transmited at 2Mb/s for
+	 * 11g, otherwise at 1Mb/s.
+	 * XXX select protection rate index from rate table.
+	 */
+	sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0);
+}
+
+static enum wireless_mode
+arn_chan2mode(struct ath9k_channel *chan)
+{
+	if (chan->chanmode == CHANNEL_A)
+		return (ATH9K_MODE_11A);
+	else if (chan->chanmode == CHANNEL_G)
+		return (ATH9K_MODE_11G);
+	else if (chan->chanmode == CHANNEL_B)
+		return (ATH9K_MODE_11B);
+	else if (chan->chanmode == CHANNEL_A_HT20)
+		return (ATH9K_MODE_11NA_HT20);
+	else if (chan->chanmode == CHANNEL_G_HT20)
+		return (ATH9K_MODE_11NG_HT20);
+	else if (chan->chanmode == CHANNEL_A_HT40PLUS)
+		return (ATH9K_MODE_11NA_HT40PLUS);
+	else if (chan->chanmode == CHANNEL_A_HT40MINUS)
+		return (ATH9K_MODE_11NA_HT40MINUS);
+	else if (chan->chanmode == CHANNEL_G_HT40PLUS)
+		return (ATH9K_MODE_11NG_HT40PLUS);
+	else if (chan->chanmode == CHANNEL_G_HT40MINUS)
+		return (ATH9K_MODE_11NG_HT40MINUS);
+
+	return (ATH9K_MODE_11B);
+}
+
+static void
+arn_update_txpow(struct arn_softc *sc)
+{
+	struct ath_hal 	*ah = sc->sc_ah;
+	uint32_t txpow;
+
+	if (sc->sc_curtxpow != sc->sc_config.txpowlimit) {
+		(void) ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit);
+		/* read back in case value is clamped */
+		(void) ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
+		sc->sc_curtxpow = (uint32_t)txpow;
+	}
+}
+
+static void
+arn_setup_rates(struct arn_softc *sc, uint32_t mode)
+{
+	int i, maxrates;
+	struct ath_rate_table *rate_table = NULL;
+	struct ieee80211_rateset *rateset;
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+
+	/* rate_table = arn_get_ratetable(sc, mode); */
+	switch (mode) {
+	case IEEE80211_MODE_11A:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
+		break;
+	case IEEE80211_MODE_11B:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11B];
+		break;
+	case IEEE80211_MODE_11G:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
+		break;
+#ifdef ARN_11N
+	case IEEE80211_MODE_11NA_HT20:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
+		break;
+	case IEEE80211_MODE_11NG_HT20:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
+		break;
+	case IEEE80211_MODE_11NA_HT40PLUS:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+		break;
+	case IEEE80211_MODE_11NA_HT40MINUS:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+		break;
+	case IEEE80211_MODE_11NG_HT40PLUS:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+		break;
+	case IEEE80211_MODE_11NG_HT40MINUS:
+		rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+		break;
+#endif
+	default:
+		ARN_DBG((ARN_DBG_RATE, "arn: arn_get_ratetable(): "
+		    "invalid mode %u\n", mode));
+		break;
+	}
+	if (rate_table == NULL)
+		return;
+	if (rate_table->rate_cnt > ATH_RATE_MAX) {
+		ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_setup(): "
+		    "rate table too small (%u > %u)\n",
+		    rate_table->rate_cnt, IEEE80211_RATE_MAXSIZE));
+		maxrates = ATH_RATE_MAX;
+	} else
+		maxrates = rate_table->rate_cnt;
+
+	ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_setup(): "
+	    "maxrates is %d\n", maxrates));
+
+	rateset = &ic->ic_sup_rates[mode];
+	for (i = 0; i < maxrates; i++) {
+		rateset->ir_rates[i] = rate_table->info[i].dot11rate;
+		ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_setup(): "
+		    "%d\n", rate_table->info[i].dot11rate));
+	}
+	rateset->ir_nrates = (uint8_t)maxrates; /* ??? */
+}
+
+static int
+arn_setup_channels(struct arn_softc *sc)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	int nchan, i, index;
+	uint8_t regclassids[ATH_REGCLASSIDS_MAX];
+	uint32_t nregclass = 0;
+	struct ath9k_channel *c;
+
+	/* Fill in ah->ah_channels */
+	if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (uint32_t *)&nchan,
+	    regclassids, ATH_REGCLASSIDS_MAX, &nregclass, CTRY_DEFAULT,
+	    B_FALSE, 1)) {
+		uint32_t rd = ah->ah_currentRD;
+		ARN_DBG((ARN_DBG_CHANNEL, "arn: arn_setup_channels(): "
+		    "unable to collect channel list; "
+		    "regdomain likely %u country code %u\n",
+		    rd, CTRY_DEFAULT));
+		return (EINVAL);
+	}
+
+	ARN_DBG((ARN_DBG_CHANNEL, "arn: arn_setup_channels(): "
+	    "number of channel is %d\n", nchan));
+
+	for (i = 0; i < nchan; i++) {
+		c = &ah->ah_channels[i];
+		uint16_t flags;
+		index = ath9k_hw_mhz2ieee(ah, c->channel, c->channelFlags);
+
+		if (index > IEEE80211_CHAN_MAX) {
+			ARN_DBG((ARN_DBG_CHANNEL,
+			    "arn: arn_setup_channels(): "
+			    "bad hal channel %d (%u/%x) ignored\n",
+			    index, c->channel, c->channelFlags));
+			continue;
+		}
+		/* NB: flags are known to be compatible */
+		if (index < 0) {
+			/*
+			 * can't handle frequency <2400MHz (negative
+			 * channels) right now
+			 */
+			ARN_DBG((ARN_DBG_CHANNEL,
+			    "arn: arn_setup_channels(): "
+			    "hal channel %d (%u/%x) "
+			    "cannot be handled, ignored\n",
+			    index, c->channel, c->channelFlags));
+			continue;
+		}
+
+		/*
+		 * Calculate net80211 flags; most are compatible
+		 * but some need massaging.  Note the static turbo
+		 * conversion can be removed once net80211 is updated
+		 * to understand static vs. dynamic turbo.
+		 */
+
+		flags = c->channelFlags & (CHANNEL_ALL | CHANNEL_PASSIVE);
+
+		if (ic->ic_sup_channels[index].ich_freq == 0) {
+			ic->ic_sup_channels[index].ich_freq = c->channel;
+			ic->ic_sup_channels[index].ich_flags = flags;
+		} else {
+			/* channels overlap; e.g. 11g and 11b */
+			ic->ic_sup_channels[index].ich_flags |= flags;
+		}
+		if ((c->channelFlags & CHANNEL_G) == CHANNEL_G) {
+			sc->sc_have11g = 1;
+			ic->ic_caps |= IEEE80211_C_SHPREAMBLE |
+			    IEEE80211_C_SHSLOT;	/* short slot time */
+		}
+	}
+
+	return (0);
+}
+
+uint32_t
+arn_chan2flags(ieee80211com_t *isc, struct ieee80211_channel *chan)
+{
+	static const uint32_t modeflags[] = {
+	    0,				/* IEEE80211_MODE_AUTO */
+	    CHANNEL_A,			/* IEEE80211_MODE_11A */
+	    CHANNEL_B,			/* IEEE80211_MODE_11B */
+	    CHANNEL_G,		/* IEEE80211_MODE_11G */
+	    0,				/*  */
+	    0,		/*  */
+	    0		/*  */
+	};
+	return (modeflags[ieee80211_chan2mode(isc, chan)]);
+}
+
+/*
+ * Update internal state after a channel change.
+ */
+void
+arn_chan_change(struct arn_softc *sc, struct ieee80211_channel *chan)
+{
+	struct ieee80211com *ic = &sc->sc_isc;
+	enum ieee80211_phymode mode;
+	enum wireless_mode wlmode;
+
+	/*
+	 * Change channels and update the h/w rate map
+	 * if we're switching; e.g. 11a to 11b/g.
+	 */
+	mode = ieee80211_chan2mode(ic, chan);
+	switch (mode) {
+	case IEEE80211_MODE_11A:
+		wlmode = ATH9K_MODE_11A;
+		break;
+	case IEEE80211_MODE_11B:
+		wlmode = ATH9K_MODE_11B;
+		break;
+	case IEEE80211_MODE_11G:
+		wlmode = ATH9K_MODE_11B;
+		break;
+	default:
+		break;
+	}
+	if (wlmode != sc->sc_curmode)
+		arn_setcurmode(sc, wlmode);
+
+}
+
+/*
+ * Set/change channels.  If the channel is really being changed, it's done
+ * by reseting the chip.  To accomplish this we must first cleanup any pending
+ * DMA, then restart stuff.
+ */
+static int
+arn_set_channel(struct arn_softc *sc, struct ath9k_channel *hchan)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	ieee80211com_t *ic = &sc->sc_isc;
+	boolean_t fastcc = B_TRUE;
+	boolean_t  stopped;
+	struct ieee80211_channel chan;
+	enum wireless_mode curmode;
+
+	if (sc->sc_flags & SC_OP_INVALID)
+		return (EIO);
+
+	if (hchan->channel != sc->sc_ah->ah_curchan->channel ||
+	    hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags ||
+	    (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
+	    (sc->sc_flags & SC_OP_FULL_RESET)) {
+		int status;
+
+		/*
+		 * This is only performed if the channel settings have
+		 * actually changed.
+		 *
+		 * To switch channels clear any pending DMA operations;
+		 * wait long enough for the RX fifo to drain, reset the
+		 * hardware at the new frequency, and then re-enable
+		 * the relevant bits of the h/w.
+		 */
+		(void) ath9k_hw_set_interrupts(ah, 0);	/* disable interrupts */
+		arn_draintxq(sc, B_FALSE);	/* clear pending tx frames */
+		stopped = arn_stoprecv(sc);	/* turn off frame recv */
+
+		/*
+		 * XXX: do not flush receive queue here. We don't want
+		 * to flush data frames already in queue because of
+		 * changing channel.
+		 */
+
+		if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
+			fastcc = B_FALSE;
+
+		ARN_DBG((ARN_DBG_CHANNEL, "arn: arn_set_channel(): "
+		    "(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n",
+		    sc->sc_ah->ah_curchan->channel,
+		    hchan->channel, hchan->channelFlags, sc->tx_chan_width));
+
+		if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width,
+		    sc->sc_tx_chainmask, sc->sc_rx_chainmask,
+		    sc->sc_ht_extprotspacing, fastcc, &status)) {
+			ARN_DBG((ARN_DBG_FATAL, "arn: arn_set_channel(): "
+			    "unable to reset channel %u (%uMhz) "
+			    "flags 0x%x hal status %u\n",
+			    ath9k_hw_mhz2ieee(ah, hchan->channel,
+			    hchan->channelFlags),
+			    hchan->channel, hchan->channelFlags, status));
+			return (EIO);
+		}
+
+		sc->sc_curchan = *hchan;
+
+		sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
+		sc->sc_flags &= ~SC_OP_FULL_RESET;
+
+		if (arn_startrecv(sc) != 0) {
+			arn_problem("arn: arn_set_channel(): "
+			    "unable to restart recv logic\n");
+			return (EIO);
+		}
+
+		chan.ich_freq = hchan->channel;
+		chan.ich_flags = hchan->channelFlags;
+		ic->ic_ibss_chan = &chan;
+
+		/*
+		 * Change channels and update the h/w rate map
+		 * if we're switching; e.g. 11a to 11b/g.
+		 */
+		curmode = arn_chan2mode(hchan);
+		if (curmode != sc->sc_curmode)
+			arn_setcurmode(sc, arn_chan2mode(hchan));
+
+		arn_update_txpow(sc);
+
+		(void) ath9k_hw_set_interrupts(ah, sc->sc_imask);
+	}
+
+	return (0);
+}
+
+/*
+ *  This routine performs the periodic noise floor calibration function
+ *  that is used to adjust and optimize the chip performance.  This
+ *  takes environmental changes (location, temperature) into account.
+ *  When the task is complete, it reschedules itself depending on the
+ *  appropriate interval that was calculated.
+ */
+static void
+arn_ani_calibrate(void *arg)
+
+{
+	ieee80211com_t *ic = (ieee80211com_t *)arg;
+	struct arn_softc *sc = (struct arn_softc *)ic;
+	struct ath_hal *ah = sc->sc_ah;
+	boolean_t longcal = B_FALSE;
+	boolean_t shortcal = B_FALSE;
+	boolean_t aniflag = B_FALSE;
+	unsigned int timestamp = drv_hztousec(ddi_get_lbolt())/1000;
+	uint32_t cal_interval;
+
+	/*
+	 * don't calibrate when we're scanning.
+	 * we are most likely not on our home channel.
+	 */
+	if (ic->ic_state != IEEE80211_S_RUN)
+		goto settimer;
+
+	/* Long calibration runs independently of short calibration. */
+	if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) {
+		longcal = B_TRUE;
+		ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
+		    "%s: longcal @%lu\n", __func__, drv_hztousec));
+		sc->sc_ani.sc_longcal_timer = timestamp;
+	}
+
+	/* Short calibration applies only while sc_caldone is FALSE */
+	if (!sc->sc_ani.sc_caldone) {
+		if ((timestamp - sc->sc_ani.sc_shortcal_timer) >=
+		    ATH_SHORT_CALINTERVAL) {
+			shortcal = B_TRUE;
+			ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
+			    "%s: shortcal @%lu\n",
+			    __func__, drv_hztousec));
+			sc->sc_ani.sc_shortcal_timer = timestamp;
+			sc->sc_ani.sc_resetcal_timer = timestamp;
+		}
+	} else {
+		if ((timestamp - sc->sc_ani.sc_resetcal_timer) >=
+		    ATH_RESTART_CALINTERVAL) {
+			ath9k_hw_reset_calvalid(ah, ah->ah_curchan,
+						&sc->sc_ani.sc_caldone);
+			if (sc->sc_ani.sc_caldone)
+				sc->sc_ani.sc_resetcal_timer = timestamp;
+		}
+	}
+
+	/* Verify whether we must check ANI */
+	if ((timestamp - sc->sc_ani.sc_checkani_timer) >=
+	    ATH_ANI_POLLINTERVAL) {
+		aniflag = B_TRUE;
+		sc->sc_ani.sc_checkani_timer = timestamp;
+	}
+
+	/* Skip all processing if there's nothing to do. */
+	if (longcal || shortcal || aniflag) {
+		/* Call ANI routine if necessary */
+		if (aniflag)
+			ath9k_hw_ani_monitor(ah, &sc->sc_halstats,
+			    ah->ah_curchan);
+
+		/* Perform calibration if necessary */
+		if (longcal || shortcal) {
+			boolean_t iscaldone = B_FALSE;
+
+			if (ath9k_hw_calibrate(ah, ah->ah_curchan,
+			    sc->sc_rx_chainmask, longcal, &iscaldone)) {
+				if (longcal)
+					sc->sc_ani.sc_noise_floor =
+					    ath9k_hw_getchan_noise(ah,
+					    ah->ah_curchan);
+
+				ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
+				    "%s: calibrate chan %u/%x nf: %d\n",
+				    __func__,
+				    ah->ah_curchan->channel,
+				    ah->ah_curchan->channelFlags,
+				    sc->sc_ani.sc_noise_floor));
+			} else {
+				ARN_DBG((ARN_DBG_CALIBRATE, "arn: "
+				    "%s: calibrate chan %u/%x failed\n",
+				    __func__,
+				    ah->ah_curchan->channel,
+				    ah->ah_curchan->channelFlags));
+			}
+			sc->sc_ani.sc_caldone = iscaldone;
+		}
+	}
+
+settimer:
+	/*
+	 * Set timer interval based on previous results.
+	 * The interval must be the shortest necessary to satisfy ANI,
+	 * short calibration and long calibration.
+	 */
+	cal_interval = ATH_LONG_CALINTERVAL;
+	if (sc->sc_ah->ah_config.enable_ani)
+		cal_interval =
+		    min(cal_interval, (uint32_t)ATH_ANI_POLLINTERVAL);
+
+	if (!sc->sc_ani.sc_caldone)
+		cal_interval = min(cal_interval,
+		    (uint32_t)ATH_SHORT_CALINTERVAL);
+
+	sc->sc_scan_timer = 0;
+	sc->sc_scan_timer = timeout(arn_ani_calibrate, (void *)sc,
+	    drv_usectohz(cal_interval * 1000));
+}
+
+static void
+arn_stop_caltimer(struct arn_softc *sc)
+{
+	timeout_id_t tmp_id = 0;
+
+	while ((sc->sc_cal_timer != 0) && (tmp_id != sc->sc_cal_timer)) {
+		tmp_id = sc->sc_cal_timer;
+		(void) untimeout(tmp_id);
+	}
+	sc->sc_cal_timer = 0;
+}
+
+static uint_t
+arn_isr(caddr_t arg)
+{
+	/* LINTED E_BAD_PTR_CAST_ALIGN */
+	struct arn_softc *sc = (struct arn_softc *)arg;
+	struct ath_hal *ah = sc->sc_ah;
+	enum ath9k_int status;
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+
+	ARN_LOCK(sc);
+
+	if (sc->sc_flags & SC_OP_INVALID) {
+		/*
+		 * The hardware is not ready/present, don't
+		 * touch anything. Note this can happen early
+		 * on if the IRQ is shared.
+		 */
+		ARN_UNLOCK(sc);
+		return (DDI_INTR_UNCLAIMED);
+	}
+	if (!ath9k_hw_intrpend(ah)) {	/* shared irq, not for us */
+		ARN_UNLOCK(sc);
+		return (DDI_INTR_UNCLAIMED);
+	}
+
+	/*
+	 * Figure out the reason(s) for the interrupt. Note
+	 * that the hal returns a pseudo-ISR that may include
+	 * bits we haven't explicitly enabled so we mask the
+	 * value to insure we only process bits we requested.
+	 */
+	(void) ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
+
+	status &= sc->sc_imask; /* discard unasked-for bits */
+
+	/*
+	 * If there are no status bits set, then this interrupt was not
+	 * for me (should have been caught above).
+	 */
+	if (!status) {
+		ARN_UNLOCK(sc);
+		return (DDI_INTR_UNCLAIMED);
+	}
+
+	sc->sc_intrstatus = status;
+
+	if (status & ATH9K_INT_FATAL) {
+		/* need a chip reset */
+		ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+		    "ATH9K_INT_FATAL\n"));
+		goto reset;
+	} else if (status & ATH9K_INT_RXORN) {
+		/* need a chip reset */
+		ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+		    "ATH9K_INT_RXORN\n"));
+		goto reset;
+	} else {
+		if (status & ATH9K_INT_RXEOL) {
+			/*
+			 * NB: the hardware should re-read the link when
+			 * RXE bit is written, but it doesn't work
+			 * at least on older hardware revs.
+			 */
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_RXEOL\n"));
+			sc->sc_rxlink = NULL;
+		}
+		if (status & ATH9K_INT_TXURN) {
+			/* bump tx trigger level */
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_TXURN\n"));
+			(void) ath9k_hw_updatetxtriglevel(ah, B_TRUE);
+		}
+		/* XXX: optimize this */
+		if (status & ATH9K_INT_RX) {
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_RX\n"));
+			sc->sc_rx_pend = 1;
+			ddi_trigger_softintr(sc->sc_softint_id);
+		}
+		if (status & ATH9K_INT_TX) {
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_TX\n"));
+			if (ddi_taskq_dispatch(sc->sc_tq,
+			    arn_tx_int_proc, sc, DDI_NOSLEEP) !=
+			    DDI_SUCCESS) {
+				arn_problem("arn: arn_isr(): "
+				    "No memory for tx taskq\n");
+				}
+			}
+#ifdef ARN_ATH9K_INT_MIB
+		if (status & ATH9K_INT_MIB) {
+			/*
+			 * Disable interrupts until we service the MIB
+			 * interrupt; otherwise it will continue to
+			 * fire.
+			 */
+			(void) ath9k_hw_set_interrupts(ah, 0);
+			/*
+			 * Let the hal handle the event. We assume
+			 * it will clear whatever condition caused
+			 * the interrupt.
+			 */
+			ath9k_hw_procmibevent(ah, &sc->sc_halstats);
+			(void) ath9k_hw_set_interrupts(ah, sc->sc_imask);
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_MIB\n"));
+		}
+#endif
+
+#ifdef ARN_ATH9K_INT_TIM_TIMER
+		if (status & ATH9K_INT_TIM_TIMER) {
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_TIM_TIMER\n"));
+			if (!(ah->ah_caps.hw_caps &
+			    ATH9K_HW_CAP_AUTOSLEEP)) {
+				/*
+				 * Clear RxAbort bit so that we can
+				 * receive frames
+				 */
+				ath9k_hw_setrxabort(ah, 0);
+				goto reset;
+			}
+		}
+#endif
+
+		if (status & ATH9K_INT_BMISS) {
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_BMISS\n"));
+
+			if (ddi_taskq_dispatch(sc->sc_tq, arn_bmiss_proc,
+			    sc, DDI_NOSLEEP) != DDI_SUCCESS) {
+				arn_problem("arn: arn_isr(): "
+				    "No memory available for bmiss taskq\n");
+			}
+		}
+
+		ARN_UNLOCK(sc);
+
+#ifdef ARN_ATH9K_INT_CST
+		/* carrier sense timeout */
+		if (status & ATH9K_INT_CST) {
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_CST\n"));
+			return (DDI_INTR_CLAIMED);
+		}
+#endif
+
+		if (status & ATH9K_INT_SWBA) {
+			ARN_DBG((ARN_DBG_INTERRUPT, "arn: arn_isr(): "
+			    "ATH9K_INT_SWBA\n"));
+			/* This will occur only in Host-AP or Ad-Hoc mode */
+			return (DDI_INTR_CLAIMED);
+		}
+	}
+
+	return (DDI_INTR_CLAIMED);
+reset:
+	ARN_DBG((ARN_DBG_INTERRUPT, "Rset for fatal err\n"));
+	(void) arn_reset(ic);
+	ARN_UNLOCK(sc);
+	return (DDI_INTR_CLAIMED);
+}
+
+static int
+arn_get_channel(struct arn_softc *sc, struct ieee80211_channel *chan)
+{
+	int i;
+
+	for (i = 0; i < sc->sc_ah->ah_nchan; i++) {
+		if (sc->sc_ah->ah_channels[i].channel == chan->ich_freq)
+			return (i);
+	}
+
+	return (-1);
+}
+
+int
+arn_reset(ieee80211com_t *ic)
+{
+	struct arn_softc *sc = (struct arn_softc *)ic;
+	struct ath_hal *ah = sc->sc_ah;
+	int status;
+	int error = 0;
+
+	(void) ath9k_hw_set_interrupts(ah, 0);
+	arn_draintxq(sc, 0);
+	(void) arn_stoprecv(sc);
+
+	if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, sc->tx_chan_width,
+	    sc->sc_tx_chainmask, sc->sc_rx_chainmask,
+	    sc->sc_ht_extprotspacing, B_FALSE, &status)) {
+		ARN_DBG((ARN_DBG_RESET, "arn: arn_reset(): "
+		    "unable to reset hardware; hal status %u\n", status));
+		error = EIO;
+	}
+
+	if (arn_startrecv(sc) != 0)
+		ARN_DBG((ARN_DBG_RESET, "arn: arn_reset(): "
+		    "unable to start recv logic\n"));
+
+	/*
+	 * We may be doing a reset in response to a request
+	 * that changes the channel so update any state that
+	 * might change as a result.
+	 */
+	arn_setcurmode(sc, arn_chan2mode(sc->sc_ah->ah_curchan));
+
+	arn_update_txpow(sc);
+
+	if (sc->sc_flags & SC_OP_BEACONS)
+		arn_beacon_config(sc);	/* restart beacons */
+
+	(void) ath9k_hw_set_interrupts(ah, sc->sc_imask);
+
+	return (error);
+}
+
+int
+arn_get_hal_qnum(uint16_t queue, struct arn_softc *sc)
+{
+	int qnum;
+
+	switch (queue) {
+	case WME_AC_VO:
+		qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO];
+		break;
+	case WME_AC_VI:
+		qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI];
+		break;
+	case WME_AC_BE:
+		qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
+		break;
+	case WME_AC_BK:
+		qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK];
+		break;
+	default:
+		qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
+		break;
+	}
+
+	return (qnum);
+}
+
+static struct {
+	uint32_t version;
+	const char *name;
+} ath_mac_bb_names[] = {
+	{ AR_SREV_VERSION_5416_PCI,	"5416" },
+	{ AR_SREV_VERSION_5416_PCIE,	"5418" },
+	{ AR_SREV_VERSION_9100,		"9100" },
+	{ AR_SREV_VERSION_9160,		"9160" },
+	{ AR_SREV_VERSION_9280,		"9280" },
+	{ AR_SREV_VERSION_9285,		"9285" }
+};
+
+static struct {
+	uint16_t version;
+	const char *name;
+} ath_rf_names[] = {
+	{ 0,				"5133" },
+	{ AR_RAD5133_SREV_MAJOR,	"5133" },
+	{ AR_RAD5122_SREV_MAJOR,	"5122" },
+	{ AR_RAD2133_SREV_MAJOR,	"2133" },
+	{ AR_RAD2122_SREV_MAJOR,	"2122" }
+};
+
+/*
+ * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
+ */
+
+static const char *
+arn_mac_bb_name(uint32_t mac_bb_version)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ath_mac_bb_names); i++) {
+		if (ath_mac_bb_names[i].version == mac_bb_version) {
+			return (ath_mac_bb_names[i].name);
+		}
+	}
+
+	return ("????");
+}
+
+/*
+ * Return the RF name. "????" is returned if the RF is unknown.
+ */
+
+static const char *
+arn_rf_name(uint16_t rf_version)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ath_rf_names); i++) {
+		if (ath_rf_names[i].version == rf_version) {
+			return (ath_rf_names[i].name);
+		}
+	}
+
+	return ("????");
+}
+
+static void
+arn_next_scan(void *arg)
+{
+	ieee80211com_t *ic = arg;
+	struct arn_softc *sc = (struct arn_softc *)ic;
+
+	sc->sc_scan_timer = 0;
+	if (ic->ic_state == IEEE80211_S_SCAN) {
+		sc->sc_scan_timer = timeout(arn_next_scan, (void *)sc,
+		    drv_usectohz(arn_dwelltime * 1000));
+		ieee80211_next_scan(ic);
+	}
+}
+
+static void
+arn_stop_scantimer(struct arn_softc *sc)
+{
+	timeout_id_t tmp_id = 0;
+
+	while ((sc->sc_scan_timer != 0) && (tmp_id != sc->sc_scan_timer)) {
+		tmp_id = sc->sc_scan_timer;
+		(void) untimeout(tmp_id);
+	}
+	sc->sc_scan_timer = 0;
+}
+
+static int32_t
+arn_newstate(ieee80211com_t *ic, enum ieee80211_state nstate, int arg)
+{
+	struct arn_softc *sc = (struct arn_softc *)ic;
+	struct ath_hal *ah = sc->sc_ah;
+	struct ieee80211_node *in;
+	int32_t i, error;
+	uint8_t *bssid;
+	uint32_t rfilt;
+	enum ieee80211_state ostate;
+	struct ath9k_channel *channel;
+	int pos;
+
+	/* Should set up & init LED here */
+
+	if (sc->sc_flags & SC_OP_INVALID)
+		return (0);
+
+	ostate = ic->ic_state;
+	ARN_DBG((ARN_DBG_INIT, "arn: arn_newstate(): "
+	    "%x -> %x!\n", ostate, nstate));
+
+	ARN_LOCK(sc);
+
+	if (nstate != IEEE80211_S_SCAN)
+		arn_stop_scantimer(sc);
+	if (nstate != IEEE80211_S_RUN)
+		arn_stop_caltimer(sc);
+
+	/* Should set LED here */
+
+	if (nstate == IEEE80211_S_INIT) {
+		sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+		/*
+		 * Disable interrupts.
+		 */
+		(void) ath9k_hw_set_interrupts
+		    (ah, sc->sc_imask &~ ATH9K_INT_GLOBAL);
+
+#ifdef ARN_IBSS
+		if (ic->ic_opmode == IEEE80211_M_IBSS) {
+			(void) ath9k_hw_stoptxdma(ah, sc->sc_beaconq);
+			arn_beacon_return(sc);
+		}
+#endif
+		ARN_UNLOCK(sc);
+		ieee80211_stop_watchdog(ic);
+		goto done;
+	}
+	in = ic->ic_bss;
+
+	pos = arn_get_channel(sc, ic->ic_curchan);
+
+	if (pos == -1) {
+		ARN_DBG((ARN_DBG_FATAL, "arn: "
+		    "%s: Invalid channel\n", __func__));
+		error = EINVAL;
+		ARN_UNLOCK(sc);
+		goto bad;
+	}
+	sc->tx_chan_width = ATH9K_HT_MACMODE_20;
+	sc->sc_ah->ah_channels[pos].chanmode =
+	    arn_chan2flags(ic, ic->ic_curchan);
+	channel = &sc->sc_ah->ah_channels[pos];
+	if (channel == NULL) {
+		arn_problem("arn_newstate(): channel == NULL");
+		ARN_UNLOCK(sc);
+		goto bad;
+	}
+	error = arn_set_channel(sc, channel);
+	if (error != 0) {
+		if (nstate != IEEE80211_S_SCAN) {
+			ARN_UNLOCK(sc);
+			ieee80211_reset_chan(ic);
+			goto bad;
+		}
+	}
+
+	/*
+	 * Get the receive filter according to the
+	 * operating mode and state
+	 */
+	rfilt = arn_calcrxfilter(sc);
+
+	if (nstate == IEEE80211_S_SCAN)
+		bssid = ic->ic_macaddr;
+	else
+		bssid = in->in_bssid;
+
+	ath9k_hw_setrxfilter(ah, rfilt);
+
+	if (nstate == IEEE80211_S_RUN && ic->ic_opmode != IEEE80211_M_IBSS)
+		ath9k_hw_write_associd(ah, bssid, in->in_associd);
+	else
+		ath9k_hw_write_associd(ah, bssid, 0);
+
+	/* Check for WLAN_CAPABILITY_PRIVACY ? */
+	if (ic->ic_flags & IEEE80211_F_PRIVACY) {
+		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+			if (ath9k_hw_keyisvalid(ah, (uint16_t)i))
+				(void) ath9k_hw_keysetmac(ah, (uint16_t)i,
+				    bssid);
+		}
+	}
+
+	if (nstate == IEEE80211_S_RUN) {
+		switch (ic->ic_opmode) {
+#ifdef ARN_IBSS
+		case IEEE80211_M_IBSS:
+			/*
+			 * Allocate and setup the beacon frame.
+			 * Stop any previous beacon DMA.
+			 */
+			(void) ath9k_hw_stoptxdma(ah, sc->sc_beaconq);
+			arn_beacon_return(sc);
+			error = arn_beacon_alloc(sc, in);
+			if (error != 0) {
+				ARN_UNLOCK(sc);
+				goto bad;
+			}
+			/*
+			 * If joining an adhoc network defer beacon timer
+			 * configuration to the next beacon frame so we
+			 * have a current TSF to use.  Otherwise we're
+			 * starting an ibss/bss so there's no need to delay.
+			 */
+			if (ic->ic_opmode == IEEE80211_M_IBSS &&
+			    ic->ic_bss->in_tstamp.tsf != 0) {
+				sc->sc_bsync = 1;
+			} else {
+				arn_beacon_config(sc);
+			}
+			break;
+#endif /* ARN_IBSS */
+		case IEEE80211_M_STA:
+			if (ostate != IEEE80211_S_RUN) {
+				/*
+				 * Defer beacon timer configuration to the next
+				 * beacon frame so we have a current TSF to use.
+				 * Any TSF collected when scanning is likely old
+				 */
+#ifdef ARN_IBSS
+				sc->sc_bsync = 1;
+#else
+				/* Configure the beacon and sleep timers. */
+				arn_beacon_config(sc);
+#endif /* ARN_IBSS */
+			}
+			break;
+		default:
+			break;
+		}
+	} else {
+		sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+		(void) ath9k_hw_set_interrupts(ah, sc->sc_imask);
+	}
+
+	/*
+	 * Reset the rate control state.
+	 */
+	arn_rate_ctl_reset(sc, nstate);
+
+	ARN_UNLOCK(sc);
+done:
+	/*
+	 * Invoke the parent method to complete the work.
+	 */
+	error = sc->sc_newstate(ic, nstate, arg);
+
+	/*
+	 * Finally, start any timers.
+	 */
+	if (nstate == IEEE80211_S_RUN) {
+		ieee80211_start_watchdog(ic, 1);
+		ASSERT(sc->sc_cal_timer == 0);
+		sc->sc_cal_timer = timeout(arn_ani_calibrate, (void *)sc,
+		    drv_usectohz(100 * 1000));
+	} else if ((nstate == IEEE80211_S_SCAN) && (ostate != nstate)) {
+		/* start ap/neighbor scan timer */
+		/* ASSERT(sc->sc_scan_timer == 0); */
+		if (sc->sc_scan_timer != 0) {
+			(void) untimeout(sc->sc_scan_timer);
+			sc->sc_scan_timer = 0;
+		}
+		sc->sc_scan_timer = timeout(arn_next_scan, (void *)sc,
+		    drv_usectohz(arn_dwelltime * 1000));
+	}
+
+bad:
+	return (error);
+}
+
+static void
+arn_watchdog(void *arg)
+{
+	struct arn_softc *sc = arg;
+	ieee80211com_t *ic = &sc->sc_isc;
+	int ntimer = 0;
+
+	ARN_LOCK(sc);
+	ic->ic_watchdog_timer = 0;
+	if (sc->sc_flags & SC_OP_INVALID) {
+		ARN_UNLOCK(sc);
+		return;
+	}
+
+	if (ic->ic_state == IEEE80211_S_RUN) {
+		/*
+		 * Start the background rate control thread if we
+		 * are not configured to use a fixed xmit rate.
+		 */
+		if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
+			sc->sc_stats.ast_rate_calls ++;
+			if (ic->ic_opmode == IEEE80211_M_STA)
+				arn_rate_ctl(ic, ic->ic_bss);
+			else
+				ieee80211_iterate_nodes(&ic->ic_sta,
+				    arn_rate_ctl, sc);
+		}
+
+		ntimer = 1;
+	}
+	ARN_UNLOCK(sc);
+
+	ieee80211_watchdog(ic);
+	if (ntimer != 0)
+		ieee80211_start_watchdog(ic, ntimer);
+}
+
+static struct ieee80211_node *
+arn_node_alloc(ieee80211com_t *ic)
+{
+	struct ath_node *an;
+	struct arn_softc *sc = (struct arn_softc *)ic;
+
+	an = kmem_zalloc(sizeof (struct ath_node), KM_SLEEP);
+	arn_rate_update(sc, &an->an_node, 0);
+
+	return ((an != NULL) ? &an->an_node : NULL);
+}
+
+static void
+arn_node_free(struct ieee80211_node *in)
+{
+	ieee80211com_t *ic = in->in_ic;
+	struct arn_softc *sc = (struct arn_softc *)ic;
+	struct ath_buf *bf;
+	struct ath_txq *txq;
+	int32_t i;
+
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ARN_TXQ_SETUP(sc, i)) {
+			txq = &sc->sc_txq[i];
+			mutex_enter(&txq->axq_lock);
+			bf = list_head(&txq->axq_list);
+			while (bf != NULL) {
+				if (bf->bf_in == in) {
+					bf->bf_in = NULL;
+				}
+				bf = list_next(&txq->axq_list, bf);
+			}
+			mutex_exit(&txq->axq_lock);
+		}
+	}
+
+	ic->ic_node_cleanup(in);
+	if (in->in_wpa_ie != NULL)
+		ieee80211_free(in->in_wpa_ie);
+	kmem_free(in, sizeof (struct ath_node));
+}
+
+/*
+ * Allocate tx/rx key slots for TKIP.  We allocate one slot for
+ * each key. MIC is right after the decrypt/encrypt key.
+ */
+static uint16_t
+arn_key_alloc_pair(struct arn_softc *sc, ieee80211_keyix *txkeyix,
+    ieee80211_keyix *rxkeyix)
+{
+	uint16_t i, keyix;
+
+	ASSERT(!sc->sc_splitmic);
+	for (i = 0; i < ARRAY_SIZE(sc->sc_keymap)/4; i++) {
+		uint8_t b = sc->sc_keymap[i];
+		if (b == 0xff)
+			continue;
+		for (keyix = i * NBBY; keyix < (i + 1) * NBBY;
+		    keyix++, b >>= 1) {
+			if ((b & 1) || is_set(keyix+64, sc->sc_keymap)) {
+				/* full pair unavailable */
+				continue;
+			}
+			set_bit(keyix, sc->sc_keymap);
+			set_bit(keyix+64, sc->sc_keymap);
+			ARN_DBG((ARN_DBG_KEYCACHE,
+			    "arn_key_alloc_pair(): key pair %u,%u\n",
+			    keyix, keyix+64));
+			*txkeyix = *rxkeyix = keyix;
+			return (1);
+		}
+	}
+	ARN_DBG((ARN_DBG_KEYCACHE, "arn_key_alloc_pair():"
+	    " out of pair space\n"));
+
+	return (0);
+}
+
+/*
+ * Allocate tx/rx key slots for TKIP.  We allocate two slots for
+ * each key, one for decrypt/encrypt and the other for the MIC.
+ */
+static int
+arn_key_alloc_2pair(struct arn_softc *sc, ieee80211_keyix *txkeyix,
+    ieee80211_keyix *rxkeyix)
+{
+	uint16_t i, keyix;
+
+	ASSERT(sc->sc_splitmic);
+	for (i = 0; i < ARRAY_SIZE(sc->sc_keymap)/4; i++) {
+		uint8_t b = sc->sc_keymap[i];
+		if (b != 0xff) {
+			/*
+			 * One or more slots in this byte are free.
+			 */
+			keyix = i*NBBY;
+			while (b & 1) {
+		again:
+				keyix++;
+				b >>= 1;
+			}
+			/* XXX IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV */
+			if (is_set(keyix+32, sc->sc_keymap) ||
+			    is_set(keyix+64, sc->sc_keymap) ||
+			    is_set(keyix+32+64, sc->sc_keymap)) {
+				/* full pair unavailable */
+				if (keyix == (i+1)*NBBY) {
+					/* no slots were appropriate, advance */
+					continue;
+				}
+				goto again;
+			}
+			set_bit(keyix, sc->sc_keymap);
+			set_bit(keyix+64, sc->sc_keymap);
+			set_bit(keyix+32, sc->sc_keymap);
+			set_bit(keyix+32+64, sc->sc_keymap);
+			ARN_DBG((ARN_DBG_KEYCACHE,
+			    "arn_key_alloc_2pair(): key pair %u,%u %u,%u\n",
+			    keyix, keyix+64,
+			    keyix+32, keyix+32+64));
+			*txkeyix = *rxkeyix = keyix;
+			return (1);
+		}
+	}
+	ARN_DBG((ARN_DBG_KEYCACHE, "arn_key_alloc_2pair(): "
+	    " out of pair space\n"));
+
+	return (0);
+}
+/*
+ * Allocate a single key cache slot.
+ */
+static int
+arn_key_alloc_single(struct arn_softc *sc, ieee80211_keyix *txkeyix,
+    ieee80211_keyix *rxkeyix)
+{
+	uint16_t i, keyix;
+
+	/* try i,i+32,i+64,i+32+64 to minimize key pair conflicts */
+	for (i = 0; i < ARRAY_SIZE(sc->sc_keymap); i++) {
+		uint8_t b = sc->sc_keymap[i];
+
+		if (b != 0xff) {
+			/*
+			 * One or more slots are free.
+			 */
+			keyix = i*NBBY;
+			while (b & 1)
+				keyix++, b >>= 1;
+			set_bit(keyix, sc->sc_keymap);
+			ARN_DBG((ARN_DBG_KEYCACHE, "arn_key_alloc_single(): "
+			    "key %u\n", keyix));
+			*txkeyix = *rxkeyix = keyix;
+			return (1);
+		}
+	}
+	return (0);
+}
+
+/*
+ * Allocate one or more key cache slots for a unicast key.  The
+ * key itself is needed only to identify the cipher.  For hardware
+ * TKIP with split cipher+MIC keys we allocate two key cache slot
+ * pairs so that we can setup separate TX and RX MIC keys.  Note
+ * that the MIC key for a TKIP key at slot i is assumed by the
+ * hardware to be at slot i+64.  This limits TKIP keys to the first
+ * 64 entries.
+ */
+/* ARGSUSED */
+int
+arn_key_alloc(ieee80211com_t *ic, const struct ieee80211_key *k,
+    ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
+{
+	struct arn_softc *sc = (struct arn_softc *)ic;
+
+	/*
+	 * We allocate two pair for TKIP when using the h/w to do
+	 * the MIC.  For everything else, including software crypto,
+	 * we allocate a single entry.  Note that s/w crypto requires
+	 * a pass-through slot on the 5211 and 5212.  The 5210 does
+	 * not support pass-through cache entries and we map all
+	 * those requests to slot 0.
+	 */
+	if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
+		return (arn_key_alloc_single(sc, keyix, rxkeyix));
+	} else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP &&
+	    (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
+		if (sc->sc_splitmic)
+			return (arn_key_alloc_2pair(sc, keyix, rxkeyix));
+		else
+			return (arn_key_alloc_pair(sc, keyix, rxkeyix));
+	} else {
+		return (arn_key_alloc_single(sc, keyix, rxkeyix));
+	}
+}
+
+/*
+ * Delete an entry in the key cache allocated by ath_key_alloc.
+ */
+int
+arn_key_delete(ieee80211com_t *ic, const struct ieee80211_key *k)
+{
+	struct arn_softc *sc = (struct arn_softc *)ic;
+	struct ath_hal *ah = sc->sc_ah;
+	const struct ieee80211_cipher *cip = k->wk_cipher;
+	ieee80211_keyix keyix = k->wk_keyix;
+
+	ARN_DBG((ARN_DBG_KEYCACHE, "arn_key_delete():"
+	    " delete key %u ic_cipher=0x%x\n", keyix, cip->ic_cipher));
+
+	(void) ath9k_hw_keyreset(ah, keyix);
+	/*
+	 * Handle split tx/rx keying required for TKIP with h/w MIC.
+	 */
+	if (cip->ic_cipher == IEEE80211_CIPHER_TKIP &&
+	    (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && sc->sc_splitmic)
+		(void) ath9k_hw_keyreset(ah, keyix+32);		/* RX key */
+
+	if (keyix >= IEEE80211_WEP_NKID) {
+		/*
+		 * Don't touch keymap entries for global keys so
+		 * they are never considered for dynamic allocation.
+		 */
+		clr_bit(keyix, sc->sc_keymap);
+		if (cip->ic_cipher == IEEE80211_CIPHER_TKIP &&
+		    (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
+			/*
+			 * If splitmic is true +64 is TX key MIC,
+			 * else +64 is RX key + RX key MIC.
+			 */
+			clr_bit(keyix+64, sc->sc_keymap);
+			if (sc->sc_splitmic) {
+				/* Rx key */
+				clr_bit(keyix+32, sc->sc_keymap);
+				/* RX key MIC */
+				clr_bit(keyix+32+64, sc->sc_keymap);
+			}
+		}
+	}
+	return (1);
+}
+
+/*
+ * Set a TKIP key into the hardware.  This handles the
+ * potential distribution of key state to multiple key
+ * cache slots for TKIP.
+ */
+static int
+arn_keyset_tkip(struct arn_softc *sc, const struct ieee80211_key *k,
+    struct ath9k_keyval *hk, const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+	uint8_t *key_rxmic = NULL;
+	uint8_t *key_txmic = NULL;
+	uint8_t  *key = (uint8_t *)&(k->wk_key[0]);
+	struct ath_hal *ah = sc->sc_ah;
+
+	key_txmic = key + 16;
+	key_rxmic = key + 24;
+
+	if (mac == NULL) {
+		/* Group key installation */
+		(void) memcpy(hk->kv_mic,  key_rxmic, sizeof (hk->kv_mic));
+		return (ath9k_hw_set_keycache_entry(ah, k->wk_keyix, hk,
+		    mac, B_FALSE));
+	}
+	if (!sc->sc_splitmic) {
+		/*
+		 * data key goes at first index,
+		 * the hal handles the MIC keys at index+64.
+		 */
+		(void) memcpy(hk->kv_mic, key_rxmic, sizeof (hk->kv_mic));
+		(void) memcpy(hk->kv_txmic, key_txmic, sizeof (hk->kv_txmic));
+		return (ath9k_hw_set_keycache_entry(ah, k->wk_keyix, hk,
+		    mac, B_FALSE));
+	}
+	/*
+	 * TX key goes at first index, RX key at +32.
+	 * The hal handles the MIC keys at index+64.
+	 */
+	(void) memcpy(hk->kv_mic, key_txmic, sizeof (hk->kv_mic));
+	if (!(ath9k_hw_set_keycache_entry(ah, k->wk_keyix, hk, NULL,
+	    B_FALSE))) {
+		/* Txmic entry failed. No need to proceed further */
+		ARN_DBG((ARN_DBG_KEYCACHE,
+		    "%s Setting TX MIC Key Failed\n", __func__));
+		return (0);
+	}
+
+	(void) memcpy(hk->kv_mic, key_rxmic, sizeof (hk->kv_mic));
+
+	/* XXX delete tx key on failure? */
+	return (ath9k_hw_set_keycache_entry(ah, k->wk_keyix, hk, mac, B_FALSE));
+
+}
+
+int
+arn_key_set(ieee80211com_t *ic, const struct ieee80211_key *k,
+    const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+	struct arn_softc *sc = (struct arn_softc *)ic;
+	const struct ieee80211_cipher *cip = k->wk_cipher;
+	struct ath9k_keyval hk;
+
+	/* cipher table */
+	static const uint8_t ciphermap[] = {
+		ATH9K_CIPHER_WEP,		/* IEEE80211_CIPHER_WEP */
+		ATH9K_CIPHER_TKIP,		/* IEEE80211_CIPHER_TKIP */
+		ATH9K_CIPHER_AES_OCB,	/* IEEE80211_CIPHER_AES_OCB */
+		ATH9K_CIPHER_AES_CCM,	/* IEEE80211_CIPHER_AES_CCM */
+		ATH9K_CIPHER_CKIP,		/* IEEE80211_CIPHER_CKIP */
+		ATH9K_CIPHER_CLR,		/* IEEE80211_CIPHER_NONE */
+	};
+
+	bzero(&hk, sizeof (hk));
+
+	/*
+	 * Software crypto uses a "clear key" so non-crypto
+	 * state kept in the key cache are maintainedd so that
+	 * rx frames have an entry to match.
+	 */
+	if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) {
+		ASSERT(cip->ic_cipher < 6);
+		hk.kv_type = ciphermap[cip->ic_cipher];
+		hk.kv_len = k->wk_keylen;
+		bcopy(k->wk_key, hk.kv_val, k->wk_keylen);
+	} else {
+		hk.kv_type = ATH9K_CIPHER_CLR;
+	}
+
+	if (hk.kv_type == ATH9K_CIPHER_TKIP &&
+	    (k->wk_flags & IEEE80211_KEY_SWMIC) == 0) {
+		return (arn_keyset_tkip(sc, k, &hk, mac));
+	} else {
+		return (ath9k_hw_set_keycache_entry(sc->sc_ah,
+		    k->wk_keyix, &hk, mac, B_FALSE));
+	}
+}
+
+/*
+ * Enable/Disable short slot timing
+ */
+void
+arn_set_shortslot(ieee80211com_t *ic, int onoff)
+{
+	struct ath_hal *ah = ((struct arn_softc *)ic)->sc_ah;
+
+	if (onoff)
+		(void) ath9k_hw_setslottime(ah, ATH9K_SLOT_TIME_9);
+	else
+		(void) ath9k_hw_setslottime(ah, ATH9K_SLOT_TIME_20);
+}
+
+static int
+arn_open(struct arn_softc *sc)
+{
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ieee80211_channel *curchan = ic->ic_curchan;
+	struct ath9k_channel *init_channel;
+	int error = 0, pos, status;
+
+	ARN_LOCK_ASSERT(sc);
+
+	pos = arn_get_channel(sc, curchan);
+	if (pos == -1) {
+		ARN_DBG((ARN_DBG_FATAL, "arn: "
+		    "%s: Invalid channel\n", __func__));
+		error = EINVAL;
+		goto error;
+	}
+
+	sc->tx_chan_width = ATH9K_HT_MACMODE_20;
+
+	if (sc->sc_curmode == ATH9K_MODE_11A) {
+		sc->sc_ah->ah_channels[pos].chanmode = CHANNEL_A;
+	} else {
+		sc->sc_ah->ah_channels[pos].chanmode = CHANNEL_G;
+	}
+
+	init_channel = &sc->sc_ah->ah_channels[pos];
+
+	/* Reset SERDES registers */
+	ath9k_hw_configpcipowersave(sc->sc_ah, 0);
+
+	/*
+	 * The basic interface to setting the hardware in a good
+	 * state is ``reset''.	On return the hardware is known to
+	 * be powered up and with interrupts disabled.	This must
+	 * be followed by initialization of the appropriate bits
+	 * and then setup of the interrupt mask.
+	 */
+	if (!ath9k_hw_reset(sc->sc_ah, init_channel,
+	    sc->tx_chan_width, sc->sc_tx_chainmask,
+	    sc->sc_rx_chainmask, sc->sc_ht_extprotspacing,
+	    B_FALSE, &status)) {
+		ARN_DBG((ARN_DBG_FATAL, "arn: "
+		    "%s: unable to reset hardware; hal status %u "
+		    "(freq %u flags 0x%x)\n", __func__, status,
+		    init_channel->channel, init_channel->channelFlags));
+
+		error = EIO;
+		goto error;
+	}
+
+	/*
+	 * This is needed only to setup initial state
+	 * but it's best done after a reset.
+	 */
+	arn_update_txpow(sc);
+
+	/*
+	 * Setup the hardware after reset:
+	 * The receive engine is set going.
+	 * Frame transmit is handled entirely
+	 * in the frame output path; there's nothing to do
+	 * here except setup the interrupt mask.
+	 */
+	if (arn_startrecv(sc) != 0) {
+		ARN_DBG((ARN_DBG_INIT, "arn: "
+		    "%s: unable to start recv logic\n", __func__));
+		error = EIO;
+		goto error;
+	}
+
+	/* Setup our intr mask. */
+	sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX |
+	    ATH9K_INT_RXEOL | ATH9K_INT_RXORN |
+	    ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
+#ifdef ARN_ATH9K_HW_CAP_GTT
+	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_GTT)
+		sc->sc_imask |= ATH9K_INT_GTT;
+#endif
+
+#ifdef ARN_ATH9K_HW_CAP_GTT
+	if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
+		sc->sc_imask |= ATH9K_INT_CST;
+#endif
+
+	/*
+	 * Enable MIB interrupts when there are hardware phy counters.
+	 * Note we only do this (at the moment) for station mode.
+	 */
+#ifdef ARN_ATH9K_INT_MIB
+	if (ath9k_hw_phycounters(sc->sc_ah) &&
+	    ((sc->sc_ah->ah_opmode == ATH9K_M_STA) ||
+	    (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)))
+		sc->sc_imask |= ATH9K_INT_MIB;
+#endif
+	/*
+	 * Some hardware processes the TIM IE and fires an
+	 * interrupt when the TIM bit is set.  For hardware
+	 * that does, if not overridden by configuration,
+	 * enable the TIM interrupt when operating as station.
+	 */
+#ifdef ARN_ATH9K_INT_TIM
+	if ((sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
+	    (sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
+	    !sc->sc_config.swBeaconProcess)
+		sc->sc_imask |= ATH9K_INT_TIM;
+#endif
+	if (arn_chan2mode(init_channel) != sc->sc_curmode)
+		arn_setcurmode(sc, arn_chan2mode(init_channel));
+	ARN_DBG((ARN_DBG_INIT, "arn: "
+	    "%s: current mode after arn_setcurmode is %d\n",
+	    __func__, sc->sc_curmode));
+
+	sc->sc_isrunning = 1;
+
+	/* Disable BMISS interrupt when we're not associated */
+	sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+	(void) ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
+
+	return (0);
+
+error:
+	return (error);
+}
+
+static void
+arn_close(struct arn_softc *sc)
+{
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ath_hal *ah = sc->sc_ah;
+
+	ARN_LOCK_ASSERT(sc);
+
+	if (!sc->sc_isrunning)
+		return;
+
+	/*
+	 * Shutdown the hardware and driver
+	 * Note that some of this work is not possible if the
+	 * hardware is gone (invalid).
+	 */
+	ARN_UNLOCK(sc);
+	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+	ieee80211_stop_watchdog(ic);
+	ARN_LOCK(sc);
+
+	/*
+	 * make sure h/w will not generate any interrupt
+	 * before setting the invalid flag.
+	 */
+	(void) ath9k_hw_set_interrupts(ah, 0);
+
+	if (!(sc->sc_flags & SC_OP_INVALID)) {
+		arn_draintxq(sc, 0);
+		(void) arn_stoprecv(sc);
+		(void) ath9k_hw_phy_disable(ah);
+	} else {
+		sc->sc_rxlink = NULL;
+	}
+
+	sc->sc_isrunning = 0;
+}
+
+/*
+ * MAC callback functions
+ */
+static int
+arn_m_stat(void *arg, uint_t stat, uint64_t *val)
+{
+	struct arn_softc *sc = arg;
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ieee80211_node *in;
+	struct ieee80211_rateset *rs;
+
+	ARN_LOCK(sc);
+	switch (stat) {
+	case MAC_STAT_IFSPEED:
+		in = ic->ic_bss;
+		rs = &in->in_rates;
+		*val = (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) / 2 *
+		    1000000ull;
+		break;
+	case MAC_STAT_NOXMTBUF:
+		*val = sc->sc_stats.ast_tx_nobuf +
+		    sc->sc_stats.ast_tx_nobufmgt;
+		break;
+	case MAC_STAT_IERRORS:
+		*val = sc->sc_stats.ast_rx_tooshort;
+		break;
+	case MAC_STAT_RBYTES:
+		*val = ic->ic_stats.is_rx_bytes;
+		break;
+	case MAC_STAT_IPACKETS:
+		*val = ic->ic_stats.is_rx_frags;
+		break;
+	case MAC_STAT_OBYTES:
+		*val = ic->ic_stats.is_tx_bytes;
+		break;
+	case MAC_STAT_OPACKETS:
+		*val = ic->ic_stats.is_tx_frags;
+		break;
+	case MAC_STAT_OERRORS:
+	case WIFI_STAT_TX_FAILED:
+		*val = sc->sc_stats.ast_tx_fifoerr +
+		    sc->sc_stats.ast_tx_xretries +
+		    sc->sc_stats.ast_tx_discard;
+		break;
+	case WIFI_STAT_TX_RETRANS:
+		*val = sc->sc_stats.ast_tx_xretries;
+		break;
+	case WIFI_STAT_FCS_ERRORS:
+		*val = sc->sc_stats.ast_rx_crcerr;
+		break;
+	case WIFI_STAT_WEP_ERRORS:
+		*val = sc->sc_stats.ast_rx_badcrypt;
+		break;
+	case WIFI_STAT_TX_FRAGS:
+	case WIFI_STAT_MCAST_TX:
+	case WIFI_STAT_RTS_SUCCESS:
+	case WIFI_STAT_RTS_FAILURE:
+	case WIFI_STAT_ACK_FAILURE:
+	case WIFI_STAT_RX_FRAGS:
+	case WIFI_STAT_MCAST_RX:
+	case WIFI_STAT_RX_DUPS:
+		ARN_UNLOCK(sc);
+		return (ieee80211_stat(ic, stat, val));
+	default:
+		ARN_UNLOCK(sc);
+		return (ENOTSUP);
+	}
+	ARN_UNLOCK(sc);
+
+	return (0);
+}
+
+int
+arn_m_start(void *arg)
+{
+	struct arn_softc *sc = arg;
+	int err = 0;
+
+	ARN_LOCK(sc);
+
+	/*
+	 * Stop anything previously setup.  This is safe
+	 * whether this is the first time through or not.
+	 */
+
+	arn_close(sc);
+
+	if ((err = arn_open(sc)) != 0) {
+		ARN_UNLOCK(sc);
+		return (err);
+	}
+
+	/* H/W is reday now */
+	sc->sc_flags &= ~SC_OP_INVALID;
+
+	ARN_UNLOCK(sc);
+
+	return (0);
+}
+
+static void
+arn_m_stop(void *arg)
+{
+	struct arn_softc *sc = arg;
+
+	ARN_LOCK(sc);
+	arn_close(sc);
+
+	/* disable HAL and put h/w to sleep */
+	(void) ath9k_hw_disable(sc->sc_ah);
+	ath9k_hw_configpcipowersave(sc->sc_ah, 1);
+
+	/* XXX: hardware will not be ready in suspend state */
+	sc->sc_flags |= SC_OP_INVALID;
+	ARN_UNLOCK(sc);
+}
+
+static int
+arn_m_promisc(void *arg, boolean_t on)
+{
+	struct arn_softc *sc = arg;
+	struct ath_hal *ah = sc->sc_ah;
+	uint32_t rfilt;
+
+	ARN_LOCK(sc);
+
+	rfilt = ath9k_hw_getrxfilter(ah);
+	if (on)
+		rfilt |= ATH9K_RX_FILTER_PROM;
+	else
+		rfilt &= ~ATH9K_RX_FILTER_PROM;
+	sc->sc_promisc = on;
+	ath9k_hw_setrxfilter(ah, rfilt);
+
+	ARN_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+arn_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
+{
+	struct arn_softc *sc = arg;
+	struct ath_hal *ah = sc->sc_ah;
+	uint32_t val, index, bit;
+	uint8_t pos;
+	uint32_t *mfilt = sc->sc_mcast_hash;
+
+	ARN_LOCK(sc);
+
+	/* calculate XOR of eight 6bit values */
+	val = ARN_LE_READ_32(mca + 0);
+	pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+	val = ARN_LE_READ_32(mca + 3);
+	pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+	pos &= 0x3f;
+	index = pos / 32;
+	bit = 1 << (pos % 32);
+
+	if (add) {	/* enable multicast */
+		sc->sc_mcast_refs[pos]++;
+		mfilt[index] |= bit;
+	} else {	/* disable multicast */
+		if (--sc->sc_mcast_refs[pos] == 0)
+			mfilt[index] &= ~bit;
+	}
+	ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
+
+	ARN_UNLOCK(sc);
+	return (0);
+}
+
+static int
+arn_m_unicst(void *arg, const uint8_t *macaddr)
+{
+	struct arn_softc *sc = arg;
+	struct ath_hal *ah = sc->sc_ah;
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+
+	ARN_DBG((ARN_DBG_XMIT, "ath: ath_gld_saddr(): "
+	    "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+	    macaddr[0], macaddr[1], macaddr[2],
+	    macaddr[3], macaddr[4], macaddr[5]));
+
+	ARN_LOCK(sc);
+	IEEE80211_ADDR_COPY(sc->sc_isc.ic_macaddr, macaddr);
+	(void) ath9k_hw_setmac(ah, sc->sc_isc.ic_macaddr);
+	(void) arn_reset(ic);
+	ARN_UNLOCK(sc);
+	return (0);
+}
+
+static mblk_t *
+arn_m_tx(void *arg, mblk_t *mp)
+{
+	struct arn_softc *sc = arg;
+	int error = 0;
+	mblk_t *next;
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+
+	/*
+	 * No data frames go out unless we're associated; this
+	 * should not happen as the 802.11 layer does not enable
+	 * the xmit queue until we enter the RUN state.
+	 */
+	if (ic->ic_state != IEEE80211_S_RUN) {
+		ARN_DBG((ARN_DBG_XMIT, "arn: arn_m_tx(): "
+		    "discard, state %u\n", ic->ic_state));
+		sc->sc_stats.ast_tx_discard++;
+		freemsgchain(mp);
+		return (NULL);
+	}
+
+	while (mp != NULL) {
+		next = mp->b_next;
+		mp->b_next = NULL;
+		error = arn_tx(ic, mp, IEEE80211_FC0_TYPE_DATA);
+		if (error != 0) {
+			mp->b_next = next;
+			if (error == ENOMEM) {
+				break;
+			} else {
+				freemsgchain(mp);
+				return (NULL);
+			}
+		}
+		mp = next;
+	}
+
+	return (mp);
+}
+
+static void
+arn_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
+{
+	struct arn_softc *sc = arg;
+	int32_t err;
+
+	err = ieee80211_ioctl(&sc->sc_isc, wq, mp);
+
+	ARN_LOCK(sc);
+	if (err == ENETRESET) {
+		if (!(sc->sc_flags & SC_OP_INVALID)) {
+			ARN_UNLOCK(sc);
+
+			(void) arn_m_start(sc);
+
+			(void) ieee80211_new_state(&sc->sc_isc,
+			    IEEE80211_S_SCAN, -1);
+			ARN_LOCK(sc);
+		}
+	}
+	ARN_UNLOCK(sc);
+}
+
+static int
+arn_m_setprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
+    uint_t wldp_length, const void *wldp_buf)
+{
+	struct arn_softc *sc = arg;
+	int	err;
+
+	err = ieee80211_setprop(&sc->sc_isc, pr_name, wldp_pr_num,
+	    wldp_length, wldp_buf);
+
+	ARN_LOCK(sc);
+
+	if (err == ENETRESET) {
+		if (!(sc->sc_flags & SC_OP_INVALID)) {
+			ARN_UNLOCK(sc);
+			(void) arn_m_start(sc);
+			(void) ieee80211_new_state(&sc->sc_isc,
+			    IEEE80211_S_SCAN, -1);
+			ARN_LOCK(sc);
+		}
+		err = 0;
+	}
+
+	ARN_UNLOCK(sc);
+
+	return (err);
+}
+
+/* ARGSUSED */
+static int
+arn_m_getprop(void *arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
+    uint_t pr_flags, uint_t wldp_length, void *wldp_buf, uint_t *perm)
+{
+	struct arn_softc *sc = arg;
+	int	err = 0;
+
+	err = ieee80211_getprop(&sc->sc_isc, pr_name, wldp_pr_num,
+	    pr_flags, wldp_length, wldp_buf, perm);
+
+	return (err);
+}
+
+/* return bus cachesize in 4B word units */
+static void
+arn_pci_config_cachesize(struct arn_softc *sc)
+{
+	uint8_t csz;
+
+	/*
+	 * Cache line size is used to size and align various
+	 * structures used to communicate with the hardware.
+	 */
+	csz = pci_config_get8(sc->sc_cfg_handle, PCI_CONF_CACHE_LINESZ);
+	if (csz == 0) {
+		/*
+		 * We must have this setup properly for rx buffer
+		 * DMA to work so force a reasonable value here if it
+		 * comes up zero.
+		 */
+		csz = ATH_DEF_CACHE_BYTES / sizeof (uint32_t);
+		pci_config_put8(sc->sc_cfg_handle, PCI_CONF_CACHE_LINESZ,
+		    csz);
+	}
+	sc->sc_cachelsz = csz << 2;
+}
+
+static int
+arn_pci_setup(struct arn_softc *sc)
+{
+	uint16_t command;
+
+	/*
+	 * Enable memory mapping and bus mastering
+	 */
+	ASSERT(sc != NULL);
+	command = pci_config_get16(sc->sc_cfg_handle, PCI_CONF_COMM);
+	command	|= PCI_COMM_MAE | PCI_COMM_ME;
+	pci_config_put16(sc->sc_cfg_handle, PCI_CONF_COMM, command);
+	command = pci_config_get16(sc->sc_cfg_handle, PCI_CONF_COMM);
+	if ((command & PCI_COMM_MAE) == 0) {
+		arn_problem("arn: arn_pci_setup(): "
+		    "failed to enable memory mapping\n");
+		return (EIO);
+	}
+	if ((command & PCI_COMM_ME) == 0) {
+		arn_problem("arn: arn_pci_setup(): "
+		    "failed to enable bus mastering\n");
+		return (EIO);
+	}
+	ARN_DBG((ARN_DBG_INIT, "arn: arn_pci_setup(): "
+	    "set command reg to 0x%x \n", command));
+
+	return (0);
+}
+
+static void
+arn_get_hw_encap(struct arn_softc *sc)
+{
+	ieee80211com_t *ic;
+	struct ath_hal *ah;
+
+	ic = (ieee80211com_t *)sc;
+	ah = sc->sc_ah;
+
+	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+	    ATH9K_CIPHER_AES_CCM, NULL))
+		ic->ic_caps |= IEEE80211_C_AES_CCM;
+	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+	    ATH9K_CIPHER_AES_OCB, NULL))
+		ic->ic_caps |= IEEE80211_C_AES;
+	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+	    ATH9K_CIPHER_TKIP, NULL))
+		ic->ic_caps |= IEEE80211_C_TKIP;
+	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+	    ATH9K_CIPHER_WEP, NULL))
+		ic->ic_caps |= IEEE80211_C_WEP;
+	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+	    ATH9K_CIPHER_MIC, NULL))
+		ic->ic_caps |= IEEE80211_C_TKIPMIC;
+}
+
+static int
+arn_resume(dev_info_t *devinfo)
+{
+	struct arn_softc *sc;
+	int ret = DDI_SUCCESS;
+
+	sc = ddi_get_soft_state(arn_soft_state_p, ddi_get_instance(devinfo));
+	if (sc == NULL) {
+		ARN_DBG((ARN_DBG_INIT, "ath: ath_resume(): "
+		    "failed to get soft state\n"));
+		return (DDI_FAILURE);
+	}
+
+	ARN_LOCK(sc);
+	/*
+	 * Set up config space command register(s). Refuse
+	 * to resume on failure.
+	 */
+	if (arn_pci_setup(sc) != 0) {
+		ARN_DBG((ARN_DBG_INIT, "ath: ath_resume(): "
+		    "ath_pci_setup() failed\n"));
+		ARN_UNLOCK(sc);
+		return (DDI_FAILURE);
+	}
+
+	if (!(sc->sc_flags & SC_OP_INVALID))
+		ret = arn_open(sc);
+	ARN_UNLOCK(sc);
+
+	return (ret);
+}
+
+static int
+arn_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
+{
+	struct arn_softc *sc;
+	int		instance;
+	int		status;
+	int32_t		err;
+	uint16_t	vendor_id;
+	uint16_t	device_id;
+	uint32_t	i;
+	uint32_t	val;
+	char		strbuf[32];
+	ieee80211com_t *ic;
+	struct ath_hal *ah;
+	wifi_data_t wd = { 0 };
+	mac_register_t *macp;
+
+	switch (cmd) {
+	case DDI_ATTACH:
+		break;
+	case DDI_RESUME:
+		return (arn_resume(devinfo));
+	default:
+		return (DDI_FAILURE);
+	}
+
+	instance = ddi_get_instance(devinfo);
+	if (ddi_soft_state_zalloc(arn_soft_state_p, instance) != DDI_SUCCESS) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: "
+		    "%s: Unable to alloc softstate\n", __func__));
+		return (DDI_FAILURE);
+	}
+
+	sc = ddi_get_soft_state(arn_soft_state_p, ddi_get_instance(devinfo));
+	ic = (ieee80211com_t *)sc;
+	sc->sc_dev = devinfo;
+
+	mutex_init(&sc->sc_genlock, NULL, MUTEX_DRIVER, NULL);
+	mutex_init(&sc->sc_serial_rw, NULL, MUTEX_DRIVER, NULL);
+	mutex_init(&sc->sc_txbuflock, NULL, MUTEX_DRIVER, NULL);
+	mutex_init(&sc->sc_rxbuflock, NULL, MUTEX_DRIVER, NULL);
+	mutex_init(&sc->sc_resched_lock, NULL, MUTEX_DRIVER, NULL);
+#ifdef ARN_IBSS
+	mutex_init(&sc->sc_bcbuflock, NULL, MUTEX_DRIVER, NULL);
+#endif
+
+	sc->sc_flags |= SC_OP_INVALID;
+
+	err = pci_config_setup(devinfo, &sc->sc_cfg_handle);
+	if (err != DDI_SUCCESS) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "pci_config_setup() failed"));
+		goto attach_fail0;
+	}
+
+	if (arn_pci_setup(sc) != 0)
+		goto attach_fail1;
+
+	/* Cache line size set up */
+	arn_pci_config_cachesize(sc);
+
+	vendor_id = pci_config_get16(sc->sc_cfg_handle, PCI_CONF_VENID);
+	device_id = pci_config_get16(sc->sc_cfg_handle, PCI_CONF_DEVID);
+	ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): vendor 0x%x, "
+	    "device id 0x%x, cache size %d\n",
+	    vendor_id, device_id,
+	    pci_config_get8(sc->sc_cfg_handle, PCI_CONF_CACHE_LINESZ)));
+
+	pci_config_put8(sc->sc_cfg_handle, PCI_CONF_LATENCY_TIMER, 0xa8);
+	val = pci_config_get32(sc->sc_cfg_handle, 0x40);
+	if ((val & 0x0000ff00) != 0)
+		pci_config_put32(sc->sc_cfg_handle, 0x40, val & 0xffff00ff);
+
+	err = ddi_regs_map_setup(devinfo, 1,
+	    &sc->mem, 0, 0, &arn_reg_accattr, &sc->sc_io_handle);
+	ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+	    "regs map1 = %x err=%d\n", sc->mem, err));
+	if (err != DDI_SUCCESS) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "ddi_regs_map_setup() failed"));
+		goto attach_fail1;
+	}
+
+	ah = ath9k_hw_attach(device_id, sc, sc->mem, &status);
+	if (ah == NULL) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "unable to attach hw: H/W status %u\n",
+		    status));
+		goto attach_fail2;
+	}
+	sc->sc_ah = ah;
+
+	ath9k_hw_getmac(ah, ic->ic_macaddr);
+
+	/* Get the hardware key cache size. */
+	sc->sc_keymax = ah->ah_caps.keycache_size;
+	if (sc->sc_keymax > ATH_KEYMAX) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "Warning, using only %u entries in %u key cache\n",
+		    ATH_KEYMAX, sc->sc_keymax));
+		sc->sc_keymax = ATH_KEYMAX;
+	}
+
+	/*
+	 * Reset the key cache since some parts do not
+	 * reset the contents on initial power up.
+	 */
+	for (i = 0; i < sc->sc_keymax; i++)
+		(void) ath9k_hw_keyreset(ah, (uint16_t)i);
+	/*
+	 * Mark key cache slots associated with global keys
+	 * as in use.  If we knew TKIP was not to be used we
+	 * could leave the +32, +64, and +32+64 slots free.
+	 * XXX only for splitmic.
+	 */
+	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+		set_bit(i, sc->sc_keymap);
+		set_bit(i + 32, sc->sc_keymap);
+		set_bit(i + 64, sc->sc_keymap);
+		set_bit(i + 32 + 64, sc->sc_keymap);
+	}
+
+	/* Collect the channel list using the default country code */
+	err = arn_setup_channels(sc);
+	if (err == EINVAL) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "ERR:arn_setup_channels\n"));
+		goto attach_fail3;
+	}
+
+	/* default to STA mode */
+	sc->sc_ah->ah_opmode = ATH9K_M_STA;
+
+	/* Setup rate tables */
+	arn_rate_attach(sc);
+	arn_setup_rates(sc, IEEE80211_MODE_11A);
+	arn_setup_rates(sc, IEEE80211_MODE_11B);
+	arn_setup_rates(sc, IEEE80211_MODE_11G);
+
+	/* Setup current mode here */
+	arn_setcurmode(sc, ATH9K_MODE_11G);
+
+	/* 802.11g features */
+	if (sc->sc_have11g)
+		ic->ic_caps |= IEEE80211_C_SHPREAMBLE |
+		    IEEE80211_C_SHSLOT;		/* short slot time */
+
+	/* temp workaround */
+	sc->sc_mrretry = 1;
+
+	/* Setup tx/rx descriptors */
+	err = arn_desc_alloc(devinfo, sc);
+	if (err != DDI_SUCCESS) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "failed to allocate descriptors: %d\n", err));
+		goto attach_fail3;
+	}
+
+	if ((sc->sc_tq = ddi_taskq_create(devinfo, "ath_taskq", 1,
+	    TASKQ_DEFAULTPRI, 0)) == NULL) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "ERR:ddi_taskq_create\n"));
+		goto attach_fail4;
+	}
+
+	/*
+	 * Allocate hardware transmit queues: one queue for
+	 * beacon frames and one data queue for each QoS
+	 * priority.  Note that the hal handles reseting
+	 * these queues at the needed time.
+	 */
+#ifdef ARN_IBSS
+	sc->sc_beaconq = arn_beaconq_setup(ah);
+	if (sc->sc_beaconq == (-1)) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "unable to setup a beacon xmit queue\n"));
+		goto attach_fail4;
+	}
+#endif
+#ifdef ARN_HOSTAP
+	sc->sc_cabq = arn_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
+	if (sc->sc_cabq == NULL) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "unable to setup CAB xmit queue\n"));
+		goto attach_fail4;
+	}
+
+	sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
+	ath_cabq_update(sc);
+#endif
+
+	for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++)
+		sc->sc_haltype2q[i] = -1;
+
+	/* Setup data queues */
+	/* NB: ensure BK queue is the lowest priority h/w queue */
+	if (!arn_tx_setup(sc, ATH9K_WME_AC_BK)) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "unable to setup xmit queue for BK traffic\n"));
+		goto attach_fail4;
+	}
+	if (!arn_tx_setup(sc, ATH9K_WME_AC_BE)) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "unable to setup xmit queue for BE traffic\n"));
+		goto attach_fail4;
+	}
+	if (!arn_tx_setup(sc, ATH9K_WME_AC_VI)) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "unable to setup xmit queue for VI traffic\n"));
+		goto attach_fail4;
+	}
+	if (!arn_tx_setup(sc, ATH9K_WME_AC_VO)) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "unable to setup xmit queue for VO traffic\n"));
+		goto attach_fail4;
+	}
+
+	/*
+	 * Initializes the noise floor to a reasonable default value.
+	 * Later on this will be updated during ANI processing.
+	 */
+
+	sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+
+
+	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+	    ATH9K_CIPHER_TKIP, NULL)) {
+		/*
+		 * Whether we should enable h/w TKIP MIC.
+		 * XXX: if we don't support WME TKIP MIC, then we wouldn't
+		 * report WMM capable, so it's always safe to turn on
+		 * TKIP MIC in this case.
+		 */
+		(void) ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
+		    0, 1, NULL);
+	}
+
+	/* Get cipher releated capability information */
+	arn_get_hw_encap(sc);
+
+	/*
+	 * Check whether the separate key cache entries
+	 * are required to handle both tx+rx MIC keys.
+	 * With split mic keys the number of stations is limited
+	 * to 27 otherwise 59.
+	 */
+	if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+	    ATH9K_CIPHER_TKIP, NULL) &&
+	    ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+	    ATH9K_CIPHER_MIC, NULL) &&
+	    ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
+	    0, NULL))
+		sc->sc_splitmic = 1;
+
+	/* turn on mcast key search if possible */
+	if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
+		(void) ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
+		    1, NULL);
+
+	sc->sc_config.txpowlimit = ATH_TXPOWER_MAX;
+	sc->sc_config.txpowlimit_override = 0;
+
+#ifdef ARN_11N
+	/* 11n Capabilities */
+	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
+		sc->sc_flags |= SC_OP_TXAGGR;
+		sc->sc_flags |= SC_OP_RXAGGR;
+	}
+#endif
+
+#ifdef ARN_11N
+	sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
+	sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
+#else
+	sc->sc_tx_chainmask = 1;
+	sc->sc_rx_chainmask = 1;
+#endif
+	ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+	    "tx_chainmask = %d, rx_chainmask = %d\n",
+	    sc->sc_tx_chainmask, sc->sc_rx_chainmask));
+
+	(void) ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, B_TRUE, NULL);
+	sc->sc_defant = ath9k_hw_getdefantenna(ah);
+
+	ath9k_hw_getmac(ah, sc->sc_myaddr);
+	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
+		ath9k_hw_getbssidmask(ah, sc->sc_bssidmask);
+		ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask);
+		(void) ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
+	}
+
+	/* set default value to short slot time */
+	sc->sc_slottime = ATH9K_SLOT_TIME_9;
+	(void) ath9k_hw_setslottime(ah, ATH9K_SLOT_TIME_9);
+
+	/* initialize beacon slots */
+	for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++)
+		sc->sc_bslot[i] = ATH_IF_ID_ANY;
+
+	/* save MISC configurations */
+	sc->sc_config.swBeaconProcess = 1;
+
+
+	ic->ic_caps |= IEEE80211_C_WPA;	/* Support WPA/WPA2 */
+	ic->ic_phytype = IEEE80211_T_OFDM;
+	ic->ic_opmode = IEEE80211_M_STA;
+	ic->ic_state = IEEE80211_S_INIT;
+	ic->ic_maxrssi = ARN_MAX_RSSI;
+	ic->ic_set_shortslot = arn_set_shortslot;
+	ic->ic_xmit = arn_tx;
+	ieee80211_attach(ic);
+
+	ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+	    "ic->ic_curchan->ich_freq: %d\n", ic->ic_curchan->ich_freq));
+
+	/* different instance has different WPA door */
+	(void) snprintf(ic->ic_wpadoor, MAX_IEEE80211STR, "%s_%s%d", WPA_DOOR,
+	    ddi_driver_name(devinfo),
+	    ddi_get_instance(devinfo));
+
+	/* Override 80211 default routines */
+	ic->ic_reset = arn_reset;
+	sc->sc_newstate = ic->ic_newstate;
+	ic->ic_newstate = arn_newstate;
+#ifdef ARN_IBSS
+	sc->sc_recv_mgmt = ic->ic_recv_mgmt;
+	ic->ic_recv_mgmt = arn_recv_mgmt;
+#endif
+	ic->ic_watchdog = arn_watchdog;
+	ic->ic_node_alloc = arn_node_alloc;
+	ic->ic_node_free = arn_node_free;
+	ic->ic_crypto.cs_key_alloc = arn_key_alloc;
+	ic->ic_crypto.cs_key_delete = arn_key_delete;
+	ic->ic_crypto.cs_key_set = arn_key_set;
+
+	ieee80211_media_init(ic);
+
+	/*
+	 * initialize default tx key
+	 */
+	ic->ic_def_txkey = 0;
+
+	sc->sc_rx_pend = 0;
+	(void) ath9k_hw_set_interrupts(sc->sc_ah, 0);
+	err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW,
+	    &sc->sc_softint_id, NULL, 0, arn_softint_handler, (caddr_t)sc);
+	if (err != DDI_SUCCESS) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "ddi_add_softintr() failed....\n"));
+		goto attach_fail5;
+	}
+
+	if (ddi_get_iblock_cookie(devinfo, 0, &sc->sc_iblock)
+	    != DDI_SUCCESS) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "Can not get iblock cookie for INT\n"));
+		goto attach_fail6;
+	}
+
+	if (ddi_add_intr(devinfo, 0, NULL, NULL, arn_isr,
+	    (caddr_t)sc) != DDI_SUCCESS) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "Can not set intr for ARN driver\n"));
+		goto attach_fail6;
+	}
+
+	/*
+	 * Provide initial settings for the WiFi plugin; whenever this
+	 * information changes, we need to call mac_plugindata_update()
+	 */
+	wd.wd_opmode = ic->ic_opmode;
+	wd.wd_secalloc = WIFI_SEC_NONE;
+	IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid);
+
+	ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+	    "IEEE80211_ADDR_COPY(wd.wd_bssid, ic->ic_bss->in_bssid)"
+	    "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+	    wd.wd_bssid[0], wd.wd_bssid[1], wd.wd_bssid[2],
+	    wd.wd_bssid[3], wd.wd_bssid[4], wd.wd_bssid[5]));
+
+	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "MAC version mismatch\n"));
+		goto attach_fail7;
+	}
+
+	macp->m_type_ident	= MAC_PLUGIN_IDENT_WIFI;
+	macp->m_driver		= sc;
+	macp->m_dip		= devinfo;
+	macp->m_src_addr	= ic->ic_macaddr;
+	macp->m_callbacks	= &arn_m_callbacks;
+	macp->m_min_sdu		= 0;
+	macp->m_max_sdu		= IEEE80211_MTU;
+	macp->m_pdata		= &wd;
+	macp->m_pdata_size	= sizeof (wd);
+
+	err = mac_register(macp, &ic->ic_mach);
+	mac_free(macp);
+	if (err != 0) {
+		ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+		    "mac_register err %x\n", err));
+		goto attach_fail7;
+	}
+
+	/* Create minor node of type DDI_NT_NET_WIFI */
+	(void) snprintf(strbuf, sizeof (strbuf), "%s%d",
+	    ARN_NODENAME, instance);
+	err = ddi_create_minor_node(devinfo, strbuf, S_IFCHR,
+	    instance + 1, DDI_NT_NET_WIFI, 0);
+	if (err != DDI_SUCCESS)
+		ARN_DBG((ARN_DBG_ATTACH, "WARN: arn: arn_attach(): "
+		    "Create minor node failed - %d\n", err));
+
+	mac_link_update(ic->ic_mach, LINK_STATE_DOWN);
+
+	sc->sc_promisc = B_FALSE;
+	bzero(sc->sc_mcast_refs, sizeof (sc->sc_mcast_refs));
+	bzero(sc->sc_mcast_hash, sizeof (sc->sc_mcast_hash));
+
+	ARN_DBG((ARN_DBG_ATTACH, "arn: arn_attach(): "
+	    "Atheros AR%s MAC/BB Rev:%x "
+	    "AR%s RF Rev:%x: mem=0x%lx\n",
+	    arn_mac_bb_name(ah->ah_macVersion),
+	    ah->ah_macRev,
+	    arn_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+	    ah->ah_phyRev,
+	    (unsigned long)sc->mem));
+
+	/* XXX: hardware will not be ready until arn_open() being called */
+	sc->sc_flags |= SC_OP_INVALID;
+	sc->sc_isrunning = 0;
+
+	return (DDI_SUCCESS);
+
+attach_fail7:
+	ddi_remove_intr(devinfo, 0, sc->sc_iblock);
+attach_fail6:
+	ddi_remove_softintr(sc->sc_softint_id);
+attach_fail5:
+	(void) ieee80211_detach(ic);
+attach_fail4:
+	arn_desc_free(sc);
+	if (sc->sc_tq)
+		ddi_taskq_destroy(sc->sc_tq);
+attach_fail3:
+	ath9k_hw_detach(ah);
+attach_fail2:
+	ddi_regs_map_free(&sc->sc_io_handle);
+attach_fail1:
+	pci_config_teardown(&sc->sc_cfg_handle);
+attach_fail0:
+	sc->sc_flags |= SC_OP_INVALID;
+	/* cleanup tx queues */
+	mutex_destroy(&sc->sc_txbuflock);
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ARN_TXQ_SETUP(sc, i)) {
+			/* arn_tx_cleanupq(asc, &asc->sc_txq[i]); */
+			mutex_destroy(&((&sc->sc_txq[i])->axq_lock));
+		}
+	}
+	mutex_destroy(&sc->sc_rxbuflock);
+	mutex_destroy(&sc->sc_serial_rw);
+	mutex_destroy(&sc->sc_genlock);
+	mutex_destroy(&sc->sc_resched_lock);
+#ifdef ARN_IBSS
+	mutex_destroy(&sc->sc_bcbuflock);
+#endif
+
+	ddi_soft_state_free(arn_soft_state_p, instance);
+
+	return (DDI_FAILURE);
+
+}
+
+/*
+ * Suspend transmit/receive for powerdown
+ */
+static int
+arn_suspend(struct arn_softc *sc)
+{
+	ARN_LOCK(sc);
+	arn_close(sc);
+	ARN_UNLOCK(sc);
+
+	return (DDI_SUCCESS);
+}
+
+static int32_t
+arn_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
+{
+	struct arn_softc *sc;
+	int i;
+
+	sc = ddi_get_soft_state(arn_soft_state_p, ddi_get_instance(devinfo));
+	ASSERT(sc != NULL);
+
+	switch (cmd) {
+	case DDI_DETACH:
+		break;
+
+	case DDI_SUSPEND:
+		return (arn_suspend(sc));
+
+	default:
+		return (DDI_FAILURE);
+	}
+
+	if (mac_disable(sc->sc_isc.ic_mach) != 0)
+		return (DDI_FAILURE);
+
+	arn_stop_scantimer(sc);
+	arn_stop_caltimer(sc);
+
+	/* disable interrupts */
+	(void) ath9k_hw_set_interrupts(sc->sc_ah, 0);
+
+	/*
+	 * Unregister from the MAC layer subsystem
+	 */
+	(void) mac_unregister(sc->sc_isc.ic_mach);
+
+	/* free intterrupt resources */
+	ddi_remove_intr(devinfo, 0, sc->sc_iblock);
+	ddi_remove_softintr(sc->sc_softint_id);
+
+	/*
+	 * NB: the order of these is important:
+	 * o call the 802.11 layer before detaching the hal to
+	 *   insure callbacks into the driver to delete global
+	 *   key cache entries can be handled
+	 * o reclaim the tx queue data structures after calling
+	 *   the 802.11 layer as we'll get called back to reclaim
+	 *   node state and potentially want to use them
+	 * o to cleanup the tx queues the hal is called, so detach
+	 *   it last
+	 */
+	ieee80211_detach(&sc->sc_isc);
+
+	arn_desc_free(sc);
+
+	ddi_taskq_destroy(sc->sc_tq);
+
+	if (!(sc->sc_flags & SC_OP_INVALID))
+		(void) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+
+	/* cleanup tx queues */
+	mutex_destroy(&sc->sc_txbuflock);
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ARN_TXQ_SETUP(sc, i)) {
+			arn_tx_cleanupq(sc, &sc->sc_txq[i]);
+			mutex_destroy(&((&sc->sc_txq[i])->axq_lock));
+		}
+	}
+
+	ath9k_hw_detach(sc->sc_ah);
+
+	/* free io handle */
+	ddi_regs_map_free(&sc->sc_io_handle);
+	pci_config_teardown(&sc->sc_cfg_handle);
+
+	/* destroy locks */
+	mutex_destroy(&sc->sc_genlock);
+	mutex_destroy(&sc->sc_serial_rw);
+	mutex_destroy(&sc->sc_rxbuflock);
+	mutex_destroy(&sc->sc_resched_lock);
+#ifdef ARN_IBSS
+	mutex_destroy(&sc->sc_bcbuflock);
+#endif
+
+	ddi_remove_minor_node(devinfo, NULL);
+	ddi_soft_state_free(arn_soft_state_p, ddi_get_instance(devinfo));
+
+	return (DDI_SUCCESS);
+}
+
+/*
+ * quiesce(9E) entry point.
+ *
+ * This function is called when the system is single-threaded at high
+ * PIL with preemption disabled. Therefore, this function must not be
+ * blocked.
+ *
+ * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
+ * DDI_FAILURE indicates an error condition and should almost never happen.
+ */
+static int32_t
+arn_quiesce(dev_info_t *devinfo)
+{
+	struct arn_softc *sc;
+	int i;
+	struct ath_hal *ah;
+
+	sc = ddi_get_soft_state(arn_soft_state_p, ddi_get_instance(devinfo));
+
+	if (sc == NULL || (ah = sc->sc_ah) == NULL)
+		return (DDI_FAILURE);
+
+	/*
+	 * Disable interrupts
+	 */
+	(void) ath9k_hw_set_interrupts(ah, 0);
+
+	/*
+	 * Disable TX HW
+	 */
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ARN_TXQ_SETUP(sc, i))
+			(void) ath9k_hw_stoptxdma(ah, sc->sc_txq[i].axq_qnum);
+	}
+
+	/*
+	 * Disable RX HW
+	 */
+	ath9k_hw_stoppcurecv(ah);
+	ath9k_hw_setrxfilter(ah, 0);
+	(void) ath9k_hw_stopdmarecv(ah);
+	drv_usecwait(3000);
+
+	/*
+	 * Power down HW
+	 */
+	(void) ath9k_hw_phy_disable(ah);
+
+	return (DDI_SUCCESS);
+}
+
+DDI_DEFINE_STREAM_OPS(arn_dev_ops, nulldev, nulldev, arn_attach, arn_detach,
+    nodev, NULL, D_MP, NULL, arn_quiesce);
+
+static struct modldrv arn_modldrv = {
+	&mod_driverops, /* Type of module.  This one is a driver */
+	"arn-Atheros 9000 series driver:vertion 1.1", /* short description */
+	&arn_dev_ops /* driver specific ops */
+};
+
+static struct modlinkage modlinkage = {
+	MODREV_1, (void *)&arn_modldrv, NULL
+};
+
+int
+_info(struct modinfo *modinfop)
+{
+	return (mod_info(&modlinkage, modinfop));
+}
+
+int
+_init(void)
+{
+	int status;
+
+	status = ddi_soft_state_init
+	    (&arn_soft_state_p, sizeof (struct arn_softc), 1);
+	if (status != 0)
+		return (status);
+
+	mutex_init(&arn_loglock, NULL, MUTEX_DRIVER, NULL);
+	mac_init_ops(&arn_dev_ops, "arn");
+	status = mod_install(&modlinkage);
+	if (status != 0) {
+		mac_fini_ops(&arn_dev_ops);
+		mutex_destroy(&arn_loglock);
+		ddi_soft_state_fini(&arn_soft_state_p);
+	}
+
+	return (status);
+}
+
+int
+_fini(void)
+{
+	int status;
+
+	status = mod_remove(&modlinkage);
+	if (status == 0) {
+		mac_fini_ops(&arn_dev_ops);
+		mutex_destroy(&arn_loglock);
+		ddi_soft_state_fini(&arn_soft_state_p);
+	}
+	return (status);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_phy.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "arn_core.h"
+#include "arn_hw.h"
+#include "arn_reg.h"
+#include "arn_phy.h"
+
+/* ARGSUSED */
+void
+ath9k_hw_write_regs(struct ath_hal *ah, uint32_t modesIndex, uint32_t freqIndex,
+		    int regWrites)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	/* LINTED: E_CONSTANT_CONDITION */
+	REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
+}
+
+boolean_t
+ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	uint32_t channelSel = 0;
+	uint32_t bModeSynth = 0;
+	uint32_t aModeRefSel = 0;
+	uint32_t reg32 = 0;
+	uint16_t freq;
+	struct chan_centers centers;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	if (freq < 4800) {
+		uint32_t txctl;
+
+		if (((freq - 2192) % 5) == 0) {
+			channelSel = ((freq - 672) * 2 - 3040) / 10;
+			bModeSynth = 0;
+		} else if (((freq - 2224) % 5) == 0) {
+			channelSel = ((freq - 704) * 2 - 3040) / 10;
+			bModeSynth = 1;
+		} else {
+			arn_problem("%s: invalid channel %u MHz\n",
+			    __func__, freq);
+			return (B_FALSE);
+		}
+
+		channelSel = (channelSel << 2) & 0xff;
+		channelSel = ath9k_hw_reverse_bits(channelSel, 8);
+
+		txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+		if (freq == 2484) {
+
+			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+			    txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+		} else {
+			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+			    txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+		}
+
+	} else if ((freq % 20) == 0 && freq >= 5120) {
+		channelSel =
+		    ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
+		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else if ((freq % 10) == 0) {
+		channelSel =
+		    ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
+		if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
+			aModeRefSel = ath9k_hw_reverse_bits(2, 2);
+		else
+			aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else if ((freq % 5) == 0) {
+		channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
+		aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+	} else {
+		arn_problem("%s: invalid channel %u MHz\n", __func__, freq);
+		return (B_FALSE);
+	}
+
+	reg32 =
+	    (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
+	    (1 << 5) | 0x1;
+
+	REG_WRITE(ah, AR_PHY(0x37), reg32);
+
+	ah->ah_curchan = chan;
+
+	AH5416(ah)->ah_curchanRadIndex = -1;
+
+	return (B_TRUE);
+}
+
+boolean_t
+ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
+    struct ath9k_channel *chan)
+{
+	uint16_t bMode, fracMode, aModeRefSel = 0;
+	uint32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
+	struct chan_centers centers;
+	uint32_t refDivA = 24;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+	freq = centers.synth_center;
+
+	reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
+	reg32 &= 0xc0000000;
+
+	if (freq < 4800) {
+		uint32_t txctl;
+
+		bMode = 1;
+		fracMode = 1;
+		aModeRefSel = 0;
+		channelSel = (freq * 0x10000) / 15;
+
+		txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+		if (freq == 2484) {
+
+			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+			    txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+		} else {
+			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+			    txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+		}
+	} else {
+		bMode = 0;
+		fracMode = 0;
+
+		if ((freq % 20) == 0) {
+			aModeRefSel = 3;
+		} else if ((freq % 10) == 0) {
+			aModeRefSel = 2;
+		} else {
+			aModeRefSel = 0;
+
+			fracMode = 1;
+			refDivA = 1;
+			channelSel = (freq * 0x8000) / 15;
+
+			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
+			    AR_AN_SYNTH9_REFDIVA, refDivA);
+		}
+		if (!fracMode) {
+			ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
+			channelSel = ndiv & 0x1ff;
+			channelFrac = (ndiv & 0xfffffe00) * 2;
+			channelSel = (channelSel << 17) | channelFrac;
+		}
+	}
+
+	reg32 = reg32 |
+	    (bMode << 29) |
+	    (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
+
+	REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
+
+	ah->ah_curchan = chan;
+
+	AH5416(ah)->ah_curchanRadIndex = -1;
+
+	return (B_TRUE);
+}
+
+static void
+ath9k_phy_modify_rx_buffer(uint32_t *rfBuf, uint32_t reg32,
+    uint32_t numBits, uint32_t firstBit, uint32_t column)
+{
+	uint32_t tmp32, mask, arrayEntry, lastBit;
+	int32_t bitPosition, bitsLeft;
+
+	tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
+	arrayEntry = (firstBit - 1) / 8;
+	bitPosition = (firstBit - 1) % 8;
+	bitsLeft = numBits;
+	while (bitsLeft > 0) {
+		lastBit = (bitPosition + bitsLeft > 8) ?
+		    8 : bitPosition + bitsLeft;
+		mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
+		    (column * 8);
+		rfBuf[arrayEntry] &= ~mask;
+		rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
+		    (column * 8)) & mask;
+		bitsLeft -= 8 - bitPosition;
+		tmp32 = tmp32 >> (8 - bitPosition);
+		bitPosition = 0;
+		arrayEntry++;
+	}
+}
+
+boolean_t
+ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+    uint16_t modesIndex)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	uint32_t eepMinorRev;
+	uint32_t ob5GHz = 0, db5GHz = 0;
+	uint32_t ob2GHz = 0, db2GHz = 0;
+	/* LINTED E_FUNC_SET_NOT_USED */
+	int regWrites = 0;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		return (B_TRUE);
+
+	eepMinorRev = ath9k_hw_get_eeprom(ah, EEP_MINOR_REV);
+
+	RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
+
+	RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1);
+
+	RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1);
+
+	RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3,
+	    modesIndex);
+	{
+		int i;
+		for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) {
+			ahp->ah_analogBank6Data[i] =
+			    INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex);
+		}
+	}
+
+	if (eepMinorRev >= 2) {
+		if (IS_CHAN_2GHZ(chan)) {
+			ob2GHz = ath9k_hw_get_eeprom(ah, EEP_OB_2);
+			db2GHz = ath9k_hw_get_eeprom(ah, EEP_DB_2);
+			ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+			    ob2GHz, 3, 197, 0);
+			ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+			    db2GHz, 3, 194, 0);
+		} else {
+			ob5GHz = ath9k_hw_get_eeprom(ah, EEP_OB_5);
+			db5GHz = ath9k_hw_get_eeprom(ah, EEP_DB_5);
+			ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+			    ob5GHz, 3, 203, 0);
+			ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+			    db5GHz, 3, 200, 0);
+		}
+	}
+
+	RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1);
+
+	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data,
+	    regWrites);
+
+	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data,
+	    regWrites);
+
+	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data,
+	    regWrites);
+
+	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data,
+	    regWrites);
+
+	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data,
+	    regWrites);
+
+	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data,
+	    regWrites);
+
+	return (B_TRUE);
+}
+
+void
+ath9k_hw_rfdetach(struct ath_hal *ah)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (ahp->ah_analogBank0Data != NULL) {
+		kmem_free(ahp->ah_analogBank0Data,
+		    (sizeof (uint32_t) * ahp->ah_iniBank0.ia_rows));
+		ahp->ah_analogBank0Data = NULL;
+	}
+	if (ahp->ah_analogBank1Data != NULL) {
+		kmem_free(ahp->ah_analogBank1Data,
+		    (sizeof (uint32_t) * ahp->ah_iniBank1.ia_rows));
+		ahp->ah_analogBank1Data = NULL;
+	}
+	if (ahp->ah_analogBank2Data != NULL) {
+		kmem_free(ahp->ah_analogBank2Data,
+		    (sizeof (uint32_t) * ahp->ah_iniBank2.ia_rows));
+		ahp->ah_analogBank2Data = NULL;
+	}
+	if (ahp->ah_analogBank3Data != NULL) {
+		kmem_free(ahp->ah_analogBank3Data,
+		    (sizeof (uint32_t) * ahp->ah_iniBank3.ia_rows));
+		ahp->ah_analogBank3Data = NULL;
+	}
+	if (ahp->ah_analogBank6Data != NULL) {
+		kmem_free(ahp->ah_analogBank6Data,
+		    (sizeof (uint32_t) * ahp->ah_iniBank6.ia_rows));
+		ahp->ah_analogBank6Data = NULL;
+	}
+	if (ahp->ah_analogBank6TPCData != NULL) {
+		kmem_free(ahp->ah_analogBank6TPCData,
+		    (sizeof (uint32_t) * ahp->ah_iniBank6TPC.ia_rows));
+		ahp->ah_analogBank6TPCData = NULL;
+	}
+	if (ahp->ah_analogBank7Data != NULL) {
+		kmem_free(ahp->ah_analogBank7Data,
+		    (sizeof (uint32_t) * ahp->ah_iniBank7.ia_rows));
+		ahp->ah_analogBank7Data = NULL;
+	}
+	if (ahp->ah_addac5416_21 != NULL) {
+		kmem_free(ahp->ah_addac5416_21,
+		    (sizeof (uint32_t) * ahp->ah_iniAddac.ia_rows *
+		    ahp->ah_iniAddac.ia_columns));
+		ahp->ah_addac5416_21 = NULL;
+	}
+	if (ahp->ah_bank6Temp != NULL) {
+		kmem_free(ahp->ah_bank6Temp,
+		    (sizeof (uint32_t) * ahp->ah_iniBank6.ia_rows));
+		ahp->ah_bank6Temp = NULL;
+	}
+}
+
+boolean_t
+ath9k_hw_init_rf(struct ath_hal *ah, int *status)
+{
+	struct ath_hal_5416 *ahp = AH5416(ah);
+
+	if (!AR_SREV_9280_10_OR_LATER(ah)) {
+
+		ahp->ah_analogBank0Data =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniBank0.ia_rows), KM_SLEEP);
+		ahp->ah_analogBank1Data =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniBank1.ia_rows), KM_SLEEP);
+		ahp->ah_analogBank2Data =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniBank2.ia_rows), KM_SLEEP);
+		ahp->ah_analogBank3Data =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniBank3.ia_rows), KM_SLEEP);
+		ahp->ah_analogBank6Data =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniBank6.ia_rows), KM_SLEEP);
+		ahp->ah_analogBank6TPCData =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniBank6TPC.ia_rows), KM_SLEEP);
+		ahp->ah_analogBank7Data =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniBank7.ia_rows), KM_SLEEP);
+
+		if (ahp->ah_analogBank0Data == NULL ||
+		    ahp->ah_analogBank1Data == NULL ||
+		    ahp->ah_analogBank2Data == NULL ||
+		    ahp->ah_analogBank3Data == NULL ||
+		    ahp->ah_analogBank6Data == NULL ||
+		    ahp->ah_analogBank6TPCData == NULL ||
+		    ahp->ah_analogBank7Data == NULL) {
+			ARN_DBG((ARN_DBG_FATAL, "arn: ath9k_hw_init_rf(): "
+			    "cannot allocate RF banks\n"));
+			*status = ENOMEM;
+			return (B_FALSE);
+		}
+
+		ahp->ah_addac5416_21 =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniAddac.ia_rows *
+		    ahp->ah_iniAddac.ia_columns), KM_SLEEP);
+		if (ahp->ah_addac5416_21 == NULL) {
+			ARN_DBG((ARN_DBG_FATAL, "arn: ath9k_hw_init_rf(): "
+			    "cannot allocate ah_addac5416_21\n"));
+			*status = ENOMEM;
+			return (B_FALSE);
+		}
+
+		ahp->ah_bank6Temp =
+		    kmem_zalloc((sizeof (uint32_t) *
+		    ahp->ah_iniBank6.ia_rows), KM_SLEEP);
+		if (ahp->ah_bank6Temp == NULL) {
+			ARN_DBG((ARN_DBG_FATAL, "arn: ath9k_hw_init_rf(): "
+			    "cannot allocate ah_bank6Temp\n"));
+			*status = ENOMEM;
+			return (B_FALSE);
+		}
+	}
+
+	return (B_TRUE);
+}
+
+/* ARGSUSED */
+void
+ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	/* LINTED E_FUNC_SET_NOT_USED */
+	int i, regWrites = 0;
+	struct ath_hal_5416 *ahp = AH5416(ah);
+	uint32_t bank6SelMask;
+	uint32_t *bank6Temp = ahp->ah_bank6Temp;
+
+	switch (ahp->ah_diversityControl) {
+	case ATH9K_ANT_FIXED_A:
+		bank6SelMask =
+		    (ahp-> ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
+		    REDUCE_CHAIN_1;
+		break;
+	case ATH9K_ANT_FIXED_B:
+		bank6SelMask =
+		    (ahp-> ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
+		    REDUCE_CHAIN_0;
+		break;
+	case ATH9K_ANT_VARIABLE:
+	default:
+		return;
+	}
+
+	for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++)
+		bank6Temp[i] = ahp->ah_analogBank6Data[i];
+
+	REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
+
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
+	ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
+
+	REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites);
+
+	REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
+#ifdef ALTER_SWITCH
+	REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
+	    (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
+	    | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_phy.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,555 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_ARN_PHY_H
+#define	_ARN_PHY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+boolean_t ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+boolean_t ath9k_hw_set_channel(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+void ath9k_hw_write_regs(struct ath_hal *ah, uint32_t modesIndex,
+    uint32_t freqIndex, int regWrites);
+boolean_t ath9k_hw_set_rf_regs(struct ath_hal *ah,
+    struct ath9k_channel *chan, uint16_t modesIndex);
+void ath9k_hw_decrease_chain_power(struct ath_hal *ah,
+    struct ath9k_channel *chan);
+boolean_t ath9k_hw_init_rf(struct ath_hal *ah, int *status);
+
+#define	AR_PHY_BASE	0x9800
+#define	AR_PHY(_n)	(AR_PHY_BASE + ((_n)<<2))
+
+#define	AR_PHY_TEST	0x9800
+#define	PHY_AGC_CLR	0x10000000
+#define	RFSILENT_BB	0x00002000
+
+#define	AR_PHY_TURBO			0x9804
+#define	AR_PHY_FC_TURBO_MODE		0x00000001
+#define	AR_PHY_FC_TURBO_SHORT		0x00000002
+#define	AR_PHY_FC_DYN2040_EN		0x00000004
+#define	AR_PHY_FC_DYN2040_PRI_ONLY	0x00000008
+#define	AR_PHY_FC_DYN2040_PRI_CH	0x00000010
+#define	AR_PHY_FC_DYN2040_EXT_CH	0x00000020
+#define	AR_PHY_FC_HT_EN			0x00000040
+#define	AR_PHY_FC_SHORT_GI_40		0x00000080
+#define	AR_PHY_FC_WALSH			0x00000100
+#define	AR_PHY_FC_SINGLE_HT_LTF1	0x00000200
+#define	AR_PHY_FC_ENABLE_DAC_FIFO	0x00000800
+#define	AR_PHY_TEST2	0x9808
+
+#define	AR_PHY_TIMING2			0x9810
+#define	AR_PHY_TIMING3			0x9814
+#define	AR_PHY_TIMING3_DSC_MAN		0xFFFE0000
+#define	AR_PHY_TIMING3_DSC_MAN_S	17
+#define	AR_PHY_TIMING3_DSC_EXP		0x0001E000
+#define	AR_PHY_TIMING3_DSC_EXP_S	13
+
+#define	AR_PHY_CHIP_ID			0x9818
+#define	AR_PHY_CHIP_ID_REV_0		0x80
+#define	AR_PHY_CHIP_ID_REV_1		0x81
+#define	AR_PHY_CHIP_ID_9160_REV_0	0xb0
+
+#define	AR_PHY_ACTIVE			0x981C
+#define	AR_PHY_ACTIVE_EN		0x00000001
+#define	AR_PHY_ACTIVE_DIS		0x00000000
+
+#define	AR_PHY_RF_CTL2			0x9824
+#define	AR_PHY_TX_END_DATA_START	0x000000FF
+#define	AR_PHY_TX_END_DATA_START_S	0
+#define	AR_PHY_TX_END_PA_ON		0x0000FF00
+#define	AR_PHY_TX_END_PA_ON_S		8
+
+#define	AR_PHY_RF_CTL3			0x9828
+#define	AR_PHY_TX_END_TO_A2_RX_ON	0x00FF0000
+#define	AR_PHY_TX_END_TO_A2_RX_ON_S	16
+
+#define	AR_PHY_ADC_CTL			0x982C
+#define	AR_PHY_ADC_CTL_OFF_INBUFGAIN	0x00000003
+#define	AR_PHY_ADC_CTL_OFF_INBUFGAIN_S	0
+#define	AR_PHY_ADC_CTL_OFF_PWDDAC	0x00002000
+#define	AR_PHY_ADC_CTL_OFF_PWDBANDGAP	0x00004000
+#define	AR_PHY_ADC_CTL_OFF_PWDADC	0x00008000
+#define	AR_PHY_ADC_CTL_ON_INBUFGAIN	0x00030000
+#define	AR_PHY_ADC_CTL_ON_INBUFGAIN_S	16
+
+#define	AR_PHY_ADC_SERIAL_CTL		0x9830
+#define	AR_PHY_SEL_INTERNAL_ADDAC	0x00000000
+#define	AR_PHY_SEL_EXTERNAL_RADIO	0x00000001
+
+#define	AR_PHY_RF_CTL4				0x9834
+#define	AR_PHY_RF_CTL4_TX_END_XPAB_OFF		0xFF000000
+#define	AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S	24
+#define	AR_PHY_RF_CTL4_TX_END_XPAA_OFF		0x00FF0000
+#define	AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S	16
+#define	AR_PHY_RF_CTL4_FRAME_XPAB_ON		0x0000FF00
+#define	AR_PHY_RF_CTL4_FRAME_XPAB_ON_S		8
+#define	AR_PHY_RF_CTL4_FRAME_XPAA_ON		0x000000FF
+#define	AR_PHY_RF_CTL4_FRAME_XPAA_ON_S		0
+#define	AR_PHY_TSTDAC_CONST	0x983c
+
+#define	AR_PHY_SETTLING			0x9844
+#define	AR_PHY_SETTLING_SWITCH		0x00003F80
+#define	AR_PHY_SETTLING_SWITCH_S	7
+
+#define	AR_PHY_RXGAIN			0x9848
+#define	AR_PHY_RXGAIN_TXRX_ATTEN	0x0003F000
+#define	AR_PHY_RXGAIN_TXRX_ATTEN_S	12
+#define	AR_PHY_RXGAIN_TXRX_RF_MAX	0x007C0000
+#define	AR_PHY_RXGAIN_TXRX_RF_MAX_S	18
+#define	AR9280_PHY_RXGAIN_TXRX_ATTEN	0x00003F80
+#define	AR9280_PHY_RXGAIN_TXRX_ATTEN_S	7
+#define	AR9280_PHY_RXGAIN_TXRX_MARGIN	0x001FC000
+#define	AR9280_PHY_RXGAIN_TXRX_MARGIN_S	14
+
+#define	AR_PHY_DESIRED_SZ		0x9850
+#define	AR_PHY_DESIRED_SZ_ADC		0x000000FF
+#define	AR_PHY_DESIRED_SZ_ADC_S		0
+#define	AR_PHY_DESIRED_SZ_PGA		0x0000FF00
+#define	AR_PHY_DESIRED_SZ_PGA_S		8
+#define	AR_PHY_DESIRED_SZ_TOT_DES	0x0FF00000
+#define	AR_PHY_DESIRED_SZ_TOT_DES_S	20
+
+#define	AR_PHY_FIND_SIG			0x9858
+#define	AR_PHY_FIND_SIG_FIRSTEP		0x0003F000
+#define	AR_PHY_FIND_SIG_FIRSTEP_S	12
+#define	AR_PHY_FIND_SIG_FIRPWR		0x03FC0000
+#define	AR_PHY_FIND_SIG_FIRPWR_S	18
+
+#define	AR_PHY_AGC_CTL1			0x985C
+#define	AR_PHY_AGC_CTL1_COARSE_LOW	0x00007F80
+#define	AR_PHY_AGC_CTL1_COARSE_LOW_S	7
+#define	AR_PHY_AGC_CTL1_COARSE_HIGH	0x003F8000
+#define	AR_PHY_AGC_CTL1_COARSE_HIGH_S	15
+
+#define	AR_PHY_AGC_CONTROL		0x9860
+#define	AR_PHY_AGC_CONTROL_CAL		0x00000001
+#define	AR_PHY_AGC_CONTROL_NF		0x00000002
+#define	AR_PHY_AGC_CONTROL_ENABLE_NF	0x00008000
+#define	AR_PHY_AGC_CONTROL_FLTR_CAL	0x00010000
+#define	AR_PHY_AGC_CONTROL_NO_UPDATE_NF	0x00020000
+
+#define	AR_PHY_CCA			0x9864
+#define	AR_PHY_MINCCA_PWR		0x0FF80000
+#define	AR_PHY_MINCCA_PWR_S		19
+#define	AR_PHY_CCA_THRESH62		0x0007F000
+#define	AR_PHY_CCA_THRESH62_S		12
+#define	AR9280_PHY_MINCCA_PWR		0x1FF00000
+#define	AR9280_PHY_MINCCA_PWR_S		20
+#define	AR9280_PHY_CCA_THRESH62		0x000FF000
+#define	AR9280_PHY_CCA_THRESH62_S	12
+
+#define	AR_PHY_SFCORR_LOW			0x986C
+#define	AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW	0x00000001
+#define	AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW	0x00003F00
+#define	AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S	8
+#define	AR_PHY_SFCORR_LOW_M1_THRESH_LOW		0x001FC000
+#define	AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S	14
+#define	AR_PHY_SFCORR_LOW_M2_THRESH_LOW		0x0FE00000
+#define	AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S	21
+
+#define	AR_PHY_SFCORR			0x9868
+#define	AR_PHY_SFCORR_M2COUNT_THR	0x0000001F
+#define	AR_PHY_SFCORR_M2COUNT_THR_S	0
+#define	AR_PHY_SFCORR_M1_THRESH		0x00FE0000
+#define	AR_PHY_SFCORR_M1_THRESH_S	17
+#define	AR_PHY_SFCORR_M2_THRESH		0x7F000000
+#define	AR_PHY_SFCORR_M2_THRESH_S	24
+
+#define	AR_PHY_SLEEP_CTR_CONTROL	0x9870
+#define	AR_PHY_SLEEP_CTR_LIMIT		0x9874
+#define	AR_PHY_SYNTH_CONTROL		0x9874
+#define	AR_PHY_SLEEP_SCAL		0x9878
+
+#define	AR_PHY_PLL_CTL			0x987c
+#define	AR_PHY_PLL_CTL_40		0xaa
+#define	AR_PHY_PLL_CTL_40_5413		0x04
+#define	AR_PHY_PLL_CTL_44		0xab
+#define	AR_PHY_PLL_CTL_44_2133		0xeb
+#define	AR_PHY_PLL_CTL_40_2133		0xea
+
+#define	AR_PHY_RX_DELAY			0x9914
+#define	AR_PHY_SEARCH_START_DELAY	0x9918
+#define	AR_PHY_RX_DELAY_DELAY		0x00003FFF
+
+#define	AR_PHY_TIMING_CTRL4(_i)	(0x9920 + ((_i) << 12))
+#define	AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF		0x01F
+#define	AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S		0
+#define	AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF		0x7E0
+#define	AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S		5
+#define	AR_PHY_TIMING_CTRL4_IQCORR_ENABLE		0x800
+#define	AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX		0xF000
+#define	AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S	12
+#define	AR_PHY_TIMING_CTRL4_DO_CAL			0x10000
+
+#define	AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI	0x80000000
+#define	AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER	0x40000000
+#define	AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK	0x20000000
+#define	AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK	0x10000000
+
+#define	AR_PHY_TIMING5			0x9924
+#define	AR_PHY_TIMING5_CYCPWR_THR1	0x000000FE
+#define	AR_PHY_TIMING5_CYCPWR_THR1_S	1
+
+#define	AR_PHY_POWER_TX_RATE1			0x9934
+#define	AR_PHY_POWER_TX_RATE2			0x9938
+#define	AR_PHY_POWER_TX_RATE_MAX		0x993c
+#define	AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE	0x00000040
+
+#define	AR_PHY_FRAME_CTL		0x9944
+#define	AR_PHY_FRAME_CTL_TX_CLIP	0x00000038
+#define	AR_PHY_FRAME_CTL_TX_CLIP_S	3
+
+#define	AR_PHY_TXPWRADJ				0x994C
+#define	AR_PHY_TXPWRADJ_CCK_GAIN_DELTA		0x00000FC0
+#define	AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S  	6
+#define	AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX		0x00FC0000
+#define	AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S	18
+
+#define	AR_PHY_RADAR_EXT	0x9940
+#define	AR_PHY_RADAR_EXT_ENA	0x00004000
+
+#define	AR_PHY_RADAR_0		0x9954
+#define	AR_PHY_RADAR_0_ENA	0x00000001
+#define	AR_PHY_RADAR_0_FFT_ENA	0x80000000
+#define	AR_PHY_RADAR_0_INBAND	0x0000003e
+#define	AR_PHY_RADAR_0_INBAND_S	1
+#define	AR_PHY_RADAR_0_PRSSI	0x00000FC0
+#define	AR_PHY_RADAR_0_PRSSI_S	6
+#define	AR_PHY_RADAR_0_HEIGHT	0x0003F000
+#define	AR_PHY_RADAR_0_HEIGHT_S	12
+#define	AR_PHY_RADAR_0_RRSSI	0x00FC0000
+#define	AR_PHY_RADAR_0_RRSSI_S	18
+#define	AR_PHY_RADAR_0_FIRPWR	0x7F000000
+#define	AR_PHY_RADAR_0_FIRPWR_S	24
+
+#define	AR_PHY_RADAR_1			0x9958
+#define	AR_PHY_RADAR_1_RELPWR_ENA	0x00800000
+#define	AR_PHY_RADAR_1_USE_FIR128	0x00400000
+#define	AR_PHY_RADAR_1_RELPWR_THRESH	0x003F0000
+#define	AR_PHY_RADAR_1_RELPWR_THRESH_S	16
+#define	AR_PHY_RADAR_1_BLOCK_CHECK	0x00008000
+#define	AR_PHY_RADAR_1_MAX_RRSSI	0x00004000
+#define	AR_PHY_RADAR_1_RELSTEP_CHECK	0x00002000
+#define	AR_PHY_RADAR_1_RELSTEP_THRESH	0x00001F00
+#define	AR_PHY_RADAR_1_RELSTEP_THRESH_S	8
+#define	AR_PHY_RADAR_1_MAXLEN		0x000000FF
+#define	AR_PHY_RADAR_1_MAXLEN_S		0
+
+#define	AR_PHY_SWITCH_CHAIN_0		0x9960
+#define	AR_PHY_SWITCH_COM		0x9964
+
+#define	AR_PHY_SIGMA_DELTA		0x996C
+#define	AR_PHY_SIGMA_DELTA_ADC_SEL	0x00000003
+#define	AR_PHY_SIGMA_DELTA_ADC_SEL_S	0
+#define	AR_PHY_SIGMA_DELTA_FILT2	0x000000F8
+#define	AR_PHY_SIGMA_DELTA_FILT2_S	3
+#define	AR_PHY_SIGMA_DELTA_FILT1	0x00001F00
+#define	AR_PHY_SIGMA_DELTA_FILT1_S	8
+#define	AR_PHY_SIGMA_DELTA_ADC_CLIP	0x01FFE000
+#define	AR_PHY_SIGMA_DELTA_ADC_CLIP_S	13
+
+#define	AR_PHY_RESTART			0x9970
+#define	AR_PHY_RESTART_DIV_GC		0x001C0000
+#define	AR_PHY_RESTART_DIV_GC_S		18
+
+#define	AR_PHY_RFBUS_REQ		0x997C
+#define	AR_PHY_RFBUS_REQ_EN		0x00000001
+
+#define	AR_PHY_TIMING7			0x9980
+#define	AR_PHY_TIMING8			0x9984
+#define	AR_PHY_TIMING8_PILOT_MASK_2	0x000FFFFF
+#define	AR_PHY_TIMING8_PILOT_MASK_2_S	0
+
+#define	AR_PHY_BIN_MASK2_1	0x9988
+#define	AR_PHY_BIN_MASK2_2	0x998c
+#define	AR_PHY_BIN_MASK2_3	0x9990
+#define	AR_PHY_BIN_MASK2_4	0x9994
+
+#define	AR_PHY_BIN_MASK_1	0x9900
+#define	AR_PHY_BIN_MASK_2	0x9904
+#define	AR_PHY_BIN_MASK_3	0x9908
+
+#define	AR_PHY_MASK_CTL		0x990c
+
+#define	AR_PHY_BIN_MASK2_4_MASK_4	0x00003FFF
+#define	AR_PHY_BIN_MASK2_4_MASK_4_S	0
+
+#define	AR_PHY_TIMING9			0x9998
+#define	AR_PHY_TIMING10			0x999c
+#define	AR_PHY_TIMING10_PILOT_MASK_2	0x000FFFFF
+#define	AR_PHY_TIMING10_PILOT_MASK_2_S	0
+
+#define	AR_PHY_TIMING11				0x99a0
+#define	AR_PHY_TIMING11_SPUR_DELTA_PHASE	0x000FFFFF
+#define	AR_PHY_TIMING11_SPUR_DELTA_PHASE_S	0
+#define	AR_PHY_TIMING11_SPUR_FREQ_SD		0x3FF00000
+#define	AR_PHY_TIMING11_SPUR_FREQ_SD_S		20
+#define	AR_PHY_TIMING11_USE_SPUR_IN_AGC		0x40000000
+#define	AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR	0x80000000
+
+#define	AR_PHY_RX_CHAINMASK			0x99a4
+#define	AR_PHY_NEW_ADC_DC_GAIN_CORR(_i)		(0x99b4 + ((_i) << 12))
+#define	AR_PHY_NEW_ADC_GAIN_CORR_ENABLE		0x40000000
+#define	AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE	0x80000000
+#define	AR_PHY_MULTICHAIN_GAIN_CTL  0x99ac
+
+#define	AR_PHY_EXT_CCA0			0x99b8
+#define	AR_PHY_EXT_CCA0_THRESH62	0x000000FF
+#define	AR_PHY_EXT_CCA0_THRESH62_S	0
+
+#define	AR_PHY_EXT_CCA			0x99bc
+#define	AR_PHY_EXT_CCA_CYCPWR_THR1	0x0000FE00
+#define	AR_PHY_EXT_CCA_CYCPWR_THR1_S	9
+#define	AR_PHY_EXT_CCA_THRESH62		0x007F0000
+#define	AR_PHY_EXT_CCA_THRESH62_S	16
+#define	AR_PHY_EXT_MINCCA_PWR		0xFF800000
+#define	AR_PHY_EXT_MINCCA_PWR_S		23
+#define	AR9280_PHY_EXT_MINCCA_PWR	0x01FF0000
+#define	AR9280_PHY_EXT_MINCCA_PWR_S	16
+
+#define	AR_PHY_SFCORR_EXT			0x99c0
+#define	AR_PHY_SFCORR_EXT_M1_THRESH		0x0000007F
+#define	AR_PHY_SFCORR_EXT_M1_THRESH_S		0
+#define	AR_PHY_SFCORR_EXT_M2_THRESH		0x00003F80
+#define	AR_PHY_SFCORR_EXT_M2_THRESH_S		7
+#define	AR_PHY_SFCORR_EXT_M1_THRESH_LOW		0x001FC000
+#define	AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S	14
+#define	AR_PHY_SFCORR_EXT_M2_THRESH_LOW		0x0FE00000
+#define	AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S	21
+#define	AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S		28
+
+#define	AR_PHY_HALFGI		0x99D0
+#define	AR_PHY_HALFGI_DSC_MAN	0x0007FFF0
+#define	AR_PHY_HALFGI_DSC_MAN_S	4
+#define	AR_PHY_HALFGI_DSC_EXP	0x0000000F
+#define	AR_PHY_HALFGI_DSC_EXP_S	0
+
+#define	AR_PHY_CHAN_INFO_MEMORY			0x99DC
+#define	AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK	0x0001
+
+#define	AR_PHY_HEAVY_CLIP_ENABLE	0x99E0
+
+#define	AR_PHY_M_SLEEP		0x99f0
+#define	AR_PHY_REFCLKDLY	0x99f4
+#define	AR_PHY_REFCLKPD		0x99f8
+
+#define	AR_PHY_CALMODE		0x99f0
+
+#define	AR_PHY_CALMODE_IQ		0x00000000
+#define	AR_PHY_CALMODE_ADC_GAIN		0x00000001
+#define	AR_PHY_CALMODE_ADC_DC_PER	0x00000002
+#define	AR_PHY_CALMODE_ADC_DC_INIT	0x00000003
+
+#define	AR_PHY_CAL_MEAS_0(_i)	(0x9c10 + ((_i) << 12))
+#define	AR_PHY_CAL_MEAS_1(_i)	(0x9c14 + ((_i) << 12))
+#define	AR_PHY_CAL_MEAS_2(_i)	(0x9c18 + ((_i) << 12))
+#define	AR_PHY_CAL_MEAS_3(_i)	(0x9c1c + ((_i) << 12))
+
+#define	AR_PHY_CURRENT_RSSI	0x9c1c
+#define	AR9280_PHY_CURRENT_RSSI	0x9c3c
+
+#define	AR_PHY_RFBUS_GRANT	0x9C20
+#define	AR_PHY_RFBUS_GRANT_EN	0x00000001
+
+#define	AR_PHY_CHAN_INFO_GAIN_DIFF		0x9CF4
+#define	AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT	320
+
+#define	AR_PHY_CHAN_INFO_GAIN	0x9CFC
+
+#define	AR_PHY_MODE		0xA200
+#define	AR_PHY_MODE_AR2133	0x08
+#define	AR_PHY_MODE_AR5111	0x00
+#define	AR_PHY_MODE_AR5112	0x08
+#define	AR_PHY_MODE_DYNAMIC	0x04
+#define	AR_PHY_MODE_RF2GHZ	0x02
+#define	AR_PHY_MODE_RF5GHZ	0x00
+#define	AR_PHY_MODE_CCK		0x01
+#define	AR_PHY_MODE_OFDM	0x00
+#define	AR_PHY_MODE_DYN_CCK_DISABLE	0x100
+
+#define	AR_PHY_CCK_TX_CTRL		0xA204
+#define	AR_PHY_CCK_TX_CTRL_JAPAN	0x00000010
+
+#define	AR_PHY_CCK_DETECT			0xA208
+#define	AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK	0x0000003F
+#define	AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S	0
+/* [12:6] settling time for antenna switch */
+#define	AR_PHY_CCK_DETECT_ANT_SWITCH_TIME		0x00001FC0
+#define	AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S		6
+#define	AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV	0x2000
+
+#define	AR_PHY_GAIN_2GHZ		0xA20C
+#define	AR_PHY_GAIN_2GHZ_RXTX_MARGIN	0x00FC0000
+#define	AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S	18
+#define	AR_PHY_GAIN_2GHZ_BSW_MARGIN	0x00003C00
+#define	AR_PHY_GAIN_2GHZ_BSW_MARGIN_S	10
+#define	AR_PHY_GAIN_2GHZ_BSW_ATTEN	0x0000001F
+#define	AR_PHY_GAIN_2GHZ_BSW_ATTEN_S	0
+
+#define	AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN		0x003E0000
+#define	AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S	17
+#define	AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN		0x0001F000
+#define	AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S	12
+#define	AR_PHY_GAIN_2GHZ_XATTEN2_DB		0x00000FC0
+#define	AR_PHY_GAIN_2GHZ_XATTEN2_DB_S		6
+#define	AR_PHY_GAIN_2GHZ_XATTEN1_DB		0x0000003F
+#define	AR_PHY_GAIN_2GHZ_XATTEN1_DB_S		0
+
+#define	AR_PHY_CCK_RXCTRL4			0xA21C
+#define	AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT	0x01F80000
+#define	AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S	19
+
+#define	AR_PHY_DAG_CTRLCCK		0xA228
+#define	AR_PHY_DAG_CTRLCCK_EN_RSSI_THR	0x00000200
+#define	AR_PHY_DAG_CTRLCCK_RSSI_THR	0x0001FC00
+#define	AR_PHY_DAG_CTRLCCK_RSSI_THR_S	10
+
+#define	AR_PHY_FORCE_CLKEN_CCK		0xA22C
+#define	AR_PHY_FORCE_CLKEN_CCK_MRC_MUX	0x00000040
+
+#define	AR_PHY_POWER_TX_RATE3	0xA234
+#define	AR_PHY_POWER_TX_RATE4	0xA238
+
+#define	AR_PHY_SCRM_SEQ_XR		0xA23C
+#define	AR_PHY_HEADER_DETECT_XR		0xA240
+#define	AR_PHY_CHIRP_DETECTED_XR	0xA244
+#define	AR_PHY_BLUETOOTH		0xA254
+
+#define	AR_PHY_TPCRG1			0xA258
+#define	AR_PHY_TPCRG1_NUM_PD_GAIN	0x0000c000
+#define	AR_PHY_TPCRG1_NUM_PD_GAIN_S	14
+
+#define	AR_PHY_TPCRG1_PD_GAIN_1		0x00030000
+#define	AR_PHY_TPCRG1_PD_GAIN_1_S	16
+#define	AR_PHY_TPCRG1_PD_GAIN_2		0x000C0000
+#define	AR_PHY_TPCRG1_PD_GAIN_2_S	18
+#define	AR_PHY_TPCRG1_PD_GAIN_3		0x00300000
+#define	AR_PHY_TPCRG1_PD_GAIN_3_S	20
+
+#define	AR_PHY_VIT_MASK2_M_46_61	0xa3a0
+#define	AR_PHY_MASK2_M_31_45		0xa3a4
+#define	AR_PHY_MASK2_M_16_30		0xa3a8
+#define	AR_PHY_MASK2_M_00_15		0xa3ac
+#define	AR_PHY_MASK2_P_15_01		0xa3b8
+#define	AR_PHY_MASK2_P_30_16		0xa3bc
+#define	AR_PHY_MASK2_P_45_31		0xa3c0
+#define	AR_PHY_MASK2_P_61_45		0xa3c4
+#define	AR_PHY_SPUR_REG			0x994c
+
+#define	AR_PHY_SPUR_REG_MASK_RATE_CNTL		(0xFF << 18)
+#define	AR_PHY_SPUR_REG_MASK_RATE_CNTL_S	18
+
+#define	AR_PHY_SPUR_REG_ENABLE_MASK_PPM		0x20000
+#define	AR_PHY_SPUR_REG_MASK_RATE_SELECT	(0xFF << 9)
+#define	AR_PHY_SPUR_REG_MASK_RATE_SELECT_S	9
+#define	AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI	0x100
+#define	AR_PHY_SPUR_REG_SPUR_RSSI_THRESH	0x7F
+#define	AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S	0
+
+#define	AR_PHY_PILOT_MASK_01_30		0xa3b0
+#define	AR_PHY_PILOT_MASK_31_60		0xa3b4
+
+#define	AR_PHY_CHANNEL_MASK_01_30	0x99d4
+#define	AR_PHY_CHANNEL_MASK_31_60	0x99d8
+
+#define	AR_PHY_ANALOG_SWAP		0xa268
+#define	AR_PHY_SWAP_ALT_CHAIN		0x00000040
+
+#define	AR_PHY_TPCRG5	0xA26C
+#define	AR_PHY_TPCRG5_PD_GAIN_OVERLAP		0x0000000F
+#define	AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S		0
+#define	AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1	0x000003F0
+#define	AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S	4
+#define	AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2	0x0000FC00
+#define	AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S	10
+#define	AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3	0x003F0000
+#define	AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S	16
+#define	AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4	0x0FC00000
+#define	AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S	22
+
+#define	AR_PHY_POWER_TX_RATE5	0xA38C
+#define	AR_PHY_POWER_TX_RATE6	0xA390
+
+#define	AR_PHY_CAL_CHAINMASK	0xA39C
+
+#define	AR_PHY_POWER_TX_SUB	0xA3C8
+#define	AR_PHY_POWER_TX_RATE7	0xA3CC
+#define	AR_PHY_POWER_TX_RATE8	0xA3D0
+#define	AR_PHY_POWER_TX_RATE9	0xA3D4
+
+#define	AR_PHY_XPA_CFG		0xA3D8
+#define	AR_PHY_FORCE_XPA_CFG	0x000000001
+#define	AR_PHY_FORCE_XPA_CFG_S	0
+
+#define	AR_PHY_CH1_CCA			0xa864
+#define	AR_PHY_CH1_MINCCA_PWR		0x0FF80000
+#define	AR_PHY_CH1_MINCCA_PWR_S		19
+#define	AR9280_PHY_CH1_MINCCA_PWR	0x1FF00000
+#define	AR9280_PHY_CH1_MINCCA_PWR_S	20
+
+#define	AR_PHY_CH2_CCA		0xb864
+#define	AR_PHY_CH2_MINCCA_PWR	0x0FF80000
+#define	AR_PHY_CH2_MINCCA_PWR_S	19
+
+#define	AR_PHY_CH1_EXT_CCA		0xa9bc
+#define	AR_PHY_CH1_EXT_MINCCA_PWR	0xFF800000
+#define	AR_PHY_CH1_EXT_MINCCA_PWR_S	23
+#define	AR9280_PHY_CH1_EXT_MINCCA_PWR	0x01FF0000
+#define	AR9280_PHY_CH1_EXT_MINCCA_PWR_S	16
+
+#define	AR_PHY_CH2_EXT_CCA		0xb9bc
+#define	AR_PHY_CH2_EXT_MINCCA_PWR	0xFF800000
+#define	AR_PHY_CH2_EXT_MINCCA_PWR_S	23
+
+#define	REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do {               \
+		int r;							\
+		for (r = 0; r < ((iniarray)->ia_rows); r++) {		\
+			REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
+		}							\
+		_NOTE(CONSTCOND) \
+	} while (0)
+
+#define	ATH9K_KEY_XOR	0xaau
+
+#define	ATH9K_IS_MIC_ENABLED(ah)					\
+	(AH5416(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
+
+#define	ANTSWAP_AB	0x0001
+#define	REDUCE_CHAIN_0	0x00000050
+#define	REDUCE_CHAIN_1	0x00000051
+
+#define	RF_BANK_SETUP(_bank, _iniarray, _col) do {			\
+		int i;							\
+		for (i = 0; i < (_iniarray)->ia_rows; i++)		\
+			(_bank)[i] = INI_RA((_iniarray), i, _col);	\
+		_NOTE(CONSTCOND) \
+	} while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _ARN_PHY_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_rc.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,704 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2004 Video54 Technologies, Inc.
+ * Copyright (c) 2004-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ddi.h>
+
+#include "arn_core.h"
+
+static struct ath_rate_table ar5416_11na_ratetable = {
+	42,
+	{0},
+	{
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+			5400, 0x0b, 0x00, 12,
+			0, 2, 1, 0, 0, 0, 0, 0 },
+		{ VALID,	VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+			7800,  0x0f, 0x00, 18,
+			0, 3, 1, 1, 1, 1, 1, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+			10000, 0x0a, 0x00, 24,
+			2, 4, 2, 2, 2, 2, 2, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+			13900, 0x0e, 0x00, 36,
+			2, 6,  2, 3, 3, 3, 3, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+			17300, 0x09, 0x00, 48,
+			4, 10, 3, 4, 4, 4, 4, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+			23000, 0x0d, 0x00, 72,
+			4, 14, 3, 5, 5, 5, 5, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+			27400, 0x08, 0x00, 96,
+			4, 20, 3, 6, 6, 6, 6, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+			29300, 0x0c, 0x00, 108,
+			4, 23, 3, 7, 7, 7, 7, 0 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
+			6400, 0x80, 0x00, 0,
+			0, 2, 3, 8, 24, 8, 24, 3216 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
+			12700, 0x81, 0x00, 1,
+			2, 4, 3, 9, 25, 9, 25, 6434 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
+			18800, 0x82, 0x00, 2,
+			2, 6, 3, 10, 26, 10, 26, 9650 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
+			25000, 0x83, 0x00, 3,
+			4, 10, 3, 11, 27, 11, 27, 12868 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
+			36700, 0x84, 0x00, 4,
+			4, 14, 3, 12, 28, 12, 28, 19304 },
+		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
+			48100, 0x85, 0x00, 5,
+			4, 20, 3, 13, 29, 13, 29, 25740 },
+		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
+			53500, 0x86, 0x00, 6,
+			4, 23, 3, 14, 30, 14, 30,  28956 },
+		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
+			59000, 0x87, 0x00, 7,
+			4, 25, 3, 15, 31, 15, 32, 32180 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
+			12700, 0x88, 0x00,
+			8, 0, 2, 3, 16, 33, 16, 33, 6430 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
+			24800, 0x89, 0x00, 9,
+			2, 4, 3, 17, 34, 17, 34, 12860 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
+			36600, 0x8a, 0x00, 10,
+			2, 6, 3, 18, 35, 18, 35, 19300 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
+			48100, 0x8b, 0x00, 11,
+			4, 10, 3, 19, 36, 19, 36, 25736 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
+			69500, 0x8c, 0x00, 12,
+			4, 14, 3, 20, 37, 20, 37, 38600 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
+			89500, 0x8d, 0x00, 13,
+			4, 20, 3, 21, 38, 21, 38, 51472 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
+			98900, 0x8e, 0x00, 14,
+			4, 23, 3, 22, 39, 22, 39, 57890 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
+			108300, 0x8f, 0x00, 15,
+			4, 25, 3, 23, 40, 23, 41, 64320 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
+			13200, 0x80, 0x00, 0,
+			0, 2, 3, 8, 24, 24, 24, 6684 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
+			25900, 0x81, 0x00, 1,
+			2, 4, 3, 9, 25, 25, 25, 13368 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
+			38600, 0x82, 0x00, 2,
+			2, 6, 3, 10, 26, 26, 26, 20052 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
+			49800, 0x83, 0x00, 3,
+			4, 10, 3, 11, 27, 27, 27, 26738 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
+			72200, 0x84, 0x00, 4,
+			4, 14, 3, 12, 28, 28, 28, 40104 },
+		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
+			92900, 0x85, 0x00, 5,
+			4, 20, 3, 13, 29, 29, 29, 53476 },
+		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5Mb */
+			102700, 0x86, 0x00, 6,
+			4, 23, 3, 14, 30, 30, 30, 60156 },
+		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
+			112000, 0x87, 0x00, 7,
+			4, 25, 3, 15, 31, 32, 32, 66840 },
+		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI,
+			150000, /* 150Mb */
+			122000, 0x87, 0x00, 7,
+			4, 25, 3, 15, 31, 32, 32, 74200 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
+			25800, 0x88, 0x00, 8,
+			0, 2, 3, 16, 33, 33, 33, 13360 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
+			49800, 0x89, 0x00, 9,
+			2, 4, 3, 17, 34, 34, 34, 26720 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
+			71900, 0x8a, 0x00, 10,
+			2, 6, 3, 18, 35, 35, 35, 40080 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
+			92500, 0x8b, 0x00, 11,
+			4, 10, 3, 19, 36, 36, 36, 53440 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
+			130300, 0x8c, 0x00, 12,
+			4, 14, 3, 20, 37, 37, 37, 80160 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
+			162800, 0x8d, 0x00, 13,
+			4, 20, 3, 21, 38, 38, 38, 106880 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
+			178200, 0x8e, 0x00, 14,
+			4, 23, 3, 22, 39, 39, 39, 120240 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
+			192100, 0x8f, 0x00, 15,
+			4, 25, 3, 23, 40, 41, 41, 133600 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI,
+			300000, /* 300 Mb */
+			207000, 0x8f, 0x00, 15,
+			4, 25, 3, 23, 40, 41, 41, 148400 },
+	},
+	50,  /* probe interval */
+	50,  /* rssi reduce interval */
+	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
+};
+
+/*
+ * 4ms frame limit not used for NG mode.  The values filled
+ * for HT are the 64K max aggregate limit
+ */
+
+static struct ath_rate_table ar5416_11ng_ratetable = {
+	46,
+	{0},
+	{
+		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+			900, 0x1b, 0x00, 2,
+			0, 0, 1, 0, 0, 0, 0, 0 },
+		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+			1900, 0x1a, 0x04, 4,
+			1, 1, 1, 1, 1, 1, 1, 0 },
+		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+			4900, 0x19, 0x04, 11,
+			2, 2, 2, 2, 2, 2, 2, 0 },
+		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+			8100, 0x18, 0x04, 22,
+			3, 3, 2, 3, 3, 3, 3, 0 },
+		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+			5400, 0x0b, 0x00, 12,
+			4, 2, 1, 4, 4, 4, 4, 0 },
+		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+			7800, 0x0f, 0x00, 18,
+			4, 3, 1, 5, 5, 5, 5, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+			10100, 0x0a, 0x00, 24,
+			6, 4, 1, 6, 6, 6, 6, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+			14100,  0x0e, 0x00, 36,
+			6, 6, 2, 7, 7, 7, 7, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+			17700, 0x09, 0x00, 48,
+			8, 10, 3, 8, 8, 8, 8, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+			23700, 0x0d, 0x00, 72,
+			8, 14, 3, 9, 9, 9, 9, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+			27400, 0x08, 0x00, 96,
+			8, 20, 3, 10, 10, 10, 10, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+			30900, 0x0c, 0x00, 108,
+			8, 23, 3, 11, 11, 11, 11, 0 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
+			6400, 0x80, 0x00, 0,
+			4, 2, 3, 12, 28, 12, 28, 3216 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
+			12700, 0x81, 0x00, 1,
+			6, 4, 3, 13, 29, 13, 29, 6434 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
+			18800, 0x82, 0x00, 2,
+			6, 6, 3, 14, 30, 14, 30, 9650 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
+			25000, 0x83, 0x00, 3,
+			8, 10, 3, 15, 31, 15, 31, 12868 },
+		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
+			36700, 0x84, 0x00, 4,
+			8, 14, 3, 16, 32, 16, 32, 19304 },
+		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
+			48100, 0x85, 0x00, 5,
+			8, 20, 3, 17, 33, 17, 33, 25740 },
+		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
+			53500, 0x86, 0x00, 6,
+			8, 23, 3, 18, 34, 18, 34, 28956 },
+		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
+			59000, 0x87, 0x00, 7,
+			8, 25, 3, 19, 35, 19, 36, 32180 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
+			12700, 0x88, 0x00, 8,
+			4, 2, 3, 20, 37, 20, 37, 6430 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
+			24800, 0x89, 0x00, 9,
+			6, 4, 3, 21, 38, 21, 38, 12860 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
+			36600, 0x8a, 0x00, 10,
+			6, 6, 3, 22, 39, 22, 39, 19300 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
+			48100, 0x8b, 0x00, 11,
+			8, 10, 3, 23, 40, 23, 40, 25736 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
+			69500, 0x8c, 0x00, 12,
+			8, 14, 3, 24, 41, 24, 41, 38600 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
+			89500, 0x8d, 0x00, 13,
+			8, 20, 3, 25, 42, 25, 42, 51472 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
+			98900, 0x8e, 0x00, 14,
+			8, 23, 3, 26, 43, 26, 44, 57890 },
+		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
+			108300, 0x8f, 0x00, 15,
+			8, 25, 3, 27, 44, 27, 45, 64320 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
+			13200, 0x80, 0x00, 0,
+			8, 2, 3, 12, 28, 28, 28, 6684 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
+			25900, 0x81, 0x00, 1,
+			8, 4, 3, 13, 29, 29, 29, 13368 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
+			38600, 0x82, 0x00, 2,
+			8, 6, 3, 14, 30, 30, 30, 20052 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
+			49800, 0x83, 0x00, 3,
+			8, 10, 3, 15, 31, 31, 31, 26738 },
+		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
+			72200, 0x84, 0x00, 4,
+			8, 14, 3, 16, 32, 32, 32, 40104 },
+		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
+			92900, 0x85, 0x00, 5,
+			8, 20, 3, 17, 33, 33, 33, 53476 },
+		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS,
+			121500, /* 121.5 Mb */
+			102700, 0x86, 0x00, 6,
+			8, 23, 3, 18, 34, 34, 34, 60156 },
+		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
+			112000, 0x87, 0x00, 7,
+			8, 23, 3, 19, 35, 36, 36, 66840 },
+		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI,
+			150000, /* 150 Mb */
+			122000, 0x87, 0x00, 7,
+			8, 25, 3, 19, 35, 36, 36, 74200 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
+			25800, 0x88, 0x00, 8,
+			8, 2, 3, 20, 37, 37, 37, 13360 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
+			49800, 0x89, 0x00, 9,
+			8, 4, 3, 21, 38, 38, 38, 26720 },
+		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
+			71900, 0x8a, 0x00, 10,
+			8, 6, 3, 22, 39, 39, 39, 40080 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
+			92500, 0x8b, 0x00, 11,
+			8, 10, 3, 23, 40, 40, 40, 53440 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
+			130300, 0x8c, 0x00, 12,
+			8, 14, 3, 24, 41, 41, 41, 80160 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
+			162800, 0x8d, 0x00, 13,
+			8, 20, 3, 25, 42, 42, 42, 106880 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
+			178200, 0x8e, 0x00, 14,
+			8, 23, 3, 26, 43, 43, 43, 120240 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
+			192100, 0x8f, 0x00, 15,
+			8, 23, 3, 27, 44, 45, 45, 133600 },
+		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI,
+			300000, /* 300 Mb */
+			207000, 0x8f, 0x00, 15,
+			8, 25, 3, 27, 44, 45, 45, 148400 },
+		},
+	50,  /* probe interval */
+	50,  /* rssi reduce interval */
+	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
+};
+
+static struct ath_rate_table ar5416_11a_ratetable = {
+	8,
+	{0},
+	{
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+			5400, 0x0b, 0x00, (0x80|12),
+			0, 2, 1, 0, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+			7800, 0x0f, 0x00, 18,
+			0, 3, 1, 1, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+			10000, 0x0a, 0x00, (0x80|24),
+			2, 4, 2, 2, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+			13900, 0x0e, 0x00, 36,
+			2, 6, 2, 3, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+			17300, 0x09, 0x00, (0x80|48),
+			4, 10, 3, 4, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+			23000, 0x0d, 0x00, 72,
+			4, 14, 3, 5, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+			27400, 0x08, 0x00, 96,
+			4, 19, 3, 6, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+			29300, 0x0c, 0x00, 108,
+			4, 23, 3, 7, 0 },
+	},
+	50,  /* probe interval */
+	50,  /* rssi reduce interval */
+	0,   /* Phy rates allowed initially */
+};
+
+static struct ath_rate_table ar5416_11g_ratetable = {
+	12,
+	{0},
+	{
+		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+			900, 0x1b, 0x00, 2,
+			0, 0, 1, 0, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+			1900, 0x1a, 0x04, 4,
+			1, 1, 1, 1, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+			4900, 0x19, 0x04, 11,
+			2, 2, 2, 2, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+			8100, 0x18, 0x04, 22,
+			3, 3, 2, 3, 0 },
+		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+			5400, 0x0b, 0x00, 12,
+			4, 2, 1, 4, 0 },
+		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+			7800, 0x0f, 0x00, 18,
+			4, 3, 1, 5, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+			10000, 0x0a, 0x00, 24,
+			6, 4, 1, 6, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+			13900, 0x0e, 0x00, 36,
+			6, 6, 2, 7, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+			17300, 0x09, 0x00, 48,
+			8, 10, 3, 8, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+			23000, 0x0d, 0x00, 72,
+			8, 14, 3, 9, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+			27400, 0x08, 0x00, 96,
+			8, 19, 3, 10, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+			29300, 0x0c, 0x00, 108,
+			8, 23, 3, 11, 0 },
+	},
+	50,  /* probe interval */
+	50,  /* rssi reduce interval */
+	0,   /* Phy rates allowed initially */
+};
+
+static struct ath_rate_table ar5416_11b_ratetable = {
+	4,
+	{0},
+	{
+		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+			900, 0x1b,  0x00, (0x80|2),
+			0, 0, 1, 0, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+			1800, 0x1a, 0x04, (0x80|4),
+			1, 1, 1, 1, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+			4300, 0x19, 0x04, (0x80|11),
+			1, 2, 2, 2, 0 },
+		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+			7100, 0x18, 0x04, (0x80|22),
+			1, 4, 100, 3, 0 },
+	},
+	100, /* probe interval */
+	100, /* rssi reduce interval */
+	0,   /* Phy rates allowed initially */
+};
+
+static void
+arn_setup_rate_table(struct arn_softc *sc,
+    struct ath_rate_table *rate_table)
+{
+	int i;
+
+	for (i = 0; i < 256; i++)
+		rate_table->rateCodeToIndex[i] = (uint8_t)-1;
+
+	for (i = 0; i < rate_table->rate_cnt; i++) {
+		uint8_t code = rate_table->info[i].ratecode;
+		uint8_t cix = rate_table->info[i].ctrl_rate;
+		uint8_t sh = rate_table->info[i].short_preamble;
+
+		rate_table->rateCodeToIndex[code] = (int)i;
+		rate_table->rateCodeToIndex[code | sh] = (int)i;
+
+		rate_table->info[i].lpAckDuration =
+		    ath9k_hw_computetxtime(sc->sc_ah, rate_table,
+		    WLAN_CTRL_FRAME_SIZE,
+		    cix,
+		    B_FALSE);
+		rate_table->info[i].spAckDuration =
+		    ath9k_hw_computetxtime(sc->sc_ah, rate_table,
+		    WLAN_CTRL_FRAME_SIZE,
+		    cix,
+		    B_TRUE);
+	}
+}
+
+void
+arn_rate_attach(struct arn_softc *sc)
+{
+	sc->hw_rate_table[ATH9K_MODE_11B] =
+	    &ar5416_11b_ratetable;
+	sc->hw_rate_table[ATH9K_MODE_11A] =
+	    &ar5416_11a_ratetable;
+	sc->hw_rate_table[ATH9K_MODE_11G] =
+	    &ar5416_11g_ratetable;
+	sc->hw_rate_table[ATH9K_MODE_11NA_HT20] =
+	    &ar5416_11na_ratetable;
+	sc->hw_rate_table[ATH9K_MODE_11NG_HT20] =
+	    &ar5416_11ng_ratetable;
+	sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
+	    &ar5416_11na_ratetable;
+	sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
+	    &ar5416_11na_ratetable;
+	sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
+	    &ar5416_11ng_ratetable;
+	sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
+	    &ar5416_11ng_ratetable;
+
+	arn_setup_rate_table(sc, &ar5416_11b_ratetable);
+	arn_setup_rate_table(sc, &ar5416_11a_ratetable);
+	arn_setup_rate_table(sc, &ar5416_11g_ratetable);
+	arn_setup_rate_table(sc, &ar5416_11na_ratetable);
+	arn_setup_rate_table(sc, &ar5416_11ng_ratetable);
+}
+
+void
+arn_rate_update(struct arn_softc *sc, struct ieee80211_node *in, int32_t rate)
+{
+	struct ath_node *an = ATH_NODE(in);
+	const struct ath_rate_table *rt = sc->sc_currates;
+	uint8_t rix;
+
+	ASSERT(rt != NULL);
+
+	in->in_txrate = rate;
+
+	/* management/control frames always go at the lowest speed */
+	an->an_tx_mgtrate = rt->info[0].ratecode;
+	an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].short_preamble;
+
+	ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_update(): "
+	    "mgtrate=%d mgtratesp=%d\n",
+	    an->an_tx_mgtrate, an->an_tx_mgtratesp));
+
+	/*
+	 * Before associating a node has no rate set setup
+	 * so we can't calculate any transmit codes to use.
+	 * This is ok since we should never be sending anything
+	 * but management frames and those always go at the
+	 * lowest hardware rate.
+	 */
+	if (in->in_rates.ir_nrates == 0)
+		goto done;
+	an->an_tx_rix0 = sc->asc_rixmap[
+	    in->in_rates.ir_rates[rate] & IEEE80211_RATE_VAL];
+	an->an_tx_rate0 = rt->info[an->an_tx_rix0].ratecode;
+	an->an_tx_rate0sp = an->an_tx_rate0 |
+	    rt->info[an->an_tx_rix0].short_preamble;
+	if (sc->sc_mrretry) {
+		/*
+		 * Hardware supports multi-rate retry; setup two
+		 * step-down retry rates and make the lowest rate
+		 * be the ``last chance''.  We use 4, 2, 2, 2 tries
+		 * respectively (4 is set here, the rest are fixed
+		 * in the xmit routine).
+		 */
+		an->an_tx_try0 = 1 + 3;		/* 4 tries at rate 0 */
+		if (--rate >= 0) {
+			rix = sc->asc_rixmap[
+			    in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL];
+			an->an_tx_rate1 = rt->info[rix].ratecode;
+			an->an_tx_rate1sp = an->an_tx_rate1 |
+			    rt->info[rix].short_preamble;
+		} else {
+			an->an_tx_rate1 = an->an_tx_rate1sp = 0;
+		}
+		if (--rate >= 0) {
+			rix = sc->asc_rixmap[
+			    in->in_rates.ir_rates[rate]&IEEE80211_RATE_VAL];
+			an->an_tx_rate2 = rt->info[rix].ratecode;
+			an->an_tx_rate2sp = an->an_tx_rate2 |
+			    rt->info[rix].short_preamble;
+		} else {
+			an->an_tx_rate2 = an->an_tx_rate2sp = 0;
+		}
+		if (rate > 0) {
+			an->an_tx_rate3 = rt->info[0].ratecode;
+			an->an_tx_rate3sp =
+			    an->an_tx_mgtrate | rt->info[0].short_preamble;
+		} else {
+			an->an_tx_rate3 = an->an_tx_rate3sp = 0;
+		}
+	} else {
+		an->an_tx_try0 = ATH_TXMAXTRY;  /* max tries at rate 0 */
+		an->an_tx_rate1 = an->an_tx_rate1sp = 0;
+		an->an_tx_rate2 = an->an_tx_rate2sp = 0;
+		an->an_tx_rate3 = an->an_tx_rate3sp = 0;
+	}
+done:
+	an->an_tx_ok = an->an_tx_err = an->an_tx_retr = an->an_tx_upper = 0;
+}
+
+/*
+ * Set the starting transmit rate for a node.
+ */
+void
+arn_rate_ctl_start(struct arn_softc *sc, struct ieee80211_node *in)
+{
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	int32_t srate;
+
+	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
+		/*
+		 * No fixed rate is requested. For 11b start with
+		 * the highest negotiated rate; otherwise, for 11g
+		 * and 11a, we start "in the middle" at 24Mb or 36Mb.
+		 */
+		srate = in->in_rates.ir_nrates - 1;
+		if (sc->sc_curmode != IEEE80211_MODE_11B) {
+			/*
+			 * Scan the negotiated rate set to find the
+			 * closest rate.
+			 */
+			/* NB: the rate set is assumed sorted */
+			for (; srate >= 0 && IEEE80211_RATE(srate) > 72;
+			    srate--) {}
+		}
+	} else {
+		/*
+		 * A fixed rate is to be used; We know the rate is
+		 * there because the rate set is checked when the
+		 * station associates.
+		 */
+		/* NB: the rate set is assumed sorted */
+		srate = in->in_rates.ir_nrates - 1;
+		for (; srate >= 0 && IEEE80211_RATE(srate) != ic->ic_fixed_rate;
+		    srate--) {}
+	}
+
+	ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl_start(): "
+	    "srate=%d rate=%d\n", srate, IEEE80211_RATE(srate)));
+
+	arn_rate_update(sc, in, srate);
+}
+
+void
+arn_rate_cb(void *arg, struct ieee80211_node *in)
+{
+	arn_rate_update((struct arn_softc *)arg, in, 0);
+}
+
+/*
+ * Reset the rate control state for each 802.11 state transition.
+ */
+void
+arn_rate_ctl_reset(struct arn_softc *sc, enum ieee80211_state state)
+{
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ieee80211_node *in;
+
+	if (ic->ic_opmode == IEEE80211_M_STA) {
+		/*
+		 * Reset local xmit state; this is really only
+		 * meaningful when operating in station mode.
+		 */
+		in = (struct ieee80211_node *)ic->ic_bss;
+		if (state == IEEE80211_S_RUN) {
+			arn_rate_ctl_start(sc, in);
+		} else {
+			arn_rate_update(sc, in, 0);
+		}
+	} else {
+		/*
+		 * When operating as a station the node table holds
+		 * the AP's that were discovered during scanning.
+		 * For any other operating mode we want to reset the
+		 * tx rate state of each node.
+		 */
+		ieee80211_iterate_nodes(&ic->ic_sta, arn_rate_cb, sc);
+		arn_rate_update(sc, ic->ic_bss, 0);
+	}
+}
+
+/*
+ * Examine and potentially adjust the transmit rate.
+ */
+void
+arn_rate_ctl(void *arg, struct ieee80211_node *in)
+{
+	struct arn_softc *sc = arg;
+	struct ath_node *an = ATH_NODE(in);
+	struct ieee80211_rateset *rs = &in->in_rates;
+	int32_t mod = 0, nrate, enough;
+
+	/*
+	 * Rate control(very primitive version).
+	 */
+	sc->sc_stats.ast_rate_calls++;
+
+	enough = (an->an_tx_ok + an->an_tx_err >= 10);
+
+	/* no packet reached -> down */
+	if (an->an_tx_err > 0 && an->an_tx_ok == 0)
+		mod = -1;
+
+	/* all packets needs retry in average -> down */
+	if (enough && an->an_tx_ok < an->an_tx_retr)
+		mod = -1;
+
+	/* no error and less than 10% of packets needs retry -> up */
+	if (enough && an->an_tx_err == 0 && an->an_tx_ok > an->an_tx_retr * 10)
+		mod = 1;
+
+	nrate = in->in_txrate;
+	switch (mod) {
+	case 0:
+		if (enough && an->an_tx_upper > 0)
+			an->an_tx_upper--;
+		break;
+	case -1:
+		if (nrate > 0) {
+			nrate--;
+			sc->sc_stats.ast_rate_drop++;
+		}
+		an->an_tx_upper = 0;
+		break;
+	case 1:
+		if (++an->an_tx_upper < 10)
+			break;
+		an->an_tx_upper = 0;
+		if (nrate + 1 < rs->ir_nrates) {
+			nrate++;
+			sc->sc_stats.ast_rate_raise++;
+		}
+		break;
+	}
+
+	if (nrate != in->in_txrate) {
+		ARN_DBG((ARN_DBG_RATE, "arn: arn_rate_ctl(): %dM -> %dM "
+		    "(%d ok, %d err, %d retr)\n",
+		    (rs->ir_rates[in->in_txrate] & IEEE80211_RATE_VAL) / 2,
+		    (rs->ir_rates[nrate] & IEEE80211_RATE_VAL) / 2,
+		    an->an_tx_ok, an->an_tx_err, an->an_tx_retr));
+		arn_rate_update(sc, in, nrate);
+	} else if (enough)
+		an->an_tx_ok = an->an_tx_err = an->an_tx_retr = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_rc.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2004 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004 Video54 Technologies, Inc.
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_ARN_RC_H
+#define	_ARN_RC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "arn_ath9k.h"
+
+struct arn_softc;
+
+#define	ATH_RATE_MAX		30
+#define	RATE_TABLE_SIZE		64
+#define	MAX_TX_RATE_PHY		48
+
+/*
+ * VALID_ALL - valid for 20/40/Legacy,
+ * VALID - Legacy only,
+ * VALID_20 - HT 20 only,
+ * VALID_40 - HT 40 only
+ */
+
+#define	INVALID		0x0
+#define	VALID		0x1
+#define	VALID_20	0x2
+#define	VALID_40	0x4
+#define	VALID_2040	(VALID_20|VALID_40)
+#define	VALID_ALL	(VALID_2040|VALID)
+
+#define	WLAN_RC_PHY_DS(_phy)	((_phy == WLAN_RC_PHY_HT_20_DS)		|| \
+				(_phy == WLAN_RC_PHY_HT_40_DS)		|| \
+				(_phy == WLAN_RC_PHY_HT_20_DS_HGI)	|| \
+				(_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+#define	WLAN_RC_PHY_40(_phy)	((_phy == WLAN_RC_PHY_HT_40_SS) 	|| \
+				(_phy == WLAN_RC_PHY_HT_40_DS)		|| \
+				(_phy == WLAN_RC_PHY_HT_40_SS_HGI)	|| \
+				(_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+#define	WLAN_RC_PHY_SGI(_phy)	((_phy == WLAN_RC_PHY_HT_20_SS_HGI)	|| \
+				(_phy == WLAN_RC_PHY_HT_20_DS_HGI)	|| \
+				(_phy == WLAN_RC_PHY_HT_40_SS_HGI)	|| \
+				(_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+
+#define	WLAN_RC_PHY_HT(_phy)	(_phy >= WLAN_RC_PHY_HT_20_SS)
+
+#define	WLAN_RC_CAP_MODE(capflag)	(((capflag & WLAN_RC_HT_FLAG) ?	\
+	(capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID))
+
+/*
+ * Return TRUE if flag supports HT20 && client supports HT20 or
+ * return TRUE if flag supports HT40 && client supports HT40.
+ * This is used becos some rates overlap between HT20/HT40.
+ */
+#define	WLAN_RC_PHY_HT_VALID(flag, capflag)			\
+	(((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \
+	((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG)))
+
+#define	WLAN_RC_DS_FLAG		(0x01)
+#define	WLAN_RC_40_FLAG		(0x02)
+#define	WLAN_RC_SGI_FLAG	(0x04)
+#define	WLAN_RC_HT_FLAG		(0x08)
+
+/*
+ * struct ath_rate_table - Rate Control table
+ * @valid: valid for use in rate control
+ * @valid_single_stream: valid for use in rate control for
+ * 	single stream operation
+ * @phy: CCK/OFDM
+ * @ratekbps: rate in Kbits per second
+ * @user_ratekbps: user rate in Kbits per second
+ * @ratecode: rate that goes into HW descriptors
+ * @short_preamble: Mask for enabling short preamble in ratecode for CCK
+ * @dot11rate: value that goes into supported
+ * 	rates info element of MLME
+ * @ctrl_rate: Index of next lower basic rate, used for duration computation
+ * @max_4ms_framelen: maximum frame length(bytes) for tx duration
+ * @probe_interval: interval for rate control to probe for other rates
+ * @rssi_reduce_interval: interval for rate control to reduce rssi
+ * @initial_ratemax: initial ratemax value
+ */
+struct ath_rate_table {
+	int rate_cnt;
+	uint8_t rateCodeToIndex[256];
+	struct {
+		int valid;
+		int valid_single_stream;
+		uint8_t phy;
+		uint32_t ratekbps;
+		uint32_t user_ratekbps;
+		uint8_t ratecode;
+		uint8_t short_preamble;
+		uint8_t dot11rate;
+		uint8_t ctrl_rate;
+		int8_t rssi_ack_validmin;
+		int8_t rssi_ack_deltamin;
+		uint8_t base_index;
+		uint8_t cw40index;
+		uint8_t sgi_index;
+		uint8_t ht_index;
+		uint32_t max_4ms_framelen;
+		uint16_t lpAckDuration;
+		uint16_t spAckDuration;
+	} info[RATE_TABLE_SIZE];
+	uint32_t probe_interval;
+	uint32_t rssi_reduce_interval;
+	uint8_t initial_ratemax;
+};
+
+struct ath_tx_ratectrl_state {
+	int8_t rssi_thres; /* required rssi for this rate (dB) */
+	uint8_t per; /* recent estimate of packet error rate (%) */
+};
+
+struct ath_rateset {
+	uint8_t rs_nrates;
+	uint8_t rs_rates[ATH_RATE_MAX];
+};
+
+/*
+ * struct ath_rate_priv - Rate Control priv data
+ * @state: RC state
+ * @rssi_last: last ACK rssi
+ * @rssi_last_lookup: last ACK rssi used for lookup
+ * @rssi_last_prev: previous last ACK rssi
+ * @rssi_last_prev2: 2nd previous last ACK rssi
+ * @rssi_sum_cnt: count of rssi_sum for averaging
+ * @rssi_sum_rate: rate that we are averaging
+ * @rssi_sum: running sum of rssi for averaging
+ * @probe_rate: rate we are probing at
+ * @rssi_time: msec timestamp for last ack rssi
+ * @rssi_down_time: msec timestamp for last down step
+ * @probe_time: msec timestamp for last probe
+ * @hw_maxretry_pktcnt: num of packets since we got HW max retry error
+ * @max_valid_rate: maximum number of valid rate
+ * @per_down_time: msec timestamp for last PER down step
+ * @valid_phy_ratecnt: valid rate count
+ * @rate_max_phy: phy index for the max rate
+ * @probe_interval: interval for ratectrl to probe for other rates
+ * @prev_data_rix: rate idx of last data frame
+ * @ht_cap: HT capabilities
+ * @single_stream: When TRUE, only single TX stream possible
+ * @neg_rates: Negotatied rates
+ * @neg_ht_rates: Negotiated HT rates
+ */
+struct ath_rate_priv {
+	int8_t rssi_last;
+	int8_t rssi_last_lookup;
+	int8_t rssi_last_prev;
+	int8_t rssi_last_prev2;
+	int32_t rssi_sum_cnt;
+	int32_t rssi_sum_rate;
+	int32_t rssi_sum;
+	uint8_t rate_table_size;
+	uint8_t probe_rate;
+	uint8_t hw_maxretry_pktcnt;
+	uint8_t max_valid_rate;
+	uint8_t valid_rate_index[RATE_TABLE_SIZE];
+	uint8_t ht_cap;
+	uint8_t single_stream;
+	uint8_t valid_phy_ratecnt[WLAN_RC_PHY_MAX];
+	uint8_t valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
+	uint8_t rc_phy_mode;
+	uint8_t rate_max_phy;
+	uint32_t rssi_time;
+	uint32_t rssi_down_time;
+	uint32_t probe_time;
+	uint32_t per_down_time;
+	uint32_t probe_interval;
+	uint32_t prev_data_rix;
+	uint32_t tx_triglevel_max;
+	struct ath_tx_ratectrl_state state[RATE_TABLE_SIZE];
+	struct ath_rateset neg_rates;
+	struct ath_rateset neg_ht_rates;
+};
+
+struct ath_tx_info_priv {
+	struct ath_tx_status tx;
+	int n_frames;
+	int n_bad_frames;
+	boolean_t update_rc;
+};
+
+#define	ATH_TX_INFO_PRIV(tx_info)	\
+	((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0]))
+
+/* RATE */
+void arn_rate_attach(struct arn_softc *sc);
+void arn_rate_update(struct arn_softc *sc, struct ieee80211_node *in,
+    int32_t rate);
+void arn_rate_ctl_start(struct arn_softc *sc, struct ieee80211_node *in);
+void arn_rate_cb(void *arg, struct ieee80211_node *in);
+void arn_rate_ctl_reset(struct arn_softc *sc, enum ieee80211_state state);
+void arn_rate_ctl(void *arg, struct ieee80211_node *in);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARN_RC_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_recv.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/byteorder.h>
+
+#include "arn_core.h"
+
+void
+arn_setdefantenna(struct arn_softc *sc, uint32_t antenna)
+{
+	/* XXX block beacon interrupts */
+	ath9k_hw_setantenna(sc->sc_ah, antenna);
+	sc->sc_defant = (uint8_t)antenna; /* LINT */
+	sc->sc_rxotherant = 0;
+}
+
+/*
+ *  Extend 15-bit time stamp from rx descriptor to
+ *  a full 64-bit TSF using the current h/w TSF.
+ */
+
+static uint64_t
+arn_extend_tsf(struct arn_softc *sc, uint32_t rstamp)
+{
+	uint64_t tsf;
+
+	tsf = ath9k_hw_gettsf64(sc->sc_ah);
+	if ((tsf & 0x7fff) < rstamp)
+		tsf -= 0x8000;
+	return ((tsf & ~0x7fff) | rstamp);
+}
+
+static void
+arn_opmode_init(struct arn_softc *sc)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	uint32_t rfilt;
+	uint32_t mfilt[2];
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+
+	/* configure rx filter */
+	rfilt = arn_calcrxfilter(sc);
+	ath9k_hw_setrxfilter(ah, rfilt);
+
+	/* configure bssid mask */
+	if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+		(void) ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
+
+	/* configure operational mode */
+	ath9k_hw_setopmode(ah);
+
+	/* Handle any link-level address change. */
+	(void) ath9k_hw_setmac(ah, sc->sc_myaddr);
+
+	/* calculate and install multicast filter */
+	mfilt[0] = ~((uint32_t)0); /* LINT */
+	mfilt[1] = ~((uint32_t)0); /* LINT */
+
+	ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
+
+	ARN_DBG((ARN_DBG_RECV, "arn: arn_opmode_init(): "
+	    "mode = %d RX filter 0x%x, MC filter %08x:%08x\n",
+	    ic->ic_opmode, rfilt, mfilt[0], mfilt[1]));
+}
+
+/*
+ * Calculate the receive filter according to the
+ * operating mode and state:
+ *
+ * o always accept unicast, broadcast, and multicast traffic
+ * o maintain current state of phy error reception (the hal
+ *   may enable phy error frames for noise immunity work)
+ * o probe request frames are accepted only when operating in
+ *   hostap, adhoc, or monitor modes
+ * o enable promiscuous mode according to the interface state
+ * o accept beacons:
+ * - when operating in adhoc mode so the 802.11 layer creates
+ * node table entries for peers,
+ * - when operating in station mode for collecting rssi data when
+ * the station is otherwise quiet, or
+ * - when operating as a repeater so we see repeater-sta beacons
+ * - when scanning
+ */
+
+uint32_t
+arn_calcrxfilter(struct arn_softc *sc)
+{
+#define	RX_FILTER_PRESERVE	(ATH9K_RX_FILTER_PHYERR |	\
+	ATH9K_RX_FILTER_PHYRADAR)
+
+	uint32_t rfilt;
+
+	rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) |
+	    ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST |
+	    ATH9K_RX_FILTER_MCAST;
+
+	/* If not a STA, enable processing of Probe Requests */
+	if (sc->sc_ah->ah_opmode != ATH9K_M_STA)
+		rfilt |= ATH9K_RX_FILTER_PROBEREQ;
+
+	/* Can't set HOSTAP into promiscous mode */
+	if (((sc->sc_ah->ah_opmode != ATH9K_M_HOSTAP) &&
+	    (sc->sc_promisc)) ||
+	    (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR)) {
+		rfilt |= ATH9K_RX_FILTER_PROM;
+		/* ??? To prevent from sending ACK */
+		rfilt &= ~ATH9K_RX_FILTER_UCAST;
+	}
+
+	if (sc->sc_ah->ah_opmode == ATH9K_M_STA ||
+	    sc->sc_ah->ah_opmode == ATH9K_M_IBSS)
+		rfilt |= ATH9K_RX_FILTER_BEACON;
+
+	/*
+	 * If in HOSTAP mode, want to enable reception of PSPOLL
+	 * frames & beacon frames
+	 */
+	if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP)
+		rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
+
+	return (rfilt);
+
+#undef RX_FILTER_PRESERVE
+}
+
+int
+arn_startrecv(struct arn_softc *sc)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	struct ath_buf *bf;
+
+	/* clean up rx link firstly */
+	sc->sc_rxlink = NULL;
+
+	/* rx descriptor link set up */
+	bf = list_head(&sc->sc_rxbuf_list);
+	while (bf != NULL) {
+		arn_rx_buf_link(sc, bf);
+		bf = list_next(&sc->sc_rxbuf_list, bf);
+	}
+
+	bf = list_head(&sc->sc_rxbuf_list);
+
+	ath9k_hw_putrxbuf(ah, bf->bf_daddr);
+	ath9k_hw_rxena(ah);
+
+	arn_opmode_init(sc);
+	ath9k_hw_startpcureceive(ah);
+
+	return (0);
+}
+
+boolean_t
+arn_stoprecv(struct arn_softc *sc)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	boolean_t stopped;
+
+	ath9k_hw_stoppcurecv(ah);
+	ath9k_hw_setrxfilter(ah, 0);
+	stopped = ath9k_hw_stopdmarecv(ah);
+
+	/* 3ms is long enough for 1 frame ??? */
+	drv_usecwait(3000);
+
+	sc->sc_rxlink = NULL;
+
+	return (stopped);
+}
+
+/*
+ * Intercept management frames to collect beacon rssi data
+ * and to do ibss merges.
+ */
+
+void
+arn_recv_mgmt(struct ieee80211com *ic, mblk_t *mp, struct ieee80211_node *in,
+    int subtype, int rssi, uint32_t rstamp)
+{
+	struct arn_softc *sc = (struct arn_softc *)ic;
+
+	/*
+	 * Call up first so subsequent work can use information
+	 * potentially stored in the node (e.g. for ibss merge).
+	 */
+	sc->sc_recv_mgmt(ic, mp, in, subtype, rssi, rstamp);
+
+	ARN_LOCK(sc);
+	switch (subtype) {
+	case IEEE80211_FC0_SUBTYPE_BEACON:
+		/* update rssi statistics */
+		if (sc->sc_bsync && in == ic->ic_bss &&
+		    ic->ic_state == IEEE80211_S_RUN) {
+			/*
+			 * Resync beacon timers using the tsf of the beacon
+			 * frame we just received.
+			 */
+			arn_beacon_config(sc);
+		}
+		/* FALLTHRU */
+	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
+		if (ic->ic_opmode == IEEE80211_M_IBSS &&
+		    ic->ic_state == IEEE80211_S_RUN &&
+		    (in->in_capinfo & IEEE80211_CAPINFO_IBSS)) {
+			uint64_t tsf = arn_extend_tsf(sc, rstamp);
+			/*
+			 * Handle ibss merge as needed; check the tsf on the
+			 * frame before attempting the merge.  The 802.11 spec
+			 * says the station should change it's bssid to match
+			 * the oldest station with the same ssid, where oldest
+			 * is determined by the tsf.  Note that hardware
+			 * reconfiguration happens through callback to
+			 * ath_newstate as the state machine will go from
+			 * RUN -> RUN when this happens.
+			 */
+			if (LE_64(in->in_tstamp.tsf) >= tsf) {
+				ARN_DBG((ARN_DBG_BEACON, "arn: arn_recv_mgmt:"
+				    "ibss merge, rstamp %u tsf %lu "
+				    "tstamp %lu\n", rstamp, tsf,
+				    in->in_tstamp.tsf));
+				ARN_UNLOCK(sc);
+				ARN_DBG((ARN_DBG_BEACON, "arn_recv_mgmt():"
+				    "ibss_merge: rstamp=%d in_tstamp=%02x %02x"
+				    " %02x %02x %02x %02x %02x %02x\n",
+				    rstamp, in->in_tstamp.data[0],
+				    in->in_tstamp.data[1],
+				    in->in_tstamp.data[2],
+				    in->in_tstamp.data[3],
+				    in->in_tstamp.data[4],
+				    in->in_tstamp.data[5],
+				    in->in_tstamp.data[6],
+				    in->in_tstamp.data[7]));
+				(void) ieee80211_ibss_merge(in);
+				return;
+			}
+		}
+		break;
+	}
+	ARN_UNLOCK(sc);
+}
+
+static void
+arn_printrxbuf(struct ath_buf *bf, int32_t done)
+{
+	struct ath_desc *ds = bf->bf_desc;
+	const struct ath_rx_status *rs = &ds->ds_rxstat;
+
+	ARN_DBG((ARN_DBG_RECV, "arn: R (%p %p) %08x %08x %08x "
+	    "%08x %08x %08x %c\n",
+	    ds, bf->bf_daddr,
+	    ds->ds_link, ds->ds_data,
+	    ds->ds_ctl0, ds->ds_ctl1,
+	    ds->ds_hw[0], ds->ds_hw[1],
+	    !done ? ' ' : (rs->rs_status == 0) ? '*' : '!'));
+}
+
+static void
+arn_rx_handler(struct arn_softc *sc)
+{
+#define	PA2DESC(_sc, _pa) \
+		((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
+		((_pa) - (_sc)->sc_desc_dma.cookie.dmac_address)))
+
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ath_buf *bf;
+	struct ath_hal *ah = sc->sc_ah;
+	struct ath_desc *ds;
+	struct ath_rx_status *rs;
+	mblk_t *rx_mp;
+	struct ieee80211_frame *wh;
+	int32_t len, ngood, loop = 1;
+	uint8_t phyerr;
+	int status;
+	struct ieee80211_node *in;
+
+	ngood = 0;
+	do {
+		mutex_enter(&sc->sc_rxbuflock);
+		bf = list_head(&sc->sc_rxbuf_list);
+		if (bf == NULL) {
+			ARN_DBG((ARN_DBG_RECV, "arn: arn_rx_handler(): "
+			    "no buffer\n"));
+			mutex_exit(&sc->sc_rxbuflock);
+			break;
+		}
+		ASSERT(bf->bf_dma.cookie.dmac_address != NULL);
+		ds = bf->bf_desc;
+		if (ds->ds_link == bf->bf_daddr) {
+			/*
+			 * Never process the self-linked entry at the end,
+			 * this may be met at heavy load.
+			 */
+			mutex_exit(&sc->sc_rxbuflock);
+			break;
+		}
+
+		/*
+		 * Must provide the virtual address of the current
+		 * descriptor, the physical address, and the virtual
+		 * address of the next descriptor in the h/w chain.
+		 * This allows the HAL to look ahead to see if the
+		 * hardware is done with a descriptor by checking the
+		 * done bit in the following descriptor and the address
+		 * of the current descriptor the DMA engine is working
+		 * on.  All this is necessary because of our use of
+		 * a self-linked list to avoid rx overruns.
+		 */
+		status = ath9k_hw_rxprocdesc(ah, ds,
+		    bf->bf_daddr,
+		    PA2DESC(sc, ds->ds_link), 0);
+		if (status == EINPROGRESS) {
+			mutex_exit(&sc->sc_rxbuflock);
+			break;
+		}
+		list_remove(&sc->sc_rxbuf_list, bf);
+		mutex_exit(&sc->sc_rxbuflock);
+
+		rs = &ds->ds_rxstat;
+		if (rs->rs_status != 0) {
+			if (rs->rs_status & ATH9K_RXERR_CRC) {
+				sc->sc_stats.ast_rx_crcerr++;
+			}
+			if (rs->rs_status & ATH9K_RXERR_FIFO) {
+				sc->sc_stats.ast_rx_fifoerr++;
+			}
+			if (rs->rs_status & ATH9K_RXERR_DECRYPT) {
+				sc->sc_stats.ast_rx_badcrypt++;
+			}
+			if (rs->rs_status & ATH9K_RXERR_PHY) {
+				sc->sc_stats.ast_rx_phyerr++;
+				phyerr = rs->rs_phyerr & 0x1f;
+				sc->sc_stats.ast_rx_phy[phyerr]++;
+			}
+			goto rx_next;
+		}
+		len = rs->rs_datalen;
+
+		/* less than sizeof(struct ieee80211_frame) */
+		if (len < 20) {
+			sc->sc_stats.ast_rx_tooshort++;
+			goto rx_next;
+		}
+
+		if ((rx_mp = allocb(sc->sc_dmabuf_size, BPRI_MED)) == NULL) {
+			arn_problem("arn: arn_rx_handler(): "
+			    "allocing mblk buffer failed.\n");
+			return;
+		}
+
+		ARN_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORCPU);
+		bcopy(bf->bf_dma.mem_va, rx_mp->b_rptr, len);
+
+		rx_mp->b_wptr += len;
+		wh = (struct ieee80211_frame *)rx_mp->b_rptr;
+
+		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+		    IEEE80211_FC0_TYPE_CTL) {
+			/*
+			 * Ignore control frame received in promisc mode.
+			 */
+			freemsg(rx_mp);
+			goto rx_next;
+		}
+		/* Remove the CRC at the end of IEEE80211 frame */
+		rx_mp->b_wptr -= IEEE80211_CRC_LEN;
+
+#ifdef DEBUG
+		arn_printrxbuf(bf, status == 0);
+#endif
+
+		/*
+		 * Locate the node for sender, track state, and then
+		 * pass the (referenced) node up to the 802.11 layer
+		 * for its use.
+		 */
+		in = ieee80211_find_rxnode(ic, wh);
+
+		/*
+		 * Send the frame to net80211 for processing
+		 */
+		(void) ieee80211_input(ic, rx_mp, in,
+		    rs->rs_rssi, rs->rs_tstamp);
+
+		/* release node */
+		ieee80211_free_node(in);
+
+		/*
+		 * Arrange to update the last rx timestamp only for
+		 * frames from our ap when operating in station mode.
+		 * This assumes the rx key is always setup when associated.
+		 */
+		if (ic->ic_opmode == IEEE80211_M_STA &&
+		    rs->rs_keyix != ATH9K_RXKEYIX_INVALID) {
+			ngood++;
+		}
+
+		/*
+		 * change the default rx antenna if rx diversity chooses the
+		 * other antenna 3 times in a row.
+		 */
+		if (sc->sc_defant != ds->ds_rxstat.rs_antenna) {
+			if (++sc->sc_rxotherant >= 3) {
+				ath9k_hw_setantenna(sc->sc_ah,
+				    ds->ds_rxstat.rs_antenna);
+				sc->sc_defant = ds->ds_rxstat.rs_antenna;
+				sc->sc_rxotherant = 0;
+			}
+		} else {
+			sc->sc_rxotherant = 0;
+		}
+
+rx_next:
+		mutex_enter(&sc->sc_rxbuflock);
+		list_insert_tail(&sc->sc_rxbuf_list, bf);
+		mutex_exit(&sc->sc_rxbuflock);
+		arn_rx_buf_link(sc, bf);
+	} while (loop);
+
+	if (ngood)
+		sc->sc_lastrx = ath9k_hw_gettsf64(ah);
+
+#undef PA2DESC
+}
+
+uint_t
+arn_softint_handler(caddr_t data)
+{
+	struct arn_softc *sc = (struct arn_softc *)data;
+
+	ARN_LOCK(sc);
+
+	if (sc->sc_rx_pend) {
+		/* Soft interrupt for this driver */
+		sc->sc_rx_pend = 0;
+		ARN_UNLOCK(sc);
+		arn_rx_handler(sc);
+		return (DDI_INTR_CLAIMED);
+	}
+
+	ARN_UNLOCK(sc);
+
+	return (DDI_INTR_UNCLAIMED);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_reg.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,1485 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _ARN_REG_H
+#define	_ARN_REG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	AR_CR		0x0008
+#define	AR_CR_RXE	0x00000004
+#define	AR_CR_RXD	0x00000020
+#define	AR_CR_SWI	0x00000040
+
+#define	AR_RXDP		0x000C
+
+#define	AR_CFG				0x0014
+#define	AR_CFG_SWTD			0x00000001
+#define	AR_CFG_SWTB			0x00000002
+#define	AR_CFG_SWRD			0x00000004
+#define	AR_CFG_SWRB			0x00000008
+#define	AR_CFG_SWRG			0x00000010
+#define	AR_CFG_AP_ADHOC_INDICATION	0x00000020
+#define	AR_CFG_PHOK			0x00000100
+#define	AR_CFG_CLK_GATE_DIS		0x00000400
+#define	AR_CFG_EEBS			0x00000200
+#define	AR_CFG_PCI_MASTER_REQ_Q_THRESH	0x00060000
+#define	AR_CFG_PCI_MASTER_REQ_Q_THRESH_S	17
+
+#define	AR_MIRT			0x0020
+#define	AR_MIRT_VAL		0x0000ffff
+#define	AR_MIRT_VAL_S		16
+
+#define	AR_IER			0x0024
+#define	AR_IER_ENABLE		0x00000001
+#define	AR_IER_DISABLE		0x00000000
+
+#define	AR_TIMT			0x0028
+#define	AR_TIMT_LAST		0x0000ffff
+#define	AR_TIMT_LAST_S		0
+#define	AR_TIMT_FIRST		0xffff0000
+#define	AR_TIMT_FIRST_S		16
+
+#define	AR_RIMT			0x002C
+#define	AR_RIMT_LAST		0x0000ffff
+#define	AR_RIMT_LAST_S		0
+#define	AR_RIMT_FIRST		0xffff0000
+#define	AR_RIMT_FIRST_S		16
+
+#define	AR_DMASIZE_4B		0x00000000
+#define	AR_DMASIZE_8B		0x00000001
+#define	AR_DMASIZE_16B		0x00000002
+#define	AR_DMASIZE_32B		0x00000003
+#define	AR_DMASIZE_64B		0x00000004
+#define	AR_DMASIZE_128B		0x00000005
+#define	AR_DMASIZE_256B		0x00000006
+#define	AR_DMASIZE_512B		0x00000007
+
+#define	AR_TXCFG		0x0030
+#define	AR_TXCFG_DMASZ_MASK	0x00000003
+#define	AR_TXCFG_DMASZ_4B	0
+#define	AR_TXCFG_DMASZ_8B	1
+#define	AR_TXCFG_DMASZ_16B	2
+#define	AR_TXCFG_DMASZ_32B	3
+#define	AR_TXCFG_DMASZ_64B	4
+#define	AR_TXCFG_DMASZ_128B	5
+#define	AR_TXCFG_DMASZ_256B	6
+#define	AR_TXCFG_DMASZ_512B	7
+#define	AR_FTRIG		0x000003F0
+#define	AR_FTRIG_S		4
+#define	AR_FTRIG_IMMED		0x00000000
+#define	AR_FTRIG_64B		0x00000010
+#define	AR_FTRIG_128B		0x00000020
+#define	AR_FTRIG_192B		0x00000030
+#define	AR_FTRIG_256B		0x00000040
+#define	AR_FTRIG_512B		0x00000080
+#define	AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY	0x00000800
+
+#define	AR_RXCFG		0x0034
+#define	AR_RXCFG_CHIRP		0x00000008
+#define	AR_RXCFG_ZLFDMA		0x00000010
+#define	AR_RXCFG_DMASZ_MASK	0x00000007
+#define	AR_RXCFG_DMASZ_4B	0
+#define	AR_RXCFG_DMASZ_8B	1
+#define	AR_RXCFG_DMASZ_16B	2
+#define	AR_RXCFG_DMASZ_32B	3
+#define	AR_RXCFG_DMASZ_64B	4
+#define	AR_RXCFG_DMASZ_128B	5
+#define	AR_RXCFG_DMASZ_256B	6
+#define	AR_RXCFG_DMASZ_512B	7
+
+#define	AR_MIBC			0x0040
+#define	AR_MIBC_COW		0x00000001
+#define	AR_MIBC_FMC		0x00000002
+#define	AR_MIBC_CMC		0x00000004
+#define	AR_MIBC_MCS		0x00000008
+
+#define	AR_TOPS			0x0044
+#define	AR_TOPS_MASK		0x0000FFFF
+
+#define	AR_RXNPTO		0x0048
+#define	AR_RXNPTO_MASK		0x000003FF
+
+#define	AR_TXNPTO		0x004C
+#define	AR_TXNPTO_MASK		0x000003FF
+#define	AR_TXNPTO_QCU_MASK	0x000FFC00
+
+#define	AR_RPGTO		0x0050
+#define	AR_RPGTO_MASK		0x000003FF
+
+#define	AR_RPCNT		0x0054
+#define	AR_RPCNT_MASK		0x0000001F
+
+#define	AR_MACMISC			0x0058
+#define	AR_MACMISC_PCI_EXT_FORCE	0x00000010
+#define	AR_MACMISC_DMA_OBS		0x000001E0
+#define	AR_MACMISC_DMA_OBS_S		5
+#define	AR_MACMISC_DMA_OBS_LINE_0	0
+#define	AR_MACMISC_DMA_OBS_LINE_1	1
+#define	AR_MACMISC_DMA_OBS_LINE_2	2
+#define	AR_MACMISC_DMA_OBS_LINE_3	3
+#define	AR_MACMISC_DMA_OBS_LINE_4	4
+#define	AR_MACMISC_DMA_OBS_LINE_5	5
+#define	AR_MACMISC_DMA_OBS_LINE_6	6
+#define	AR_MACMISC_DMA_OBS_LINE_7	7
+#define	AR_MACMISC_DMA_OBS_LINE_8	8
+#define	AR_MACMISC_MISC_OBS		0x00000E00
+#define	AR_MACMISC_MISC_OBS_S		9
+#define	AR_MACMISC_MISC_OBS_BUS_LSB	0x00007000
+#define	AR_MACMISC_MISC_OBS_BUS_LSB_S	12
+#define	AR_MACMISC_MISC_OBS_BUS_MSB	0x00038000
+#define	AR_MACMISC_MISC_OBS_BUS_MSB_S	15
+#define	AR_MACMISC_MISC_OBS_BUS_1	1
+
+#define	AR_GTXTO			0x0064
+#define	AR_GTXTO_TIMEOUT_COUNTER	0x0000FFFF
+#define	AR_GTXTO_TIMEOUT_LIMIT		0xFFFF0000
+#define	AR_GTXTO_TIMEOUT_LIMIT_S	16
+
+#define	AR_GTTM				0x0068
+#define	AR_GTTM_USEC			0x00000001
+#define	AR_GTTM_IGNORE_IDLE		0x00000002
+#define	AR_GTTM_RESET_IDLE		0x00000004
+#define	AR_GTTM_CST_USEC		0x00000008
+
+#define	AR_CST				0x006C
+#define	AR_CST_TIMEOUT_COUNTER		0x0000FFFF
+#define	AR_CST_TIMEOUT_LIMIT		0xFFFF0000
+#define	AR_CST_TIMEOUT_LIMIT_S		16
+
+#define	AR_SREV_VERSION_9100		0x014
+
+#define	AR_SREV_5416_V20_OR_LATER(_ah) \
+	(AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah))
+#define	AR_SREV_5416_V22_OR_LATER(_ah) \
+	(AR_SREV_9100((_ah)) || AR_SREV_5416_22_OR_LATER(_ah))
+
+#define	AR_ISR			0x0080
+#define	AR_ISR_RXOK		0x00000001
+#define	AR_ISR_RXDESC		0x00000002
+#define	AR_ISR_RXERR		0x00000004
+#define	AR_ISR_RXNOPKT		0x00000008
+#define	AR_ISR_RXEOL		0x00000010
+#define	AR_ISR_RXORN		0x00000020
+#define	AR_ISR_TXOK		0x00000040
+#define	AR_ISR_TXDESC		0x00000080
+#define	AR_ISR_TXERR		0x00000100
+#define	AR_ISR_TXNOPKT		0x00000200
+#define	AR_ISR_TXEOL		0x00000400
+#define	AR_ISR_TXURN		0x00000800
+#define	AR_ISR_MIB		0x00001000
+#define	AR_ISR_SWI		0x00002000
+#define	AR_ISR_RXPHY		0x00004000
+#define	AR_ISR_RXKCM		0x00008000
+#define	AR_ISR_SWBA		0x00010000
+#define	AR_ISR_BRSSI		0x00020000
+#define	AR_ISR_BMISS		0x00040000
+#define	AR_ISR_BNR		0x00100000
+#define	AR_ISR_RXCHIRP		0x00200000
+#define	AR_ISR_BCNMISC		0x00800000
+#define	AR_ISR_TIM		0x00800000
+#define	AR_ISR_QCBROVF		0x02000000
+#define	AR_ISR_QCBRURN		0x04000000
+#define	AR_ISR_QTRIG		0x08000000
+#define	AR_ISR_GENTMR		0x10000000
+
+#define	AR_ISR_TXMINTR		0x00080000
+#define	AR_ISR_RXMINTR		0x01000000
+#define	AR_ISR_TXINTM		0x40000000
+#define	AR_ISR_RXINTM		0x80000000
+
+#define	AR_ISR_S0		0x0084
+#define	AR_ISR_S0_QCU_TXOK	0x000003FF
+#define	AR_ISR_S0_QCU_TXOK_S	0
+#define	AR_ISR_S0_QCU_TXDESC	0x03FF0000
+#define	AR_ISR_S0_QCU_TXDESC_S	16
+
+#define	AR_ISR_S1		0x0088
+#define	AR_ISR_S1_QCU_TXERR	0x000003FF
+#define	AR_ISR_S1_QCU_TXERR_S	0
+#define	AR_ISR_S1_QCU_TXEOL	0x03FF0000
+#define	AR_ISR_S1_QCU_TXEOL_S	16
+
+#define	AR_ISR_S2		0x008c
+#define	AR_ISR_S2_QCU_TXURN	0x000003FF
+#define	AR_ISR_S2_CST		0x00400000
+#define	AR_ISR_S2_GTT		0x00800000
+#define	AR_ISR_S2_TIM		0x01000000
+#define	AR_ISR_S2_CABEND	0x02000000
+#define	AR_ISR_S2_DTIMSYNC	0x04000000
+#define	AR_ISR_S2_BCNTO		0x08000000
+#define	AR_ISR_S2_CABTO		0x10000000
+#define	AR_ISR_S2_DTIM		0x20000000
+#define	AR_ISR_S2_TSFOOR	0x40000000
+#define	AR_ISR_S2_TBTT_TIME	0x80000000
+
+#define	AR_ISR_S3		0x0090
+#define	AR_ISR_S3_QCU_QCBROVF	0x000003FF
+#define	AR_ISR_S3_QCU_QCBRURN	0x03FF0000
+
+#define	AR_ISR_S4		0x0094
+#define	AR_ISR_S4_QCU_QTRIG	0x000003FF
+#define	AR_ISR_S4_RESV0		0xFFFFFC00
+
+#define	AR_ISR_S5		0x0098
+#define	AR_ISR_S5_TIMER_TRIG	0x000000FF
+#define	AR_ISR_S5_TIMER_THRESH	0x0007FE00
+#define	AR_ISR_S5_TIM_TIMER	0x00000010
+#define	AR_ISR_S5_DTIM_TIMER	0x00000020
+#define	AR_ISR_S5_S		0x00d8
+#define	AR_IMR_S5		0x00b8
+#define	AR_IMR_S5_TIM_TIMER	0x00000010
+#define	AR_IMR_S5_DTIM_TIMER	0x00000020
+
+
+#define	AR_IMR			0x00a0
+#define	AR_IMR_RXOK		0x00000001
+#define	AR_IMR_RXDESC		0x00000002
+#define	AR_IMR_RXERR		0x00000004
+#define	AR_IMR_RXNOPKT		0x00000008
+#define	AR_IMR_RXEOL		0x00000010
+#define	AR_IMR_RXORN		0x00000020
+#define	AR_IMR_TXOK		0x00000040
+#define	AR_IMR_TXDESC		0x00000080
+#define	AR_IMR_TXERR		0x00000100
+#define	AR_IMR_TXNOPKT		0x00000200
+#define	AR_IMR_TXEOL		0x00000400
+#define	AR_IMR_TXURN		0x00000800
+#define	AR_IMR_MIB		0x00001000
+#define	AR_IMR_SWI		0x00002000
+#define	AR_IMR_RXPHY		0x00004000
+#define	AR_IMR_RXKCM		0x00008000
+#define	AR_IMR_SWBA		0x00010000
+#define	AR_IMR_BRSSI		0x00020000
+#define	AR_IMR_BMISS		0x00040000
+#define	AR_IMR_BNR		0x00100000
+#define	AR_IMR_RXCHIRP		0x00200000
+#define	AR_IMR_BCNMISC		0x00800000
+#define	AR_IMR_TIM		0x00800000
+#define	AR_IMR_QCBROVF		0x02000000
+#define	AR_IMR_QCBRURN		0x04000000
+#define	AR_IMR_QTRIG		0x08000000
+#define	AR_IMR_GENTMR		0x10000000
+
+#define	AR_IMR_TXMINTR		0x00080000
+#define	AR_IMR_RXMINTR		0x01000000
+#define	AR_IMR_TXINTM		0x40000000
+#define	AR_IMR_RXINTM		0x80000000
+
+#define	AR_IMR_S0		0x00a4
+#define	AR_IMR_S0_QCU_TXOK	0x000003FF
+#define	AR_IMR_S0_QCU_TXOK_S	0
+#define	AR_IMR_S0_QCU_TXDESC	0x03FF0000
+#define	AR_IMR_S0_QCU_TXDESC_S	16
+
+#define	AR_IMR_S1		0x00a8
+#define	AR_IMR_S1_QCU_TXERR	0x000003FF
+#define	AR_IMR_S1_QCU_TXERR_S	0
+#define	AR_IMR_S1_QCU_TXEOL	0x03FF0000
+#define	AR_IMR_S1_QCU_TXEOL_S	16
+
+#define	AR_IMR_S2		0x00ac
+#define	AR_IMR_S2_QCU_TXURN	0x000003FF
+#define	AR_IMR_S2_QCU_TXURN_S	0
+#define	AR_IMR_S2_CST		0x00400000
+#define	AR_IMR_S2_GTT		0x00800000
+#define	AR_IMR_S2_TIM		0x01000000
+#define	AR_IMR_S2_CABEND	0x02000000
+#define	AR_IMR_S2_DTIMSYNC	0x04000000
+#define	AR_IMR_S2_BCNTO		0x08000000
+#define	AR_IMR_S2_CABTO		0x10000000
+#define	AR_IMR_S2_DTIM		0x20000000
+#define	AR_IMR_S2_TSFOOR	0x40000000
+
+#define	AR_IMR_S3		0x00b0
+#define	AR_IMR_S3_QCU_QCBROVF	0x000003FF
+#define	AR_IMR_S3_QCU_QCBRURN	0x03FF0000
+#define	AR_IMR_S3_QCU_QCBRURN_S	16
+
+#define	AR_IMR_S4		0x00b4
+#define	AR_IMR_S4_QCU_QTRIG	0x000003FF
+#define	AR_IMR_S4_RESV0		0xFFFFFC00
+
+#define	AR_IMR_S5		0x00b8
+#define	AR_IMR_S5_TIMER_TRIG	0x000000FF
+#define	AR_IMR_S5_TIMER_THRESH	0x0000FF00
+
+
+#define	AR_ISR_RAC		0x00c0
+#define	AR_ISR_S0_S		0x00c4
+#define	AR_ISR_S0_QCU_TXOK	0x000003FF
+#define	AR_ISR_S0_QCU_TXOK_S	0
+#define	AR_ISR_S0_QCU_TXDESC	0x03FF0000
+#define	AR_ISR_S0_QCU_TXDESC_S	16
+
+#define	AR_ISR_S1_S		0x00c8
+#define	AR_ISR_S1_QCU_TXERR	0x000003FF
+#define	AR_ISR_S1_QCU_TXERR_S	0
+#define	AR_ISR_S1_QCU_TXEOL	0x03FF0000
+#define	AR_ISR_S1_QCU_TXEOL_S	16
+
+#define	AR_ISR_S2_S	0x00cc
+#define	AR_ISR_S3_S	0x00d0
+#define	AR_ISR_S4_S	0x00d4
+#define	AR_ISR_S5_S	0x00d8
+#define	AR_DMADBG_0	0x00e0
+#define	AR_DMADBG_1	0x00e4
+#define	AR_DMADBG_2	0x00e8
+#define	AR_DMADBG_3	0x00ec
+#define	AR_DMADBG_4	0x00f0
+#define	AR_DMADBG_5	0x00f4
+#define	AR_DMADBG_6	0x00f8
+#define	AR_DMADBG_7	0x00fc
+
+#define	AR_NUM_QCU	10
+#define	AR_QCU_0	0x0001
+#define	AR_QCU_1	0x0002
+#define	AR_QCU_2	0x0004
+#define	AR_QCU_3	0x0008
+#define	AR_QCU_4	0x0010
+#define	AR_QCU_5	0x0020
+#define	AR_QCU_6	0x0040
+#define	AR_QCU_7	0x0080
+#define	AR_QCU_8	0x0100
+#define	AR_QCU_9	0x0200
+
+#define	AR_Q0_TXDP	0x0800
+#define	AR_Q1_TXDP	0x0804
+#define	AR_Q2_TXDP	0x0808
+#define	AR_Q3_TXDP	0x080c
+#define	AR_Q4_TXDP	0x0810
+#define	AR_Q5_TXDP	0x0814
+#define	AR_Q6_TXDP	0x0818
+#define	AR_Q7_TXDP	0x081c
+#define	AR_Q8_TXDP	0x0820
+#define	AR_Q9_TXDP	0x0824
+#define	AR_QTXDP(_i)	(AR_Q0_TXDP + ((_i)<<2))
+
+#define	AR_Q_TXE	0x0840
+#define	AR_Q_TXE_M	0x000003FF
+
+#define	AR_Q_TXD	0x0880
+#define	AR_Q_TXD_M	0x000003FF
+
+#define	AR_Q0_CBRCFG	0x08c0
+#define	AR_Q1_CBRCFG	0x08c4
+#define	AR_Q2_CBRCFG	0x08c8
+#define	AR_Q3_CBRCFG	0x08cc
+#define	AR_Q4_CBRCFG	0x08d0
+#define	AR_Q5_CBRCFG	0x08d4
+#define	AR_Q6_CBRCFG	0x08d8
+#define	AR_Q7_CBRCFG	0x08dc
+#define	AR_Q8_CBRCFG	0x08e0
+#define	AR_Q9_CBRCFG	0x08e4
+#define	AR_QCBRCFG(_i)	(AR_Q0_CBRCFG + ((_i)<<2))
+#define	AR_Q_CBRCFG_INTERVAL		0x00FFFFFF
+#define	AR_Q_CBRCFG_INTERVAL_S		0
+#define	AR_Q_CBRCFG_OVF_THRESH		0xFF000000
+#define	AR_Q_CBRCFG_OVF_THRESH_S	24
+
+#define	AR_Q0_RDYTIMECFG		0x0900
+#define	AR_Q1_RDYTIMECFG		0x0904
+#define	AR_Q2_RDYTIMECFG		0x0908
+#define	AR_Q3_RDYTIMECFG		0x090c
+#define	AR_Q4_RDYTIMECFG		0x0910
+#define	AR_Q5_RDYTIMECFG		0x0914
+#define	AR_Q6_RDYTIMECFG		0x0918
+#define	AR_Q7_RDYTIMECFG		0x091c
+#define	AR_Q8_RDYTIMECFG		0x0920
+#define	AR_Q9_RDYTIMECFG		0x0924
+#define	AR_QRDYTIMECFG(_i)		(AR_Q0_RDYTIMECFG + ((_i)<<2))
+#define	AR_Q_RDYTIMECFG_DURATION	0x00FFFFFF
+#define	AR_Q_RDYTIMECFG_DURATION_S	0
+#define	AR_Q_RDYTIMECFG_EN		0x01000000
+
+#define	AR_Q_ONESHOTARM_SC		0x0940
+#define	AR_Q_ONESHOTARM_SC_M		0x000003FF
+#define	AR_Q_ONESHOTARM_SC_RESV0	0xFFFFFC00
+
+#define	AR_Q_ONESHOTARM_CC		0x0980
+#define	AR_Q_ONESHOTARM_CC_M		0x000003FF
+#define	AR_Q_ONESHOTARM_CC_RESV0	0xFFFFFC00
+
+#define	AR_Q0_MISC			0x09c0
+#define	AR_Q1_MISC			0x09c4
+#define	AR_Q2_MISC			0x09c8
+#define	AR_Q3_MISC			0x09cc
+#define	AR_Q4_MISC			0x09d0
+#define	AR_Q5_MISC			0x09d4
+#define	AR_Q6_MISC			0x09d8
+#define	AR_Q7_MISC			0x09dc
+#define	AR_Q8_MISC			0x09e0
+#define	AR_Q9_MISC			0x09e4
+#define	AR_QMISC(_i)			(AR_Q0_MISC + ((_i)<<2))
+#define	AR_Q_MISC_FSP			0x0000000F
+#define	AR_Q_MISC_FSP_ASAP		0
+#define	AR_Q_MISC_FSP_CBR		1
+#define	AR_Q_MISC_FSP_DBA_GATED		2
+#define	AR_Q_MISC_FSP_TIM_GATED		3
+#define	AR_Q_MISC_FSP_BEACON_SENT_GATED	4
+#define	AR_Q_MISC_FSP_BEACON_RCVD_GATED	5
+#define	AR_Q_MISC_ONE_SHOT_EN		0x00000010
+#define	AR_Q_MISC_CBR_INCR_DIS1		0x00000020
+#define	AR_Q_MISC_CBR_INCR_DIS0		0x00000040
+#define	AR_Q_MISC_BEACON_USE		0x00000080
+#define	AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN	0x00000100
+#define	AR_Q_MISC_RDYTIME_EXP_POLICY	0x00000200
+#define	AR_Q_MISC_RESET_CBR_EXP_CTR	0x00000400
+#define	AR_Q_MISC_DCU_EARLY_TERM_REQ	0x00000800
+#define	AR_Q_MISC_RESV0			0xFFFFF000
+
+#define	AR_Q0_STS		0x0a00
+#define	AR_Q1_STS		0x0a04
+#define	AR_Q2_STS		0x0a08
+#define	AR_Q3_STS		0x0a0c
+#define	AR_Q4_STS		0x0a10
+#define	AR_Q5_STS		0x0a14
+#define	AR_Q6_STS		0x0a18
+#define	AR_Q7_STS		0x0a1c
+#define	AR_Q8_STS		0x0a20
+#define	AR_Q9_STS		0x0a24
+#define	AR_QSTS(_i)		(AR_Q0_STS + ((_i)<<2))
+#define	AR_Q_STS_PEND_FR_CNT	0x00000003
+#define	AR_Q_STS_RESV0		0x000000FC
+#define	AR_Q_STS_CBR_EXP_CNT	0x0000FF00
+#define	AR_Q_STS_RESV1		0xFFFF0000
+
+#define	AR_Q_RDYTIMESHDN	0x0a40
+#define	AR_Q_RDYTIMESHDN_M	0x000003FF
+
+
+#define	AR_NUM_DCU	10
+#define	AR_DCU_0	0x0001
+#define	AR_DCU_1	0x0002
+#define	AR_DCU_2	0x0004
+#define	AR_DCU_3	0x0008
+#define	AR_DCU_4	0x0010
+#define	AR_DCU_5	0x0020
+#define	AR_DCU_6	0x0040
+#define	AR_DCU_7	0x0080
+#define	AR_DCU_8	0x0100
+#define	AR_DCU_9	0x0200
+
+#define	AR_D0_QCUMASK		0x1000
+#define	AR_D1_QCUMASK		0x1004
+#define	AR_D2_QCUMASK		0x1008
+#define	AR_D3_QCUMASK		0x100c
+#define	AR_D4_QCUMASK		0x1010
+#define	AR_D5_QCUMASK		0x1014
+#define	AR_D6_QCUMASK		0x1018
+#define	AR_D7_QCUMASK		0x101c
+#define	AR_D8_QCUMASK		0x1020
+#define	AR_D9_QCUMASK		0x1024
+#define	AR_DQCUMASK(_i)		(AR_D0_QCUMASK + ((_i)<<2))
+#define	AR_D_QCUMASK		0x000003FF
+#define	AR_D_QCUMASK_RESV0	0xFFFFFC00
+
+#define	AR_D_TXBLK_CMD		0x1038
+#define	AR_D_TXBLK_DATA(i)	(AR_D_TXBLK_CMD+(i))
+
+#define	AR_D0_LCL_IFS		0x1040
+#define	AR_D1_LCL_IFS		0x1044
+#define	AR_D2_LCL_IFS		0x1048
+#define	AR_D3_LCL_IFS		0x104c
+#define	AR_D4_LCL_IFS		0x1050
+#define	AR_D5_LCL_IFS		0x1054
+#define	AR_D6_LCL_IFS		0x1058
+#define	AR_D7_LCL_IFS		0x105c
+#define	AR_D8_LCL_IFS		0x1060
+#define	AR_D9_LCL_IFS		0x1064
+#define	AR_DLCL_IFS(_i)		(AR_D0_LCL_IFS + ((_i)<<2))
+#define	AR_D_LCL_IFS_CWMIN	0x000003FF
+#define	AR_D_LCL_IFS_CWMIN_S	0
+#define	AR_D_LCL_IFS_CWMAX	0x000FFC00
+#define	AR_D_LCL_IFS_CWMAX_S	10
+#define	AR_D_LCL_IFS_AIFS	0x0FF00000
+#define	AR_D_LCL_IFS_AIFS_S	20
+
+#define	AR_D_LCL_IFS_RESV0	0xF0000000
+
+#define	AR_D0_RETRY_LIMIT		0x1080
+#define	AR_D1_RETRY_LIMIT		0x1084
+#define	AR_D2_RETRY_LIMIT		0x1088
+#define	AR_D3_RETRY_LIMIT		0x108c
+#define	AR_D4_RETRY_LIMIT		0x1090
+#define	AR_D5_RETRY_LIMIT		0x1094
+#define	AR_D6_RETRY_LIMIT		0x1098
+#define	AR_D7_RETRY_LIMIT		0x109c
+#define	AR_D8_RETRY_LIMIT		0x10a0
+#define	AR_D9_RETRY_LIMIT		0x10a4
+#define	AR_DRETRY_LIMIT(_i)		(AR_D0_RETRY_LIMIT + ((_i)<<2))
+#define	AR_D_RETRY_LIMIT_FR_SH		0x0000000F
+#define	AR_D_RETRY_LIMIT_FR_SH_S	0
+#define	AR_D_RETRY_LIMIT_STA_SH		0x00003F00
+#define	AR_D_RETRY_LIMIT_STA_SH_S	8
+#define	AR_D_RETRY_LIMIT_STA_LG		0x000FC000
+#define	AR_D_RETRY_LIMIT_STA_LG_S	14
+#define	AR_D_RETRY_LIMIT_RESV0		0xFFF00000
+
+#define	AR_D0_CHNTIME		0x10c0
+#define	AR_D1_CHNTIME		0x10c4
+#define	AR_D2_CHNTIME		0x10c8
+#define	AR_D3_CHNTIME		0x10cc
+#define	AR_D4_CHNTIME		0x10d0
+#define	AR_D5_CHNTIME		0x10d4
+#define	AR_D6_CHNTIME		0x10d8
+#define	AR_D7_CHNTIME		0x10dc
+#define	AR_D8_CHNTIME		0x10e0
+#define	AR_D9_CHNTIME		0x10e4
+#define	AR_DCHNTIME(_i)		(AR_D0_CHNTIME + ((_i)<<2))
+#define	AR_D_CHNTIME_DUR	0x000FFFFF
+#define	AR_D_CHNTIME_DUR_S	0
+#define	AR_D_CHNTIME_EN		0x00100000
+#define	AR_D_CHNTIME_RESV0	0xFFE00000
+
+#define	AR_D0_MISC	0x1100
+#define	AR_D1_MISC	0x1104
+#define	AR_D2_MISC	0x1108
+#define	AR_D3_MISC	0x110c
+#define	AR_D4_MISC	0x1110
+#define	AR_D5_MISC	0x1114
+#define	AR_D6_MISC	0x1118
+#define	AR_D7_MISC	0x111c
+#define	AR_D8_MISC	0x1120
+#define	AR_D9_MISC	0x1124
+#define	AR_DMISC(_i)	(AR_D0_MISC + ((_i)<<2))
+#define	AR_D_MISC_BKOFF_THRESH		0x0000003F
+#define	AR_D_MISC_RETRY_CNT_RESET_EN	0x00000040
+#define	AR_D_MISC_CW_RESET_EN		0x00000080
+#define	AR_D_MISC_FRAG_WAIT_EN		0x00000100
+#define	AR_D_MISC_FRAG_BKOFF_EN		0x00000200
+#define	AR_D_MISC_CW_BKOFF_EN		0x00001000
+#define	AR_D_MISC_VIR_COL_HANDLING	0x0000C000
+#define	AR_D_MISC_VIR_COL_HANDLING_S	14
+#define	AR_D_MISC_VIR_COL_HANDLING_DEFAULT	0
+#define	AR_D_MISC_VIR_COL_HANDLING_IGNORE	1
+#define	AR_D_MISC_BEACON_USE		0x00010000
+#define	AR_D_MISC_ARB_LOCKOUT_CNTRL	0x00060000
+#define	AR_D_MISC_ARB_LOCKOUT_CNTRL_S	17
+#define	AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE	0
+#define	AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR	1
+#define	AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL	2
+#define	AR_D_MISC_ARB_LOCKOUT_IGNORE	0x00080000
+#define	AR_D_MISC_SEQ_NUM_INCR_DIS	0x00100000
+#define	AR_D_MISC_POST_FR_BKOFF_DIS	0x00200000
+#define	AR_D_MISC_VIT_COL_CW_BKOFF_EN	0x00400000
+#define	AR_D_MISC_BLOWN_IFS_RETRY_EN	0x00800000
+#define	AR_D_MISC_RESV0			0xFF000000
+
+#define	AR_D_SEQNUM	0x1140
+
+#define	AR_D_GBL_IFS_SIFS		0x1030
+#define	AR_D_GBL_IFS_SIFS_M		0x0000FFFF
+#define	AR_D_GBL_IFS_SIFS_RESV0		0xFFFFFFFF
+
+#define	AR_D_TXBLK_BASE			0x1038
+#define	AR_D_TXBLK_WRITE_BITMASK	0x0000FFFF
+#define	AR_D_TXBLK_WRITE_BITMASK_S	0
+#define	AR_D_TXBLK_WRITE_SLICE		0x000F0000
+#define	AR_D_TXBLK_WRITE_SLICE_S	16
+#define	AR_D_TXBLK_WRITE_DCU		0x00F00000
+#define	AR_D_TXBLK_WRITE_DCU_S		20
+#define	AR_D_TXBLK_WRITE_COMMAND	0x0F000000
+#define	AR_D_TXBLK_WRITE_COMMAND_S	24
+
+#define	AR_D_GBL_IFS_SLOT	0x1070
+#define	AR_D_GBL_IFS_SLOT_M	0x0000FFFF
+#define	AR_D_GBL_IFS_SLOT_RESV0	0xFFFF0000
+
+#define	AR_D_GBL_IFS_EIFS	0x10b0
+#define	AR_D_GBL_IFS_EIFS_M	0x0000FFFF
+#define	AR_D_GBL_IFS_EIFS_RESV0	0xFFFF0000
+
+#define	AR_D_GBL_IFS_MISC			0x10f0
+#define	AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL	0x00000007
+#define	AR_D_GBL_IFS_MISC_TURBO_MODE		0x00000008
+#define	AR_D_GBL_IFS_MISC_USEC_DURATION		0x000FFC00
+#define	AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY	0x00300000
+#define	AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS	0x01000000
+#define	AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN	0x06000000
+#define	AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND	0x08000000
+#define	AR_D_GBL_IFS_MISC_IGNORE_BACKOFF	0x10000000
+
+#define	AR_D_FPCTL			0x1230
+#define	AR_D_FPCTL_DCU			0x0000000F
+#define	AR_D_FPCTL_DCU_S		0
+#define	AR_D_FPCTL_PREFETCH_EN		0x00000010
+#define	AR_D_FPCTL_BURST_PREFETCH	0x00007FE0
+#define	AR_D_FPCTL_BURST_PREFETCH_S	5
+
+#define	AR_D_TXPSE			0x1270
+#define	AR_D_TXPSE_CTRL			0x000003FF
+#define	AR_D_TXPSE_RESV0		0x0000FC00
+#define	AR_D_TXPSE_STATUS		0x00010000
+#define	AR_D_TXPSE_RESV1		0xFFFE0000
+
+#define	AR_D_TXSLOTMASK			0x12f0
+#define	AR_D_TXSLOTMASK_NUM		0x0000000F
+
+#define	AR_CFG_LED			0x1f04
+#define	AR_CFG_SCLK_RATE_IND		0x00000003
+#define	AR_CFG_SCLK_RATE_IND_S		0
+#define	AR_CFG_SCLK_32MHZ		0x00000000
+#define	AR_CFG_SCLK_4MHZ		0x00000001
+#define	AR_CFG_SCLK_1MHZ		0x00000002
+#define	AR_CFG_SCLK_32KHZ		0x00000003
+#define	AR_CFG_LED_BLINK_SLOW		0x00000008
+#define	AR_CFG_LED_BLINK_THRESH_SEL	0x00000070
+#define	AR_CFG_LED_MODE_SEL		0x00000380
+#define	AR_CFG_LED_MODE_SEL_S		7
+#define	AR_CFG_LED_POWER		0x00000280
+#define	AR_CFG_LED_POWER_S		7
+#define	AR_CFG_LED_NETWORK		0x00000300
+#define	AR_CFG_LED_NETWORK_S		7
+#define	AR_CFG_LED_MODE_PROP		0x0
+#define	AR_CFG_LED_MODE_RPROP		0x1
+#define	AR_CFG_LED_MODE_SPLIT		0x2
+#define	AR_CFG_LED_MODE_RAND		0x3
+#define	AR_CFG_LED_MODE_POWER_OFF	0x4
+#define	AR_CFG_LED_MODE_POWER_ON	0x5
+#define	AR_CFG_LED_MODE_NETWORK_OFF	0x4
+#define	AR_CFG_LED_MODE_NETWORK_ON	0x6
+#define	AR_CFG_LED_ASSOC_CTL		0x00000c00
+#define	AR_CFG_LED_ASSOC_CTL_S		10
+#define	AR_CFG_LED_ASSOC_NONE		0x0
+#define	AR_CFG_LED_ASSOC_ACTIVE		0x1
+#define	AR_CFG_LED_ASSOC_PENDING	0x2
+
+#define	AR_CFG_LED_BLINK_SLOW		0x00000008
+#define	AR_CFG_LED_BLINK_SLOW_S		3
+
+#define	AR_CFG_LED_BLINK_THRESH_SEL	0x00000070
+#define	AR_CFG_LED_BLINK_THRESH_SEL_S	4
+
+#define	AR_MAC_SLEEP			0x1f00
+#define	AR_MAC_SLEEP_MAC_AWAKE		0x00000000
+#define	AR_MAC_SLEEP_MAC_ASLEEP		0x00000001
+
+#define	AR_RC		0x4000
+#define	AR_RC_AHB	0x00000001
+#define	AR_RC_APB	0x00000002
+#define	AR_RC_HOSTIF	0x00000100
+
+#define	AR_WA		0x4004
+#define	AR9285_WA_DEFAULT		0x004a05cb
+#define	AR9280_WA_DEFAULT		0x0040073f
+#define	AR_WA_DEFAULT			0x0000073f
+
+#define	AR_PM_STATE			0x4008
+#define	AR_PM_STATE_PME_D3COLD_VAUX	0x00100000
+
+#define	AR_HOST_TIMEOUT			0x4018
+#define	AR_HOST_TIMEOUT_APB_CNTR	0x0000FFFF
+#define	AR_HOST_TIMEOUT_APB_CNTR_S	0
+#define	AR_HOST_TIMEOUT_LCL_CNTR	0xFFFF0000
+#define	AR_HOST_TIMEOUT_LCL_CNTR_S	16
+
+#define	AR_EEPROM			0x401c
+#define	AR_EEPROM_ABSENT		0x00000100
+#define	AR_EEPROM_CORRUPT		0x00000200
+#define	AR_EEPROM_PROT_MASK		0x03FFFC00
+#define	AR_EEPROM_PROT_MASK_S		10
+
+#define	EEPROM_PROTECT_RP_0_31		0x0001
+#define	EEPROM_PROTECT_WP_0_31		0x0002
+#define	EEPROM_PROTECT_RP_32_63		0x0004
+#define	EEPROM_PROTECT_WP_32_63		0x0008
+#define	EEPROM_PROTECT_RP_64_127	0x0010
+#define	EEPROM_PROTECT_WP_64_127	0x0020
+#define	EEPROM_PROTECT_RP_128_191	0x0040
+#define	EEPROM_PROTECT_WP_128_191	0x0080
+#define	EEPROM_PROTECT_RP_192_255	0x0100
+#define	EEPROM_PROTECT_WP_192_255	0x0200
+#define	EEPROM_PROTECT_RP_256_511	0x0400
+#define	EEPROM_PROTECT_WP_256_511	0x0800
+#define	EEPROM_PROTECT_RP_512_1023	0x1000
+#define	EEPROM_PROTECT_WP_512_1023	0x2000
+#define	EEPROM_PROTECT_RP_1024_2047	0x4000
+#define	EEPROM_PROTECT_WP_1024_2047	0x8000
+
+#define	AR_SREV \
+	((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
+
+#define	AR_SREV_ID \
+	((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
+#define	AR_SREV_VERSION			0x000000F0
+#define	AR_SREV_VERSION_S		4
+#define	AR_SREV_REVISION		0x00000007
+
+#define	AR_SREV_ID2			0xFFFFFFFF
+#define	AR_SREV_VERSION2		0xFFFC0000
+#define	AR_SREV_VERSION2_S		18
+#define	AR_SREV_TYPE2			0x0003F000
+#define	AR_SREV_TYPE2_S			12
+#define	AR_SREV_TYPE2_CHAIN		0x00001000
+#define	AR_SREV_TYPE2_HOST_MODE		0x00002000
+#define	AR_SREV_REVISION2		0x00000F00
+#define	AR_SREV_REVISION2_S		8
+
+#define	AR_SREV_VERSION_5416_PCI	0xD
+#define	AR_SREV_VERSION_5416_PCIE	0xC
+#define	AR_SREV_REVISION_5416_10	0
+#define	AR_SREV_REVISION_5416_20	1
+#define	AR_SREV_REVISION_5416_22	2
+#define	AR_SREV_VERSION_9160		0x40
+#define	AR_SREV_REVISION_9160_10	0
+#define	AR_SREV_REVISION_9160_11	1
+#define	AR_SREV_VERSION_9280		0x80
+#define	AR_SREV_REVISION_9280_10	0
+#define	AR_SREV_REVISION_9280_20	1
+#define	AR_SREV_REVISION_9280_21	2
+#define	AR_SREV_VERSION_9285		0xC0
+#define	AR_SREV_REVISION_9285_10	0
+#define	AR_SREV_REVISION_9285_11	1
+#define	AR_SREV_REVISION_9285_12	2
+
+#define	AR_SREV_9100_OR_LATER(_ah) \
+	(((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
+#define	AR_SREV_5416_20_OR_LATER(_ah) \
+	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
+		((_ah)->ah_macRev >= AR_SREV_REVISION_5416_20))
+#define	AR_SREV_5416_22_OR_LATER(_ah) \
+	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
+		((_ah)->ah_macRev >= AR_SREV_REVISION_5416_22))
+#define	AR_SREV_9160(_ah) \
+	(((_ah)->ah_macVersion == AR_SREV_VERSION_9160))
+#define	AR_SREV_9160_10_OR_LATER(_ah) \
+	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9160))
+#define	AR_SREV_9160_11(_ah) \
+	(AR_SREV_9160(_ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9160_11))
+#define	AR_SREV_9280(_ah) \
+	(((_ah)->ah_macVersion == AR_SREV_VERSION_9280))
+#define	AR_SREV_9280_10_OR_LATER(_ah) \
+	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9280))
+#define	AR_SREV_9280_20(_ah) \
+	(((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
+		((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20))
+#define	AR_SREV_9280_20_OR_LATER(_ah) \
+	(((_ah)->ah_macVersion > AR_SREV_VERSION_9280) || \
+	(((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
+	((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20)))
+
+#define	AR_SREV_9285(_ah)	(((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
+#define	AR_SREV_9285_10_OR_LATER(_ah)	\
+	(((_ah)->ah_macVersion >= AR_SREV_VERSION_9285))
+#define	AR_SREV_9285_11(_ah) \
+	(AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_11))
+#define	AR_SREV_9285_11_OR_LATER(_ah)	\
+	(((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
+	(AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_11)))
+#define	AR_SREV_9285_12(_ah)	\
+	(AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_12))
+#define	AR_SREV_9285_12_OR_LATER(_ah)	\
+	(((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
+	(AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_12)))
+
+#define	AR_RADIO_SREV_MAJOR		0xf0
+#define	AR_RAD5133_SREV_MAJOR		0xc0
+#define	AR_RAD2133_SREV_MAJOR		0xd0
+#define	AR_RAD5122_SREV_MAJOR		0xe0
+#define	AR_RAD2122_SREV_MAJOR		0xf0
+
+#define	AR_AHB_MODE			0x4024
+#define	AR_AHB_EXACT_WR_EN		0x00000000
+#define	AR_AHB_BUF_WR_EN		0x00000001
+#define	AR_AHB_EXACT_RD_EN		0x00000000
+#define	AR_AHB_CACHELINE_RD_EN		0x00000002
+#define	AR_AHB_PREFETCH_RD_EN		0x00000004
+#define	AR_AHB_PAGE_SIZE_1K		0x00000000
+#define	AR_AHB_PAGE_SIZE_2K		0x00000008
+#define	AR_AHB_PAGE_SIZE_4K		0x00000010
+
+#define	AR_INTR_RTC_IRQ			0x00000001
+#define	AR_INTR_MAC_IRQ			0x00000002
+#define	AR_INTR_EEP_PROT_ACCESS		0x00000004
+#define	AR_INTR_MAC_AWAKE		0x00020000
+#define	AR_INTR_MAC_ASLEEP		0x00040000
+#define	AR_INTR_SPURIOUS		0xFFFFFFFF
+
+
+#define	AR_INTR_SYNC_CAUSE_CLR		0x4028
+
+#define	AR_INTR_SYNC_CAUSE		0x4028
+
+#define	AR_INTR_SYNC_ENABLE		0x402c
+#define	AR_INTR_SYNC_ENABLE_GPIO	0xFFFC0000
+#define	AR_INTR_SYNC_ENABLE_GPIO_S	18
+
+enum {
+	AR_INTR_SYNC_RTC_IRQ = 0x00000001,
+	AR_INTR_SYNC_MAC_IRQ = 0x00000002,
+	AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS = 0x00000004,
+	AR_INTR_SYNC_APB_TIMEOUT = 0x00000008,
+	AR_INTR_SYNC_PCI_MODE_CONFLICT = 0x00000010,
+	AR_INTR_SYNC_HOST1_FATAL = 0x00000020,
+	AR_INTR_SYNC_HOST1_PERR = 0x00000040,
+	AR_INTR_SYNC_TRCV_FIFO_PERR = 0x00000080,
+	AR_INTR_SYNC_RADM_CPL_EP = 0x00000100,
+	AR_INTR_SYNC_RADM_CPL_DLLP_ABORT = 0x00000200,
+	AR_INTR_SYNC_RADM_CPL_TLP_ABORT = 0x00000400,
+	AR_INTR_SYNC_RADM_CPL_ECRC_ERR = 0x00000800,
+	AR_INTR_SYNC_RADM_CPL_TIMEOUT = 0x00001000,
+	AR_INTR_SYNC_LOCAL_TIMEOUT = 0x00002000,
+	AR_INTR_SYNC_PM_ACCESS = 0x00004000,
+	AR_INTR_SYNC_MAC_AWAKE = 0x00008000,
+	AR_INTR_SYNC_MAC_ASLEEP = 0x00010000,
+	AR_INTR_SYNC_MAC_SLEEP_ACCESS = 0x00020000,
+	AR_INTR_SYNC_ALL = 0x0003FFFF,
+
+
+	AR_INTR_SYNC_DEFAULT = (AR_INTR_SYNC_HOST1_FATAL |
+	    AR_INTR_SYNC_HOST1_PERR |
+	    AR_INTR_SYNC_RADM_CPL_EP |
+	    AR_INTR_SYNC_RADM_CPL_DLLP_ABORT |
+	    AR_INTR_SYNC_RADM_CPL_TLP_ABORT |
+	    AR_INTR_SYNC_RADM_CPL_ECRC_ERR |
+	    AR_INTR_SYNC_RADM_CPL_TIMEOUT |
+	    AR_INTR_SYNC_LOCAL_TIMEOUT |
+	    AR_INTR_SYNC_MAC_SLEEP_ACCESS),
+
+	/* AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF, */
+	AR_INTR_SYNC_SPURIOUS = -1,
+
+};
+
+#define	AR_INTR_ASYNC_MASK		0x4030
+#define	AR_INTR_ASYNC_MASK_GPIO		0xFFFC0000
+#define	AR_INTR_ASYNC_MASK_GPIO_S	18
+
+#define	AR_INTR_SYNC_MASK		0x4034
+#define	AR_INTR_SYNC_MASK_GPIO		0xFFFC0000
+#define	AR_INTR_SYNC_MASK_GPIO_S	18
+
+#define	AR_INTR_ASYNC_CAUSE_CLR		0x4038
+#define	AR_INTR_ASYNC_CAUSE		0x4038
+
+#define	AR_INTR_ASYNC_ENABLE		0x403c
+#define	AR_INTR_ASYNC_ENABLE_GPIO	0xFFFC0000
+#define	AR_INTR_ASYNC_ENABLE_GPIO_S	18
+
+#define	AR_PCIE_SERDES		0x4040
+#define	AR_PCIE_SERDES2		0x4044
+#define	AR_PCIE_PM_CTRL		0x4014
+#define	AR_PCIE_PM_CTRL_ENA	0x00080000
+
+#define	AR_NUM_GPIO	14
+#define	AR928X_NUM_GPIO	10
+
+#define	AR_GPIO_IN_OUT		0x4048
+#define	AR_GPIO_IN_VAL		0x0FFFC000
+#define	AR_GPIO_IN_VAL_S	14
+#define	AR928X_GPIO_IN_VAL	0x000FFC00
+#define	AR928X_GPIO_IN_VAL_S	10
+
+#define	AR_GPIO_OE_OUT		0x404c
+#define	AR_GPIO_OE_OUT_DRV	0x3
+#define	AR_GPIO_OE_OUT_DRV_NO	0x0
+#define	AR_GPIO_OE_OUT_DRV_LOW	0x1
+#define	AR_GPIO_OE_OUT_DRV_HI	0x2
+#define	AR_GPIO_OE_OUT_DRV_ALL	0x3
+
+#define	AR_GPIO_INTR_POL	0x4050
+#define	AR_GPIO_INTR_POL_VAL	0x00001FFF
+#define	AR_GPIO_INTR_POL_VAL_S	0
+
+#define	AR_GPIO_INPUT_EN_VAL			0x4054
+#define	AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF	0x00000080
+#define	AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S	7
+#define	AR_GPIO_INPUT_EN_VAL_RFSILENT_BB	0x00008000
+#define	AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S	15
+#define	AR_GPIO_RTC_RESET_OVERRIDE_ENABLE	0x00010000
+#define	AR_GPIO_JTAG_DISABLE			0x00020000
+
+#define	AR_GPIO_INPUT_MUX1	0x4058
+
+#define	AR_GPIO_INPUT_MUX2		0x405c
+#define	AR_GPIO_INPUT_MUX2_CLK25	0x0000000f
+#define	AR_GPIO_INPUT_MUX2_CLK25_S	0
+#define	AR_GPIO_INPUT_MUX2_RFSILENT	0x000000f0
+#define	AR_GPIO_INPUT_MUX2_RFSILENT_S	4
+#define	AR_GPIO_INPUT_MUX2_RTC_RESET	0x00000f00
+#define	AR_GPIO_INPUT_MUX2_RTC_RESET_S	8
+
+#define	AR_GPIO_OUTPUT_MUX1	0x4060
+#define	AR_GPIO_OUTPUT_MUX2	0x4064
+#define	AR_GPIO_OUTPUT_MUX3	0x4068
+
+#define	AR_INPUT_STATE		0x406c
+
+#define	AR_EEPROM_STATUS_DATA			0x407c
+#define	AR_EEPROM_STATUS_DATA_VAL		0x0000ffff
+#define	AR_EEPROM_STATUS_DATA_VAL_S		0
+#define	AR_EEPROM_STATUS_DATA_BUSY		0x00010000
+#define	AR_EEPROM_STATUS_DATA_BUSY_ACCESS	0x00020000
+#define	AR_EEPROM_STATUS_DATA_PROT_ACCESS	0x00040000
+#define	AR_EEPROM_STATUS_DATA_ABSENT_ACCESS	0x00080000
+
+#define	AR_OBS	0x4080
+
+#define	AR_PCIE_MSI		0x4094
+#define	AR_PCIE_MSI_ENABLE	0x00000001
+
+
+#define	AR_RTC_9160_PLL_DIV		0x000003ff
+#define	AR_RTC_9160_PLL_DIV_S		0
+#define	AR_RTC_9160_PLL_REFDIV		0x00003C00
+#define	AR_RTC_9160_PLL_REFDIV_S	10
+#define	AR_RTC_9160_PLL_CLKSEL		0x0000C000
+#define	AR_RTC_9160_PLL_CLKSEL_S	14
+
+#define	AR_RTC_BASE	0x00020000
+#define	AR_RTC_RC \
+	(AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000
+#define	AR_RTC_RC_M		0x00000003
+#define	AR_RTC_RC_MAC_WARM	0x00000001
+#define	AR_RTC_RC_MAC_COLD	0x00000002
+#define	AR_RTC_RC_COLD_RESET	0x00000004
+#define	AR_RTC_RC_WARM_RESET	0x00000008
+
+#define	AR_RTC_PLL_CONTROL \
+	(AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014
+
+#define	AR_RTC_PLL_DIV		0x0000001f
+#define	AR_RTC_PLL_DIV_S	0
+#define	AR_RTC_PLL_DIV2		0x00000020
+#define	AR_RTC_PLL_REFDIV_5	0x000000c0
+#define	AR_RTC_PLL_CLKSEL	0x00000300
+#define	AR_RTC_PLL_CLKSEL_S	8
+
+
+
+#define	AR_RTC_RESET \
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
+#define	AR_RTC_RESET_EN		(0x00000001)
+
+#define	AR_RTC_STATUS \
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0044) : 0x7044)
+
+#define	AR_RTC_STATUS_M \
+	((AR_SREV_9100(ah)) ? 0x0000003f : 0x0000000f)
+
+#define	AR_RTC_PM_STATUS_M	0x0000000f
+
+#define	AR_RTC_STATUS_SHUTDOWN	0x00000001
+#define	AR_RTC_STATUS_ON	0x00000002
+#define	AR_RTC_STATUS_SLEEP	0x00000004
+#define	AR_RTC_STATUS_WAKEUP	0x00000008
+
+#define	AR_RTC_SLEEP_CLK \
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
+#define	AR_RTC_FORCE_DERIVED_CLK    0x2
+
+#define	AR_RTC_FORCE_WAKE \
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
+#define	AR_RTC_FORCE_WAKE_EN		0x00000001
+#define	AR_RTC_FORCE_WAKE_ON_INT	0x00000002
+
+
+#define	AR_RTC_INTR_CAUSE \
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0050) : 0x7050)
+
+#define	AR_RTC_INTR_ENABLE \
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0054) : 0x7054)
+
+#define	AR_RTC_INTR_MASK \
+	((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
+
+#define	AR_SEQ_MASK		0x8060
+
+#define	AR_AN_RF2G1_CH0		0x7810
+#define	AR_AN_RF2G1_CH0_OB	0x03800000
+#define	AR_AN_RF2G1_CH0_OB_S	23
+#define	AR_AN_RF2G1_CH0_DB	0x1C000000
+#define	AR_AN_RF2G1_CH0_DB_S	26
+
+#define	AR_AN_RF5G1_CH0		0x7818
+#define	AR_AN_RF5G1_CH0_OB5	0x00070000
+#define	AR_AN_RF5G1_CH0_OB5_S	16
+#define	AR_AN_RF5G1_CH0_DB5	0x00380000
+#define	AR_AN_RF5G1_CH0_DB5_S	19
+
+#define	AR_AN_RF2G1_CH1		0x7834
+#define	AR_AN_RF2G1_CH1_OB	0x03800000
+#define	AR_AN_RF2G1_CH1_OB_S	23
+#define	AR_AN_RF2G1_CH1_DB	0x1C000000
+#define	AR_AN_RF2G1_CH1_DB_S	26
+
+#define	AR_AN_RF5G1_CH1		0x783C
+#define	AR_AN_RF5G1_CH1_OB5	0x00070000
+#define	AR_AN_RF5G1_CH1_OB5_S	16
+#define	AR_AN_RF5G1_CH1_DB5	0x00380000
+#define	AR_AN_RF5G1_CH1_DB5_S	19
+
+#define	AR_AN_TOP2			0x7894
+#define	AR_AN_TOP2_XPABIAS_LVL		0xC0000000
+#define	AR_AN_TOP2_XPABIAS_LVL_S	30
+#define	AR_AN_TOP2_LOCALBIAS		0x00200000
+#define	AR_AN_TOP2_LOCALBIAS_S		21
+#define	AR_AN_TOP2_PWDCLKIND		0x00400000
+#define	AR_AN_TOP2_PWDCLKIND_S		22
+
+#define	AR_AN_SYNTH9		0x7868
+#define	AR_AN_SYNTH9_REFDIVA	0xf8000000
+#define	AR_AN_SYNTH9_REFDIVA_S	27
+
+#define	AR9285_AN_RF2G1			0x7820
+#define	AR9285_AN_RF2G1_ENPACAL		0x00000800
+#define	AR9285_AN_RF2G1_ENPACAL_S	11
+#define	AR9285_AN_RF2G1_PDPADRV1	0x02000000
+#define	AR9285_AN_RF2G1_PDPADRV1_S	25
+#define	AR9285_AN_RF2G1_PDPADRV2	0x01000000
+#define	AR9285_AN_RF2G1_PDPADRV2_S	24
+#define	AR9285_AN_RF2G1_PDPAOUT		0x00800000
+#define	AR9285_AN_RF2G1_PDPAOUT_S	23
+#define	AR9285_AN_RF2G2			0x7824
+#define	AR9285_AN_RF2G2_OFFCAL		0x00001000
+#define	AR9285_AN_RF2G2_OFFCAL_S	12
+#define	AR9285_AN_RF2G3			0x7828
+#define	AR9285_AN_RF2G3_PDVCCOMP	0x02000000
+#define	AR9285_AN_RF2G3_PDVCCOMP_S	25
+#define	AR9285_AN_RF2G3_OB_0		0x00E00000
+#define	AR9285_AN_RF2G3_OB_0_S		21
+#define	AR9285_AN_RF2G3_OB_1		0x001C0000
+#define	AR9285_AN_RF2G3_OB_1_S		18
+#define	AR9285_AN_RF2G3_OB_2		0x00038000
+#define	AR9285_AN_RF2G3_OB_2_S		15
+#define	AR9285_AN_RF2G3_OB_3		0x00007000
+#define	AR9285_AN_RF2G3_OB_3_S		12
+#define	AR9285_AN_RF2G3_OB_4		0x00000E00
+#define	AR9285_AN_RF2G3_OB_4_S		9
+#define	AR9285_AN_RF2G3_DB1_0		0x000001C0
+#define	AR9285_AN_RF2G3_DB1_0_S		6
+#define	AR9285_AN_RF2G3_DB1_1		0x00000038
+#define	AR9285_AN_RF2G3_DB1_1_S		3
+#define	AR9285_AN_RF2G3_DB1_2		0x00000007
+#define	AR9285_AN_RF2G3_DB1_2_S		0
+#define	AR9285_AN_RF2G4			0x782C
+#define	AR9285_AN_RF2G4_DB1_3		0xE0000000
+#define	AR9285_AN_RF2G4_DB1_3_S		29
+#define	AR9285_AN_RF2G4_DB1_4		0x1C000000
+#define	AR9285_AN_RF2G4_DB1_4_S		26
+#define	AR9285_AN_RF2G4_DB2_0		0x03800000
+#define	AR9285_AN_RF2G4_DB2_0_S		23
+#define	AR9285_AN_RF2G4_DB2_1		0x00700000
+#define	AR9285_AN_RF2G4_DB2_1_S		20
+#define	AR9285_AN_RF2G4_DB2_2		0x000E0000
+#define	AR9285_AN_RF2G4_DB2_2_S		17
+#define	AR9285_AN_RF2G4_DB2_3		0x0001C000
+#define	AR9285_AN_RF2G4_DB2_3_S		14
+#define	AR9285_AN_RF2G4_DB2_4		0x00003800
+#define	AR9285_AN_RF2G4_DB2_4_S		11
+#define	AR9285_AN_RF2G6			0x7834
+#define	AR9285_AN_RF2G6_CCOMP		0x00007800
+#define	AR9285_AN_RF2G6_CCOMP_S		11
+#define	AR9285_AN_RF2G6_OFFS		0x03f00000
+#define	AR9285_AN_RF2G6_OFFS_S		20
+#define	AR9285_AN_RF2G7			0x7838
+#define	AR9285_AN_RF2G7_PWDDB		0x00000002
+#define	AR9285_AN_RF2G7_PWDDB_S		1
+#define	AR9285_AN_RF2G7_PADRVGN2TAB0	0xE0000000
+#define	AR9285_AN_RF2G7_PADRVGN2TAB0_S	29
+#define	AR9285_AN_RF2G8			0x783C
+#define	AR9285_AN_RF2G8_PADRVGN2TAB0	0x0001C000
+#define	AR9285_AN_RF2G8_PADRVGN2TAB0_S	14
+#define	AR9285_AN_RF2G9		0x7840
+#define	AR9285_AN_RXTXBB1	0x7854
+#define	AR9285_AN_RXTXBB1_PDRXTXBB1	0x00000020
+#define	AR9285_AN_RXTXBB1_PDRXTXBB1_S	5
+#define	AR9285_AN_RXTXBB1_PDV2I	0x00000080
+#define	AR9285_AN_RXTXBB1_PDV2I_S	7
+#define	AR9285_AN_RXTXBB1_PDDACIF	0x00000100
+#define	AR9285_AN_RXTXBB1_PDDACIF_S	8
+#define	AR9285_AN_RXTXBB1_SPARE9	0x00000001
+#define	AR9285_AN_RXTXBB1_SPARE9_S	0
+#define	AR9285_AN_TOP2	0x7868
+#define	AR9285_AN_TOP3	0x786c
+#define	AR9285_AN_TOP3_XPABIAS_LVL	0x0000000C
+#define	AR9285_AN_TOP3_XPABIAS_LVL_S	2
+#define	AR9285_AN_TOP3_PWDDAC	0x00800000
+#define	AR9285_AN_TOP3_PWDDAC_S	23
+#define	AR9285_AN_TOP4	0x7870
+#define	AR9285_AN_TOP4_DEFAULT	0x10142c00
+#define	AR_STA_ID0			0x8000
+#define	AR_STA_ID1			0x8004
+#define	AR_STA_ID1_SADH_MASK		0x0000FFFF
+#define	AR_STA_ID1_STA_AP		0x00010000
+#define	AR_STA_ID1_ADHOC		0x00020000
+#define	AR_STA_ID1_PWR_SAV		0x00040000
+#define	AR_STA_ID1_KSRCHDIS		0x00080000
+#define	AR_STA_ID1_PCF			0x00100000
+#define	AR_STA_ID1_USE_DEFANT		0x00200000
+#define	AR_STA_ID1_DEFANT_UPDATE	0x00400000
+#define	AR_STA_ID1_RTS_USE_DEF		0x00800000
+#define	AR_STA_ID1_ACKCTS_6MB		0x01000000
+#define	AR_STA_ID1_BASE_RATE_11B	0x02000000
+#define	AR_STA_ID1_SECTOR_SELF_GEN	0x04000000
+#define	AR_STA_ID1_CRPT_MIC_ENABLE	0x08000000
+#define	AR_STA_ID1_KSRCH_MODE		0x10000000
+#define	AR_STA_ID1_PRESERVE_SEQNUM	0x20000000
+#define	AR_STA_ID1_CBCIV_ENDIAN		0x40000000
+#define	AR_STA_ID1_MCAST_KSRCH		0x80000000
+
+#define	AR_BSS_ID0		0x8008
+#define	AR_BSS_ID1		0x800C
+#define	AR_BSS_ID1_U16	0x0000FFFF
+#define	AR_BSS_ID1_AID		0x07FF0000
+#define	AR_BSS_ID1_AID_S	16
+
+#define	AR_BCN_RSSI_AVE		0x8010
+#define	AR_BCN_RSSI_AVE_MASK	0x00000FFF
+
+#define	AR_TIME_OUT		0x8014
+#define	AR_TIME_OUT_ACK		0x00003FFF
+#define	AR_TIME_OUT_ACK_S	0
+#define	AR_TIME_OUT_CTS		0x3FFF0000
+#define	AR_TIME_OUT_CTS_S	16
+
+#define	AR_RSSI_THR		0x8018
+#define	AR_RSSI_THR_MASK	0x000000FF
+#define	AR_RSSI_THR_BM_THR	0x0000FF00
+#define	AR_RSSI_THR_BM_THR_S	8
+#define	AR_RSSI_BCN_WEIGHT	0x1F000000
+#define	AR_RSSI_BCN_WEIGHT_S	24
+#define	AR_RSSI_BCN_RSSI_RST	0x20000000
+
+#define	AR_USEC			0x801c
+#define	AR_USEC_USEC		0x0000007F
+#define	AR_USEC_TX_LAT		0x007FC000
+#define	AR_USEC_TX_LAT_S	14
+#define	AR_USEC_RX_LAT		0x1F800000
+#define	AR_USEC_RX_LAT_S	23
+
+#define	AR_RESET_TSF		0x8020
+#define	AR_RESET_TSF_ONCE	0x01000000
+
+#define	AR_MAX_CFP_DUR		0x8038
+#define	AR_CFP_VAL		0x0000FFFF
+
+#define	AR_RX_FILTER		0x803C
+#define	AR_RX_FILTER_ALL	0x00000000
+#define	AR_RX_UCAST		0x00000001
+#define	AR_RX_MCAST		0x00000002
+#define	AR_RX_BCAST		0x00000004
+#define	AR_RX_CONTROL		0x00000008
+#define	AR_RX_BEACON		0x00000010
+#define	AR_RX_PROM		0x00000020
+#define	AR_RX_PROBE_REQ		0x00000080
+#define	AR_RX_MY_BEACON		0x00000200
+#define	AR_RX_COMPR_BAR		0x00000400
+#define	AR_RX_COMPR_BA		0x00000800
+#define	AR_RX_UNCOM_BA_BAR	0x00001000
+
+#define	AR_MCAST_FIL0		0x8040
+#define	AR_MCAST_FIL1		0x8044
+
+#define	AR_DIAG_SW			0x8048
+#define	AR_DIAG_CACHE_ACK		0x00000001
+#define	AR_DIAG_ACK_DIS			0x00000002
+#define	AR_DIAG_CTS_DIS			0x00000004
+#define	AR_DIAG_ENCRYPT_DIS		0x00000008
+#define	AR_DIAG_DECRYPT_DIS		0x00000010
+#define	AR_DIAG_RX_DIS			0x00000020
+#define	AR_DIAG_LOOP_BACK		0x00000040
+#define	AR_DIAG_CORR_FCS		0x00000080
+#define	AR_DIAG_CHAN_INFO		0x00000100
+#define	AR_DIAG_SCRAM_SEED		0x0001FE00
+#define	AR_DIAG_SCRAM_SEED_S		8
+#define	AR_DIAG_FRAME_NV0		0x00020000
+#define	AR_DIAG_OBS_PT_SEL1		0x000C0000
+#define	AR_DIAG_OBS_PT_SEL1_S		18
+#define	AR_DIAG_FORCE_RX_CLEAR		0x00100000
+#define	AR_DIAG_IGNORE_VIRT_CS		0x00200000
+#define	AR_DIAG_FORCE_CH_IDLE_HIGH	0x00400000
+#define	AR_DIAG_EIFS_CTRL_ENA		0x00800000
+#define	AR_DIAG_DUAL_CHAIN_INFO		0x01000000
+#define	AR_DIAG_RX_ABORT		0x02000000
+#define	AR_DIAG_SATURATE_CYCLE_CNT	0x04000000
+#define	AR_DIAG_OBS_PT_SEL2		0x08000000
+#define	AR_DIAG_RX_CLEAR_CTL_LOW	0x10000000
+#define	AR_DIAG_RX_CLEAR_EXT_LOW	0x20000000
+
+#define	AR_TSF_L32	0x804c
+#define	AR_TSF_U32	0x8050
+
+#define	AR_TST_ADDAC	0x8054
+#define	AR_DEF_ANTENNA	0x8058
+
+#define	AR_AES_MUTE_MASK0	0x805c
+#define	AR_AES_MUTE_MASK0_FC	0x0000FFFF
+#define	AR_AES_MUTE_MASK0_QOS	0xFFFF0000
+#define	AR_AES_MUTE_MASK0_QOS_S	16
+
+#define	AR_AES_MUTE_MASK1	0x8060
+#define	AR_AES_MUTE_MASK1_SEQ	0x0000FFFF
+
+#define	AR_GATED_CLKS		0x8064
+#define	AR_GATED_CLKS_TX	0x00000002
+#define	AR_GATED_CLKS_RX	0x00000004
+#define	AR_GATED_CLKS_REG	0x00000008
+
+#define	AR_OBS_BUS_CTRL		0x8068
+#define	AR_OBS_BUS_SEL_1	0x00040000
+#define	AR_OBS_BUS_SEL_2	0x00080000
+#define	AR_OBS_BUS_SEL_3	0x000C0000
+#define	AR_OBS_BUS_SEL_4	0x08040000
+#define	AR_OBS_BUS_SEL_5	0x08080000
+
+#define	AR_OBS_BUS_1			0x806c
+#define	AR_OBS_BUS_1_PCU		0x00000001
+#define	AR_OBS_BUS_1_RX_END		0x00000002
+#define	AR_OBS_BUS_1_RX_WEP		0x00000004
+#define	AR_OBS_BUS_1_RX_BEACON		0x00000008
+#define	AR_OBS_BUS_1_RX_FILTER		0x00000010
+#define	AR_OBS_BUS_1_TX_HCF		0x00000020
+#define	AR_OBS_BUS_1_QUIET_TIME		0x00000040
+#define	AR_OBS_BUS_1_CHAN_IDLE		0x00000080
+#define	AR_OBS_BUS_1_TX_HOLD 		0x00000100
+#define	AR_OBS_BUS_1_TX_FRAME		0x00000200
+#define	AR_OBS_BUS_1_RX_FRAME		0x00000400
+#define	AR_OBS_BUS_1_RX_CLEAR		0x00000800
+#define	AR_OBS_BUS_1_WEP_STATE		0x0003F000
+#define	AR_OBS_BUS_1_WEP_STATE_S	12
+#define	AR_OBS_BUS_1_RX_STATE		0x01F00000
+#define	AR_OBS_BUS_1_RX_STATE_S		20
+#define	AR_OBS_BUS_1_TX_STATE		0x7E000000
+#define	AR_OBS_BUS_1_TX_STATE_S		25
+
+#define	AR_LAST_TSTP	0x8080
+#define	AR_NAV		0x8084
+#define	AR_RTS_OK	0x8088
+#define	AR_RTS_FAIL	0x808c
+#define	AR_ACK_FAIL	0x8090
+#define	AR_FCS_FAIL	0x8094
+#define	AR_BEACON_CNT	0x8098
+
+#define	AR_SLEEP1		0x80d4
+#define	AR_SLEEP1_ASSUME_DTIM	0x00080000
+#define	AR_SLEEP1_CAB_TIMEOUT	0xFFE00000
+#define	AR_SLEEP1_CAB_TIMEOUT_S	21
+
+#define	AR_SLEEP2			0x80d8
+#define	AR_SLEEP2_BEACON_TIMEOUT	0xFFE00000
+#define	AR_SLEEP2_BEACON_TIMEOUT_S	21
+
+#define	AR_BSSMSKL	0x80e0
+#define	AR_BSSMSKU	0x80e4
+
+#define	AR_TPC		0x80e8
+#define	AR_TPC_ACK	0x0000003f
+#define	AR_TPC_ACK_S	0x00
+#define	AR_TPC_CTS	0x00003f00
+#define	AR_TPC_CTS_S	0x08
+#define	AR_TPC_CHIRP	0x003f0000
+#define	AR_TPC_CHIRP_S	0x16
+
+#define	AR_TFCNT	0x80ec
+#define	AR_RFCNT	0x80f0
+#define	AR_RCCNT	0x80f4
+#define	AR_CCCNT	0x80f8
+
+#define	AR_QUIET1			0x80fc
+#define	AR_QUIET1_NEXT_QUIET_S		0
+#define	AR_QUIET1_NEXT_QUIET_M		0x0000ffff
+#define	AR_QUIET1_QUIET_ENABLE		0x00010000
+#define	AR_QUIET1_QUIET_ACK_CTS_ENABLE	0x00020000
+#define	AR_QUIET2			0x8100
+#define	AR_QUIET2_QUIET_PERIOD_S	0
+#define	AR_QUIET2_QUIET_PERIOD_M	0x0000ffff
+#define	AR_QUIET2_QUIET_DUR_S		16
+#define	AR_QUIET2_QUIET_DUR		0xffff0000
+
+#define	AR_TSF_PARM		0x8104
+#define	AR_TSF_INCREMENT_M	0x000000ff
+#define	AR_TSF_INCREMENT_S	0x00
+
+#define	AR_QOS_NO_ACK			0x8108
+#define	AR_QOS_NO_ACK_TWO_BIT		0x0000000f
+#define	AR_QOS_NO_ACK_TWO_BIT_S		0
+#define	AR_QOS_NO_ACK_BIT_OFF		0x00000070
+#define	AR_QOS_NO_ACK_BIT_OFF_S		4
+#define	AR_QOS_NO_ACK_BYTE_OFF		0x00000180
+#define	AR_QOS_NO_ACK_BYTE_OFF_S	7
+
+#define	AR_PHY_ERR	0x810c
+
+#define	AR_PHY_ERR_DCHIRP	0x00000008
+#define	AR_PHY_ERR_RADAR	0x00000020
+#define	AR_PHY_ERR_OFDM_TIMING	0x00020000
+#define	AR_PHY_ERR_CCK_TIMING	0x02000000
+
+#define	AR_RXFIFO_CFG	0x8114
+
+
+#define	AR_MIC_QOS_CONTROL	0x8118
+#define	AR_MIC_QOS_SELECT	0x811c
+
+#define	AR_PCU_MISC			0x8120
+#define	AR_PCU_FORCE_BSSID_MATCH	0x00000001
+#define	AR_PCU_MIC_NEW_LOC_ENA		0x00000004
+#define	AR_PCU_TX_ADD_TSF		0x00000008
+#define	AR_PCU_CCK_SIFS_MODE		0x00000010
+#define	AR_PCU_RX_ANT_UPDT		0x00000800
+#define	AR_PCU_TXOP_TBTT_LIMIT_ENA	0x00001000
+#define	AR_PCU_MISS_BCN_IN_SLEEP	0x00004000
+#define	AR_PCU_BUG_12306_FIX_ENA	0x00020000
+#define	AR_PCU_FORCE_QUIET_COLL		0x00040000
+#define	AR_PCU_TBTT_PROTECT		0x00200000
+#define	AR_PCU_CLEAR_VMF		0x01000000
+#define	AR_PCU_CLEAR_BA_VALID		0x04000000
+
+
+#define	AR_FILT_OFDM		0x8124
+#define	AR_FILT_OFDM_COUNT	0x00FFFFFF
+
+#define	AR_FILT_CCK		0x8128
+#define	AR_FILT_CCK_COUNT	0x00FFFFFF
+
+#define	AR_PHY_ERR_1		0x812c
+#define	AR_PHY_ERR_1_COUNT	0x00FFFFFF
+#define	AR_PHY_ERR_MASK_1	0x8130
+
+#define	AR_PHY_ERR_2		0x8134
+#define	AR_PHY_ERR_2_COUNT	0x00FFFFFF
+#define	AR_PHY_ERR_MASK_2	0x8138
+
+#define	AR_PHY_COUNTMAX		(3 << 22)
+#define	AR_MIBCNT_INTRMASK	(3 << 22)
+
+#define	AR_TSF_THRESHOLD	0x813c
+#define	AR_TSF_THRESHOLD_VAL	0x0000FFFF
+
+#define	AR_PHY_ERR_EIFS_MASK	8144
+
+#define	AR_PHY_ERR_3		0x8168
+#define	AR_PHY_ERR_3_COUNT	0x00FFFFFF
+#define	AR_PHY_ERR_MASK_3	0x816c
+
+#define	AR_TXSIFS		0x81d0
+#define	AR_TXSIFS_TIME		0x000000FF
+#define	AR_TXSIFS_TX_LATENCY	0x00000F00
+#define	AR_TXSIFS_TX_LATENCY_S	8
+#define	AR_TXSIFS_ACK_SHIFT	0x00007000
+#define	AR_TXSIFS_ACK_SHIFT_S	12
+
+#define	AR_TXOP_X		0x81ec
+#define	AR_TXOP_X_VAL		0x000000FF
+
+
+#define	AR_TXOP_0_3	0x81f0
+#define	AR_TXOP_4_7	0x81f4
+#define	AR_TXOP_8_11	0x81f8
+#define	AR_TXOP_12_15	0x81fc
+
+
+#define	AR_NEXT_TBTT_TIMER		0x8200
+#define	AR_NEXT_DMA_BEACON_ALERT	0x8204
+#define	AR_NEXT_SWBA			0x8208
+#define	AR_NEXT_CFP			0x8208
+#define	AR_NEXT_HCF			0x820C
+#define	AR_NEXT_TIM			0x8210
+#define	AR_NEXT_DTIM			0x8214
+#define	AR_NEXT_QUIET_TIMER		0x8218
+#define	AR_NEXT_NDP_TIMER		0x821C
+
+#define	AR_BEACON_PERIOD		0x8220
+#define	AR_DMA_BEACON_PERIOD		0x8224
+#define	AR_SWBA_PERIOD			0x8228
+#define	AR_HCF_PERIOD			0x822C
+#define	AR_TIM_PERIOD			0x8230
+#define	AR_DTIM_PERIOD			0x8234
+#define	AR_QUIET_PERIOD			0x8238
+#define	AR_NDP_PERIOD			0x823C
+
+#define	AR_TIMER_MODE			0x8240
+#define	AR_TBTT_TIMER_EN		0x00000001
+#define	AR_DBA_TIMER_EN			0x00000002
+#define	AR_SWBA_TIMER_EN		0x00000004
+#define	AR_HCF_TIMER_EN			0x00000008
+#define	AR_TIM_TIMER_EN			0x00000010
+#define	AR_DTIM_TIMER_EN		0x00000020
+#define	AR_QUIET_TIMER_EN		0x00000040
+#define	AR_NDP_TIMER_EN			0x00000080
+#define	AR_TIMER_OVERFLOW_INDEX		0x00000700
+#define	AR_TIMER_OVERFLOW_INDEX_S	8
+#define	AR_TIMER_THRESH			0xFFFFF000
+#define	AR_TIMER_THRESH_S		12
+
+#define	AR_SLP32_MODE			0x8244
+#define	AR_SLP32_HALF_CLK_LATENCY	0x000FFFFF
+#define	AR_SLP32_ENA			0x00100000
+#define	AR_SLP32_TSF_WRITE_STATUS	0x00200000
+
+#define	AR_SLP32_WAKE			0x8248
+#define	AR_SLP32_WAKE_XTL_TIME		0x0000FFFF
+
+#define	AR_SLP32_INC		0x824c
+#define	AR_SLP32_TST_INC	0x000FFFFF
+
+#define	AR_SLP_CNT		0x8250
+#define	AR_SLP_CYCLE_CNT	0x8254
+
+#define	AR_SLP_MIB_CTRL		0x8258
+#define	AR_SLP_MIB_CLEAR	0x00000001
+#define	AR_SLP_MIB_PENDING	0x00000002
+
+#define	AR_2040_MODE		0x8318
+#define	AR_2040_JOINED_RX_CLEAR	0x00000001
+
+
+#define	AR_EXTRCCNT		0x8328
+
+#define	AR_SELFGEN_MASK		0x832c
+
+#define	AR_PCU_TXBUF_CTRL		0x8340
+#define	AR_PCU_TXBUF_CTRL_SIZE_MASK	0x7FF
+#define	AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
+#define	AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
+
+#define	AR_KEYTABLE_0		0x8800
+#define	AR_KEYTABLE(_n)		(AR_KEYTABLE_0 + ((_n)*32))
+#define	AR_KEY_CACHE_SIZE	128
+#define	AR_RSVD_KEYTABLE_ENTRIES	4
+#define	AR_KEY_TYPE		0x00000007
+#define	AR_KEYTABLE_TYPE_40	0x00000000
+#define	AR_KEYTABLE_TYPE_104	0x00000001
+#define	AR_KEYTABLE_TYPE_128	0x00000003
+#define	AR_KEYTABLE_TYPE_TKIP	0x00000004
+#define	AR_KEYTABLE_TYPE_AES	0x00000005
+#define	AR_KEYTABLE_TYPE_CCM	0x00000006
+#define	AR_KEYTABLE_TYPE_CLR	0x00000007
+#define	AR_KEYTABLE_ANT		0x00000008
+#define	AR_KEYTABLE_VALID	0x00008000
+#define	AR_KEYTABLE_KEY0(_n)	(AR_KEYTABLE(_n) + 0)
+#define	AR_KEYTABLE_KEY1(_n)	(AR_KEYTABLE(_n) + 4)
+#define	AR_KEYTABLE_KEY2(_n)	(AR_KEYTABLE(_n) + 8)
+#define	AR_KEYTABLE_KEY3(_n)	(AR_KEYTABLE(_n) + 12)
+#define	AR_KEYTABLE_KEY4(_n)	(AR_KEYTABLE(_n) + 16)
+#define	AR_KEYTABLE_TYPE(_n)	(AR_KEYTABLE(_n) + 20)
+#define	AR_KEYTABLE_MAC0(_n)	(AR_KEYTABLE(_n) + 24)
+#define	AR_KEYTABLE_MAC1(_n)	(AR_KEYTABLE(_n) + 28)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARN_REG_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_regd.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,1046 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "arn_core.h"
+#include "arn_hw.h"
+#include "arn_regd.h"
+#include "arn_regd_common.h"
+
+static int
+ath9k_regd_chansort(const void *a, const void *b)
+{
+	const struct ath9k_channel *ca = a;
+	const struct ath9k_channel *cb = b;
+
+	return (ca->channel == cb->channel) ?
+	    (ca->channelFlags & CHAN_FLAGS) -
+	    (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel;
+}
+
+static void
+ath9k_regd_sort(void *a, uint32_t n, uint32_t size, ath_hal_cmp_t *cmp)
+{
+	uint8_t *aa = a;
+	uint8_t *ai, *t;
+
+	for (ai = aa + size; --n >= 1; ai += size)
+		for (t = ai; t > aa; t -= size) {
+			uint8_t *u = t - size;
+			if (cmp(u, t) <= 0)
+				break;
+			swap(u, t, size);
+		}
+}
+
+static uint16_t
+ath9k_regd_get_eepromRD(struct ath_hal *ah)
+{
+	return (ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG);
+}
+
+static boolean_t
+ath9k_regd_is_chan_bm_zero(uint64_t *bitmask)
+{
+	int i;
+
+	for (i = 0; i < BMLEN; i++) {
+		if (bitmask[i] != 0)
+			return (B_FALSE);
+	}
+	return (B_TRUE);
+}
+
+static boolean_t
+ath9k_regd_is_eeprom_valid(struct ath_hal *ah)
+{
+	uint16_t rd = ath9k_regd_get_eepromRD(ah);
+	int i;
+
+	if (rd & COUNTRY_ERD_FLAG) {
+		uint16_t cc = rd & ~COUNTRY_ERD_FLAG;
+		for (i = 0; i < ARRAY_SIZE(allCountries); i++)
+			if (allCountries[i].countryCode == cc)
+				return (B_TRUE);
+	} else {
+		for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
+			if (regDomainPairs[i].regDmnEnum == rd)
+				return (B_TRUE);
+	}
+
+	ARN_DBG((ARN_DBG_REGULATORY,
+	    "%s: invalid regulatory domain/country code 0x%x\n",
+	    __func__, rd));
+
+	return (B_FALSE);
+}
+
+static boolean_t
+ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah)
+{
+	uint32_t regcap;
+
+	regcap = ah->ah_caps.reg_cap;
+
+	if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND)
+		return (B_TRUE);
+	else
+		return (B_FALSE);
+}
+
+static boolean_t
+ath9k_regd_is_ccode_valid(struct ath_hal *ah, uint16_t cc)
+{
+	uint16_t rd;
+	int i;
+
+	if (cc == CTRY_DEFAULT)
+		return (B_TRUE);
+	if (cc == CTRY_DEBUG)
+		return (B_TRUE);
+
+	rd = ath9k_regd_get_eepromRD(ah);
+
+	ARN_DBG((ARN_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n",
+	    __func__, rd));
+
+	if (rd & COUNTRY_ERD_FLAG) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "%s: EEPROM setting is country code %u\n",
+		    __func__, rd & ~COUNTRY_ERD_FLAG));
+		return (cc == (rd & ~COUNTRY_ERD_FLAG));
+	}
+
+	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+		if (cc == allCountries[i].countryCode) {
+#ifdef ARN_SUPPORT_11D
+			if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)
+				return (B_TRUE);
+#endif
+			if (allCountries[i].regDmnEnum == rd ||
+			    rd == DEBUG_REG_DMN || rd == NO_ENUMRD)
+				return (B_TRUE);
+		}
+	}
+	return (B_FALSE);
+}
+
+static void
+ath9k_regd_get_wmodes_nreg(struct ath_hal *ah,
+    struct country_code_to_enum_rd *country,
+    struct regDomain *rd5GHz,
+    uint8_t *modes_allowed)
+
+{
+	bcopy(ah->ah_caps.wireless_modes, modes_allowed,
+	    sizeof (ah->ah_caps.wireless_modes));
+
+	if (is_set(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) &&
+	    (!country->allow11g))
+		clr_bit(ATH9K_MODE_11G, modes_allowed);
+
+	if (is_set(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) &&
+	    (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a)))
+		clr_bit(ATH9K_MODE_11A, modes_allowed);
+
+	if (is_set(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes) &&
+	    (!country->allow11ng20))
+		clr_bit(ATH9K_MODE_11NG_HT20, modes_allowed);
+
+	if (is_set(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes) &&
+	    (!country->allow11na20))
+		clr_bit(ATH9K_MODE_11NA_HT20, modes_allowed);
+
+	if (is_set(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) &&
+	    (!country->allow11ng40))
+		clr_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed);
+
+	if (is_set(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) &&
+	    (!country->allow11ng40))
+		clr_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed);
+
+	if (is_set(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) &&
+	    (!country->allow11na40))
+		clr_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed);
+
+	if (is_set(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) &&
+	    (!country->allow11na40))
+		clr_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed);
+}
+
+boolean_t
+ath9k_regd_is_public_safety_sku(struct ath_hal *ah)
+{
+	uint16_t rd;
+
+	rd = ath9k_regd_get_eepromRD(ah);
+
+	switch (rd) {
+	case FCC4_FCCA:
+	case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG):
+		return (B_TRUE);
+	case DEBUG_REG_DMN:
+	case NO_ENUMRD:
+		if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49)
+			return (B_TRUE);
+		break;
+	}
+	return (B_FALSE);
+}
+
+static struct country_code_to_enum_rd *
+ath9k_regd_find_country(uint16_t countryCode)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+		if (allCountries[i].countryCode == countryCode)
+			return (&allCountries[i]);
+	}
+	return (NULL);
+}
+
+static uint16_t
+ath9k_regd_get_default_country(struct ath_hal *ah)
+{
+	uint16_t rd;
+	int i;
+
+	rd = ath9k_regd_get_eepromRD(ah);
+	if (rd & COUNTRY_ERD_FLAG) {
+		struct country_code_to_enum_rd *country = NULL;
+		uint16_t cc = rd & ~COUNTRY_ERD_FLAG;
+
+		country = ath9k_regd_find_country(cc);
+		if (country != NULL)
+			return (cc);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
+		if (regDomainPairs[i].regDmnEnum == rd) {
+			if (regDomainPairs[i].singleCC != 0)
+				return (regDomainPairs[i].singleCC);
+			else
+				i = ARRAY_SIZE(regDomainPairs);
+		}
+	return (CTRY_DEFAULT);
+}
+
+static boolean_t
+ath9k_regd_is_valid_reg_domain(int regDmn, struct regDomain *rd)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(regDomains); i++) {
+		if (regDomains[i].regDmnEnum == regDmn) {
+			if (rd != NULL) {
+				(void) memcpy(rd, &regDomains[i],
+				    sizeof (struct regDomain));
+			}
+			return (B_TRUE);
+		}
+	}
+	return (B_FALSE);
+}
+
+static boolean_t
+ath9k_regd_is_valid_reg_domainPair(int regDmnPair)
+{
+	int i;
+
+	if (regDmnPair == NO_ENUMRD)
+		return (B_FALSE);
+	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
+		if (regDomainPairs[i].regDmnEnum == regDmnPair)
+			return (B_TRUE);
+	}
+	return (B_FALSE);
+}
+
+static boolean_t
+ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
+    uint16_t channelFlag, struct regDomain *rd)
+{
+	int i, found;
+	uint64_t flags = NO_REQ;
+	struct reg_dmn_pair_mapping *regPair = NULL;
+	int regOrg;
+
+	regOrg = regDmn;
+	if (regDmn == CTRY_DEFAULT) {
+		uint16_t rdnum;
+		rdnum = ath9k_regd_get_eepromRD(ah);
+
+		if (!(rdnum & COUNTRY_ERD_FLAG)) {
+			if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) ||
+			    ath9k_regd_is_valid_reg_domainPair(rdnum)) {
+				regDmn = rdnum;
+			}
+		}
+	}
+
+	if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
+		for (i = 0, found = 0;
+		    (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) {
+			if (regDomainPairs[i].regDmnEnum == regDmn) {
+				regPair = &regDomainPairs[i];
+				found = 1;
+			}
+		}
+		if (!found) {
+			ARN_DBG((ARN_DBG_REGULATORY,
+			    "%s: Failed to find reg domain pair %u\n",
+			    __func__, regDmn));
+			return (B_FALSE);
+		}
+		if (!(channelFlag & CHANNEL_2GHZ)) {
+			regDmn = regPair->regDmn5GHz;
+			flags = regPair->flags5GHz;
+		}
+		if (channelFlag & CHANNEL_2GHZ) {
+			regDmn = regPair->regDmn2GHz;
+			flags = regPair->flags2GHz;
+		}
+	}
+
+	found = ath9k_regd_is_valid_reg_domain(regDmn, rd);
+	if (!found) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "%s: Failed to find unitary reg domain %u\n",
+		    __func__, regDmn));
+		return (B_FALSE);
+	} else {
+		rd->pscan &= regPair->pscanMask;
+		if (((regOrg & MULTI_DOMAIN_MASK) == 0) &&
+		    (flags != NO_REQ)) {
+			rd->flags = (uint32_t)flags; /* LINT */
+		}
+
+		rd->flags &= (channelFlag & CHANNEL_2GHZ) ?
+		    REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK;
+		return (B_TRUE);
+	}
+}
+
+static boolean_t
+ath9k_regd_is_bit_set(int bit, uint64_t *bitmask)
+{
+	int byteOffset, bitnum;
+	uint64_t val;
+
+	byteOffset = bit / 64;
+	bitnum = bit - byteOffset * 64;
+	val = ((uint64_t)1) << bitnum;
+	if (bitmask[byteOffset] & val)
+		return (B_TRUE);
+	else
+		return (B_FALSE);
+}
+
+static void
+ath9k_regd_add_reg_classid(uint8_t *regclassids, uint32_t maxregids,
+    uint32_t *nregids, uint8_t regclassid)
+{
+	int i;
+
+	if (regclassid == 0)
+		return;
+
+	for (i = 0; i < maxregids; i++) {
+		if (regclassids[i] == regclassid)
+			return;
+		if (regclassids[i] == 0)
+			break;
+	}
+
+	if (i == maxregids)
+		return;
+	else {
+		regclassids[i] = regclassid;
+		*nregids += 1;
+	}
+}
+
+static boolean_t
+ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah,
+    enum reg_ext_bitmap bit)
+{
+	return ((ah->ah_currentRDExt & (1 << bit)) ? B_TRUE : B_FALSE);
+}
+
+#ifdef ARN_NF_PER_CHAN
+
+static void
+ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans, int nchans)
+{
+	int i, j, next;
+
+	for (next = 0; next < nchans; next++) {
+		for (i = 0; i < NUM_NF_READINGS; i++) {
+			ichans[next].nfCalHist[i].currIndex = 0;
+			ichans[next].nfCalHist[i].privNF =
+			    AR_PHY_CCA_MAX_GOOD_VALUE;
+			ichans[next].nfCalHist[i].invalidNFcount =
+			    AR_PHY_CCA_FILTERWINDOW_LENGTH;
+			for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
+				ichans[next].nfCalHist[i].nfCalBuffer[j] =
+				    AR_PHY_CCA_MAX_GOOD_VALUE;
+			}
+		}
+	}
+}
+#endif
+
+static int
+ath9k_regd_is_chan_present(struct ath_hal *ah, uint16_t c)
+{
+	int i;
+
+	for (i = 0; i < 150; i++) {
+		if (!ah->ah_channels[i].channel)
+			return (-1);
+		else if (ah->ah_channels[i].channel == c)
+			return (i);
+	}
+
+	return (-1);
+}
+
+/* ARGSUSED */
+static boolean_t
+ath9k_regd_add_channel(
+    struct ath_hal *ah,
+    uint16_t c,
+    uint16_t c_lo,
+    uint16_t c_hi,
+    uint16_t maxChan,
+    uint8_t ctl,
+    int pos,
+    struct regDomain rd5GHz,
+    struct RegDmnFreqBand *fband,
+    struct regDomain *rd,
+    const struct cmode *cm,
+    struct ath9k_channel *ichans,
+    boolean_t enableExtendedChannels)
+{
+	struct ath9k_channel *chan;
+	int ret;
+	uint32_t channelFlags = 0;
+	uint8_t privFlags = 0;
+
+	if (!(c_lo <= c && c <= c_hi)) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "%s: c %u out of range [%u..%u]\n",
+		    __func__, c, c_lo, c_hi));
+		return (B_FALSE);
+	}
+	if ((fband->channelBW == CHANNEL_HALF_BW) &&
+	    !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "%s: Skipping %u half rate channel\n",
+		    __func__, c));
+		return (B_FALSE);
+	}
+
+	if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
+	    !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "%s: Skipping %u quarter rate channel\n",
+		    __func__, c));
+		return (B_FALSE);
+	}
+
+	if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "%s: c %u > maxChan %u\n",
+		    __func__, c, maxChan));
+		return (B_FALSE);
+	}
+
+	if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "Skipping ecm channel\n"));
+		return (B_FALSE);
+	}
+
+	if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == ATH9K_M_HOSTAP)) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "Skipping HOSTAP channel\n"));
+		return (B_FALSE);
+	}
+
+	if (IS_HT40_MODE(cm->mode) &&
+	    !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) &&
+	    (fband->useDfs) &&
+	    (rd->conformanceTestLimit != MKK)) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n"));
+		return (B_FALSE);
+	}
+
+	if (IS_HT40_MODE(cm->mode) &&
+	    !(ath9k_regd_get_eeprom_reg_ext_bits(ah,
+	    REG_EXT_JAPAN_NONDFS_HT40)) &&
+	    !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "Skipping HT40 channel (en_jap_ht40 = 0)\n"));
+		return (B_FALSE);
+	}
+
+	if (IS_HT40_MODE(cm->mode) &&
+	    !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) &&
+	    (fband->useDfs) &&
+	    (rd->conformanceTestLimit == MKK)) {
+		ARN_DBG((ARN_DBG_REGULATORY,
+		    "Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n"));
+		return (B_FALSE);
+	}
+
+	/* Calculate channel flags */
+
+	channelFlags = cm->flags;
+
+	switch (fband->channelBW) {
+	case CHANNEL_HALF_BW:
+		channelFlags |= CHANNEL_HALF;
+		break;
+	case CHANNEL_QUARTER_BW:
+		channelFlags |= CHANNEL_QUARTER;
+		break;
+	}
+
+	if (fband->usePassScan & rd->pscan)
+		channelFlags |= CHANNEL_PASSIVE;
+	else
+		channelFlags &= ~CHANNEL_PASSIVE;
+	if (fband->useDfs & rd->dfsMask)
+		privFlags = CHANNEL_DFS;
+	else
+		privFlags = 0;
+	if (rd->flags & LIMIT_FRAME_4MS)
+		privFlags |= CHANNEL_4MS_LIMIT;
+	if (privFlags & CHANNEL_DFS)
+		privFlags |= CHANNEL_DISALLOW_ADHOC;
+	if (rd->flags & ADHOC_PER_11D)
+		privFlags |= CHANNEL_PER_11D_ADHOC;
+
+	if (channelFlags & CHANNEL_PASSIVE) {
+		if ((c < 2412) || (c > 2462)) {
+			if (rd5GHz.regDmnEnum == MKK1 ||
+			    rd5GHz.regDmnEnum == MKK2) {
+				uint32_t regcap = ah->ah_caps.reg_cap;
+				if (!(regcap &
+				    (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
+				    AR_EEPROM_EEREGCAP_EN_KK_U2 |
+				    AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) &&
+				    isUNII1OddChan(c)) {
+					channelFlags &= ~CHANNEL_PASSIVE;
+				} else {
+					privFlags |= CHANNEL_DISALLOW_ADHOC;
+				}
+			} else {
+				privFlags |= CHANNEL_DISALLOW_ADHOC;
+			}
+		}
+	}
+
+	if ((cm->mode == ATH9K_MODE_11A) ||
+	    (cm->mode == ATH9K_MODE_11NA_HT20) ||
+	    (cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
+	    (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) {
+		if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
+			privFlags |= CHANNEL_DISALLOW_ADHOC;
+	}
+
+	/* Fill in channel details */
+
+	ret = ath9k_regd_is_chan_present(ah, c);
+	if (ret == -1) {
+		chan = &ah->ah_channels[pos];
+		chan->channel = c;
+		chan->maxRegTxPower = fband->powerDfs;
+		chan->antennaMax = fband->antennaMax;
+		chan->regDmnFlags = rd->flags;
+		chan->maxTxPower = AR5416_MAX_RATE_POWER;
+		chan->minTxPower = AR5416_MAX_RATE_POWER;
+		chan->channelFlags = channelFlags;
+		chan->privFlags = privFlags;
+	} else {
+		chan = &ah->ah_channels[ret];
+		chan->channelFlags |= channelFlags;
+		chan->privFlags |= privFlags;
+	}
+
+	/* Set CTLs */
+
+	if ((cm->flags & CHANNEL_ALL) == CHANNEL_A)
+		chan->conformanceTestLimit[0] = ctl;
+	else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B)
+		chan->conformanceTestLimit[1] = ctl;
+	else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G)
+		chan->conformanceTestLimit[2] = ctl;
+
+	return ((ret == -1) ? B_TRUE : B_FALSE);
+}
+
+static boolean_t
+ath9k_regd_japan_check(struct ath_hal *ah, int b, struct regDomain *rd5GHz)
+{
+	boolean_t skipband = B_FALSE;
+	int i;
+	uint32_t regcap;
+
+	for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) {
+		if (j_bandcheck[i].freqbandbit == b) {
+			regcap = ah->ah_caps.reg_cap;
+			if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) {
+				skipband = B_TRUE;
+			} else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) ||
+			    (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) {
+				rd5GHz->dfsMask |= DFS_MKK4;
+				rd5GHz->pscan |= PSCAN_MKK3;
+			}
+			break;
+		}
+	}
+
+	ARN_DBG((ARN_DBG_REGULATORY,
+	    "%s: Skipping %d freq band\n",
+	    __func__, j_bandcheck[i].freqbandbit));
+
+	return (skipband);
+}
+
+boolean_t
+ath9k_regd_init_channels(
+    struct ath_hal *ah,
+    uint32_t maxchans,
+    uint32_t *nchans,
+    uint8_t *regclassids,
+    uint32_t maxregids,
+    uint32_t *nregids,
+    uint16_t cc,
+    boolean_t enableOutdoor,
+    boolean_t enableExtendedChannels)
+{
+	uint16_t maxChan = 7000;
+	struct country_code_to_enum_rd *country = NULL;
+	struct regDomain rd5GHz, rd2GHz;
+	const struct cmode *cm;
+	struct ath9k_channel *ichans = &ah->ah_channels[0];
+	int next = 0, b;
+	uint8_t ctl;
+	int regdmn;
+	uint16_t chanSep;
+	uint8_t *modes_avail;
+	uint8_t modes_allowed[4];
+
+	(void) memset(modes_allowed, 0, sizeof (modes_allowed));
+	ARN_DBG((ARN_DBG_REGULATORY, "arn: ath9k_regd_init_channels(): "
+	    "cc %u %s %s\n",
+	    cc,
+	    enableOutdoor ? "Enable outdoor" : "",
+	    enableExtendedChannels ? "Enable ecm" : ""));
+
+	if (!ath9k_regd_is_ccode_valid(ah, cc)) {
+		ARN_DBG((ARN_DBG_XMIT, "arn: ath9k_regd_init_channels(): "
+		    "invalid country code %d\n", cc));
+		return (B_FALSE);
+	}
+
+	if (!ath9k_regd_is_eeprom_valid(ah)) {
+		ARN_DBG((ARN_DBG_ANY, "arn: ath9k_regd_init_channels(): "
+		    "invalid EEPROM contents\n"));
+		return (B_FALSE);
+	}
+
+	ah->ah_countryCode = ath9k_regd_get_default_country(ah);
+
+	if (ah->ah_countryCode == CTRY_DEFAULT) {
+		ah->ah_countryCode = cc & COUNTRY_CODE_MASK;
+		if ((ah->ah_countryCode == CTRY_DEFAULT) &&
+		    (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) {
+			ah->ah_countryCode = CTRY_UNITED_STATES;
+		}
+	}
+
+#ifdef ARN_SUPPORT_11D
+	if (ah->ah_countryCode == CTRY_DEFAULT) {
+		regdmn = ath9k_regd_get_eepromRD(ah);
+		country = NULL;
+	} else {
+#endif
+		country = ath9k_regd_find_country(ah->ah_countryCode);
+		if (country == NULL) {
+			ARN_DBG((ARN_DBG_REGULATORY,
+			    "arn: ath9k_regd_init_channels(): "
+			    "Country is NULL!!!!, cc= %d\n",
+			    ah->ah_countryCode));
+
+			return (B_FALSE);
+		} else {
+			regdmn = country->regDmnEnum;
+#ifdef ARN_SUPPORT_11D
+			if (((ath9k_regd_get_eepromRD(ah) &
+			    WORLD_SKU_MASK) == WORLD_SKU_PREFIX) &&
+			    (cc == CTRY_UNITED_STATES)) {
+				if (!isWwrSKU_NoMidband(ah) &&
+				    ath9k_regd_is_fcc_midband_supported(ah))
+					regdmn = FCC3_FCCA;
+				else
+					regdmn = FCC1_FCCA;
+			}
+#endif
+		}
+#ifdef ARN_SUPPORT_11D
+	}
+#endif
+	if (!ath9k_regd_get_wmode_regdomain(ah, regdmn,
+	    ~CHANNEL_2GHZ, &rd5GHz)) {
+		ARN_DBG((ARN_DBG_REGULATORY, "arn: ath9k_regd_init_channels(): "
+		    "couldn't find unitary "
+		    "5GHz reg domain for country %u\n",
+		    ah->ah_countryCode));
+		return (B_FALSE);
+	}
+	if (!ath9k_regd_get_wmode_regdomain(ah, regdmn,
+	    CHANNEL_2GHZ, &rd2GHz)) {
+		ARN_DBG((ARN_DBG_REGULATORY, "arn: ath9k_regd_init_channels(): "
+		    "couldn't find unitary 2GHz "
+		    "reg domain for country %u\n",
+		    ah->ah_countryCode));
+		return (B_FALSE);
+	}
+
+	if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) ||
+	    (rd5GHz.regDmnEnum == FCC2))) {
+		if (ath9k_regd_is_fcc_midband_supported(ah)) {
+			if (!ath9k_regd_get_wmode_regdomain(ah,
+			    FCC3_FCCA, ~CHANNEL_2GHZ, &rd5GHz)) {
+				ARN_DBG((ARN_DBG_REGULATORY,
+				    "arn: ath9k_regd_init_channels(): "
+				    "couldn't find unitary 5GHz "
+				    "reg domain for country %u\n",
+				    ah->ah_countryCode));
+				return (B_FALSE);
+			}
+		}
+	}
+
+	if (country == NULL) {
+		modes_avail = ah->ah_caps.wireless_modes;
+	} else {
+		ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed);
+		modes_avail = modes_allowed;
+
+		if (!enableOutdoor)
+			maxChan = country->outdoorChanStart;
+	}
+
+	next = 0;
+
+	if (maxchans > ARRAY_SIZE(ah->ah_channels))
+		maxchans = ARRAY_SIZE(ah->ah_channels);
+
+	for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) {
+		uint16_t c, c_hi, c_lo;
+		uint64_t *channelBM = NULL;
+		struct regDomain *rd = NULL;
+		struct RegDmnFreqBand *fband = NULL, *freqs;
+		int8_t low_adj = 0, hi_adj = 0;
+
+		if (!is_set(cm->mode, modes_avail)) {
+			ARN_DBG((ARN_DBG_REGULATORY,
+			    "%s: !avail mode %d flags 0x%x\n",
+			    __func__, cm->mode, cm->flags));
+			continue;
+		}
+		if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
+			ARN_DBG((ARN_DBG_REGULATORY,
+			    "arn: ath9k_regd_init_channels(): "
+			    "channels 0x%x not supported "
+			    "by hardware\n", cm->flags));
+			continue;
+		}
+
+		switch (cm->mode) {
+		case ATH9K_MODE_11A:
+		case ATH9K_MODE_11NA_HT20:
+		case ATH9K_MODE_11NA_HT40PLUS:
+		case ATH9K_MODE_11NA_HT40MINUS:
+			rd = &rd5GHz;
+			channelBM = rd->chan11a;
+			freqs = &regDmn5GhzFreq[0];
+			ctl = rd->conformanceTestLimit;
+			break;
+		case ATH9K_MODE_11B:
+			rd = &rd2GHz;
+			channelBM = rd->chan11b;
+			freqs = &regDmn2GhzFreq[0];
+			ctl = rd->conformanceTestLimit | CTL_11B;
+			break;
+		case ATH9K_MODE_11G:
+		case ATH9K_MODE_11NG_HT20:
+		case ATH9K_MODE_11NG_HT40PLUS:
+		case ATH9K_MODE_11NG_HT40MINUS:
+			rd = &rd2GHz;
+			channelBM = rd->chan11g;
+			freqs = &regDmn2Ghz11gFreq[0];
+			ctl = rd->conformanceTestLimit | CTL_11G;
+			break;
+		default:
+			ARN_DBG((ARN_DBG_REGULATORY,
+			    "arn: ath9k_regd_init_channels(): "
+			    "Unknown HAL mode 0x%x\n", cm->mode));
+			continue;
+		}
+
+		if (ath9k_regd_is_chan_bm_zero(channelBM))
+			continue;
+
+		if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
+		    (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) {
+			hi_adj = -20;
+		}
+
+		if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) ||
+		    (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) {
+			low_adj = 20;
+		}
+
+		/* XXX: Add a helper here instead */
+		for (b = 0; b < 64 * BMLEN; b++) {
+			if (ath9k_regd_is_bit_set(b, channelBM)) {
+				fband = &freqs[b];
+				if (rd5GHz.regDmnEnum == MKK1 ||
+				    rd5GHz.regDmnEnum == MKK2) {
+					if (ath9k_regd_japan_check(ah,
+					    b, &rd5GHz))
+						continue;
+				}
+
+				ath9k_regd_add_reg_classid(regclassids,
+				    maxregids,
+				    nregids,
+				    fband->regClassId);
+
+				if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) {
+					chanSep = 40;
+					if (fband->lowChannel == 5280)
+						low_adj += 20;
+
+					if (fband->lowChannel == 5170)
+						continue;
+				} else
+					chanSep = fband->channelSep;
+
+				for (c = fband->lowChannel + low_adj;
+				    ((c <= (fband->highChannel + hi_adj)) &&
+				    (c >= (fband->lowChannel + low_adj)));
+				    c += chanSep) {
+					if (next >= maxchans) {
+						ARN_DBG((ARN_DBG_REGULATORY,
+						    "too many channels "
+						    "for channel table\n"));
+						goto done;
+					}
+					if (ath9k_regd_add_channel(ah,
+					    c, c_lo, c_hi,
+					    maxChan, ctl,
+					    next,
+					    rd5GHz,
+					    fband, rd, cm,
+					    ichans,
+					    enableExtendedChannels))
+						next++;
+				}
+				if (IS_HT40_MODE(cm->mode) &&
+				    (fband->lowChannel == 5280)) {
+					low_adj -= 20;
+				}
+			}
+		}
+	}
+done:
+	if (next != 0) {
+		int i;
+
+		if (next > ARRAY_SIZE(ah->ah_channels)) {
+			ARN_DBG((ARN_DBG_REGULATORY,
+			    "arn: ath9k_regd_init_channels(): "
+			    "too many channels %u; truncating to %u\n",
+			    next, (int)ARRAY_SIZE(ah->ah_channels)));
+			next = ARRAY_SIZE(ah->ah_channels);
+		}
+#ifdef ARN_NF_PER_CHAN
+		ath9k_regd_init_rf_buffer(ichans, next);
+#endif
+		ath9k_regd_sort(ichans, next, sizeof (struct ath9k_channel),
+		    ath9k_regd_chansort);
+
+		ah->ah_nchan = next;
+
+		ARN_DBG((ARN_DBG_REGULATORY, "arn: ath9k_regd_init_channels(): "
+		    "Channel list:\n"));
+		for (i = 0; i < next; i++) {
+			ARN_DBG((ARN_DBG_REGULATORY, "arn: "
+			    "chan: %d flags: 0x%x\n",
+			    ah->ah_channels[i].channel,
+			    ah->ah_channels[i].channelFlags));
+		}
+	}
+	*nchans = next;
+
+	ah->ah_countryCode = ah->ah_countryCode;
+
+	ah->ah_currentRDInUse = (uint16_t)regdmn; /* LINT */
+	ah->ah_currentRD5G = rd5GHz.regDmnEnum;
+	ah->ah_currentRD2G = rd2GHz.regDmnEnum;
+	if (country == NULL) {
+		ah->ah_iso[0] = 0;
+		ah->ah_iso[1] = 0;
+	} else {
+		ah->ah_iso[0] = country->isoName[0];
+		ah->ah_iso[1] = country->isoName[1];
+	}
+
+	return (next != 0);
+}
+
+struct ath9k_channel *
+ath9k_regd_check_channel(struct ath_hal *ah, const struct ath9k_channel *c)
+{
+	struct ath9k_channel *base, *cc;
+
+	int flags = c->channelFlags & CHAN_FLAGS;
+	int n, lim;
+
+	ARN_DBG((ARN_DBG_REGULATORY, "arn: "
+	    "%s: channel %u/0x%x (0x%x) requested\n", __func__,
+	    c->channel, c->channelFlags, flags));
+
+	cc = ah->ah_curchan;
+	if (cc != NULL && cc->channel == c->channel &&
+	    (cc->channelFlags & CHAN_FLAGS) == flags) {
+		if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
+		    (cc->privFlags & CHANNEL_DFS))
+			return (NULL);
+		else
+			return (cc);
+	}
+
+	base = ah->ah_channels;
+	n = ah->ah_nchan;
+
+	for (lim = n; lim != 0; lim >>= 1) {
+		int d;
+		cc = &base[lim >> 1];
+		d = c->channel - cc->channel;
+		if (d == 0) {
+			if ((cc->channelFlags & CHAN_FLAGS) == flags) {
+				if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
+				    (cc->privFlags & CHANNEL_DFS))
+					return (NULL);
+				else
+					return (cc);
+			}
+			d = flags - (cc->channelFlags & CHAN_FLAGS);
+		}
+
+		ARN_DBG((ARN_DBG_REGULATORY, "arn: "
+		    "%s: channel %u/0x%x d %d\n", __func__,
+		    cc->channel, cc->channelFlags, d));
+
+		if (d > 0) {
+			base = cc + 1;
+			lim--;
+		}
+	}
+
+	ARN_DBG((ARN_DBG_REGULATORY, "arn: "
+	    "%s: no match for %u/0x%x\n",
+	    __func__, c->channel, c->channelFlags));
+
+	return (NULL);
+}
+
+uint32_t
+ath9k_regd_get_antenna_allowed(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	struct ath9k_channel *ichan = NULL;
+
+	ichan = ath9k_regd_check_channel(ah, chan);
+	if (!ichan)
+		return (0);
+
+	return (ichan->antennaMax);
+}
+
+uint32_t
+ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+	uint32_t ctl = NO_CTL;
+	struct ath9k_channel *ichan;
+
+	if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
+		if (IS_CHAN_B(chan))
+			ctl = SD_NO_CTL | CTL_11B;
+		else if (IS_CHAN_G(chan))
+			ctl = SD_NO_CTL | CTL_11G;
+		else
+			ctl = SD_NO_CTL | CTL_11A;
+	} else {
+		ichan = ath9k_regd_check_channel(ah, chan);
+		if (ichan != NULL) {
+			/* FIXME */
+			if (IS_CHAN_A(ichan))
+				ctl = ichan->conformanceTestLimit[0];
+			else if (IS_CHAN_B(ichan))
+				ctl = ichan->conformanceTestLimit[1];
+			else if (IS_CHAN_G(ichan))
+				ctl = ichan->conformanceTestLimit[2];
+
+			if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B)
+				ctl = (ctl & ~0xf) | CTL_11G;
+		}
+	}
+	return (ctl);
+}
+
+void
+ath9k_regd_get_current_country(struct ath_hal *ah,
+    struct ath9k_country_entry *ctry)
+{
+	uint16_t rd = ath9k_regd_get_eepromRD(ah);
+
+	ctry->isMultidomain = B_FALSE;
+	if (rd == CTRY_DEFAULT)
+		ctry->isMultidomain = B_TRUE;
+	else if (!(rd & COUNTRY_ERD_FLAG))
+		ctry->isMultidomain = isWwrSKU(ah);
+
+	ctry->countryCode = ah->ah_countryCode;
+	ctry->regDmnEnum = ah->ah_currentRD;
+	ctry->regDmn5G = ah->ah_currentRD5G;
+	ctry->regDmn2G = ah->ah_currentRD2G;
+	ctry->iso[0] = ah->ah_iso[0];
+	ctry->iso[1] = ah->ah_iso[1];
+	ctry->iso[2] = ah->ah_iso[2];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_regd.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,425 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_ARN_REGD_H
+#define	_ARN_REGD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "arn_ath9k.h"
+
+#define	BMLEN 2
+#define	BMZERO {(uint64_t)0, (uint64_t)0}
+
+#define	BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
+	{((((_fa >= 0) && (_fa < 64)) ? \
+		(((uint64_t)1) << _fa) : (uint64_t)0) | \
+	(((_fb >= 0) && (_fb < 64)) ? \
+		(((uint64_t)1) << _fb) : (uint64_t)0) | \
+	(((_fc >= 0) && (_fc < 64)) ? \
+		(((uint64_t)1) << _fc) : (uint64_t)0) | \
+	(((_fd >= 0) && (_fd < 64)) ? \
+		(((uint64_t)1) << _fd) : (uint64_t)0) | \
+	(((_fe >= 0) && (_fe < 64)) ? \
+		(((uint64_t)1) << _fe) : (uint64_t)0) | \
+	(((_ff >= 0) && (_ff < 64)) ? \
+		(((uint64_t)1) << _ff) : (uint64_t)0) | \
+	(((_fg >= 0) && (_fg < 64)) ? \
+		(((uint64_t)1) << _fg) : (uint64_t)0) | \
+	(((_fh >= 0) && (_fh < 64)) ? \
+		(((uint64_t)1) << _fh) : (uint64_t)0) | \
+	(((_fi >= 0) && (_fi < 64)) ? \
+		(((uint64_t)1) << _fi) : (uint64_t)0) | \
+	(((_fj >= 0) && (_fj < 64)) ? \
+		(((uint64_t)1) << _fj) : (uint64_t)0) | \
+	(((_fk >= 0) && (_fk < 64)) ? \
+		(((uint64_t)1) << _fk) : (uint64_t)0) | \
+	(((_fl >= 0) && (_fl < 64)) ? \
+		(((uint64_t)1) << _fl) : (uint64_t)0) | \
+	((((_fa > 63) && (_fa < 128)) ? \
+		(((uint64_t)1) << (_fa - 64)) : (uint64_t)0) | \
+	(((_fb > 63) && (_fb < 128)) ? \
+		(((uint64_t)1) << (_fb - 64)) : (uint64_t)0) | \
+	(((_fc > 63) && (_fc < 128)) ? \
+		(((uint64_t)1) << (_fc - 64)) : (uint64_t)0) | \
+	(((_fd > 63) && (_fd < 128)) ? \
+		(((uint64_t)1) << (_fd - 64)) : (uint64_t)0) | \
+	(((_fe > 63) && (_fe < 128)) ? \
+		(((uint64_t)1) << (_fe - 64)) : (uint64_t)0) | \
+	(((_ff > 63) && (_ff < 128)) ? \
+		(((uint64_t)1) << (_ff - 64)) : (uint64_t)0) | \
+	(((_fg > 63) && (_fg < 128)) ? \
+		(((uint64_t)1) << (_fg - 64)) : (uint64_t)0) | \
+	(((_fh > 63) && (_fh < 128)) ? \
+		(((uint64_t)1) << (_fh - 64)) : (uint64_t)0) | \
+	(((_fi > 63) && (_fi < 128)) ? \
+		(((uint64_t)1) << (_fi - 64)) : (uint64_t)0) | \
+	(((_fj > 63) && (_fj < 128)) ? \
+		(((uint64_t)1) << (_fj - 64)) : (uint64_t)0) | \
+	(((_fk > 63) && (_fk < 128)) ? \
+		(((uint64_t)1) << (_fk - 64)) : (uint64_t)0) | \
+	(((_fl > 63) && (_fl < 128)) ? \
+		(((uint64_t)1) << (_fl - 64)) : (uint64_t)0)))}
+
+#define	DEF_REGDMN		FCC1_FCCA
+#define	DEF_DMN_5		FCC1
+#define	DEF_DMN_2		FCCA
+#define	COUNTRY_ERD_FLAG	0x8000
+#define	WORLDWIDE_ROAMING_FLAG	0x4000
+#define	SUPER_DOMAIN_MASK	0x0fff
+#define	COUNTRY_CODE_MASK	0x3fff
+#define	CF_INTERFERENCE		(CHANNEL_CW_INT | CHANNEL_RADAR_INT)
+#define	CHANNEL_14		(2484)
+#define	IS_11G_CH14(_ch, _cf) \
+	(((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G))
+
+#define	NO_PSCAN	0x0ULL
+#define	PSCAN_FCC	0x0000000000000001ULL
+#define	PSCAN_FCC_T	0x0000000000000002ULL
+#define	PSCAN_ETSI 	0x0000000000000004ULL
+#define	PSCAN_MKK1	0x0000000000000008ULL
+#define	PSCAN_MKK2	0x0000000000000010ULL
+#define	PSCAN_MKKA	0x0000000000000020ULL
+#define	PSCAN_MKKA_G	0x0000000000000040ULL
+#define	PSCAN_ETSIA	0x0000000000000080ULL
+#define	PSCAN_ETSIB	0x0000000000000100ULL
+#define	PSCAN_ETSIC	0x0000000000000200ULL
+#define	PSCAN_WWR	0x0000000000000400ULL
+#define	PSCAN_MKKA1	0x0000000000000800ULL
+#define	PSCAN_MKKA1_G	0x0000000000001000ULL
+#define	PSCAN_MKKA2	0x0000000000002000ULL
+#define	PSCAN_MKKA2_G	0x0000000000004000ULL
+#define	PSCAN_MKK3	0x0000000000008000ULL
+#define	PSCAN_DEFER	0x7FFFFFFFFFFFFFFFULL
+#define	IS_ECM_CHAN	0x8000000000000000ULL
+
+#define	isWwrSKU(_ah) \
+	(((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \
+	    WORLD_SKU_PREFIX) || \
+	    (ath9k_regd_get_eepromRD(_ah) == WORLD))
+
+#define	isWwrSKU_NoMidband(_ah) \
+	((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \
+	(ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \
+	(ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC))
+
+#define	isUNII1OddChan(ch) \
+	((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
+
+#define	IS_HT40_MODE(_mode)					\
+	(((_mode == ATH9K_MODE_11NA_HT40PLUS	||		\
+	_mode == ATH9K_MODE_11NG_HT40PLUS	||		\
+	_mode == ATH9K_MODE_11NA_HT40MINUS	||		\
+	_mode == ATH9K_MODE_11NG_HT40MINUS) ? B_TRUE : B_FALSE))
+
+#define	CHAN_FLAGS	(CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
+
+#define	swap(_a, _b, _size) {		\
+	uint8_t *s = _b;		\
+	int i = _size;			\
+	do {				\
+		uint8_t tmp = *_a;	\
+		*_a++ = *s;		\
+		*s++ = tmp;		\
+	} while (--i);			\
+	_a -= _size;			\
+}
+
+
+#define	HALF_MAXCHANBW		10
+
+#define	MULTI_DOMAIN_MASK	0xFF00
+
+#define	WORLD_SKU_MASK		0x00F0
+#define	WORLD_SKU_PREFIX	0x0060
+
+#define	CHANNEL_HALF_BW		10
+#define	CHANNEL_QUARTER_BW	5
+
+typedef int ath_hal_cmp_t(const void *, const void *);
+
+struct reg_dmn_pair_mapping {
+	uint16_t regDmnEnum;
+	uint16_t regDmn5GHz;
+	uint16_t regDmn2GHz;
+	uint32_t flags5GHz;
+	uint32_t flags2GHz;
+	uint64_t pscanMask;
+	uint16_t singleCC;
+};
+
+struct ccmap {
+	char isoName[3];
+	uint16_t countryCode;
+};
+
+struct country_code_to_enum_rd {
+	uint16_t countryCode;
+	uint16_t regDmnEnum;
+	const char *isoName;
+	const char *name;
+	boolean_t allow11g;
+	boolean_t allow11aTurbo;
+	boolean_t allow11gTurbo;
+	boolean_t allow11ng20;
+	boolean_t allow11ng40;
+	boolean_t allow11na20;
+	boolean_t allow11na40;
+	uint16_t outdoorChanStart;
+};
+
+struct RegDmnFreqBand {
+	uint16_t lowChannel;
+	uint16_t highChannel;
+	uint8_t powerDfs;
+	uint8_t antennaMax;
+	uint8_t channelBW;
+	uint8_t channelSep;
+	uint64_t useDfs;
+	uint64_t usePassScan;
+	uint8_t regClassId;
+};
+
+struct regDomain {
+	uint16_t regDmnEnum;
+	uint8_t conformanceTestLimit;
+	uint64_t dfsMask;
+	uint64_t pscan;
+	uint32_t flags;
+	uint64_t chan11a[BMLEN];
+	uint64_t chan11a_turbo[BMLEN];
+	uint64_t chan11a_dyn_turbo[BMLEN];
+	uint64_t chan11b[BMLEN];
+	uint64_t chan11g[BMLEN];
+	uint64_t chan11g_turbo[BMLEN];
+};
+
+struct cmode {
+	uint32_t mode;
+	uint32_t flags;
+};
+
+#define	YES	B_TRUE
+#define	NO	B_FALSE
+
+struct japan_bandcheck {
+	uint16_t freqbandbit;
+	uint32_t eepromflagtocheck;
+};
+
+struct common_mode_power {
+	uint16_t lchan;
+	uint16_t hchan;
+	uint8_t pwrlvl;
+};
+
+enum CountryCode {
+	CTRY_ALBANIA = 8,
+	CTRY_ALGERIA = 12,
+	CTRY_ARGENTINA = 32,
+	CTRY_ARMENIA = 51,
+	CTRY_AUSTRALIA = 36,
+	CTRY_AUSTRIA = 40,
+	CTRY_AZERBAIJAN = 31,
+	CTRY_BAHRAIN = 48,
+	CTRY_BELARUS = 112,
+	CTRY_BELGIUM = 56,
+	CTRY_BELIZE = 84,
+	CTRY_BOLIVIA = 68,
+	CTRY_BOSNIA_HERZ = 70,
+	CTRY_BRAZIL = 76,
+	CTRY_BRUNEI_DARUSSALAM = 96,
+	CTRY_BULGARIA = 100,
+	CTRY_CANADA = 124,
+	CTRY_CHILE = 152,
+	CTRY_CHINA = 156,
+	CTRY_COLOMBIA = 170,
+	CTRY_COSTA_RICA = 188,
+	CTRY_CROATIA = 191,
+	CTRY_CYPRUS = 196,
+	CTRY_CZECH = 203,
+	CTRY_DENMARK = 208,
+	CTRY_DOMINICAN_REPUBLIC = 214,
+	CTRY_ECUADOR = 218,
+	CTRY_EGYPT = 818,
+	CTRY_EL_SALVADOR = 222,
+	CTRY_ESTONIA = 233,
+	CTRY_FAEROE_ISLANDS = 234,
+	CTRY_FINLAND = 246,
+	CTRY_FRANCE = 250,
+	CTRY_GEORGIA = 268,
+	CTRY_GERMANY = 276,
+	CTRY_GREECE = 300,
+	CTRY_GUATEMALA = 320,
+	CTRY_HONDURAS = 340,
+	CTRY_HONG_KONG = 344,
+	CTRY_HUNGARY = 348,
+	CTRY_ICELAND = 352,
+	CTRY_INDIA = 356,
+	CTRY_INDONESIA = 360,
+	CTRY_IRAN = 364,
+	CTRY_IRAQ = 368,
+	CTRY_IRELAND = 372,
+	CTRY_ISRAEL = 376,
+	CTRY_ITALY = 380,
+	CTRY_JAMAICA = 388,
+	CTRY_JAPAN = 392,
+	CTRY_JORDAN = 400,
+	CTRY_KAZAKHSTAN = 398,
+	CTRY_KENYA = 404,
+	CTRY_KOREA_NORTH = 408,
+	CTRY_KOREA_ROC = 410,
+	CTRY_KOREA_ROC2 = 411,
+	CTRY_KOREA_ROC3 = 412,
+	CTRY_KUWAIT = 414,
+	CTRY_LATVIA = 428,
+	CTRY_LEBANON = 422,
+	CTRY_LIBYA = 434,
+	CTRY_LIECHTENSTEIN = 438,
+	CTRY_LITHUANIA = 440,
+	CTRY_LUXEMBOURG = 442,
+	CTRY_MACAU = 446,
+	CTRY_MACEDONIA = 807,
+	CTRY_MALAYSIA = 458,
+	CTRY_MALTA = 470,
+	CTRY_MEXICO = 484,
+	CTRY_MONACO = 492,
+	CTRY_MOROCCO = 504,
+	CTRY_NEPAL = 524,
+	CTRY_NETHERLANDS = 528,
+	CTRY_NETHERLANDS_ANTILLES = 530,
+	CTRY_NEW_ZEALAND = 554,
+	CTRY_NICARAGUA = 558,
+	CTRY_NORWAY = 578,
+	CTRY_OMAN = 512,
+	CTRY_PAKISTAN = 586,
+	CTRY_PANAMA = 591,
+	CTRY_PAPUA_NEW_GUINEA = 598,
+	CTRY_PARAGUAY = 600,
+	CTRY_PERU = 604,
+	CTRY_PHILIPPINES = 608,
+	CTRY_POLAND = 616,
+	CTRY_PORTUGAL = 620,
+	CTRY_PUERTO_RICO = 630,
+	CTRY_QATAR = 634,
+	CTRY_ROMANIA = 642,
+	CTRY_RUSSIA = 643,
+	CTRY_SAUDI_ARABIA = 682,
+	CTRY_SERBIA_MONTENEGRO = 891,
+	CTRY_SINGAPORE = 702,
+	CTRY_SLOVAKIA = 703,
+	CTRY_SLOVENIA = 705,
+	CTRY_SOUTH_AFRICA = 710,
+	CTRY_SPAIN = 724,
+	CTRY_SRI_LANKA = 144,
+	CTRY_SWEDEN = 752,
+	CTRY_SWITZERLAND = 756,
+	CTRY_SYRIA = 760,
+	CTRY_TAIWAN = 158,
+	CTRY_THAILAND = 764,
+	CTRY_TRINIDAD_Y_TOBAGO = 780,
+	CTRY_TUNISIA = 788,
+	CTRY_TURKEY = 792,
+	CTRY_UAE = 784,
+	CTRY_UKRAINE = 804,
+	CTRY_UNITED_KINGDOM = 826,
+	CTRY_UNITED_STATES = 840,
+	CTRY_UNITED_STATES_FCC49 = 842,
+	CTRY_URUGUAY = 858,
+	CTRY_UZBEKISTAN = 860,
+	CTRY_VENEZUELA = 862,
+	CTRY_VIET_NAM = 704,
+	CTRY_YEMEN = 887,
+	CTRY_ZIMBABWE = 716,
+	CTRY_JAPAN1 = 393,
+	CTRY_JAPAN2 = 394,
+	CTRY_JAPAN3 = 395,
+	CTRY_JAPAN4 = 396,
+	CTRY_JAPAN5 = 397,
+	CTRY_JAPAN6 = 4006,
+	CTRY_JAPAN7 = 4007,
+	CTRY_JAPAN8 = 4008,
+	CTRY_JAPAN9 = 4009,
+	CTRY_JAPAN10 = 4010,
+	CTRY_JAPAN11 = 4011,
+	CTRY_JAPAN12 = 4012,
+	CTRY_JAPAN13 = 4013,
+	CTRY_JAPAN14 = 4014,
+	CTRY_JAPAN15 = 4015,
+	CTRY_JAPAN16 = 4016,
+	CTRY_JAPAN17 = 4017,
+	CTRY_JAPAN18 = 4018,
+	CTRY_JAPAN19 = 4019,
+	CTRY_JAPAN20 = 4020,
+	CTRY_JAPAN21 = 4021,
+	CTRY_JAPAN22 = 4022,
+	CTRY_JAPAN23 = 4023,
+	CTRY_JAPAN24 = 4024,
+	CTRY_JAPAN25 = 4025,
+	CTRY_JAPAN26 = 4026,
+	CTRY_JAPAN27 = 4027,
+	CTRY_JAPAN28 = 4028,
+	CTRY_JAPAN29 = 4029,
+	CTRY_JAPAN30 = 4030,
+	CTRY_JAPAN31 = 4031,
+	CTRY_JAPAN32 = 4032,
+	CTRY_JAPAN33 = 4033,
+	CTRY_JAPAN34 = 4034,
+	CTRY_JAPAN35 = 4035,
+	CTRY_JAPAN36 = 4036,
+	CTRY_JAPAN37 = 4037,
+	CTRY_JAPAN38 = 4038,
+	CTRY_JAPAN39 = 4039,
+	CTRY_JAPAN40 = 4040,
+	CTRY_JAPAN41 = 4041,
+	CTRY_JAPAN42 = 4042,
+	CTRY_JAPAN43 = 4043,
+	CTRY_JAPAN44 = 4044,
+	CTRY_JAPAN45 = 4045,
+	CTRY_JAPAN46 = 4046,
+	CTRY_JAPAN47 = 4047,
+	CTRY_JAPAN48 = 4048,
+	CTRY_JAPAN49 = 4049,
+	CTRY_JAPAN50 = 4050,
+	CTRY_JAPAN51 = 4051,
+	CTRY_JAPAN52 = 4052,
+	CTRY_JAPAN53 = 4053,
+	CTRY_JAPAN54 = 4054,
+	CTRY_JAPAN55 = 4055,
+	CTRY_JAPAN56 = 4056,
+	CTRY_JAPAN57 = 4057,
+	CTRY_JAPAN58 = 4058,
+	CTRY_JAPAN59 = 4059,
+	CTRY_AUSTRALIA2 = 5000,
+	CTRY_CANADA2 = 5001,
+	CTRY_BELGIUM2 = 5002
+};
+
+void ath9k_regd_get_current_country(struct ath_hal *ah,
+				    struct ath9k_country_entry *ctry);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARN_REGD_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_regd_common.h	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,2117 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_ARN_REGD_COMMON_H
+#define	_ARN_REGD_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum EnumRd {
+	NO_ENUMRD =	0x00,
+	NULL1_WORLD =	0x03,
+	NULL1_ETSIB =	0x07,
+	NULL1_ETSIC =	0x08,
+	FCC1_FCCA =	0x10,
+	FCC1_WORLD =	0x11,
+	FCC4_FCCA =	0x12,
+	FCC5_FCCA =	0x13,
+	FCC6_FCCA =	0x14,
+
+	FCC2_FCCA =	0x20,
+	FCC2_WORLD =	0x21,
+	FCC2_ETSIC =	0x22,
+	FCC6_WORLD =	0x23,
+	FRANCE_RES =	0x31,
+	FCC3_FCCA =	0x3A,
+	FCC3_WORLD =	0x3B,
+
+	ETSI1_WORLD =	0x37,
+	ETSI3_ETSIA =	0x32,
+	ETSI2_WORLD =	0x35,
+	ETSI3_WORLD =	0x36,
+	ETSI4_WORLD =	0x30,
+	ETSI4_ETSIC =	0x38,
+	ETSI5_WORLD =	0x39,
+	ETSI6_WORLD =	0x34,
+	ETSI_RESERVED =	0x33,
+
+	MKK1_MKKA =	0x40,
+	MKK1_MKKB =	0x41,
+	APL4_WORLD =	0x42,
+	MKK2_MKKA =	0x43,
+	APL_RESERVED =	0x44,
+	APL2_WORLD =	0x45,
+	APL2_APLC =	0x46,
+	APL3_WORLD =	0x47,
+	MKK1_FCCA =	0x48,
+	APL2_APLD =	0x49,
+	MKK1_MKKA1 =	0x4A,
+	MKK1_MKKA2 =	0x4B,
+	MKK1_MKKC =	0x4C,
+
+	APL3_FCCA =	0x50,
+	APL1_WORLD =	0x52,
+	APL1_FCCA =	0x53,
+	APL1_APLA =	0x54,
+	APL1_ETSIC =	0x55,
+	APL2_ETSIC =	0x56,
+	APL5_WORLD =	0x58,
+	APL6_WORLD =	0x5B,
+	APL7_FCCA =	0x5C,
+	APL8_WORLD =	0x5D,
+	APL9_WORLD =	0x5E,
+
+	WOR0_WORLD =	0x60,
+	WOR1_WORLD =	0x61,
+	WOR2_WORLD =	0x62,
+	WOR3_WORLD =	0x63,
+	WOR4_WORLD =	0x64,
+	WOR5_ETSIC =	0x65,
+
+	WOR01_WORLD =	0x66,
+	WOR02_WORLD =	0x67,
+	EU1_WORLD =	0x68,
+
+	WOR9_WORLD =	0x69,
+	WORA_WORLD =	0x6A,
+	WORB_WORLD =	0x6B,
+
+	MKK3_MKKB =	0x80,
+	MKK3_MKKA2 =	0x81,
+	MKK3_MKKC =	0x82,
+
+	MKK4_MKKB =	0x83,
+	MKK4_MKKA2 =	0x84,
+	MKK4_MKKC =	0x85,
+
+	MKK5_MKKB =	0x86,
+	MKK5_MKKA2 =	0x87,
+	MKK5_MKKC =	0x88,
+
+	MKK6_MKKB =	0x89,
+	MKK6_MKKA2 =	0x8A,
+	MKK6_MKKC =	0x8B,
+
+	MKK7_MKKB =	0x8C,
+	MKK7_MKKA2 =	0x8D,
+	MKK7_MKKC =	0x8E,
+
+	MKK8_MKKB =	0x8F,
+	MKK8_MKKA2 =	0x90,
+	MKK8_MKKC =	0x91,
+
+	MKK14_MKKA1 =	0x92,
+	MKK15_MKKA1 =	0x93,
+
+	MKK10_FCCA =	0xD0,
+	MKK10_MKKA1 =	0xD1,
+	MKK10_MKKC =	0xD2,
+	MKK10_MKKA2 =	0xD3,
+
+	MKK11_MKKA =	0xD4,
+	MKK11_FCCA =	0xD5,
+	MKK11_MKKA1 =	0xD6,
+	MKK11_MKKC =	0xD7,
+	MKK11_MKKA2 =	0xD8,
+
+	MKK12_MKKA =	0xD9,
+	MKK12_FCCA =	0xDA,
+	MKK12_MKKA1 =	0xDB,
+	MKK12_MKKC =	0xDC,
+	MKK12_MKKA2 =	0xDD,
+
+	MKK13_MKKB =	0xDE,
+
+	MKK3_MKKA =	0xF0,
+	MKK3_MKKA1 =	0xF1,
+	MKK3_FCCA =	0xF2,
+	MKK4_MKKA =	0xF3,
+	MKK4_MKKA1 =	0xF4,
+	MKK4_FCCA =	0xF5,
+	MKK9_MKKA = 	0xF6,
+	MKK10_MKKA =	0xF7,
+	MKK6_MKKA1 =	0xF8,
+	MKK6_FCCA =	0xF9,
+	MKK7_MKKA1 =	0xFA,
+	MKK7_FCCA =	0xFB,
+	MKK9_FCCA =	0xFC,
+	MKK9_MKKA1 =	0xFD,
+	MKK9_MKKC =	0xFE,
+	MKK9_MKKA2 =	0xFF,
+
+	APL1 =	0x0150,
+	APL2 =	0x0250,
+	APL3 =	0x0350,
+	APL4 =	0x0450,
+	APL5 =	0x0550,
+	APL6 =	0x0650,
+	APL7 =	0x0750,
+	APL8 =	0x0850,
+	APL9 =	0x0950,
+	APL10 =	0x1050,
+
+	ETSI1 =	0x0130,
+	ETSI2 =	0x0230,
+	ETSI3 =	0x0330,
+	ETSI4 =	0x0430,
+	ETSI5 =	0x0530,
+	ETSI6 =	0x0630,
+	ETSIA =	0x0A30,
+	ETSIB =	0x0B30,
+	ETSIC =	0x0C30,
+
+	FCC1 =	0x0110,
+	FCC2 =	0x0120,
+	FCC3 =	0x0160,
+	FCC4 =	0x0165,
+	FCC5 =	0x0510,
+	FCC6 =	0x0610,
+	FCCA =	0x0A10,
+
+	APLD =	0x0D50,
+
+	MKK1 =	0x0140,
+	MKK2 =	0x0240,
+	MKK3 =	0x0340,
+	MKK4 =	0x0440,
+	MKK5 =	0x0540,
+	MKK6 =	0x0640,
+	MKK7 =	0x0740,
+	MKK8 =	0x0840,
+	MKK9 =	0x0940,
+	MKK10 =	0x0B40,
+	MKK11 =	0x1140,
+	MKK12 =	0x1240,
+	MKK13 =	0x0C40,
+	MKK14 =	0x1440,
+	MKK15 =	0x1540,
+	MKKA =	0x0A40,
+	MKKC =	0x0A50,
+
+	NULL1 =	0x0198,
+	WORLD =	0x0199,
+	DEBUG_REG_DMN =	0x01ff,
+};
+
+enum {
+	FCC =	0x10,
+	MKK =	0x40,
+	ETSI =	0x30,
+};
+
+enum {
+	NO_REQ = 0x00000000,
+	DISALLOW_ADHOC_11A = 0x00000001,
+	DISALLOW_ADHOC_11A_TURB = 0x00000002,
+	NEED_NFC = 0x00000004,
+
+	ADHOC_PER_11D = 0x00000008,
+	ADHOC_NO_11A = 0x00000010,
+
+	PUBLIC_SAFETY_DOMAIN = 0x00000020,
+	LIMIT_FRAME_4MS = 0x00000040,
+
+	NO_HOSTAP = 0x00000080,
+
+	REQ_MASK = 0x000000FF,
+};
+
+#define	REG_DOMAIN_2GHZ_MASK    (REQ_MASK & \
+	(~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
+#define	REG_DOMAIN_5GHZ_MASK	REQ_MASK
+
+static struct reg_dmn_pair_mapping regDomainPairs[] = {
+	{NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ,
+	    PSCAN_DEFER, 0},
+	{NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+
+	{FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC4_FCCA, FCC4, FCCA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+
+	{ETSI1_WORLD, ETSI1, WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{ETSI2_WORLD, ETSI2, WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{ETSI3_WORLD, ETSI3, WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{ETSI4_WORLD, ETSI4, WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{ETSI5_WORLD, ETSI5, WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{ETSI6_WORLD, ETSI6, WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+
+	{ETSI3_ETSIA, ETSI3, WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+
+	{FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+
+	{APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, },
+
+	{MKK1_MKKA, MKK1, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN},
+	{MKK1_MKKB, MKK1, MKKA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
+	    LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN1},
+	{MKK1_FCCA, MKK1, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1, CTRY_JAPAN2},
+	{MKK1_MKKA1, MKK1, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4},
+	{MKK1_MKKA2, MKK1, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5},
+	{MKK1_MKKC, MKK1, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1, CTRY_JAPAN6},
+
+	{MKK2_MKKA, MKK2, MKKA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
+	    LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN3},
+
+	{MKK3_MKKA, MKK3, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKKA, CTRY_JAPAN25},
+	{MKK3_MKKB, MKK3, MKKA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
+	    LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN7},
+	{MKK3_MKKA1, MKK3, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26},
+	{MKK3_MKKA2, MKK3, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8},
+	{MKK3_MKKC, MKK3, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    NO_PSCAN, CTRY_JAPAN9},
+	{MKK3_FCCA, MKK3, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    NO_PSCAN, CTRY_JAPAN27},
+
+	{MKK4_MKKA, MKK4, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3, CTRY_JAPAN36},
+	{MKK4_MKKB, MKK4, MKKA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
+	    LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN10},
+	{MKK4_MKKA1, MKK4, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28},
+	{MKK4_MKKA2, MKK4, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11},
+	{MKK4_MKKC, MKK4, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3, CTRY_JAPAN12},
+	{MKK4_FCCA, MKK4, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3, CTRY_JAPAN29},
+
+	{MKK5_MKKB, MKK5, MKKA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
+	    LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN13},
+	{MKK5_MKKA2, MKK5, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14},
+	{MKK5_MKKC, MKK5, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3, CTRY_JAPAN15},
+
+	{MKK6_MKKB, MKK6, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16},
+	{MKK6_MKKA1, MKK6, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30},
+	{MKK6_MKKA2, MKK6, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17},
+	{MKK6_MKKC, MKK6, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1, CTRY_JAPAN18},
+	{MKK6_FCCA, MKK6, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    NO_PSCAN, CTRY_JAPAN31},
+
+	{MKK7_MKKB, MKK7, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN19},
+	{MKK7_MKKA1, MKK7, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32},
+	{MKK7_MKKA2, MKK7, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
+	    CTRY_JAPAN20},
+	{MKK7_MKKC, MKK7, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21},
+	{MKK7_FCCA, MKK7, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33},
+
+	{MKK8_MKKB, MKK8, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN22},
+	{MKK8_MKKA2, MKK8, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
+	    CTRY_JAPAN23},
+	{MKK8_MKKC, MKK8, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN24},
+
+	{MKK9_MKKA, MKK9, MKKA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
+	    LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK2 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN34},
+	{MKK9_FCCA, MKK9, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    NO_PSCAN, CTRY_JAPAN37},
+	{MKK9_MKKA1, MKK9, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38},
+	{MKK9_MKKA2, MKK9, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40},
+	{MKK9_MKKC, MKK9, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    NO_PSCAN, CTRY_JAPAN39},
+
+	{MKK10_MKKA, MKK10, MKKA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
+	    LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKK3, CTRY_JAPAN35},
+	{MKK10_FCCA, MKK10, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    NO_PSCAN, CTRY_JAPAN41},
+	{MKK10_MKKA1, MKK10, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42},
+	{MKK10_MKKA2, MKK10, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44},
+	{MKK10_MKKC, MKK10, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    NO_PSCAN, CTRY_JAPAN43},
+
+	{MKK11_MKKA, MKK11, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3, CTRY_JAPAN45},
+	{MKK11_FCCA, MKK11, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3, CTRY_JAPAN46},
+	{MKK11_MKKA1, MKK11, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47},
+	{MKK11_MKKA2, MKK11, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49},
+	{MKK11_MKKC, MKK11, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK3, CTRY_JAPAN48},
+
+	{MKK12_MKKA, MKK12, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50},
+	{MKK12_FCCA, MKK12, FCCA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51},
+	{MKK12_MKKA1, MKK12, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G,
+	    CTRY_JAPAN52},
+	{MKK12_MKKA2, MKK12, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
+	    CTRY_JAPAN54},
+	{MKK12_MKKC, MKK12, MKKC,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53},
+
+	{MKK13_MKKB, MKK13, MKKA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
+	    LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
+	    CTRY_JAPAN57},
+
+	{MKK14_MKKA1, MKK14, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58},
+	{MKK15_MKKA1, MKK15, MKKA,
+	    DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
+	    PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59},
+
+	{WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
+	    0},
+	{WOR1_WORLD, WOR1_WORLD, WOR1_WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB,
+	    NO_REQ, PSCAN_DEFER, 0},
+	{WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
+	    0},
+	{WOR4_WORLD, WOR4_WORLD, WOR4_WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ,
+	    PSCAN_DEFER, 0},
+	{WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ,
+	    PSCAN_DEFER, 0},
+	{EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
+	{WOR9_WORLD, WOR9_WORLD, WOR9_WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{WORA_WORLD, WORA_WORLD, WORA_WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+	{WORB_WORLD, WORB_WORLD, WORB_WORLD,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
+	    0},
+};
+
+#define	NO_INTERSECT_REQ	0xFFFFFFFF
+#define	NO_UNION_REQ		0
+
+static struct country_code_to_enum_rd allCountries[] = {
+	{CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, NO,
+	    NO, NO, 7000},
+	{CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, NO,
+	    NO, NO, 7000},
+	{CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES,
+	    NO, YES, NO, 7000},
+	{CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES,
+	    YES, NO, 7000},
+	{CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_BELGIUM2, ETSI4_WORLD, "BL", "BELGIUM", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA_HERZGOWINA", YES, NO,
+	    YES, YES, YES, YES, NO, 7000},
+	{CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, NO,
+	    YES, NO, 7000},
+	{CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM",
+	    YES, YES, YES, YES, YES, YES, YES, 7000},
+	{CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_CANADA, FCC2_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES,
+	    YES, YES, NO, 7000},
+	{CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES,
+	    YES, YES, YES, NO, 7000},
+	{CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, YES,
+	    YES, YES, NO, 7000},
+	{CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC",
+	    YES, YES, YES, YES, YES, YES, YES, 7000},
+	{CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES,
+	    YES, NO, 7000},
+	{CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES,
+	    YES, NO, 7000},
+	{CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES,
+	    YES, YES, YES, NO, 7000},
+	{CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES,
+	    YES, NO, 7000},
+	{CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, YES,
+	    YES, YES, NO, 7000},
+	{CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES,
+	    YES, 7000},
+	{CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES,
+	    NO, NO, 7000},
+	{CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+
+	{CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES,
+	    YES, 7000},
+	{CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES,
+	    YES, YES, 7000},
+
+	{CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES,
+	    YES, NO, 7000},
+	{CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES,
+	    YES, YES, NO, NO, 7000},
+	{CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO,
+	    YES, NO, YES, NO, 7000},
+	{CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2", YES, NO, NO,
+	    YES, NO, YES, NO, 7000},
+	{CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO,
+	    YES, NO, YES, NO, 7000},
+	{CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES,
+	    NO, NO, 7000},
+	{CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO,
+	    YES, YES, YES, YES, YES, 7000},
+	{CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, NO,
+	    YES, NO, 7000},
+	{CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN",
+	    "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, YES, YES, 7000},
+	{CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES,
+	    YES, YES, YES, NO, 7000},
+	{CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES,
+	    NO, 7000},
+	{CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES,
+	    YES, YES, YES, YES, YES, YES, 7000},
+	{CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES,
+	    NO, 7000},
+	{CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES,
+	    NO, NO, 7000},
+	{CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, YES, YES,
+	    NO, NO, 7000},
+	{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO,
+	    YES, YES, YES, NO, NO, 7000},
+	{CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO",
+	    YES, NO, YES, YES, YES, YES, YES, 7000},
+	{CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES,
+	    YES, YES, YES, 7000},
+	{CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES,
+	    YES, YES, YES, NO, 7000},
+	{CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES,
+	    YES, YES, NO, 7000},
+	{CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, YES, YES,
+	    NO, NO, 7000},
+	{CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES,
+	    YES, YES, 7000},
+	{CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO",
+	    YES, NO, YES, YES, YES, YES, NO, 7000},
+	{CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES,
+	    YES, YES, NO, 7000},
+	{CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES,
+	    YES, NO, 7000},
+	{CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES,
+	    YES, YES, NO, NO, 7000},
+	{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO,
+	    YES, YES, YES, YES, YES, 7000},
+	{CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES,
+	    YES, YES, YES, YES, YES, 5825},
+	{CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS",
+	    "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES,
+	    YES, 7000},
+	{CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES,
+	    YES, NO, 7000},
+	{CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES,
+	    YES, YES, YES, YES, 7000},
+	{CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, YES,
+	    YES, YES, NO, 7000},
+	{CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, YES,
+	    YES, NO, NO, 7000},
+	{CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES,
+	    NO, NO, 7000},
+	{CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES,
+	    YES, NO, NO, 7000}
+};
+
+enum {
+	NO_DFS = 0x0000000000000000ULL,
+	DFS_FCC3 = 0x0000000000000001ULL,
+	DFS_ETSI = 0x0000000000000002ULL,
+	DFS_MKK4 = 0x0000000000000004ULL,
+};
+
+enum {
+	F1_4915_4925,
+	F1_4935_4945,
+	F1_4920_4980,
+	F1_4942_4987,
+	F1_4945_4985,
+	F1_4950_4980,
+	F1_5035_5040,
+	F1_5040_5080,
+	F1_5055_5055,
+
+	F1_5120_5240,
+
+	F1_5170_5230,
+	F2_5170_5230,
+
+	F1_5180_5240,
+	F2_5180_5240,
+	F3_5180_5240,
+	F4_5180_5240,
+	F5_5180_5240,
+	F6_5180_5240,
+	F7_5180_5240,
+	F8_5180_5240,
+
+	F1_5180_5320,
+
+	F1_5240_5280,
+
+	F1_5260_5280,
+
+	F1_5260_5320,
+	F2_5260_5320,
+	F3_5260_5320,
+	F4_5260_5320,
+	F5_5260_5320,
+	F6_5260_5320,
+
+	F1_5260_5700,
+
+	F1_5280_5320,
+
+	F1_5500_5580,
+
+	F1_5500_5620,
+
+	F1_5500_5700,
+	F2_5500_5700,
+	F3_5500_5700,
+	F4_5500_5700,
+	F5_5500_5700,
+
+	F1_5660_5700,
+
+	F1_5745_5805,
+	F2_5745_5805,
+	F3_5745_5805,
+
+	F1_5745_5825,
+	F2_5745_5825,
+	F3_5745_5825,
+	F4_5745_5825,
+	F5_5745_5825,
+	F6_5745_5825,
+
+	W1_4920_4980,
+	W1_5040_5080,
+	W1_5170_5230,
+	W1_5180_5240,
+	W1_5260_5320,
+	W1_5745_5825,
+	W1_5500_5700,
+	A_DEMO_ALL_CHANNELS
+};
+
+static struct RegDmnFreqBand regDmn5GhzFreq[] = {
+	{4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
+	{4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
+	{4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7},
+	{4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0},
+	{4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0},
+	{4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0},
+	{5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
+	{5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2},
+	{5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
+
+	{5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
+
+	{5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
+	{5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
+
+	{5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
+	{5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1},
+	{5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
+	{5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
+	{5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
+	{5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0},
+	{5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0},
+	{5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
+
+	{5180, 5320, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
+
+	{5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0},
+
+	{5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
+	    PSCAN_FCC | PSCAN_ETSI, 0},
+
+	{5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
+	    PSCAN_FCC | PSCAN_ETSI, 0},
+
+	{5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
+	    PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3, 0},
+
+
+	{5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI,
+	    PSCAN_FCC | PSCAN_ETSI, 2},
+	{5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2},
+	{5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
+	{5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
+
+	{5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0},
+
+	{5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
+
+	{5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
+
+	{5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
+
+	{5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4},
+	{5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
+	    PSCAN_FCC | PSCAN_ETSI, 0},
+	{5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
+	    PSCAN_FCC | PSCAN_ETSI, 0},
+	{5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
+	    PSCAN_MKK3 | PSCAN_FCC, 0},
+	{5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
+
+	{5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
+
+	{5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
+	{5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
+	{5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
+	{5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
+	{5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
+	{5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
+	{5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
+	{5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3},
+	{5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
+
+
+	{4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
+	{5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
+	{5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
+	{5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
+	{5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
+	{5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
+	{5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
+	{4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
+};
+
+enum {
+	T1_5130_5650,
+	T1_5150_5670,
+
+	T1_5200_5200,
+	T2_5200_5200,
+	T3_5200_5200,
+	T4_5200_5200,
+	T5_5200_5200,
+	T6_5200_5200,
+	T7_5200_5200,
+	T8_5200_5200,
+
+	T1_5200_5280,
+	T2_5200_5280,
+	T3_5200_5280,
+	T4_5200_5280,
+	T5_5200_5280,
+	T6_5200_5280,
+
+	T1_5200_5240,
+	T1_5210_5210,
+	T2_5210_5210,
+	T3_5210_5210,
+	T4_5210_5210,
+	T5_5210_5210,
+	T6_5210_5210,
+	T7_5210_5210,
+	T8_5210_5210,
+	T9_5210_5210,
+	T10_5210_5210,
+	T1_5240_5240,
+
+	T1_5210_5250,
+	T1_5210_5290,
+	T2_5210_5290,
+	T3_5210_5290,
+
+	T1_5280_5280,
+	T2_5280_5280,
+	T1_5290_5290,
+	T2_5290_5290,
+	T3_5290_5290,
+	T1_5250_5290,
+	T2_5250_5290,
+	T3_5250_5290,
+	T4_5250_5290,
+
+	T1_5540_5660,
+	T2_5540_5660,
+	T3_5540_5660,
+	T1_5760_5800,
+	T2_5760_5800,
+	T3_5760_5800,
+	T4_5760_5800,
+	T5_5760_5800,
+	T6_5760_5800,
+	T7_5760_5800,
+
+	T1_5765_5805,
+	T2_5765_5805,
+	T3_5765_5805,
+	T4_5765_5805,
+	T5_5765_5805,
+	T6_5765_5805,
+	T7_5765_5805,
+	T8_5765_5805,
+	T9_5765_5805,
+
+	WT1_5210_5250,
+	WT1_5290_5290,
+	WT1_5540_5660,
+	WT1_5760_5800,
+};
+
+enum {
+	F1_2312_2372,
+	F2_2312_2372,
+
+	F1_2412_2472,
+	F2_2412_2472,
+	F3_2412_2472,
+
+	F1_2412_2462,
+	F2_2412_2462,
+
+	F1_2432_2442,
+
+	F1_2457_2472,
+
+	F1_2467_2472,
+
+	F1_2484_2484,
+	F2_2484_2484,
+
+	F1_2512_2732,
+
+	W1_2312_2372,
+	W1_2412_2412,
+	W1_2417_2432,
+	W1_2437_2442,
+	W1_2447_2457,
+	W1_2462_2462,
+	W1_2467_2467,
+	W2_2467_2467,
+	W1_2472_2472,
+	W2_2472_2472,
+	W1_2484_2484,
+	W2_2484_2484,
+};
+
+static struct RegDmnFreqBand regDmn2GhzFreq[] = {
+	{2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
+	{2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
+
+	{2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
+
+	{2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2484, 2484, 20, 0, 20, 5, NO_DFS,
+	    PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
+
+	{2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+	{2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+	{2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+	{2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+	{2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+	{2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+};
+
+enum {
+	G1_2312_2372,
+	G2_2312_2372,
+
+	G1_2412_2472,
+	G2_2412_2472,
+	G3_2412_2472,
+
+	G1_2412_2462,
+	G2_2412_2462,
+
+	G1_2432_2442,
+
+	G1_2457_2472,
+
+	G1_2512_2732,
+
+	G1_2467_2472,
+
+	WG1_2312_2372,
+	WG1_2412_2462,
+	WG1_2467_2472,
+	WG2_2467_2472,
+	G_DEMO_ALL_CHANNELS
+};
+
+static struct RegDmnFreqBand regDmn2Ghz11gFreq[] = {
+	{2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
+	{2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
+
+	{2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+
+	{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
+
+	{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
+	{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
+	{2467, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
+	{2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
+};
+
+enum {
+	T1_2312_2372,
+	T1_2437_2437,
+	T2_2437_2437,
+	T3_2437_2437,
+	T1_2512_2732
+};
+
+static struct regDomain regDomains[] = {
+
+	{DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(A_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5130_5650, T1_5150_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1)},
+
+	{APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL7, ETSI, DFS_ETSI, PSCAN_ETSI, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5280_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL8, ETSI, NO_DFS, NO_PSCAN,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL9, ETSI, DFS_ETSI, PSCAN_ETSI,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{APL10, ETSI, DFS_ETSI, PSCAN_ETSI,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5180_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F4_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700,
+	    F6_5745_5825, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+	{MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
+	    F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
+	    F2_5260_5320, F4_5500_5700, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
+	    DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
+	    DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3,
+	    DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
+	    F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3,
+	    DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
+	    F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
+	    F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320,
+	    F4_5500_5700, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
+	    DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
+	    F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
+	    F2_5260_5320, F4_5500_5700, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_5170_5230, F7_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
+	    F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, -1, -1,
+	    -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{MKK15, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
+	    F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240,
+	    F2_5260_5320, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO},
+
+
+	{APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    BMZERO},
+
+	{ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{ETSIB, ETSI, NO_DFS, PSCAN_ETSIB,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{ETSIC, ETSI, NO_DFS, PSCAN_ETSIC,
+	    DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{MKKA, MKK, NO_DFS,
+	    PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G |
+	    PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
+	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
+	    -1, -1, -1, -1, -1),
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
+	    ADHOC_PER_11D,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
+	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
+	    -1, -1, -1, -1, -1),
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
+	    W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
+	    ADHOC_PER_11D,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
+	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
+	    -1, -1, -1, -1, -1),
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
+	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
+	    -1, -1, -1, -1, -1),
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
+	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
+	    W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
+	    -1, -1, -1, -1, -1),
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
+	    -1, -1, -1, -1, -1),
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
+	    -1, -1, -1, -1, -1),
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
+	    W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
+	    -1, -1, -1, -1, -1),
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
+	    W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
+	    -1, -1, -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
+		/* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, -1, -1, -1, -1, -1,
+	    -1, -1, -1, -1),
+	    BMZERO,
+	    BMZERO,
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
+	    W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
+	    -1, -1),
+	    /* LINTED E_FALSE_LOGICAL_EXPR */
+	    BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
+
+	{NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO,
+	    BMZERO}
+};
+
+static const struct cmode modes[] = {
+	{ATH9K_MODE_11A, CHANNEL_A},
+	{ATH9K_MODE_11B, CHANNEL_B},
+	{ATH9K_MODE_11G, CHANNEL_G},
+	{ATH9K_MODE_11NG_HT20, CHANNEL_G_HT20},
+	{ATH9K_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
+	{ATH9K_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
+	{ATH9K_MODE_11NA_HT20, CHANNEL_A_HT20},
+	{ATH9K_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
+	{ATH9K_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
+};
+
+static struct japan_bandcheck j_bandcheck[] = {
+	{F1_5170_5230, AR_EEPROM_EEREGCAP_EN_KK_U1_ODD},
+	{F4_5180_5240, AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN},
+	{F2_5260_5320, AR_EEPROM_EEREGCAP_EN_KK_U2},
+	{F4_5500_5700, AR_EEPROM_EEREGCAP_EN_KK_MIDBAND}
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ARN_REGD_COMMON_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/io/arn/arn_xmit.c	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,1016 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <sys/stream.h>
+#include <sys/termio.h>
+#include <sys/errno.h>
+#include <sys/file.h>
+#include <sys/cmn_err.h>
+#include <sys/stropts.h>
+#include <sys/strsubr.h>
+#include <sys/strtty.h>
+#include <sys/kbio.h>
+#include <sys/cred.h>
+#include <sys/stat.h>
+#include <sys/consdev.h>
+#include <sys/kmem.h>
+#include <sys/modctl.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#include <sys/pci.h>
+#include <sys/errno.h>
+#include <sys/mac_provider.h>
+#include <sys/dlpi.h>
+#include <sys/ethernet.h>
+#include <sys/list.h>
+#include <sys/byteorder.h>
+#include <sys/strsun.h>
+#include <sys/policy.h>
+#include <inet/common.h>
+#include <inet/nd.h>
+#include <inet/mi.h>
+#include <inet/wifi_ioctl.h>
+#include <sys/mac_wifi.h>
+
+#include "arn_core.h"
+
+#define	BITS_PER_BYTE		8
+#define	OFDM_PLCP_BITS		22
+#define	HT_RC_2_MCS(_rc)	((_rc) & 0x0f)
+#define	HT_RC_2_STREAMS(_rc)	((((_rc) & 0x78) >> 3) + 1)
+#define	L_STF			8
+#define	L_LTF			8
+#define	L_SIG			4
+#define	HT_SIG			8
+#define	HT_STF			4
+#define	HT_LTF(_ns)		(4 * (_ns))
+#define	SYMBOL_TIME(_ns)	((_ns) << 2) /* ns * 4 us */
+#define	SYMBOL_TIME_HALFGI(_ns)	(((_ns) * 18 + 4) / 5)  /* ns * 3.6 us */
+#define	NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
+#define	NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
+
+#define	OFDM_SIFS_TIME	16
+
+#define	IS_HT_RATE(_rate)	((_rate) & 0x80)
+
+static void
+arn_get_beaconconfig(struct arn_softc *sc, struct ath_beacon_config *conf)
+{
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ieee80211_node *in = ic->ic_bss;
+
+	/* fill in beacon config data */
+
+	conf->beacon_interval = in->in_intval ?
+	    in->in_intval : ATH_DEFAULT_BINTVAL;
+	conf->listen_interval = 100;
+	conf->dtim_count = 1;
+	conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
+}
+
+static void
+arn_tx_stopdma(struct arn_softc *sc, struct ath_txq *txq)
+{
+	struct ath_hal *ah = sc->sc_ah;
+
+	(void) ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+
+	ARN_DBG((ARN_DBG_XMIT, "arn: arn_drain_txdataq(): "
+	    "tx queue [%u] %x, link %p\n",
+	    txq->axq_qnum,
+	    ath9k_hw_gettxbuf(ah, txq->axq_qnum), txq->axq_link));
+
+}
+
+/* Drain only the data queues */
+/* ARGSUSED */
+static void
+arn_drain_txdataq(struct arn_softc *sc, boolean_t retry_tx)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	int i, status, npend = 0;
+
+	if (!(sc->sc_flags & SC_OP_INVALID)) {
+		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+			if (ARN_TXQ_SETUP(sc, i)) {
+				arn_tx_stopdma(sc, &sc->sc_txq[i]);
+				/*
+				 * The TxDMA may not really be stopped.
+				 * Double check the hal tx pending count
+				 */
+				npend += ath9k_hw_numtxpending(ah,
+				    sc->sc_txq[i].axq_qnum);
+			}
+		}
+	}
+
+	if (npend) {
+		/* TxDMA not stopped, reset the hal */
+		ARN_DBG((ARN_DBG_XMIT, "arn: arn_drain_txdataq(): "
+		    "Unable to stop TxDMA. Reset HAL!\n"));
+
+		if (!ath9k_hw_reset(ah,
+		    sc->sc_ah->ah_curchan,
+		    sc->tx_chan_width,
+		    sc->sc_tx_chainmask, sc->sc_rx_chainmask,
+		    sc->sc_ht_extprotspacing, B_TRUE, &status)) {
+			ARN_DBG((ARN_DBG_FATAL, "arn: arn_drain_txdataq(): "
+			    "unable to reset hardware; hal status %u\n",
+			    status));
+		}
+	}
+
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ARN_TXQ_SETUP(sc, i))
+			arn_tx_draintxq(sc, &sc->sc_txq[i]);
+	}
+}
+
+/* Setup a h/w transmit queue */
+struct ath_txq *
+arn_txq_setup(struct arn_softc *sc, int qtype, int subtype)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	struct ath9k_tx_queue_info qi;
+	int qnum;
+
+	(void) memset(&qi, 0, sizeof (qi));
+	qi.tqi_subtype = subtype;
+	qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
+	qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
+	qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
+	qi.tqi_physCompBuf = 0;
+
+	/*
+	 * Enable interrupts only for EOL and DESC conditions.
+	 * We mark tx descriptors to receive a DESC interrupt
+	 * when a tx queue gets deep; otherwise waiting for the
+	 * EOL to reap descriptors.  Note that this is done to
+	 * reduce interrupt load and this only defers reaping
+	 * descriptors, never transmitting frames.  Aside from
+	 * reducing interrupts this also permits more concurrency.
+	 * The only potential downside is if the tx queue backs
+	 * up in which case the top half of the kernel may backup
+	 * due to a lack of tx descriptors.
+	 *
+	 * The UAPSD queue is an exception, since we take a desc-
+	 * based intr on the EOSP frames.
+	 */
+	if (qtype == ATH9K_TX_QUEUE_UAPSD)
+		qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
+	else
+		qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
+		    TXQ_FLAG_TXDESCINT_ENABLE;
+	qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
+	if (qnum == -1) {
+		/*
+		 * NB: don't print a message, this happens
+		 * normally on parts with too few tx queues
+		 */
+		return (NULL);
+	}
+	if (qnum >= ARRAY_SIZE(sc->sc_txq)) {
+		ARN_DBG((ARN_DBG_FATAL, "arn: arn_txq_setup(): "
+		    "hal qnum %u out of range, max %u!\n",
+		    qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq)));
+		(void) ath9k_hw_releasetxqueue(ah, qnum);
+		return (NULL);
+	}
+	if (!ARN_TXQ_SETUP(sc, qnum)) {
+		struct ath_txq *txq = &sc->sc_txq[qnum];
+
+		txq->axq_qnum = qnum;
+		txq->axq_intrcnt = 0;
+		txq->axq_link = NULL;
+
+		list_create(&txq->axq_list, sizeof (struct ath_buf),
+		    offsetof(struct ath_buf, bf_node));
+		mutex_init(&txq->axq_lock, NULL, MUTEX_DRIVER, NULL);
+
+		txq->axq_depth = 0;
+		txq->axq_aggr_depth = 0;
+		txq->axq_totalqueued = 0;
+		/* txq->axq_linkbuf = NULL; */
+		sc->sc_txqsetup |= 1<<qnum;
+	}
+	return (&sc->sc_txq[qnum]);
+}
+
+/* Reclaim resources for a setup queue */
+
+void
+arn_tx_cleanupq(struct arn_softc *sc, struct ath_txq *txq)
+{
+	(void) ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
+	sc->sc_txqsetup &= ~(1<<txq->axq_qnum);
+}
+
+/*
+ * Setup a hardware data transmit queue for the specified
+ * access control.  The hal may not support all requested
+ * queues in which case it will return a reference to a
+ * previously setup queue.  We record the mapping from ac's
+ * to h/w queues for use by arn_tx_start and also track
+ * the set of h/w queues being used to optimize work in the
+ * transmit interrupt handler and related routines.
+ */
+
+int
+arn_tx_setup(struct arn_softc *sc, int haltype)
+{
+	struct ath_txq *txq;
+
+	if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
+		ARN_DBG((ARN_DBG_FATAL, "arn: arn_tx_setup(): "
+		    "HAL AC %u out of range, max %zu!\n",
+		    haltype, ARRAY_SIZE(sc->sc_haltype2q)));
+		return (0);
+	}
+	txq = arn_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
+	if (txq != NULL) {
+		sc->sc_haltype2q[haltype] = txq->axq_qnum;
+		return (1);
+	} else
+		return (0);
+}
+
+int
+arn_tx_get_qnum(struct arn_softc *sc, int qtype, int haltype)
+{
+	int qnum;
+
+	switch (qtype) {
+	case ATH9K_TX_QUEUE_DATA:
+		if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
+			ARN_DBG((ARN_DBG_FATAL, "arn: arn_tx_get_qnum(): "
+			    "HAL AC %u out of range, max %zu!\n",
+			    haltype, ARRAY_SIZE(sc->sc_haltype2q)));
+			return (-1);
+		}
+		qnum = sc->sc_haltype2q[haltype];
+		break;
+	case ATH9K_TX_QUEUE_BEACON:
+		qnum = sc->sc_beaconq;
+		break;
+	case ATH9K_TX_QUEUE_CAB:
+		qnum = sc->sc_cabq->axq_qnum;
+		break;
+	default:
+		qnum = -1;
+	}
+	return (qnum);
+}
+
+void
+arn_tx_draintxq(struct arn_softc *sc, struct ath_txq *txq)
+{
+	struct ath_buf *bf;
+
+	/*
+	 * This assumes output has been stopped.
+	 */
+	for (;;) {
+		mutex_enter(&txq->axq_lock);
+		bf = list_head(&txq->axq_list);
+		if (bf == NULL) {
+			txq->axq_link = NULL;
+			mutex_exit(&txq->axq_lock);
+			break;
+		}
+		list_remove(&txq->axq_list, bf);
+		mutex_exit(&txq->axq_lock);
+		bf->bf_in = NULL;
+		mutex_enter(&sc->sc_txbuflock);
+		list_insert_tail(&sc->sc_txbuf_list, bf);
+		mutex_exit(&sc->sc_txbuflock);
+	}
+}
+
+/* Drain the transmit queues and reclaim resources */
+
+void
+arn_draintxq(struct arn_softc *sc, boolean_t retry_tx)
+{
+	/*
+	 * stop beacon queue. The beacon will be freed when
+	 * we go to INIT state
+	 */
+	if (!(sc->sc_flags & SC_OP_INVALID)) {
+		(void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_beaconq);
+		ARN_DBG((ARN_DBG_XMIT, "arn: arn_draintxq(): "
+		    "beacon queue %x\n",
+		    ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_beaconq)));
+	}
+
+	arn_drain_txdataq(sc, retry_tx);
+}
+
+uint32_t
+arn_txq_depth(struct arn_softc *sc, int qnum)
+{
+	return (sc->sc_txq[qnum].axq_depth);
+}
+
+uint32_t
+arn_txq_aggr_depth(struct arn_softc *sc, int qnum)
+{
+	return (sc->sc_txq[qnum].axq_aggr_depth);
+}
+
+/* Update parameters for a transmit queue */
+int
+arn_txq_update(struct arn_softc *sc, int qnum,
+    struct ath9k_tx_queue_info *qinfo)
+{
+	struct ath_hal *ah = sc->sc_ah;
+	int error = 0;
+	struct ath9k_tx_queue_info qi;
+
+	if (qnum == sc->sc_beaconq) {
+		/*
+		 * XXX: for beacon queue, we just save the parameter.
+		 * It will be picked up by arn_beaconq_config() when
+		 * it's necessary.
+		 */
+		sc->sc_beacon_qi = *qinfo;
+		return (0);
+	}
+
+	ASSERT(sc->sc_txq[qnum].axq_qnum == qnum);
+
+	(void) ath9k_hw_get_txq_props(ah, qnum, &qi);
+	qi.tqi_aifs = qinfo->tqi_aifs;
+	qi.tqi_cwmin = qinfo->tqi_cwmin;
+	qi.tqi_cwmax = qinfo->tqi_cwmax;
+	qi.tqi_burstTime = qinfo->tqi_burstTime;
+	qi.tqi_readyTime = qinfo->tqi_readyTime;
+
+	if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
+		ARN_DBG((ARN_DBG_FATAL,
+		    "Unable to update hardware queue %u!\n", qnum));
+		error = -EIO;
+	} else {
+		(void) ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */
+	}
+
+	return (error);
+}
+
+int
+ath_cabq_update(struct arn_softc *sc)
+{
+	struct ath9k_tx_queue_info qi;
+	int qnum = sc->sc_cabq->axq_qnum;
+	struct ath_beacon_config conf;
+
+	(void) ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
+	/*
+	 * Ensure the readytime % is within the bounds.
+	 */
+	if (sc->sc_config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
+		sc->sc_config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
+	else if (sc->sc_config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
+		sc->sc_config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
+
+	arn_get_beaconconfig(sc, &conf);
+	qi.tqi_readyTime =
+	    (conf.beacon_interval * sc->sc_config.cabqReadytime) / 100;
+	(void) arn_txq_update(sc, qnum, &qi);
+
+	return (0);
+}
+
+static uint32_t
+arn_tx_get_keytype(const struct ieee80211_cipher *cip)
+{
+	uint32_t index;
+	static const uint8_t ciphermap[] = {
+	    ATH9K_CIPHER_WEP,		/* IEEE80211_CIPHER_WEP */
+	    ATH9K_CIPHER_TKIP,		/* IEEE80211_CIPHER_TKIP */
+	    ATH9K_CIPHER_AES_OCB,	/* IEEE80211_CIPHER_AES_OCB */
+	    ATH9K_CIPHER_AES_CCM,	/* IEEE80211_CIPHER_AES_CCM */
+	    ATH9K_CIPHER_CKIP,		/* IEEE80211_CIPHER_CKIP */
+	    ATH9K_CIPHER_CLR,		/* IEEE80211_CIPHER_NONE */
+	};
+
+	ASSERT(cip->ic_cipher < ARRAY_SIZE(ciphermap));
+	index = cip->ic_cipher;
+
+	if (ciphermap[index] == ATH9K_CIPHER_WEP)
+		return (ATH9K_KEY_TYPE_WEP);
+	else if (ciphermap[index] == ATH9K_CIPHER_TKIP)
+		return (ATH9K_KEY_TYPE_TKIP);
+	else if (ciphermap[index] == ATH9K_CIPHER_AES_CCM)
+		return (ATH9K_KEY_TYPE_AES);
+
+	return (ATH9K_KEY_TYPE_CLEAR);
+
+}
+
+/*
+ * The input parameter mp has following assumption:
+ * For data packets, GLDv3 mac_wifi plugin allocates and fills the
+ * ieee80211 header. For management packets, net80211 allocates and
+ * fills the ieee80211 header. In both cases, enough spaces in the
+ * header are left for encryption option.
+ */
+static int32_t
+arn_tx_start(struct arn_softc *sc, struct ieee80211_node *in,
+    struct ath_buf *bf, mblk_t *mp)
+{
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ieee80211_frame *wh;
+	struct ath_hal *ah = sc->sc_ah;
+	uint32_t flags;
+	uint32_t subtype, ctsduration;
+	int32_t keyix, iswep, hdrlen, pktlen, mblen, mbslen;
+	/* LINTED E_FUNC_SET_NOT_USED */
+	int32_t try0;
+	uint8_t rix, cix, txrate, ctsrate;
+	struct ath_desc *ds;
+	struct ath_txq *txq;
+	enum ath9k_pkt_type atype;
+	struct ath_rate_table *rt;
+	boolean_t shortPreamble;
+	boolean_t is_pspoll;
+	struct ath_node *an;
+	caddr_t dest;
+	uint32_t keytype = ATH9K_KEY_TYPE_CLEAR;
+
+	/*
+	 * CRC are added by H/W, not encaped by driver,
+	 * but we must count it in pkt length.
+	 */
+	pktlen = IEEE80211_CRC_LEN;
+
+	wh = (struct ieee80211_frame *)mp->b_rptr;
+	iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
+	keyix = ATH9K_TXKEYIX_INVALID;
+	hdrlen = sizeof (struct ieee80211_frame);
+	if (iswep != 0) {
+		const struct ieee80211_cipher *cip;
+		struct ieee80211_key *k;
+
+		/*
+		 * Construct the 802.11 header+trailer for an encrypted
+		 * frame. The only reason this can fail is because of an
+		 * unknown or unsupported cipher/key type.
+		 */
+		k = ieee80211_crypto_encap(ic, mp);
+		if (k == NULL) {
+			ARN_DBG((ARN_DBG_XMIT, "arn: arn_tx_start "
+			    "crypto_encap failed\n"));
+			/*
+			 * This can happen when the key is yanked after the
+			 * frame was queued.  Just discard the frame; the
+			 * 802.11 layer counts failures and provides
+			 * debugging/diagnostics.
+			 */
+			return (EIO);
+		}
+		cip = k->wk_cipher;
+
+		keytype = arn_tx_get_keytype(cip);
+
+		/*
+		 * Adjust the packet + header lengths for the crypto
+		 * additions and calculate the h/w key index.  When
+		 * a s/w mic is done the frame will have had any mic
+		 * added to it prior to entry so m0->m_pkthdr.len above will
+		 * account for it. Otherwise we need to add it to the
+		 * packet length.
+		 */
+		hdrlen += cip->ic_header;
+		pktlen += cip->ic_trailer;
+		if ((k->wk_flags & IEEE80211_KEY_SWMIC) == 0)
+			pktlen += cip->ic_miclen;
+
+		keyix = k->wk_keyix;
+
+		/* packet header may have moved, reset our local pointer */
+		wh = (struct ieee80211_frame *)mp->b_rptr;
+	}
+
+	dest = bf->bf_dma.mem_va;
+	for (; mp != NULL; mp = mp->b_cont) {
+		mblen = MBLKL(mp);
+		bcopy(mp->b_rptr, dest, mblen);
+		dest += mblen;
+	}
+	mbslen = (uintptr_t)dest - (uintptr_t)bf->bf_dma.mem_va;
+	pktlen += mbslen;
+
+	bf->bf_in = in;
+
+	/* setup descriptors */
+	ds = bf->bf_desc;
+	rt = sc->sc_currates;
+	ASSERT(rt != NULL);
+
+	/*
+	 * The 802.11 layer marks whether or not we should
+	 * use short preamble based on the current mode and
+	 * negotiated parameters.
+	 */
+	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+	    (in->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
+		shortPreamble = B_TRUE;
+		sc->sc_stats.ast_tx_shortpre++;
+	} else {
+		shortPreamble = B_FALSE;
+	}
+
+	an = (struct ath_node *)(in);
+
+	/*
+	 * Calculate Atheros packet type from IEEE80211 packet header
+	 * and setup for rate calculations.
+	 */
+	switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
+	case IEEE80211_FC0_TYPE_MGT:
+		subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+		if (subtype == IEEE80211_FC0_SUBTYPE_BEACON)
+			atype = ATH9K_PKT_TYPE_BEACON;
+		else if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
+			atype = ATH9K_PKT_TYPE_PROBE_RESP;
+		else if (subtype == IEEE80211_FC0_SUBTYPE_ATIM)
+			atype = ATH9K_PKT_TYPE_ATIM;
+		else
+			atype = ATH9K_PKT_TYPE_NORMAL;
+		rix = 0;	/* lowest rate */
+		try0 = ATH_TXMAXTRY;
+		if (shortPreamble) {
+			txrate = an->an_tx_mgtratesp;
+		} else {
+			txrate = an->an_tx_mgtrate;
+		}
+		/* force all ctl frames to highest queue */
+		txq = &sc->sc_txq[arn_get_hal_qnum(WME_AC_VO, sc)];
+		break;
+	case IEEE80211_FC0_TYPE_CTL:
+		atype = ATH9K_PKT_TYPE_PSPOLL;
+		is_pspoll = B_TRUE;
+		subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+		rix = 0; /* lowest rate */
+		try0 = ATH_TXMAXTRY;
+		if (shortPreamble)
+			txrate = an->an_tx_mgtratesp;
+		else
+			txrate = an->an_tx_mgtrate;
+		/* force all ctl frames to highest queue */
+		txq = &sc->sc_txq[arn_get_hal_qnum(WME_AC_VO, sc)];
+		break;
+	case IEEE80211_FC0_TYPE_DATA:
+		atype = ATH9K_PKT_TYPE_NORMAL;
+		rix = an->an_tx_rix0;
+		try0 = an->an_tx_try0;
+		if (shortPreamble)
+			txrate = an->an_tx_rate0sp;
+		else
+			txrate = an->an_tx_rate0;
+		/* Always use background queue */
+		txq = &sc->sc_txq[arn_get_hal_qnum(WME_AC_BK, sc)];
+		break;
+	default:
+		/* Unknown 802.11 frame */
+		sc->sc_stats.ast_tx_invalid++;
+		return (1);
+	}
+
+	/*
+	 * Calculate miscellaneous flags.
+	 */
+	flags = ATH9K_TXDESC_CLRDMASK;
+	if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+		flags |= ATH9K_TXDESC_NOACK;	/* no ack on broad/multicast */
+		sc->sc_stats.ast_tx_noack++;
+	} else if (pktlen > ic->ic_rtsthreshold) {
+		flags |= ATH9K_TXDESC_RTSENA;	/* RTS based on frame length */
+		sc->sc_stats.ast_tx_rts++;
+	}
+
+	/*
+	 * Calculate duration.  This logically belongs in the 802.11
+	 * layer but it lacks sufficient information to calculate it.
+	 */
+	if ((flags & ATH9K_TXDESC_NOACK) == 0 &&
+	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
+	    IEEE80211_FC0_TYPE_CTL) {
+		uint16_t dur;
+		dur = ath9k_hw_computetxtime(ah, rt, IEEE80211_ACK_SIZE,
+		    rix, shortPreamble);
+		/* LINTED E_BAD_PTR_CAST_ALIGN */
+		*(uint16_t *)wh->i_dur = LE_16(dur);
+	}
+
+	/*
+	 * Calculate RTS/CTS rate and duration if needed.
+	 */
+	ctsduration = 0;
+	if (flags & (ATH9K_TXDESC_RTSENA|ATH9K_TXDESC_CTSENA)) {
+		/*
+		 * CTS transmit rate is derived from the transmit rate
+		 * by looking in the h/w rate table.  We must also factor
+		 * in whether or not a short preamble is to be used.
+		 */
+		cix = rt->info[rix].ctrl_rate;
+		ctsrate = rt->info[cix].ratecode;
+		if (shortPreamble)
+			ctsrate |= rt->info[cix].short_preamble;
+		/*
+		 * Compute the transmit duration based on the size
+		 * of an ACK frame.  We call into the HAL to do the
+		 * computation since it depends on the characteristics
+		 * of the actual PHY being used.
+		 */
+		if (flags & ATH9K_TXDESC_RTSENA) {	/* SIFS + CTS */
+			ctsduration += ath9k_hw_computetxtime(ah,
+			    rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
+		}
+		/* SIFS + data */
+		ctsduration += ath9k_hw_computetxtime(ah,
+		    rt, pktlen, rix, shortPreamble);
+		if ((flags & ATH9K_TXDESC_NOACK) == 0) {  /* SIFS + ACK */
+			ctsduration += ath9k_hw_computetxtime(ah,
+			    rt, IEEE80211_ACK_SIZE, cix, shortPreamble);
+		}
+	} else
+		ctsrate = 0;
+
+	if (++txq->axq_intrcnt >= 5) {
+		flags |= ATH9K_TXDESC_INTREQ;
+		txq->axq_intrcnt = 0;
+	}
+
+	/* setup descriptor */
+	ds->ds_link = 0;
+	ds->ds_data = bf->bf_dma.cookie.dmac_address;
+
+	/*
+	 * Formulate first tx descriptor with tx controls.
+	 */
+	ath9k_hw_set11n_txdesc(ah, ds,
+	    pktlen, /* packet length */
+	    atype, /* Atheros packet type */
+	    MAX_RATE_POWER /* MAX_RATE_POWER */,
+	    keyix /* ATH9K_TXKEYIX_INVALID */,
+	    keytype /* ATH9K_KEY_TYPE_CLEAR */,
+	    flags /* flags */);
+	bf->bf_flags = (uint16_t)flags; /* LINT */
+
+	/* LINTED E_BAD_PTR_CAST_ALIGN */
+	ARN_DBG((ARN_DBG_XMIT, "arn: arn_tx_start(): to %s totlen=%d "
+	    "an->an_tx_rate1sp=%d tx_rate2sp=%d tx_rate3sp=%d "
+	    "qnum=%d rix=%d sht=%d dur = %d\n",
+	    ieee80211_macaddr_sprintf(wh->i_addr1), mbslen, an->an_tx_rate1sp,
+	    an->an_tx_rate2sp, an->an_tx_rate3sp,
+	    txq->axq_qnum, rix, shortPreamble, *(uint16_t *)wh->i_dur));
+
+	(void) ath9k_hw_filltxdesc(ah, ds,
+	    mbslen,		/* segment length */
+	    B_TRUE,		/* first segment */
+	    B_TRUE,		/* last segment */
+	    ds);		/* first descriptor */
+
+	/* set rate related fields in tx descriptor */
+	struct ath9k_11n_rate_series series[4];
+	(void) memset(series, 0, sizeof (struct ath9k_11n_rate_series) * 4);
+
+#ifdef MULTIRATE_RETRY
+	int i;
+	for (i = 1; i < 4; i++) {
+		series[i].Tries = 2; /* ??? */
+		series[i].ChSel = sc->sc_tx_chainmask;
+
+		series[i].RateFlags &= ~ATH9K_RATESERIES_RTS_CTS;
+		series[i].RateFlags &= ~ATH9K_RATESERIES_2040;
+		series[i].RateFlags &= ~ATH9K_RATESERIES_HALFGI;
+
+		series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
+		    rt, pktlen, rix, shortPreamble);
+	}
+#endif
+
+	/* main rate */
+	series[0].Rate = txrate;
+	series[0].Tries = ATH_TXMAXTRY;
+	series[0].RateFlags &= ~ATH9K_RATESERIES_RTS_CTS;
+	series[0].RateFlags &= ~ATH9K_RATESERIES_2040;
+	series[0].RateFlags &= ~ATH9K_RATESERIES_HALFGI;
+	series[0].ChSel = sc->sc_tx_chainmask;
+	series[0].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, rt, pktlen,
+	    rix, shortPreamble);
+
+#ifdef MULTIRATE_RETRY
+	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
+	    (in->in_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
+		series[1].Rate = an->an_tx_rate1sp;
+		series[2].Rate = an->an_tx_rate2sp;
+		series[3].Rate = an->an_tx_rate3sp;
+	}
+	else
+	{
+		series[1].Rate = an->an_tx_rate1;
+		series[2].Rate = an->an_tx_rate2;
+		series[3].Rate = an->an_tx_rate3;
+	}
+#endif
+
+	/* set dur_update_en for l-sig computation except for PS-Poll frames */
+	ath9k_hw_set11n_ratescenario(sc->sc_ah, ds,
+	    ds, !is_pspoll, ctsrate, 0, series, 4, flags);
+
+	ARN_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORDEV);
+
+	mutex_enter(&txq->axq_lock);
+	list_insert_tail(&txq->axq_list, bf);
+	if (txq->axq_link == NULL) {
+		(void) ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+	} else {
+		*txq->axq_link = bf->bf_daddr;
+	}
+	txq->axq_link = &ds->ds_link;
+	mutex_exit(&txq->axq_lock);
+
+	(void) ath9k_hw_txstart(ah, txq->axq_qnum);
+
+	ic->ic_stats.is_tx_frags++;
+	ic->ic_stats.is_tx_bytes += pktlen;
+
+	return (0);
+}
+
+/*
+ * Transmit a management frame.
+ * Note that management frames come directly from the 802.11 layer
+ * and do not honor the send queue flow control.
+ */
+/* Upon failure caller should free mp */
+int
+arn_tx(ieee80211com_t *ic, mblk_t *mp, uint8_t type)
+{
+	struct arn_softc *sc = (struct arn_softc *)ic;
+	struct ath_hal *ah = sc->sc_ah;
+	struct ieee80211_node *in = NULL;
+	struct ath_buf *bf = NULL;
+	struct ieee80211_frame *wh;
+	int error = 0;
+
+	ASSERT(mp->b_next == NULL);
+	/* should check later */
+	if (sc->sc_flags & SC_OP_INVALID) {
+		if ((type & IEEE80211_FC0_TYPE_MASK) !=
+		    IEEE80211_FC0_TYPE_DATA) {
+			freemsg(mp);
+		}
+		return (ENXIO);
+	}
+
+	/* Grab a TX buffer */
+	mutex_enter(&sc->sc_txbuflock);
+	bf = list_head(&sc->sc_txbuf_list);
+	/* Check if a tx buffer is available */
+	if (bf != NULL)
+		list_remove(&sc->sc_txbuf_list, bf);
+	if (list_empty(&sc->sc_txbuf_list)) {
+		ARN_DBG((ARN_DBG_XMIT, "arn: arn_tx(): "
+		    "stop queue\n"));
+		sc->sc_stats.ast_tx_qstop++;
+	}
+	mutex_exit(&sc->sc_txbuflock);
+	if (bf == NULL) {
+		ARN_DBG((ARN_DBG_XMIT, "arn: arn_tx(): discard, "
+		    "no xmit buf\n"));
+		ic->ic_stats.is_tx_nobuf++;
+		if ((type & IEEE80211_FC0_TYPE_MASK) ==
+		    IEEE80211_FC0_TYPE_DATA) {
+			sc->sc_stats.ast_tx_nobuf++;
+			mutex_enter(&sc->sc_resched_lock);
+			sc->sc_resched_needed = B_TRUE;
+			mutex_exit(&sc->sc_resched_lock);
+		} else {
+			sc->sc_stats.ast_tx_nobufmgt++;
+			freemsg(mp);
+		}
+		return (ENOMEM);
+	}
+
+	wh = (struct ieee80211_frame *)mp->b_rptr;
+
+	/* Locate node */
+	in = ieee80211_find_txnode(ic,  wh->i_addr1);
+	if (in == NULL) {
+		error = EIO;
+		goto bad;
+	}
+
+	in->in_inact = 0;
+	switch (type & IEEE80211_FC0_TYPE_MASK) {
+	case IEEE80211_FC0_TYPE_DATA:
+		(void) ieee80211_encap(ic, mp, in);
+		break;
+	default:
+		if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
+		    IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
+			/* fill time stamp */
+			uint64_t tsf;
+			uint32_t *tstamp;
+
+			tsf = ath9k_hw_gettsf64(ah);
+			/* adjust 100us delay to xmit */
+			tsf += 100;
+			/* LINTED E_BAD_PTR_CAST_ALIGN */
+			tstamp = (uint32_t *)&wh[1];
+			tstamp[0] = LE_32(tsf & 0xffffffff);
+			tstamp[1] = LE_32(tsf >> 32);
+		}
+		sc->sc_stats.ast_tx_mgmt++;
+		break;
+	}
+
+	error = arn_tx_start(sc, in, bf, mp);
+
+	if (error != 0) {
+bad:
+		ic->ic_stats.is_tx_failed++;
+		if (bf != NULL) {
+			mutex_enter(&sc->sc_txbuflock);
+			list_insert_tail(&sc->sc_txbuf_list, bf);
+			mutex_exit(&sc->sc_txbuflock);
+		}
+	}
+	if (in != NULL)
+		ieee80211_free_node(in);
+	if ((type & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA ||
+	    error == 0) {
+		freemsg(mp);
+	}
+
+	return (error);
+}
+
+static void
+arn_printtxbuf(struct ath_buf *bf, int done)
+{
+	struct ath_desc *ds = bf->bf_desc;
+	const struct ath_tx_status *ts = &ds->ds_txstat;
+
+	ARN_DBG((ARN_DBG_XMIT, "arn: T(%p %p) %08x %08x %08x %08x %08x"
+	    " %08x %08x %08x %c\n",
+	    ds, bf->bf_daddr,
+	    ds->ds_link, ds->ds_data,
+	    ds->ds_ctl0, ds->ds_ctl1,
+	    ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
+	    !done ? ' ' : (ts->ts_status == 0) ? '*' : '!'));
+}
+
+/* Process completed xmit descriptors from the specified queue */
+
+static int
+arn_tx_processq(struct arn_softc *sc, struct ath_txq *txq)
+{
+	ieee80211com_t *ic = (ieee80211com_t *)sc;
+	struct ath_hal *ah = sc->sc_ah;
+	struct ath_buf *bf;
+	struct ath_desc *ds;
+	struct ieee80211_node *in;
+	int32_t sr, lr, nacked = 0;
+	struct ath_tx_status *ts;
+	int status;
+	struct ath_node *an;
+
+	for (;;) {
+		mutex_enter(&txq->axq_lock);
+		bf = list_head(&txq->axq_list);
+		if (bf == NULL) {
+			txq->axq_link = NULL;
+			mutex_exit(&txq->axq_lock);
+			break;
+		}
+		ds = bf->bf_desc;	/* last decriptor */
+		ts = &ds->ds_txstat;
+		status = ath9k_hw_txprocdesc(ah, ds);
+
+#ifdef DEBUG
+		arn_printtxbuf(bf, status == 0);
+#endif
+
+		if (status == EINPROGRESS) {
+			mutex_exit(&txq->axq_lock);
+			break;
+		}
+		list_remove(&txq->axq_list, bf);
+		mutex_exit(&txq->axq_lock);
+		in = bf->bf_in;
+		if (in != NULL) {
+			an = ATH_NODE(in);
+			/* Successful transmition */
+			if (ts->ts_status == 0) {
+				an->an_tx_ok++;
+				an->an_tx_antenna = ts->ts_antenna;
+				sc->sc_stats.ast_tx_rssidelta =
+				    ts->ts_rssi - sc->sc_stats.ast_tx_rssi;
+				sc->sc_stats.ast_tx_rssi = ts->ts_rssi;
+			} else {
+				an->an_tx_err++;
+				if (ts->ts_status & ATH9K_TXERR_XRETRY) {
+					sc->sc_stats.ast_tx_xretries++;
+				}
+				if (ts->ts_status & ATH9K_TXERR_FIFO) {
+					sc->sc_stats.ast_tx_fifoerr++;
+				}
+				if (ts->ts_status & ATH9K_TXERR_FILT) {
+					sc->sc_stats.ast_tx_filtered++;
+				}
+				an->an_tx_antenna = 0;	/* invalidate */
+			}
+			sr = ts->ts_shortretry;
+			lr = ts->ts_longretry;
+			sc->sc_stats.ast_tx_shortretry += sr;
+			sc->sc_stats.ast_tx_longretry += lr;
+			/*
+			 * Hand the descriptor to the rate control algorithm.
+			 */
+			if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
+			    (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
+				/*
+				 * If frame was ack'd update the last rx time
+				 * used to workaround phantom bmiss interrupts.
+				 */
+				if (ts->ts_status == 0) {
+					nacked++;
+					an->an_tx_ok++;
+				} else {
+					an->an_tx_err++;
+				}
+				an->an_tx_retr += sr + lr;
+			}
+		}
+		bf->bf_in = NULL;
+		mutex_enter(&sc->sc_txbuflock);
+		list_insert_tail(&sc->sc_txbuf_list, bf);
+		mutex_exit(&sc->sc_txbuflock);
+
+		/*
+		 * Reschedule stalled outbound packets
+		 */
+		mutex_enter(&sc->sc_resched_lock);
+		if (sc->sc_resched_needed) {
+			sc->sc_resched_needed = B_FALSE;
+			mac_tx_update(ic->ic_mach);
+		}
+		mutex_exit(&sc->sc_resched_lock);
+	}
+
+	return (nacked);
+}
+
+static void
+arn_tx_handler(struct arn_softc *sc)
+{
+	int i;
+	int nacked = 0;
+	uint32_t qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
+	ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
+
+	/*
+	 * Process each active queue.
+	 */
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (ARN_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) {
+			nacked += arn_tx_processq(sc, &sc->sc_txq[i]);
+		}
+	}
+
+	if (nacked)
+		sc->sc_lastrx = ath9k_hw_gettsf64(sc->sc_ah);
+}
+
+/* Deferred processing of transmit interrupt */
+
+void
+arn_tx_int_proc(void *arg)
+{
+	struct arn_softc *sc = arg;
+	arn_tx_handler(sc);
+}
--- a/usr/src/uts/intel/Makefile.intel.shared	Tue Jun 30 07:41:21 2009 +0100
+++ b/usr/src/uts/intel/Makefile.intel.shared	Tue Jun 30 15:05:56 2009 +0800
@@ -190,6 +190,7 @@
 DRV_KMODS	+= agpgart
 DRV_KMODS	+= srn
 DRV_KMODS	+= agptarget
+DRV_KMODS       += arn
 DRV_KMODS	+= arp
 DRV_KMODS	+= asy
 DRV_KMODS	+= ata
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/intel/arn/Makefile	Tue Jun 30 15:05:56 2009 +0800
@@ -0,0 +1,94 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+
+#
+#	This file makes the atheros IEEE 802.11n driver for an intel system
+#
+#	intel architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+#
+#	Define the module and object file sets.
+#
+MODULE		= arn
+OBJECTS		= $(ARN_OBJS:%=$(OBJS_DIR)/%) 
+LINTS		= $(ARN_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_DRV_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/intel/Makefile.intel
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
+
+#
+#	Driver depends on GLDv3 & wifi kernel support module.
+#
+LDFLAGS		+= -dy -Nmisc/mac -Nmisc/net80211
+
+LINTTAGS        += -erroff=E_BAD_PTR_CAST_ALIGN
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/intel/Makefile.targ
+
+#
+#	If you have any special case that general
+#	Makefile rules don't serve for you, just do
+#	it yourself.
+#
--- a/usr/src/uts/intel/os/minor_perm	Tue Jun 30 07:41:21 2009 +0100
+++ b/usr/src/uts/intel/os/minor_perm	Tue Jun 30 15:05:56 2009 +0800
@@ -128,6 +128,7 @@
 clone:chxge 0666 root sys
 clone:pcn 0666 root sys
 clone:rtls 0666 root sys
+clone:arn 0666 root sys
 clone:ath 0666 root sys
 clone:atu 0666 root sys
 clone:vnic 0666 root sys
@@ -160,6 +161,7 @@
 chxge:* 0666 root sys
 pcn:* 0666 root sys
 rtls:* 0666 root sys
+arn:* 0666 root sys
 ath:* 0666 root sys
 atu:* 0666 root sys
 vnic:* 0666 root sys